LINUX.ORG.RU

Макросы в Scala против макросов в Common Lisp

 , ,


2

8

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

Что можно сказать? Во-первых, CL как язык для МП устаревает и теряет привлекательность буквально у нас на глазах. В scala, конечно, МП менее удобно из-за более сложного синтаксиса, зато в Scala появилась концепция семантической БД - это результат семантического анализа текста со всеми типами данных и декларациями. В CL такой семантической БД нет. Притом что Scala - это даже не первый такой язык. Если я правильно понял, clang тоже такое умеет.

Среди не афишируемых целей проекта Яр есть цель сделать именно такую семантическую БД. Теперь нет смысла это скрывать.

Поимимо этого, кто не в курсе - Common Lisp _не является_ гомоиконным языком, потому что есть #. , квазицитаты частично обрабатываются, а комментарии теряются. Другие побочные эффекты чтения - это создание символов в пакетах. macro character-ы назначенные пользователем, могут делать что угодно, вплоть до запуска ракеты. Т.е. нельзя зачитать файл лиспа и проанализировать его средством без последствий для среды. Вообще нельзя. Для Java и C это сделать можно, а для лиспа - нет. Фига себе, да? Ещё одной целью проекта Яр является создание истинно гомоиконного языка. Причём это не моя прихоть, а обязательное условие для создания полноценной IDE, а не набора костылей, каковым является SLIME.

Если ещё остались энтузиасты лиспа, можно попробовать сделать семантическую БД для CL. Есть augment-environment, к-рая поддерживается в CCL. В ней есть кое-какая информация о типах. Хотя на самом деле скорее всего придётся патчить компиляторы.

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

И ещё одно странное наблюдение - похоже, что макросы в Scala никому особо не нужны.

★★★★★

Т.е. нельзя зачитать файл лиспа и проанализировать его средством без последствий для среды. Вообще нельзя. Для Java и C это сделать можно, а для лиспа - нет. Фига себе, да?

Тут одно из двух: или нормальные eDSL или возможность проанализировать.

К слову, на Си тоже можно сварганить что-то вроде

#define cl(a) eval_cl(#a)

cl((defun a () 1) #.(if (foo) 1 0))

Приятного анализа.

monk ★★★★★
()

И ещё одно странное наблюдение - похоже, что макросы в Scala никому особо не нужны.

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

monk ★★★★★
()

Не знаю, как там в Скале (как-то не задалось с ней), а в общелиспе макры особо хороши и ценны тем, что простые как полено.

Hertz ★★★★★
()

макросы в Scala никому особо не нужны

Действительно странное наблюдение, особенно для пользователей shapeless или specs2

Softwayer ★★
()

Common Lisp _не является_ гомоиконным языком, потому что есть #.

Т.е. не любое выражение в CL представимо в виде списка, или атома? Например?

квазицитаты частично обрабатываются, а комментарии теряются

Комментарии не являются частью программы. По крайней мере в CL. К гомоиконности это не имеет отношения.

Т.е. нельзя зачитать файл лиспа и проанализировать его средством без последствий для среды

Зачем его анализировать, если это сделает сам ридер?

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)
Ответ на: комментарий от Softwayer

Действительно странное наблюдение

Возможно, я не в теме. Это лишь очень беглый взгляд на хабр и стек оверфлоу. Точнее говоря, я один раз что-то погуглил на тему скала и макросы и увидел, что есть (довольно вялые) попытки продвинуть макросы и не увидел вопросов. На научность данного наблюдения не претендую. prove me wrong и я буду только рад.

Хотя лично я ещё до скалы пришёл к выводу, что программисты должны делиться на касты. Каста «быдлокодеров» (не хочу никого обидеть) делает полезные для людей вещи, а каста брахманов делает для быдлокодеров конкретные макросы. Причём «быдлокодеру» вообще не обязательно знать, что макросы существуют. Иллюстрирующий пример этого - фейл Nemerle.

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

В качестве примера из мира лиспа могу привести iterate, который очень хорош, но никак не интегрирован в пошаговый отладчик. В итоге я теперь почти всегда пользуюсь простой формой loop, dolist, dotimes и т.д.

А вот семантическая БД нужна однозначно, чтобы отвечать на вопросы типа: «где используется этот метод». Без неё программист как без рук, и в лиспе это тоже зачастую ощущается.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от no-such-file

Я так и знал, что сейчас набегут правильные лисперы со своими «зачем». Низачем. Пусть лисп дальше умирает. Вот тебе ответ на все твои «зачем». Если не устраивает - думай сам. И на остальные свои вопросы отвечай сам.

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

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

den73 ★★★★★
() автор топика

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

Deleted
()

Хотя на самом деле скорее всего придётся патчить компиляторы.

Нужна ли реально компиляция?

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

на Си тоже можно сварганить

Потому-то для Си и нет нормальных IDE. Во всяком случае, студия регулярно мажет мимо определения, для этого достаточно #define foo bar.

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

Да не надо раздуваться, всё вполне очевидно. Нету лисперов. Лиспер.ру месяц валялся, я уж думал всё, а потом написал Архимагу и он его за минуту поднял. Мораль: никому не нужен единственный профессиональный форум по лиспу в рунете. Сравниваем с тем, что было 5 лет назад и видим отчётливую разницу.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

И для спасения ситуации ты решил выкатить Яр на кириллице.
Ясно).

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

Даже хаскелевые темплейты вышли удачнее.

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

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

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

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

В Яре типы в основном задаются явно, как в самом распоследнем Паскале, поэтому (я надеюсь что) удастся получить доступ к информации о типах своевременно. Впрочем, как я уже писал, я вообще не планирую делать типы в Яре. Для лиспа я делал такую вещь:

(defstruct Моя-Структура Поле1 Поле2)
(defun foo () 
 (perga
  (:lett Перем Моя-Структура (MAKE-Моя-структура :Поле1 1))
  (^ Перем Поле1) ; раскрывается во время 
       ; компиляции в (Моя-Структура-Поле1 Имя)
  ))) 
Для этого как раз нужна информация о типе. Мне частично удалось достать инфу о типе из реализаций SBCL и LW (она там есть, в отличие от Scala), но это не так просто. Было бы удобно иметь слой переносимости, который бы был написан со знанием дела и позволял доставать эту инфу.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Продвигать макросы в широкие массы «быдлокодеров» может быть не только безполезно, но и вредно....

В качестве примера из мира лиспа могу привести iterate, который очень хорош, но никак не интегрирован в пошаговый отладчик. В итоге я теперь почти всегда пользуюсь простой формой loop, dolist, dotimes и т.д.

Так это исключительно из-за ограниченности CL-ных макросов. В Racket и пошаговая отладка внутри макроса работает и в DrRacket идентификаторы подсвечиваются.

А вот семантическая БД нужна однозначно, чтобы отвечать на вопросы типа: «где используется этот метод». Без неё программист как без рук, и в лиспе это тоже зачастую ощущается.

Возможно, только если совсем запретить eval и вызов метода по имени в строке (что сделает язык более ограниченным, чем 1С).

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

Возможно, только если совсем запретить eval

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

Лучше, что может дать семантическая база - это «метод используется в таких-то 25 местах и плюс см. eval», вызов по имени, работа через указатель. Для С++ даже этого нет.

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Для этого как раз нужна информация о типе.

А что делать, если

(defun foo (x) 
 (perga
  (:lett Перем Моя-Структура (MAKE-Моя-структура :Поле1 1))
  (if x (setf Перем 1))
  (^ Перем Поле1) ; раскрывается во время компиляции в (Моя-Структура-Поле1 Имя)
  ))) 

Плохая идея угадывать типы на стадии компиляции в языке с динамической типизацией. Если хочется макросов с типами, то надо брать за основу не CL, а Haskell или OCaml.

monk ★★★★★
()

комментарии теряются.

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

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

метод используется в таких-то 25 местах и плюс см. eval. Для С++ даже этого нет.

Вообще-то ctags давно есть

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

Тем временем появились и набрали популярность clojure и racket

А CL, начав с гораздо более высокой стартовой точки, её почему-то потерял. Почему? Из-за «ненужников» и «зачемников». Зачем гомоиконность? const ненужен? Зачем понятная для новичков IDE? рефакторниг ненужен. Выучите правила секты и достигните нирваны, а если вам неудобно, то это ваши проблемы. Пока лисперы, закрыв глаза на развитие отрасли, пребывали в самодовольстве и консервировали отсталость CL, конкуренты развивались и в итоге мы имеем то, что имеем.

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

Ты то с какого хера возомнил себя знатоком лиспа? И не только знатоком, но и спасителем, вождем. Все твои посты говорят о том, что в лиспе ты не разбираешься. Постоянно охаиваешь CL и сообщество. CL видишь ли умирает, а сообщество злое и без ясно видящего вождя (тебя) ему никак. После охаиваний обычно идет предложение на слабо и забесплатно, написать тебе какую-то фичу.

anonymous
()

Ты начал с этого: :-)

Макросы в Scala против макросов в Common Lisp

Закончил этим: :-)

И ещё одно странное наблюдение - похоже, что макросы в Scala никому особо не нужны.

Ну а по серединке было это: :-)

Для Java и C это сделать можно, а для лиспа - нет.

Тебе не кажется, что тебе уже просто опостылел Common Lisp с его стагнацией? :-)

Даже если ты выкатишь свой Яр на Common Lisp, то ты понимаешь, что последний - язык для одиночек :-) Отсюда следует, что свой Яр ты будешь развивать в одиночестве :-) Какая перспектива у твоего Яра в таком случае? :-)

Возьми лучше другой язык, если хочешь популярности для своего Яра :-) Или же есть риск разговаривать на яре с самим собой :-) Как на Лиспе :-)

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

Плохая идея угадывать типы на стадии компиляции в языке с динамической типизацией

Я, честно сказать, боюсь быть невеждой, но разве (declare type) и (the) - это не статическая типизация?

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

Автор посмотри на то, как устроен пиколисп.

Посмотрел. Дочитал до того, что упразднили lambda. Безусловно, есть много языков. Ценность не в том, что в каком-то языке реализована какая-то идея, а в том, что в языке реализовано несколько идей, которые должным образом связаны между собой. Да, компиляция нужна, и статическая типизация тоже нужна, поскольку они продлевают жизнь батарейкам смартфона.

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

Возьми лучше другой язык, если хочешь популярности для своего Яра :-)

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

den73 ★★★★★
() автор топика
Последнее исправление: den73 (всего исправлений: 1)
Ответ на: комментарий от den73

Хотя в принципе я ещё знаю SQL - он тоже более-менее ничего, и всегда востребован. Пойду на бекенд СУБД.

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

Лиспер.ру месяц валялся, ... Мораль: никому не нужен единственный профессиональный форум по лиспу в рунете.

Рассмешил. Даже На ЛОРе вопросы по лиспу быстрее решаются, чем на лиспер.ру.

monk ★★★★★
()

Вот ещё есть Роман Попов
https://www.youtube.com/watch?v=eBXdrQcGPSo&list=PL-_cKNuVAYAVSeutqKXm1wz...
https://www.youtube.com/watch?v=tXukFEXyChA

https://vk.com/maliculo
www.linux.org.ru/people/komputikisto/profile

Он тут тоже лисп собирался делать с фекспрами и континуациями
Ищу соавтора! Реализация Lisp.

Что ж ты его не поддержал?

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

Я, честно сказать, боюсь быть невеждой, но разве (declare type) и (the) - это не статическая типизация?

Нет, конечно. Это обещание компилятору. То есть (defun f (x) (declare (type fixnum x)) (- x 1)) позволяет компилятору использовать fixnum- без проверки значения x.

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

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

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

Кстати Shen/ex-Qi пару лет как под BSD. Там статическая типизация, работа поверх SBCL и какой-то вариант макросов и репла. Как-то оно ближе к лисперской реальности чем Скала. Хоть я ими обоими и не пользовался :(

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

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

мне казалось, что при объявлении типа параметров все проверки идут при (перед) вызове функции, а не в её теле...

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

А что если все лисперы, на самом деле нифига не лисперы. Просто сотона их заманил в лисп.

Иногда есть такая мысль. На самом деле есть определённый стиль программирования, который CL поощряет и пользуясь которым, именно CL наиболее удобен. Это исследовательское (в смысле explore, а не в смысле research) программирование. Написали кусочек выполнили, посмотрели результат. Кому такой стиль нравится, те до сих пор пишут на лиспе. Очень удобно писать прототипы, когда на момент начала написания не то что архитектура программы, но даже что она делать будет, до конца не ясно.

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

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

при объявлении типа параметров все проверки идут при (перед) вызове функции, а не в её теле

А код, выполняющийся при вызове функции — это не тело функции?

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

Это исследовательское (в смысле explore, а не в смысле research) программирование.

Это самое лучшее применение Common Lisp на сегодняшний день, кроме компиляторов, трансляторов и генераторов :-) А вот писать на Лиспе язык программирования как-то получается не очень, судя по OP :-)

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

если буквоедствовать и считать телом функции тот код, на который идёт переход в call / jamp / или что там в процессорах еще может быть, то нет, код который идёт до данной команды к телу функции не относится, даже если там 48 инструкций, повторяющихся при каждом вызове сей функции ;) Пруфов не проси - сие есть IMHO по мотивам пиэлей/асмов, изучаемых более четверти века тому назад...

yyk ★★★★★
()

Если вы пишите, что другие языки уже обошли лисп по его киллер фичам, то зачем продолжать насиловать лисп? Не проще ли просто использовать другие языки?

Im_not_a_robot ★★★★★
()

что макросы в Scala никому особо не нужны

Непонятная мне фича в Scala. Кроме экстраполяции s"super $puper", мне лично код с макросами не попадается, и это скорее хорошо.

По мне так лучше бы приделали удобный синтаксический сахар для монад, чем эти макросы, по примеру того же F#.

Но все это можно расценивать как персональное бурчание, не более того

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

Я эстет. Несмотря на старение CL, всё остальное - это мрак и ужас без света в конце тоннеля.

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

Буду искать такие задачи, встраиваться в ниши.

Возьми тогда C :-) Или цепепе :-) Будешь встраиваться со своим Яром :-) С Лиспом не встроишься - он слишком жирный и не умеет встраиваться :-) Racket умеет, но он, как говорят лисперы, не Лисп (наверное, под «не Лисп» они имеют в виду «не нужно», как это обычно у них бывает) :-) Лол :-)

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

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

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

Так проверки типов после call идут. То есть

(defun f (x)
  (declare (type fixnum x))
  (- x 1))

превращается при компиляции в

(defun f (x)
  (unless (fixnump x) (error ...))
  (fixnum- x 1))

monk ★★★★★
()

тензоръ метапарадигмъ, ога

Поимимо этого, кто не в курсе - Common Lisp _не является_ гомоиконным языком, потому что есть #. , квазицитаты частично обрабатываются, а комментарии теряются. Другие побочные эффекты чтения -

Wolfram Language в Mathematica, кстати, более гомоиконен чем сам лисп. об этом пишет Xah Lee в бложике, да и вдумчиво читая мануал по языку, видно:

* вызов функции и свойство (элемент структуры) выглядят одинаково

* хеш-таблица по ключу и вызов функции с параметром-ключевым словом — выглядят одинаково

* свойство (элемент структуры) и имя переменной-структуры можно перепутывать (то есть, как в Си: foo = *(foo + i) =*(i+foo) = i[foo], properties['name']='name'[properties]

* есть много синтаксического сахара типа как в Хаскель для применения и композиции функций, лябмд, (...свойств, ключей, именованых параметров) = foo . bar, foo $ bar, вот это всё и т.п., там много вариантов — см. пример

* далее см. другие главы этой книжки. например, про machine learning, NLP parsing, как написать свой парсер, как задать ему свою семантику

* типов данных реально много, как в REBOL или больше. есть онтология типов как в Semantic Web. есть общая база знаний типа CYC на веб-сервисах.

** в общем и целом, можно сказать что Mathematica и Wolfram Language расширяет типы данных и функции, свойства и опции — новыми семантическими значениями.

ну типа : S-выражения расширяются в M-выражения с синтаксисом в духе M-Lisp изначального.

или: однотипно записываются функции и данные, свойства и значения, свойство-функция как запрос и свойство-переменная.

модели и параметры модели, исходные и итоговые. типа как FRP и акаузальная симуляция, типа как в Modellica.

то есть, эти выражения означают это самое: тензор метапарадигм как семантическая сеть и фреймовая база знаний, с автовыводом новых «метапарадигм», знаний в виде моделей, исполняемых на сети.

гомоиконный во все поля.

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