LINUX.ORG.RU

clojure после common lisp - насколько омерзительно и в чём именно?

 , ,


3

2

Всё ещё думаю о возможности заняться разработкой на clojure. Но ява же тормозная - меня бесит скорость сборки. Вот боюсь, как бы кложа не оказалась слишком уж тормозной.

Расскажите о своих ощущениях (из серии «собираюсь жениться - отговорите»).

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

Если в программе ошибок нет, то будет продолжать работать также.

А если ошибки есть, то всё развалится в рантайме или программа не соберётся? Мне кажется, что тут и проходит разница, хотя понимаю, что можно поспорить.

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

Так на дворе 2021 уже.

Ну я не в том плане, что это доступно только избранным (хотя мы, кажется, до сих пор на С++14 сидим). Но всё-таки это до относительно недавнего времени это не был бы однострочник.

Там есть функции с initializer_list, то есть те же произвольные аргументы, но в фигурных скобках: min, max, вектора всякие, …

Начинаю забывать о чём мы «спорим». Но типизируются же большинство этиx штук ведь нормально?..

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

А если ошибки есть, то всё развалится в рантайме или программа не соберётся?

Если ошибки статически доказуемы, то не соберётся (в смысле будет Warning). Если нет, например, код `(+ (read) (read)), то может упадёт (именно + не упадёт, просто просуммирует нечто переданное, как если бы это были числа, а если, наоборот, вместо списка дать число, то упадёт). В общем, что будет, если (void*) привести не неверному типу?

P.S. Статически недоказуемые ошибки есть и во многих статически типизированных языках. В Си они называются UB.

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

printf «…» возвращает некий r, имеющий класс PrintfType.

Этот r может быть строкой или функцией a -> r, где a имеет класс PrintfArg, а r - снова PrintfType.

Таким образом, количество аргументов определяет какие типы инстанцируются.

Для простоты вот sum от произвольного числа аргументов

{-# LANGUAGE FlexibleContexts #-}

class SumRes r where 
    sumOf :: Integer -> r

instance SumRes Integer where
    sumOf = id

instance (Integral a, SumRes r) => SumRes (a -> r) where
    sumOf x = sumOf . (x +) . toInteger
*Main> sumOf 1 2 4 5
12
monk ★★★★★
()
Ответ на: комментарий от DarkEld3r

Начинаю забывать о чём мы «спорим». Но типизируются же большинство этиx штук ведь нормально?..

Я контрпримеры привожу против тезисов: «Правда остаётся ограничение на всего два аргумента, но тут уже особенность лиспов, кроме них мало какой (никакой?) язык такое позволяет.» и «польская нотация способствует появлению функций, которые работают с произвольным количеством аргументов. В С++ такая sum разве что при кодогенерации полезна будет».

Типизируется оно даже в Haskell (хотя там, конечно, вариант для «сильных программистов»).

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

Ну нет. Из коробки - это именно «есть в языке» (ну или стандартной библиотеке).

С таким подходом в С/С++/Rust в отличие от Racket нет GUI. И нет сети.

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

Статически недоказуемые ошибки есть и во многих статически типизированных языках.

Понимаю, но на мой взгляд «отключаемые проверки типов» (или предупреждения вместо ошибок) - плохая идея. Но да, свой «unsafe» в том или ином виде много где есть и в расте тоже можно «привести void* не к тому типу», так что на эту тему продолжать спорить не буду.

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

Я контрпримеры привожу против тезисов: «Правда остаётся ограничение на всего два аргумента, но тут уже особенность лиспов, кроме них мало какой (никакой?) язык такое позволяет.»

Тут я действительно ухватился за частный случай (сложение).

«польская нотация способствует появлению функций, которые работают с произвольным количеством аргументов.

А вот тут всё равно не переубедил. (:

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

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

С таким подходом в С/С++/Rust в отличие от Racket нет GUI. И нет сети.

Ну да, нет, ничего не поделаешь. Это не обязательно плохо: вон в джаве аж несколько GUI из коробки и все плохие. В расте, кстати, и со сторонними библиотеками в этом плане всё печально.

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

«отключаемые проверки типов» (или предупреждения вместо ошибок) - плохая идея

Так в случае лиспа это неустранимо. Вот программа:

(defun add (n)
        (+ n  1))

(defun bad-concat (n)
      (concatenate 'string (add n)))

выдаёт предупреждение, что add возвращает число, а concatenate ожидает строку.

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

(setf (symbol-function '+)
   (let ((old (symbol-function '+)))
      (lambda (&rest r)
        (if (stringp (car r)) 
            (apply #'concatenate 'string 
                   (mapcar (lambda (x) (format nil "~a" x)) 
                           r))
            (apply old r)))))

(bad-concat "ok")
monk ★★★★★
()
Ответ на: комментарий от DarkEld3r

В расте, кстати, и со сторонними библиотеками в этом плане всё печально.

???

gtk-rs, rust-qt, wxRust, … разве мало?

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

gtk-rs, rust-qt, wxRust, … разве мало?

Я из тех, кто из перечисленного только Qt воспринимает всерьёз для кроссплатформенного GUI. А с Qt у раста всё не очень хорошо: rust-qt весь обмазан ансейфом, причём не внутри (что было бы нормально для байндингов), а в пользовательском коде. Байдинги для qml какие-то полудохлые.

В любом случае, хотелось бы «более нативного» решения (как у Racket). Попытки сделать такое есть, но до юзабельного состояния далеко.

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

Его в статических языках нет, а его функцию выполняет либо указатель на область памяти либо контейнер

В C# разве нет нормального Any? dynamic там или просто object.

Также и с тайпхинтами: сначала документация, потом статические анализаторы, потом поддержка компилятором для оптимизации

Если тайп хинты начинают обладать какими-то отличными свойствами от документирования - проверка / вывод типов, оптимизации etc на уровне компилятора (а не внешних утилит), то это уже декларация типов. Как в CL, изначально может быть запланирована чисто для оптимизации, но затем обрасти фичами.

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

В лиспе можно в любой момент переопределить тип, класс, функцию, сделать любой побочный эффект (даже при компиляции).

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

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

в Yahoo как раз заявляли, что не смогли найти достаточно людей для поддержки и развития кодовой базы на лиспе

Заявить можно все что угодно, ты уверен что многомиллионная компания (сотни миллионов или миллиарды капитализации на тот момент) не смогла среди 6 млрд человек найти 10 лисперов для поддержки проекта? С такими ресурсами, если бы лисперов даже не существовало, их можно было бы взрастить с нуля.

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

Делает. Если появится хоть один фреймворк, активно использующий этот тип, любая программа на нём не будет существенно отличаться от программы на языке с динамической типизацией.

Активно это сколько в килограммах? Если есть возможность локализовать использование Any, то программа не будет похожа на динамически типизированную (в самой возможности я сомневаюсь). Но и в случае, когда весь фреймворк / библиотека завязана на Any в том смысле, что много где нельзя вывести типы, то декларации в других местах все же остаются и работают как минимум там, где нет взаимодействия с Any - а это и есть подход динамической среды с опциональной типизацией. В больших программах на С++ кругом используются указатели на void и подобная Any-заменительная эквилибристика. Перестают ли они от этого быть статически типизированными или по большей части статически типизированными программами? Вряд ли.

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

Заявить можно все что угодно, ты уверен что многомиллионная компания (сотни миллионов или миллиарды капитализации на тот момент) не смогла среди 6 млрд человек найти 10 лисперов для поддержки проекта?

Нет, не уверен. И ты бы это увидел, если бы процитировал моё предложение целиком. (:

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

В C# разве нет нормального Any? dynamic там или просто object.

С# dynamic делает его нормальным динамическим языком. Настолько же, насколько им является Common Lisp.

Если тайп хинты начинают обладать какими-то отличными свойствами от документирования …, то это уже декларация типов.

Именно так.

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

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

Можно. Но также как в Haskell можно сделать функцию с переменным числом аргументов, то есть через ж…

Если в CL я просто могу сделать setf на что угодно, то в Racket можно переопределить только функции текущего модуля. Все остальные модули можно только перезагрузить целиком на новую версию.

Причём надо явно указать, что можешь захотеть переопределять. Если обычный код выглядит:

#lang racket
(require "foo.rkt")
(define (bar x) (cons 'a (foo x)))

то с поддержкой обновления

#lang racket
(require racket/rerequire)
(dynamic-rerequire "foo.rkt")
(define foo #f)
(define (update-foo!) (set! foo (dynamic-require "foo.rkt" 'foo)))
(update-foo!)

(define (bar x) (cons 'a (foo x)))

И тогда можно делать так:

;; в "foo.rkt" (define (foo x) (+ x 1))
> (bar 1)
'(a . 2)
;; в "foo.rkt" записываем (define (foo x) (- x 1))
> (dynamic-rerequire "foo.rkt")
> (update-foo!)
> (bar 1)
'(a . 0)

Аргумент, кстати, об отсутствии тех или иных средств (вроде отладчика) в ракете - какой-то очень странный для мира лиспов.

Есть такая особая ветка лиспов: называется Sсheme. Её разработчики изначально объявили возможность тотальных обезьяньих патчей Common Lisp’а злом. А отладчик и изменяемость всего во время выполнения — это как раз инструменты для него. В других языках программирования тоже на возможность изменения кода программы во время выполнения смотрели косо. С другой стороны, приверженцы Common Lisp с такой же ненавистью относятся к функции call/cc и заявляют, что Scheme — это не лисп, а алгол со скобками.

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

Активно это сколько в килограммах?

Например, можно переписать стандартную библиотеку Common Lisp.

это и есть подход динамической среды с опциональной типизацией.

Именно так.

Перестают ли они от этого быть статически типизированными или по большей части статически типизированными программами? Вряд ли.

Не перестают, так как требуется явный cast. Если в очередном стандарте C++ std::any разрешат пользоваться не вызывая any_cast, С++ станет динамическим языком (и следующим естественным шагом будет разрешить опцией компилятора подключать сборщик мусора).

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

Под каким псевдонимом там Джоэл? По ссылке увидел кучу комментариев-догадок, людей никак не относящихся ни к Yahoo ни к истории с магазином Грэма.

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

С# dynamic делает его нормальным динамическим языком. Настолько же, насколько им является Common Lisp.

В C# использование dynamic, на сколько я понимаю, это такой способ в _некоторых_ местах добавить динамичности, CL же полностью динамический язык, никто в нем не пишет все с декларацией типа и не особо надеется на статическую проверку «скомпилировалось значит работает». Почему «на столько же»?

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

Sсheme. Её разработчики изначально объявили возможность тотальных обезьяньих патчей Common Lisp’а злом.

Я не знал этой истории. Т.е. примерно так же обстоят дела и в других схемах, не только в рекет?

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

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

В других языках программирования тоже на возможность изменения кода программы во время выполнения смотрели косо.

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

приверженцы Common Lisp с такой же ненавистью относятся к функции call/cc и заявляют, что Scheme — это не лисп, а алгол со скобками.

Алголистость в чем, в бондаж унд дисциплинен? Или что-то еще?

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

Активно это сколько в килограммах?

Например, можно переписать стандартную библиотеку Common Lisp.

Речь вроде бы шла о каком-то гипотетическом динамическом фреймворке, в котором должны «активно» использовать Any. Вот я и хотел узнать, что означает активность в твоем понимании в цифрах. Когда фреймворк на языке со статической типизацией (и возможностью Any одновременно) становится динамическим, когда декларации типов вообще записать не получится потому что их нельзя вывести или что-то другое? Использование Any в отдельном модуле фреймворка / либы вряд ли сделает его динамическим, не так ли? Но если предположить, что язык с Any - динамический (согласно твоему тезису), тогда все фреймворки на нем динамические по-дефолту :) Что сводит предположение об «активном» использовании к абсурду, ну то есть он и так динамический.

Зачем, допустим, переписывать стандартную библиотеку C#? Или тому же С++ переписывать STL? Что там можно улучшить в разрезе Any?

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

Нет, не уверен. И ты бы это увидел, если бы процитировал моё предложение целиком. (:

Для того чтобы увидеть - не обязательно цитировать, достаточно прочесть. Но ведь ты все же привел этот пример с Yahoo, хоть и с оговорками (обс). К чему?

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

Потому что на практике предоставленные возможности статической и динамической типизации примерно одинаковы.

никто в нем не пишет все с декларацией типа

Компилятор SBCL как контрпример. И программы на https://benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/lisp.html

и не особо надеется на статическую проверку «скомпилировалось значит работает»

На эту проверку вроде только в Haskell надеются.

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

Я не знал этой истории. Т.е. примерно так же обстоят дела и в других схемах, не только в рекет?

Да. Исключением является разве что MIT/GNU Scheme. Но в ней и разработка в образе есть и рестарты из Common Lisp.

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

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

Отладчика в Scheme не то, чтобы совсем нет, его нет в том виде, как принято в Common Lisp (с произвольными командами в точке останова). Пошаговое выполнение и просмотр переменных как в массовых языках в Scheme как правило есть.

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

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

Алголистость в чем, в бондаж унд дисциплинен? Или что-то еще?

Именно в этом. И в том, что нет нормальной разработки в образе. Если в Common Lisp легко можно получить образ без исходника (накодировал в REPL и сохранил мир), то в Scheme нормальный алголовский цикл написал/скомпилировал/запустил/закончил выполнение.

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

Именно в этом. И в том, что нет нормальной разработки в образе. Если в Common Lisp легко можно получить образ без исходника (накодировал в REPL и сохранил мир), то в Scheme нормальный алголовский цикл написал/скомпилировал/запустил/закончил выполнение

Провал Smalltalk и BlackBox людей ничему не научил.

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

Что там можно улучшить в разрезе Any?

Наличие std::list позволило бы иметь лисповые списки с элементами разных типов. Парсеры было бы проще писать, если в конце разбора может быть любой объект.

когда декларации типов вообще записать не получится потому что их нельзя вывести или что-то другое?

Когда у большей части функции в качестве типа аргумента и результата dynamic.

В качестве примера вот: http://libcello.org/. Программа, которая использует cello по факту является написанной на динамическом языке.

Но если предположить, что язык с Any - динамический (согласно твоему тезису), тогда все фреймворки на нем динамические по-дефолту

Будет ли фреймворк на Common Lisp динамическим, если его API полностью типизировано?

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

В качестве примера вот: http://libcello.org/. Программа, которая использует cello по факту является написанной на динамическом языке.

Бегло посмотрел: там, вроде, везде типы декларируются. В чём подвох?

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

На эту проверку вроде только в Haskell надеются.

Хотят надеяться много где. В конце концов, в С++ тоже можно всё подряд во враперы заворачивать и explicit вешать, чтобы более строгие типы получить. И наоборот: в хаскеле тоже могут быть ошибки в рантайме. Вроде, полноценные зависимые типы и не планируют в язык завести?..

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

Там так можно?.. В примерах не увидел, но я дальше стартовой страницы и не ходил. Тогда вопросов нет.

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

Потому что на практике предоставленные возможности статической и динамической типизации примерно одинаковы.

Я хоть и сторонник динамической типизации (с опциональной декларацией типов и реплом), но такую позицию не разделяю, потому что все еще помню свой опыт программирования на статически типизированных языках вроде delphi и C++. И статическая типизация много в чем помогает, не только гарантии (и не столько оптимизация), но и с работой в ide, рефакторинг. Особенно если мы для сравнения берем два алголоподобных языка - например шарп vs python.

Компилятор SBCL как контрпример. И программы на

Частные случаи же.

и не особо надеется на статическую проверку «скомпилировалось значит работает»

На эту проверку вроде только в Haskell надеются.

В «обычных» языках на нее тоже надеются, но не в таком утрированном варианте.

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

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

Спорное предположение.

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

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

И тем не менее на _всех_ из них пишут крупные программы.

Если в Common Lisp легко можно получить образ без исходника (накодировал в REPL и сохранил мир), то в Scheme нормальный алголовский цикл написал/скомпилировал/запустил/закончил выполнение.

На мой взгляд удобный вариант - разработка в образе с возможностью из образа восстановить исходники (сохранение истории команд и введенных данных вроде бы не такая сложная штука). Также как и хранение исходника (или истории исходников) конкретной ф-ции / объекта итд. Не в курсе, есть ли такое где-то?

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

Провал Smalltalk и BlackBox людей ничему не научил.

Расскажи нам, почему они провалились.

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

Когда у большей части функции в качестве типа аргумента и результата dynamic.

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

Будет ли фреймворк на Common Lisp динамическим, если его API полностью типизировано?

А проверяется это API в рантайме (контракты и вот это вот все)? Если да, то будет конечно.

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

но и с работой в ide, рефакторинг.

А можно конкретнее? Чем именно?

Частные случаи же.

Для опровержения утверждения с квантором всеобщности достаточно одного частного случая.

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

И тем не менее на всех из них пишут крупные программы.

Покажешь крупную программу на Lua или хотя бы на Perl?

разработка в образе с возможностью из образа восстановить исходники (сохранение истории команд и введенных данных вроде бы не такая сложная штука).

Данные в процессе работы могут читаться из файлов/сети. Функция может быть прервана и частично выполнить работу. Кроме того, не очевидно, какие команды надо выполнять при компиляции, а какие при загрузке. На практике работают от обратного: в Emacs редактируют исходник и отправляют определения функций поштучно в REPL. Но это не гарантирует того, что из исходников получится эквивалентный образ. Я пару раз натыкался, что в REPL всё работает, а при попытке скомпилировать из исходников заново получаю ошибки. Например, если изменил определение макроса и не перетыкал все функции, которые от него зависят.

Сохранение окна REPL в файл есть в Racket.

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

Что-то сомнительно, что так будут писать на сишарпе и на любом другом статическом языке.

Предположим, человек фанат динамических языков, но вынужден писать на C#, так как только на нём есть нужная библиотека.

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

Естественно. Типы в голове, а не в коде. Динамический язык даёт больше свободы, так как позволяет в качестве интерфейсов указывать «отсортированный массив», «непустой список», «чётное число от 0 до 100», …

А проверяется это API в рантайме (контракты и вот это вот все)? Если да, то будет конечно.

А если нет? Скажем библиотеки для работы с хешами и числами в SBCL полностью статически типизированы.

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

Покажешь крупную программу на Lua или хотя бы на Perl?

Мало имел дело с этими языками. На python и php покажу. Да ты и сам их знаешь.

Данные в процессе работы могут читаться из файлов/сети. Функция может быть прервана и частично выполнить работу.

Как это мешает типизации?

Кроме того, не очевидно, какие команды надо выполнять при компиляции, а какие при загрузке.

Не понял этот аргумент.

На практике работают от обратного: в Emacs редактируют исходник и отправляют определения функций поштучно в REPL. Но это не гарантирует того, что из исходников получится эквивалентный образ.

Почему?

Я пару раз натыкался, что в REPL всё работает, а при попытке скомпилировать из исходников заново получаю ошибки.

Значит исходники не эквивалентны, что-то утеряно.

Например, если изменил определение макроса и не перетыкал все функции, которые от него зависят.

Это претензии чисто к реализации.

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

но и с работой в ide, рефакторинг.

А можно конкретнее? Чем именно?

Очевидный доступ по точке и прочий интелисенс. Изменение функций / классов с одинаковыми названиям и разной сигнатурой.

Для опровержения утверждения с квантором всеобщности достаточно одного частного случая.

Вместо «все» имелось ввиду конечно же «подавляющее большинство».

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

Мало имел дело с этими языками. На python и php покажу. Да ты и сам их знаешь.

Ты написал «на всех из них пишут крупные программы» :-)

Как это мешает типизации?

Это не про типизацию. Это ответ на «с возможностью из образа восстановить исходники». Из журнала команд не всегда возможно восстановить исходники. Особенно, если у программы есть ГИП.

Почему?

Так дальше же написано.

Это претензии чисто к реализации.

???

Может быть другая реализация REPL’а?

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

Предположим, человек фанат динамических языков, но вынужден писать на C#, так как только на нём есть нужная библиотека.

Опять какие-то утрированные случаи. Да, он может написать на шарпе все в динамике, но 1) скорее, он все же выберет не сишарп и 2) если шарп это условие нанимателя - ему скорее всего не дадут писать в таком стиле.

Естественно. Типы в голове, а не в коде. Динамический язык даёт больше свободы, так как позволяет в качестве интерфейсов указывать «отсортированный массив», «непустой список», «чётное число от 0 до 100», …

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

А проверяется это API в рантайме (контракты и вот это вот все)? Если да, то будет конечно.

А если нет? Скажем библиотеки для работы с хешами и числами в SBCL полностью статически типизированы.

Значит это будет просто статически типизированная _часть_ программы.

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

Очевидный доступ по точке и прочий интелисенс. Изменение функций / классов с одинаковыми названиям и разной сигнатурой.

В питоне это всё работает.

Вместо «все» имелось ввиду конечно же «подавляющее большинство».

:-)

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

Мало имел дело с этими языками. На python и php покажу. Да ты и сам их знаешь.

Ты написал «на всех из них пишут крупные программы» :-)

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

Это ответ на «с возможностью из образа восстановить исходники». Из журнала команд не всегда возможно восстановить исходники.

Почему?

Почему?

Так дальше же написано.

Значит я не понял ответ.

Особенно, если у программы есть ГИП.

Что такое ГИП?

Может быть другая реализация REPL’а?

Может конечно, граф зависимостей ф-ций от макросов и от чего там еще нужно. И одной командой можно все «пересобрать».

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

В питоне это всё работает.

Чтобы это работало в условном питоне - все равно нужен статический анализ, который просто будет неполным.

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