LINUX.ORG.RU

[FFI] CL крут

 


1

3

В каком высокоуровневом языке еще есть такой FFI, или хотя бы возможность его создания?

http://github.com/Lovesan/virgil

//gcc -std=c99 -shared -o virgil_examples[.dll/.so] virgil_examples.c
#include <stdio.h>

typedef void (*matrix_callback)(float* matrix, int m, int n, void* param);

void print_matrix(float* matrix, int m, int n)
{
    for(int i = 0; i<m; ++i)
    {
        for(int j = 0; j<n; ++j)
            printf("%g ", matrix[i*n+j]);
        printf("\n");
    }
}

void foo (float* matrix, int m, int n, matrix_callback f, void* param)
{
    print_matrix(matrix, m, n);
    f(matrix, m, n, param);
}
(deftype matrix () '(simple-array single-float (* *)))

(define-foreign-library virgil-examples
  (t (:default "virgil_examples")))

(use-foreign-library virgil-examples)

(define-external-function "foo"
    (:cdecl virgil-examples)
  (void)
  (matrix (& (simple-array single-float) :inout))
  (m int :aux (array-dimension matrix 0))
  (n int :aux (array-dimension matrix 1))
  (callback pointer)
  (param (& float :in t) :optional void))

(define-callback add-number
    void ((data pointer) (m int) (n int) (param (& float :in t)))
  (with-value (matrix data `(simple-array single-float (,m ,n)) :inout)
    (let ((param (if (voidp param) 0.0 param)))
      (dotimes (i m)
        (dotimes (j n)
          (incf (aref matrix i j) param))))))

(defun main (matrix)
  (declare (type matrix matrix))
  (format t "~&Matrix:~%~a~%" matrix)
  (force-output *standard-output*)
  (foo matrix (get-callback 'add-number) 1.0)
  (format t "~&After processing:~%~a" matrix))
* (defparameter *matrix* (make-array '(4 4) :element-type 'single-float
                           :initial-contents '((1.0  2.0  3.0  4.0)
                                               (5.0  6.0  7.0  8.0)
                                               (9.0  10.0 11.0 12.0)
                                               (13.0 14.0 15.0 16.0))))
;;==> *MATRIX*

* (main *matrix*)
;;на stdout ==>
Matrix:
#2A((1.0 2.0 3.0 4.0)
    (5.0 6.0 7.0 8.0)
    (9.0 10.0 11.0 12.0)
    (13.0 14.0 15.0 16.0))
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
After processing:
#2A((2.0 3.0 4.0 5.0)
    (6.0 7.0 8.0 9.0)
    (10.0 11.0 12.0 13.0)
    (14.0 15.0 16.0 17.0))
Даже питоновский ctypes и рядом не валялся, особенно в плане производительности.

Ответ на: комментарий от archimag

Вон, tailgunner сидит и пишет себе на Python ;) А так затрудняюсь ответить и даже не знаю из чего исходить. Впрочем, я ведь на ЛОРе фактически меньше года активно присутствую и то, только в срачах про CL.

tailgunner - старый, жирный тролль всея ЛОР. Из него выборка нерепрезентативная.

Большинство людей с которыми я знаком и которые реально пишут на CL на ЛОР вообще (почти) не ходят. Собственно, для меня в основном интересны люди, которые не просто «чего-то там изучают», а которые пишут код, так что им можно воспользоваться или которые могу прислать патч на что-то. Я ведь тоже PHP для общего развития изучал, но только толку от меня для PHP-сообщества ноль.

Кроме ЛОРа люди ведут дневники, общаются на форумах, создают шумовой фон в интернетах. Я уверен, что омереканский ЛОР (/.) в становлении лиспа второй волны сыграл достаточно много роли. В России в принципе активность тухлая в любой области, кроме распила народного бабла.

mv ★★★★★
()
Ответ на: комментарий от Reaper

> Никому они не повредили.

но и пользы от них 0.0, лучше бы что-то практическое обсуждали - и толку больше и почитать интересно

anonymous
()
Ответ на: комментарий от shty

4.2 нормальным композиторам (а не «крутым» всяким) вообще-то инструмент только мешается, они сочиняют в голове и записывают нотками и для того чтобы «услышать» произведение им достаточно посмотреть в ноты

Угу, угу. Я пишу такие прекрасные программы на лиспе, да в таких огромных количествах, но вот вы, почему-то, хором говорите, что я на кастрюле стучу.

и тот же приведённый Вами в качестве примера Бетховен, который оглох в конце пути, но таки дописал, этому прекрасная иллюстрация

Ну да, без инструмента у него слух музыкальный вообще бы не развился. Рояль под старость у него в голове уже стоял, поэтому он мог глухим работу завершить (с ошибками, кстати, как говорят профи).

mv ★★★★★
()
Ответ на: комментарий от Reaper

> Фигня это и занудство про вред от холиваров. -)

Никому они не повредили.


Ещё сколько вреда. Ибо создают неверное впечатление о языке. Например, тут часто встречается мнение, что CL надо пилить под себя и только после этого им можно пользоваться. Или люди начитавшись всяких «сказок» пытаются как-то применить это на практике и обнаруживают, что более традиционные подходы работают лучше, т.е. их просто обманули, а это, естественно, убивает желание разбираться дальше. Всё дело в том, что «пропагандой» занимаются люди, которые сами не занимаются реально разработкой на CL.

Количество тем о CL в development зашкаливает и это почти всегда однотипный срач.

archimag ★★★
()
Ответ на: комментарий от mv

4.2 нормальным композиторам (а не «крутым» всяким) вообще-то инструмент только мешается, они сочиняют в голове и записывают нотками и для того чтобы «услышать» произведение им достаточно посмотреть в ноты

Угу, угу. Я пишу такие прекрасные программы на лиспе, да в таких огромных количествах, но вот вы, почему-то, хором говорите, что я на кастрюле стучу.

приведите ссылки, а то я Ваших сентенций не розумiю

и тот же приведённый Вами в качестве примера Бетховен, который оглох в конце пути, но таки дописал, этому прекрасная иллюстрация

Ну да, без инструмента у него слух музыкальный вообще бы не развился.

музыкальный слух - это просто-напросто способность запоминать набор нот из музыкального произведения, одним нужно развивать, у других - абсолютный (кстати FYI различают горизонтальный и вертикальный слух)

Рояль под старость у него в голове уже стоял, поэтому он мог глухим работу завершить (с ошибками, кстати, как говорят профи).

ну когда те «профи» перестанут завидовать и напишут что-нибудь своё подобного уровня тогда с ними можно будет поговорить

shty ★★★★★
()
Ответ на: комментарий от simplex

А почему сразу «завидовать»?

не знаю, может потому что люди вообще завистливы, может потому что у некоторых золотые годы уже прошли, а вроде и оставить нечего после себя, а вообще - спросите у них :)

Вы знаете, к примеру, что Скрябин - классик, великий и признанный всеми кем только можно композитор так и не закончил консерваторию по классу композиции :) прочему, как думаете?

shty ★★★★★
()
Ответ на: комментарий от Love5an

>Мне даже вонючий EDI смотреть не надо:

На заборе тоже *** написано, а там дрова. Обсуждать выравнивание с некомпетентным фанатиком не считаю сколь-нибудь интересным.

linuxfan
()
Ответ на: комментарий от mv

>Человек в теме, глядя на результаты, удивляется и спрашивает себя: «А чего это лисп такой быстрый?».

еще раз прочитай мое сообщение. мой посыл о том, что чудес не бывает и заявление топистартера о том что КЛ ацки быстр и всех рвет некорректно. будь он таким быстрым и удобным мы бы не сидели сейчас на питонах, явах, плюсах и иже с ними. я не говорю что КЛ тормоз, я говорю, что он не может быть быстрее всех в то гипотетическое количество раз, о котором заявлено в самом начале треда.

или ты все равно считаешь что КЛ быстрее ЦПУ байтики перемалывает?

скорость определяет в первую очередь алгоритм и во второй степени парадигма языка.

Deleted
()
Ответ на: комментарий от Deleted

ах, ну да, куда уж нам до ваших высот :)

Я в срачах, по тематике которых не шарю, не участвую.

mv ★★★★★
()
Ответ на: комментарий от Deleted

> будь он таким быстрым и удобным мы бы не сидели сейчас на питонах,

Вот как раз питон значимо отстаёт от SBCL, который по скорости сопоставим с жабой и крестами. И распространённость питона показывает, что максимальная скорость исполнения важна далеко не всегда.

ugoday ★★★★★
()

Да, и особенно отсутствие синтаксиса record.field «радует».

(deftype matrix () '(simple-array single-float (* *)))
Неправильно продвигаешь. Надо напирать на возможность полуавтоматической генерации биндингов. CFFI-grovel и всё такое.

den73 ★★★★★
()
Ответ на: комментарий от ugoday

> Вот как раз питон значимо отстаёт от SBCL, который по скорости

сопоставим с жабой и крестами.

Насчёт первого согласен, второе весьма спорно. Если полностью вылизать лисповый код, напихав везде декларации типов, он будет сопоставим. В среднем же, в библиотеках нет избытка деклараций типов, преобладает тип t. Какова при этом скорость - не знаю. Хеш-таблицы также проблематичны - они требуют перехеширования после сборки мусора, поэтому, чем больше выделено объектов в куче, тем медленнее программа будет работать.

Питон с его убогим дизайном, конечно, не конкурент, а вот я думаю, что средняя программа на С будет заметно быстрее.

den73 ★★★★★
()
Ответ на: комментарий от den73

>отсутствие синтаксиса record.field «радует».
Кому это надо нахрен, кроме совсем покалеченных на голову сями/плюсами/жабой/прочим говном? В CL это никому не надо. Хотя бы потому, что есть with-accessors и сопутствующее.

Надо напирать на возможность полуавтоматической генерации биндингов. CFFI-grovel и всё такое.

Чукча не читатель? FFI(то, что у меня) и Groveller - вещи довольно перпендикулярные. К тому же, на первой странице это уже обсосали.

Love5an
() автор топика
Ответ на: комментарий от Love5an

> В CL это никому не надо.
И посему CL представляет из себя секту. Есть правила стиля речи или, если угодно, правила сжатия информации при передаче. Лисперы, по моему мнению, должны обладать достаточным интеллектом и склонностью к обобщению, чтобы попытаться применить эти принципы (весьма общие) к своему языку программирования. Ведь недаром, недаром неопределённый артикль в английском языке записывается как «a», а не как «multiple-value-bind».

Если известно, что речь идёт о таком-то рекорде, то нет смысла в многократном повторении его имени. with-accessors в случае рекордов работает тухло (проверялось в своё время), во всяком случае, это так в некоторых реализациях CL. А классы вообще зачастую работают тухло. Так что выбирать остаётся не из чего. Что касается with-accessors, то необходимость перечислять слоты сводит всё удобство на нет, если к полю нужно обратиться один или два раза. В «покалеченных» языках достаточно один раз написать имя типа при объявлении переменной и всё.

На практике же, лисперы этого не понимают несмотря на всю очевидность. И в этом состоит покалеченность головы лисперов :P

FFI(то, что у меня) и Groveller - вещи довольно перпендикулярные.

Я не силён в FFI. Один раз, по сути, пользовался Groveller-ом, когда баловался с fuse. Основная трудность, как выяснилось - это #define в исходниках ядра, их и Groveller не особо-то берёт. Тяжело это было, в итоге без ручного труда всё же не обошлось и не получилось написать переносимо, пришлось кое-где выкапывать значения #define и куда-то там их ручками прописывать. А тему с начала, да, не читал, зачем, таких тем много, и в них главное - это самому пофлудить :-) Я тут в виде пятой колонны как бы выступаю. А вообще, пора спать!

den73 ★★★★★
()
Ответ на: комментарий от den73

>В среднем же, в библиотеках нет избытка деклараций типов, преобладает тип t.
«Средняя температура по больнице»?

Собственно, одна из вещей, которые я хотел показать на примере этого FFI, и о чем уже заикался на первых страницах - в лиспе абстракции совсем не обязательно влекут издержки производительности. В отличие от всех других языков, в которых нет такой продвинутой макросистемы.

В жабе же и плюсах, которые, несомненно, на базовом уровне очень эффективны, за счет статической типизации и достаточной близости к железу, каждая малейшая абстракция(классы, паттерны etc.) обязательно добавляет некоторый оверхед в рантайме. В некотором конкретном случае, в каком-нибудь хелловорде, например, этот оверхед может быть, конечно, достаточно мал, чтобы его можно было не замечать. Но учитывая склонность программистов(или даже не то, чтобы программистов, просто сами языки к этому толкают) на жабе к нагромождению иерархий классов и паттернов, и программистов на С++(да и на Си, вообще-то, если тот используется не по назначению[системное программирование] - как например в gtk) - к нагромождению костылей и заплаток, можно констатировать, что эту самую их «базовую эффективность» можно наблюдать только разве в синтетических тестах и хелловордах.

Love5an
() автор топика
Ответ на: комментарий от den73

>Лисперы, по моему мнению, должны обладать достаточным интеллектом и склонностью к обобщению, чтобы попытаться применить эти принципы (весьма общие) к своему языку программирования. Ведь недаром, недаром неопределённый артикль в английском языке записывается как «a», а не как «multiple-value-bind».

Какие принципы? При чем тут артикли? У тебя шизофрения или ты просто любишь скушать интересных таблеток на ночь?

>И посему CL представляет из себя секту.

И в эту секту тебя, надо понимать, не приняли? И именно поэтому ты теперь при каждом удобном, и не очень, случае жалуешься на то, какие лисперы плохие, айайай, не хотят поменять стандарт и зделать как в крузисе добавить возможность доступа к структурам через точку, как в моднявых мейнстримных языках с сиподобным(или паскалеподобным) синтаксисом?

>with-accessors в случае рекордов работает тухло (проверялось в своё время), во всяком случае, это так в некоторых реализациях CL.

WITH-ACCESSORS это тривиальнейший макрос. Чему там работать «тухло», я понять в принципе не могу. Ну, нехер пользоваться заброшенными реализациями, которые даже стандарт CL на тему символьных макросов осилить не могут.

>А классы вообще зачастую работают тухло. Нехер пользоваться древними, не работающими, и не поддерживаемыми реализациями.

>Если известно, что речь идёт о таком-то рекорде, то нет смысла в многократном повторении его имени.

Я тебе сейчас тааакой секрет открою, только никому не говори. Даже два. Первый такой - опция :CONC-NAME в DEFSTRUCT.

Второй такой:

В CL динамическая типизация. Реализация доступа через «точку» в языках с динамической типизацией требует как минимум динамической(ран-тайм) проверки типа структуры.

Объекты, классы которых определяются с помощью DEFSTRUCT в основном используются в местах, критичных к производительности(в местах, где использовать жирные и тормозные CLOS-объекты очень нежелательно), т.е. в таких местах, где динамический lookup типа структуры и положения слота при каждом обращении к оному добавил бы много нежелательного оверхеда. Это, фактически, чуть ли не единственная причина, по которой defstruct-объекты находятся в стандарте CL(вторая - совместимость со старыми лиспами)(вообще говоря, в стандарте присутствует довольно много вещей, учитывающих тонкие(да и толстые) моменты производительности приложений на лиспе в «реальном мире», и в т.ч. за это мне CL и нравится, в отличие от Схемы той же). Поэтому для доступа к их слотам DEFSTRUCT при компиляции генерирует функции(да и не обязательно даже функции), в которых алгоритм доступа к определенному слоту определенной структуры захардкожен. А это позволяет крайне эффективный доступ к слотам, особенно если функции инлайнятся, буквально настолько же эффективный, как и доступ к полям структуры в Сях.

«Динамический» же доступ в CL используется для слотов объектов CLOS-классов. Только оператор аналогичный, скажем, питоновскому оператору ".", в CL называется «SLOT-VALUE», и записывается, как и все в лиспе, в префиксной форме. Но я тебе лично разрешаю его переименовать в «DOT», или даже в "->".

Надеюсь, я по этой теме достаточно объяснил? Потому что в следующий раз на нытье про «нету доступа через точку» я буду отвечать матом.

Love5an
() автор топика
Ответ на: комментарий от Love5an

А чего CL Обязательно учить может он другой ЯП знает луче чем ты свой CL
и судя по теме ты как сам себя пеариш

enep ★★★★★
()
Ответ на: комментарий от baverman

Ты мне сейчас делфикодера напоминаешь. Он, при наличии компонента TEditor простой текстовый редактор меньше чем за минуту накидает. А если TOs есть, то и операционную систему.

ugoday ★★★★★
()
Ответ на: комментарий от ugoday

А ты, при наличии готовой библиотеки, всегда свои велосипеды строчишь?

Назови три причины, почему я не должен использовать чужой код? Причем, этот код хорошо протестирован и отдокументирован? Hint: это опять риторический вопрос ведь вам и не понять чуда кодреюза.

Ну нет в CL каких-то совсем уж крутых штук, по сравнению с питоном, чтоб заставить меня лисапедить на каждый чих.

baverman ★★★
()
Ответ на: комментарий от baverman

> Ну нет в CL каких-то совсем уж крутых штук, по сравнению с питоном,

чтоб заставить меня лисапедить на каждый чих.


Это сильно зависит от того, чем вы занимаетесь. Я тут уже говорил, что в качестве всеядного скриптого комбайна сравниться с Python CL не может. Но для выбранной конкретной области ситуация может оказаться иной. В частности, для тех веб-приложений, которыми я сейчас занимаюсь, разработка на CL будет намного более эффективной, чем на Python. Что бы в конкретной области CL стал превосходить Python по удобству разработки нужны относительные небольшие усилия одного или нескольких человек. Если вы постоянно работаете по «широкому» фронту, то в этом, конечно, немного смысла.

archimag ★★★
()
Ответ на: комментарий от archimag

Если вы постоянно работаете по «широкому» фронту, то в этом, конечно, немного смысла.

Очень правильная формулировка, применительно ко мне. GUI, web, парсинг, мелкие скрипты, автоматизация тестирования и управления билдами.

baverman ★★★
()
Ответ на: комментарий от baverman

> GUI, web, парсинг, мелкие скрипты, автоматизация тестирования

и управления билдами.


Ну, скажем, с web и парсингом сейчас в CL вроде более-менее нормально. Про GUI не скажу, ибо c cl-gtk2 реально не работал. Ну а для автоматизации тестирования и управления билдами я бы юзал что-нибудь вроде SCons, CL туда тащить совершенно не к чему.

archimag ★★★
()
Ответ на: комментарий от den73

> Если полностью вылизать лисповый код, напихав везде декларации типов, он будет сопоставим. В среднем же, в библиотеках нет избытка деклараций типов, преобладает тип t. Какова при этом скорость - не знаю.

если по уму, нужно что-то вроде gradual typing делать: google://«gradual typing» http://lambda-the-ultimate.org/node/1707 http://ecee.colorado.edu/~siek/gradualtyping.html . Для питона, руби и дилана уже сделали. Не думаю, что для коммон лиспа сильно сложнее будет.

anonymous
()

В Racket FFI повеселее смотрится:

#lang racket
(require ffi/unsafe)

(define ffi-test (ffi-lib "ffi_test.dll"))

(define _mcall
  (_fun #:keep #f (_vector io _float (* m n)) (m : _int) (n : _int) (_or-null (_ptr i _float)) -> _void))

(define print-matrix 
  (get-ffi-obj 'print_matrix ffi-test 
               (_fun (matr : (_vector io _float (* m n))) (m : _int) (n : _int) -> _void -> (displayln matr))))

(define foo
  (get-ffi-obj 'foo ffi-test
               (_fun (_vector io _float (* m n)) (m : _int) (n : _int) _mcall (_or-null (_ptr i _float)) -> _void)))

(define (add-number matrix m n param)
  (for* ([i (in-range m)]
         [j (in-range n)])
    (let ([pos (+ j (* i m))])
      (vector-set! matrix pos 
                   (+ (vector-ref matrix pos) 
                      (if param param 0))))))

(define matr (vector 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0))

(define (main m)
  (print-matrix m 4 4)
  (add-number m 4 4 100)
  (print-matrix m 4 4))
Добро пожаловать в DrRacket, версия 5.0.2 [3m].
Язык: racket [выбранный].
> (main matr)
#(1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0)
#(101.0 102.0 103.0 104.0 105.0 106.0 107.0 108.0 109.0 110.0 111.0 112.0 113.0 114.0 115.0 116.0)
> 

anonymous
()
Ответ на: комментарий от den73

> Есть правила стиля речи или, если угодно, правила сжатия информации при передаче. Лисперы, по моему мнению, должны обладать достаточным интеллектом и склонностью к обобщению, чтобы попытаться применить эти принципы (весьма общие) к своему языку программирования. Ведь недаром, недаром неопределённый артикль в английском языке записывается как «a», а не как «multiple-value-bind».

в этом плане весьма разумными выглядят мысли David Moon о PLOT:
http://users.rcn.com/david-moon/PLOT/ . Там по ангельски: def fib(x is integer), defproto forall (c as collection), и т.п.
Я только не понял, этот PLOT — концепт или где-то скачать можно рабочий конпелятор?

anonymous
()
Ответ на: комментарий от anonymous

> PLOT — концепт или где-то скачать можно рабочий конпелятор?

концепт

paranonymous
()
Ответ на: комментарий от Love5an

> В CL динамическая типизация. Реализация доступа через «точку» в языках с динамической типизацией требует как минимум динамической(ран-тайм) проверки типа структуры.

не всегда и не везде требует. Во-первых, google://«predicate dispatch» http://www.cs.ucla.edu/~todd/research/oopsla04.pdf http://www.cs.ucla.edu/~todd/research/oopsla04.html http://www.cs.washington.edu/homes/mernst/pubs/dispatching-ecoop98-abstract.html ftp://publications.ai.mit.edu/ai-publications/2001/AITR-2001-006.pdf http://lambda-the-ultimate.org/node/356

 — вывод, такие проверки (динамические, в ран-тайме) в большей части можно вынести «за скобки» какого-то предиката, вычисляемого/обновляемого в компайл-тайме или в некоторых местах в рантайме (а не всех, как было ранее).

Во-вторых, gradual typing — как перейти от динамической типизации к статической через опциональные аннотации типов и вывод типов по этим аннотациям. См. ссылки выше.

В-третьих, проверки на тип структуры в некоторых случаях могут быть сильно ускорены (булевы предикаты, bloom-фильтры на булевы матрицы, и т.п.). Сюда же tagged pointer и т.п.

в таких местах, где динамический lookup типа структуры и положения слота при каждом обращении к оному добавил бы много нежелательного оверхеда. Это, фактически, чуть ли не единственная причина, по которой defstruct-объекты находятся в стандарте CL


а) именно при каждом обращении — не нужно
б) костыль, однако. defstruct-объекты как pod vs. CLOS-объекты — это «предварительная оптимизация»
в) а был ли оверхед, в реальном приложении — это ещё ХЗ, смотреть надо профилятором

anonymous
()
Ответ на: комментарий от anonymous

> если по уму, нужно что-то вроде gradual typing делать: google://«gradual typing» http://lambda-the-ultimate.org/node/1707 http://ecee.colorado.edu/~siek/gradualtyping.html . Для питона, руби и дилана уже сделали. Не думаю, что для коммон лиспа сильно сложнее будет.

Таки в sbcl вывод есть твой самый gradual typing - динамическая типизация с опциональной декларацией типов и вывод варнингов, ошибок, с случае, если есть ошибки типизации.

paranonymous
()
Ответ на: комментарий от anonymous

> вывод, такие проверки (динамические, в ран-тайме) в большей части можно вынести «за скобки» какого-то предиката, вычисляемого/обновляемого в компайл-тайме или в некоторых местах в рантайме (а не всех, как было ранее).

можно и они выводятся за скобки компилятором. Если компилятор не может вывести - все долго и в рантайме.

paranonymous
()
Ответ на: комментарий от archimag

положим, вдруг не нравится тебе то, что в лиспе динамическая типизация, и ты, борясь с ветряными мельницами, решаешь перейти к статической, потому что «она быстрее» (если честно, ещё хз, быстрее ли в реальном приложении, также как хз, быстрее ли конпелятор vs. интерпретатор в каком-нибудь сильно динамичном коде который надо раз исполнить, выкинуть и забыть).
Варианты:
а) обнести всё декларациями типов, используя макросы. Вывод типов отсутствует, нужно расставлять вручную
б) взять штангу
в) постепенно, расставив опциональные декларации там, где это критично, используя «умный конпелятор» и вывод типов, перейти от динамической типизации к статической в этих местах. Это gradual typing.

anonymous
()
Ответ на: комментарий от anonymous

> не всегда и не везде требует. Во-первых, google://«predicate dispatch»

Как это вообще связано-то, а? Предикатный диспатчинг, который кстати делается в клос фактически в 10 строк, и проверка типа при диспатчинге по классам?

paranonymous
()
Ответ на: комментарий от anonymous

> а) обнести всё декларациями типов, используя макросы. Вывод типов отсутствует, нужно расставлять вручную

Есть вывод типов - в sbcl, успокойся уже.

paranonymous
()
Ответ на: комментарий от den73

>В среднем же, в библиотеках нет избытка деклараций типов, преобладает тип t.

Ну не знаю... По «CL-малолетсву» в качестве CL-практиканства именно что и делал, что ползал по библиотекам, выискивал не оттипизованные места (которые можно/нужно было типизировать) и предлагал патчи. Конечно, о сотнях библиотек речь не идёт, от силы просмотрел дюжины полторы тех, что мне были интересны. На сколько мне не изменяет память, патчи отправил (и их приняли) в проектов 5, не более. Да и то количество изменений в каждом исчислялось максимом десятком-двумя.

Ну да, «выборка не репрезентативна» :)

yyk ★★★★★
()
Ответ на: комментарий от paranonymous

А ты подумай. Проверка типа — это вычисление предиката на соответствие типу. Мультидиспетчеризация, диспетчеризация по типу первого (vtable), :around, :before, :after, контракты (с натяжной, тут нет диспетчеризации, или диспетчеризация в «ошибку компиляции») и исключения/условия (по аналогии с контрактами, только в рантайме) — это всё частные случаи predicate dispatch, с разными предикатами (которые большей частью можно посчитать во время компиляции)

anonymous
()
Ответ на: комментарий от anonymous

> это всё частные случаи predicate dispatch, с разными предикатами (которые большей частью можно посчитать во время компиляции)

Нельзя.

paranonymous
()
Ответ на: комментарий от anonymous

> это всё частные случаи predicate dispatch, с разными предикатами

(которые большей частью можно посчитать во время компиляции)


На самом деле есть большое несоответствие между максимально возможными оптимизациями на этапе компиляции и интерактивной разработкой, во время которой постоянно меняется код и предположения, верность которых не вызывала сомнений, вдруг обесцениваются.

Время компиляции в подавляющем числе случаев совпадает со временем разработки, т.е. её нельзя трактовать как просто стадию обработки кода. Код правят и тут же компилирует, небольшими кусочками. И система должна продолжать вести себя правильно.

Вообще, рассматривая языковые свойства никогда нельзя упускать из виду роль и значение REPL.

archimag ★★★
()
Ответ на: комментарий от baverman

> А ты, при наличии готовой библиотеки,

baverman, ты решил помериться количеством библиотек? Тогда иди и сделай приятное жабофилам.

ugoday ★★★★★
()
Ответ на: комментарий от paranonymous

можно. Если у тебя есть вся полная требуемая информация о типах из аннотаций. Из этих аннотаций можно вывести теорему и доказать её в compile time.
Этим примерно и отличается gradual typing от того что в sbcl — что по семантике что-то можно вывести и доказать, то что требуется твоим предикатам, а не то, что встроено в sbcl.

anonymous
()
Ответ на: комментарий от anonymous

> Из этих аннотаций можно вывести теорему и доказать её в compile time.

После этого разработчик перекомпилировал какой-либо из кусков кода, доказательство оказалось неверным и система упала с непонятным сообщением об ошибке.

archimag ★★★
()
Ответ на: комментарий от anonymous

> можно. Если у тебя есть вся полная требуемая информация о типах из аннотаций. Из этих аннотаций можно вывести теорему и доказать её в compile time.

бугага, еще один начинающий штангист неосилятор. Неужто можно решить задачу вывода типов для систем сложнее System F?

Этим примерно и отличается gradual typing от того что в sbcl — что по семантике что-то можно вывести и доказать, то что требуется твоим предикатам, а не то, что встроено в sbcl.

Дооо, иди дочитай душкина, а потом приходи на лор. Для динамической типизации нет задачи «вывода типов» - она уже решена, если у нас есть тип общий тип t. Ладно, заканчиваю с тобой спор, ибо это бесполезно.

paranonymous
()
Ответ на: комментарий от anonymous

Это не аналог.

(add-number m 4 4 100)

Должно быть:

(foo m 4 4 add-number 100)

И во-вторых, должна быть матрица.

Love5an
() автор топика
Ответ на: комментарий от ugoday

Тогда иди и сделай приятное жабофилам.

Когда писал на жабе, тоже не лисапедил это да. Очень приятное время было. Спасибо, ностальгия, эх.

baverman ★★★
()

Должно быть: > (foo m 4 4 add-number 100)

Да, действительно. Невнимательно прочитал.

И во-вторых, должна быть матрица.

Ну, во-первых, матрица в Ракете, насколкьо я знаю, отмаршалится в **float, так что код будет опять не аналогичен, а во-вторых, матрица/вектор/что там еще - к ffi отношения не имеет, это уже вопрос наличия конкретных лисповых инструкций и врапперов к обычным лисповым функциям, которые будут выступать в качестве коллбеков. В ракете подход несколько иной, чем у тебя - вместо реализации отдельных конструкций предоставляется DSL-подобный механизм расширения уже имеющейся системы, так что это будет выглядеть как-то так (чисто для примера, по-этому матрица представляется самым прсотым способом - списком из размерностей и вектора):

#lang racket
(require ffi/unsafe)
(require ffi/cvector)

(define ffi-test (ffi-lib "ffi_test.dll"))

(define _mcall
  (_fun #:keep #f (matrix m n param) :: 
        (_gcpointer = (cblock->vector matrix _float (* m n)))
        (m : _int) 
        (n : _int) 
        (_gcpointer = (ptr-ref param _float)) 
        -> _void))

(define foo
  (get-ffi-obj 'foo ffi-test
               (_fun (matrix f param) ::
                     ((_vector io _float (* m n)) = (cadr matrix))
                     (m : _int = (caar matrix)) 
                     (n : _int = (cadar matrix)) 
                     (f : _mcall) 
                     (param : (_ptr i _float)) 
                     -> _void)))

(define (add-number matrix m n param)
  (for* ([i (in-range m)] 
         [j (in-range n)])
    (let ([pos (+ j (* i m))])
      (vector-set! matrix pos 
                   (+ (vector-ref matrix pos) 
                      (if param param 0)))))
  (displayln matrix))

(define matr `((4 4) ,(vector 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0 11.0 12.0 13.0 14.0 15.0 16.0)))

(foo matr add-number 100.0)

anonymous
()
Ответ на: комментарий от paranonymous

> сложнее System F

Зачем тут «сложнее System F»? Под системой типов я понимаю $\lambda_{\rightarrow}^{?\alpha}$ , то есть, polymorphic gradually typed lambda calculus , под «выводом типов» — unification-based inference.
Под «можно вывести теорему в compile-time» — подразумевается, что ill-typed terms не принимаются, и случаи «теорема обломалась», «теорема не вычислима в compile time» решаются диспетчеризацией в «большую красную кнопку» на этапе разработки, вроде юнит-тестов.
Под «частными случаями, которые можно посчитать в compile time» — понимается не все абстрактные типы лямбда-куба в раёне правого верхнего его угла, а практически полезные приёмы для оптимизации тех мест, где «динамическая диспетчеризация тормозит» (если она вообще тормозит), вроде выбора, какая ООП система будет эффективнее в данной ситуации, vtable (генерируемая автоматически, по предикатам, а не жёстко заданной иерархией) или clos (и динамика).

для динамической диспетчеризации нет задачи вывода типов она уже решена у нас есть общий тип t


она решена, скажем так, неэффективно. И решена как компромис между вычислением чего-то частично в рантайме, частично во время компиляции. Дык вот, смысл не в том чтобы всё полностью переложить на время компиляции (что потребует вывод всех типов), а в том, чтобы практически оптимизировать только выгодные места. Не выводя типы там где не надо.

anonymous
()
Ответ на: комментарий от anonymous

> она решена, скажем так, неэффективно

На основании чего сделан такой вывод? Какие проблемы с производительностью программ на CL вы имеете? Подтверждаются ли ваши вывода профайлером?

а в том, чтобы практически оптимизировать только выгодные места.

Не выводя типы там где не надо.



Хм, а разве сейчас делается не так?

archimag ★★★
()
Ответ на: комментарий от archimag

Расскажите лучше, как вы рефакторите библиотеки. У меня (да и у всех, думаю), поначалу новая функция пихается куда попало, а потом наступает время сортировки по пакетам. Как это делать?

anonymous
()
Ответ на: комментарий от anonymous

> Зачем тут «сложнее System F»?

Не знаю, в хаскелле зачем-то понадобилась :) Да и вообще system F, всясечкие типизированные лямбда исчисления и полновесный вывод типов вообще никак не ложится на системы с eval и хитрым ООП, т.е. к реально существующим динамическим и не только языками, не имеющим под собой сухого математического формализма, слабо относятся. А значит, нужны только штангистам.

Под «можно вывести теорему в compile-time» — подразумевается, что ill-typed terms не принимаются, и случаи «теорема обломалась», «теорема не вычислима в compile time» решаются диспетчеризацией в «большую красную кнопку» на этапе разработки, вроде юнит-тестов.

Да ладно, ты думаешь в обычном компиляторе это не оптимизируется и не используется? Ты думаешь sbcl не способен вызов метода оптимизировать сразу на нужный метод, если при компиляции известен класс? И что не предупредит о возможных ошибках типизации? Ты глубоко ошибаешься.

она решена, скажем так, неэффективно. И решена как компромис между вычислением чего-то частично в рантайме, частично во время компиляции. Дык вот, смысл не в том чтобы всё полностью переложить на время компиляции (что потребует вывод всех типов), а в том, чтобы практически оптимизировать только выгодные места. Не выводя типы там где не надо.

Что за бред? Почему не вывести типы везде, где это можно?

paranonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.