LINUX.ORG.RU

Вышел Racket 6.3

 , ,


2

9

Доступен для скачивания релиз 6.3 языка программирования Racket — http://racket-lang.org/.

Новшества:

  • При раскрытии макросов используется новое представление связывания, что позволяет проще понимать как макросы сохраняют связывания, особенно при вовлечении в процесс раскрытия нескольких модулей и при отклонении от гигиены при раскрытии.
  • GUI-библиотека Racket теперь использует Gtk3+ по умолчанию.
  • Новое руководство по Redex.
  • Улучшена проверка синтаксических ошибок для Redex-паттернов.
  • Bluebox стали более агрессивными в плане отыскания имён для поиска в документации.
  • Подмодули теперь полностью поддерживаются в Typed Racket.
  • Библиотека typed/racket/unsafe предоставляет формы импорта/экспорта для обхода генерации контрактов.
  • Typed Racket предоставляет экспериментальную поддержку units (из racket/unit).
  • Экспериментальная форма define-new-subtype позволяет указывать тонкие различия, без которых типы считаются идентичными (аналог new type в Haskell).
  • Конструктор типов Promise изменился, нарушив обратную совместимость для устранения promise, созданных с помощью promise/name.
  • Пакеты unstable-* исключены из главного дистрибутива.
  • big-bang поддерживает режим display-mode, что позволяет т.н. «мировым» программам (интерактивным, графическим программам, состоящих из простых математических функций) занимать весь экран целиком.

>>> Подробности

anonymous

Проверено: maxcom ()

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

Любят использовать всякие там CLOS, т.е. кодят как на цепепе.

Проще понимать, расширять и сопровождать. Макры — для бойлерплейта

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

Проще понимать, расширять и сопровождать. Макры — для бойлерплейта

Да нахрен он не нужен этот CLOS в решении прикладной задачи. Если выражать задачу в терминах классов, то лучше уж взять жаву или цепепе и размазывать это месиво из классов и циклов по файликам. Какой смысл делать это на Лиспе? Интерактивная разработка? Без неё и так не плохо обходятся «программисты» на других языках. Что-то ещё?

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

Мне нужно: multiple dispatch, restarts, macros, hot-code upgrade, repl, interactive development and debugging, efficient machine code execution — все это из коробки в CL. Нахер мне твой алгол?

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

Мне нужно: multiple dispatch, restarts, macros, hot-code upgrade, repl, interactive development and debugging, efficient machine code execution — все это из коробки в CL.

Ты, походу, не понял. (Как и большинство лисперов.) Понятно, что это всё есть в CL из коробки. И это хорошо. Только вот что ты с этим всем делаешь?

Нахер мне твой алгол?

Я этого не слышал :-)

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

Очевидно, пишу программки за деньги и форфан.

Т.е. выражаешь решение прикладной задачи непосредственно на Common Lisp? Я правильно понял?

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

Ну да, а почему собственно нет? У меня задачи нормально без специфичного дсл решаются, хотя есть автоматическая генерация кода поддержки протоколов из описания в json и xml средствами CL. Будет нужен дсл для решения задачи — возьму тот же CL. Без фанатизма.

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

Взгляни на библиотеки Common Lisp. Почти все они написаны на Common Lisp, а не на DSL.

Мы какие-то разные библиотеки смотрим.

Есть iterate со своим DSL.

Есть пачка библиотек hu.dwim.* со своим (def function ...) (def class ...) (def page ...) ....

Есть библиотека den73: budden-tools с (perga (let a 1 b 2) (flet f () (list a b)) (f))

И скрестить даже последние два уже проблематично.

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

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

Синтаксического переусложнения там нет. И 90% библиотек можешь не учить пока не понадобятся. Я уже приводил пример glib в Си. Нельзя считать, что библиотека неотъемлемая часть языка.

А так

Racket:
> (length (namespace-mapped-symbols (make-base-namespace)))
1442

SBCL:
* (length (let ((lst ()))
   (do-symbols (s (find-package 'cl)) (push s lst))
   lst))
978

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

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

Не скажи. 90% паттернов для CLOS выражаются в 2-3 строки. А наличие :before, :after, :around позволяет дописывать алгоритмы по мере необходимости

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

Ну да, а почему собственно нет? У меня задачи нормально без специфичного дсл решаются

Следует ли из этого, что ты - одиночка, либо единственный лиспер в конторе, либо один из лисперов в конторе, чьи задачи никак не пересекаются с другим(-и) лиспером(-ами) в конторе? Потому что вряд-ли кто-то захочет разбираться с тем, что ты там делаешь такого в своём коде со списками, решая прикладную задачу. Логичнее было бы читать код на языке, который описывает задачу, а не манипуляцию со списками, сигналами, loop-ми и проч.

Будет нужен дсл для решения задачи — возьму тот же CL. Без фанатизма.

Возьми :-)

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

Не скажи. 90% паттернов для CLOS выражаются в 2-3 строки.

В программировании нужно не паттерны выражать, а решение задачи. И на CLOS это не будет сильно отличаться от цепепе по сути.

А наличие :before, :after, :around позволяет дописывать алгоритмы по мере необходимости

Правильно, но яснее код от этого не становится.

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

Не скажи. 90% паттернов для CLOS выражаются в 2-3 строки

Зато там где на Java рефакторинг делается в пол-пинка и с гарантией корректности, в CLOS мрак и головная боль.

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

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

Не скажи. Вот, например, код

(iterate
  (for i from 1 to 4)
  (collect i)
  (when (> i 7) (finally (return i))))

Что вернёт?

В то время, как цикл do или do* всегда предсказуем.

Логичнее было бы читать код на языке, который описывает задачу

Почти всегда хватает имён функций и переменных.

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

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

Ещё одна проблема с DSL: их сложнее расширять. Классический пример: loop. Сделал коллекцию, а в язык loop её никак добавить нельзя.

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

Зато там где на Java рефакторинг делается в пол-пинка и с гарантией корректности, в CLOS мрак и головная боль.

Ты что-то путаешь. Наоборот в Java для любого изменения намного больше текста править приходится. Причём проблема владельца метода (как правильно Picture.Draw(Screen) или Screen.Draw(Picture) или DrawManger.Draw(Screen, Picture)?) в CLOS вообще не существует.

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

Что вернёт?

Для того, чтобы понять, что он вернёт, нужно знать его семантику. Т.е., понятное дело, перед чтением DSL-кода нужно потратить время на изучение его семантики. Однако, эти затраты быстро окупаются, потому что...

В то время, как цикл do или do* всегда предсказуем.

... потому что последующее понимание кода, выражающего решение задачи, будет многим проще, чем при чтении хорошо знакомых do или do*, за счёт более сжатого и более абстрактного описания. Что проще понять, «виджет содержит множество виджетов предосмотра товаров, удовлетворяющих критерию» или «выполнить запрос к базе данных с множеством критериев, который получает данные о предосмотрах товаров, пройтись по результату и сформировать список виджетов товаров, который затем сделать частью виджета-контейнера»?

Почти всегда хватает имён функций и переменных.

Ну, в таком случае, почти всегда хватает C или C++ :-)

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

Ещё одна проблема с DSL: их сложнее расширять. Классический пример: loop. Сделал коллекцию, а в язык loop её никак добавить нельзя.

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

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

А можешь привести пример такого dsl'я, чтобы сомневающимся (в необходимости dsl'ей) стало понятно, что дескать, да, тут без dsl'я не обойтись и никакими библиотеками на python'е эту задачу не решить?

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

за счёт более сжатого и более абстрактного описания

Это как раз про декларативное описание. Оно не всегда возможно.

Что проще понять, «виджет содержит множество виджетов предосмотра товаров, удовлетворяющих критерию» или «выполнить запрос к базе данных с множеством критериев, который получает данные о предосмотрах товаров, пройтись по результату и сформировать список виджетов товаров, который затем сделать частью виджета-контейнера»

Давай на лиспе. Первый вариант с DSL будет что-то вроде

   (defvar *cond* '(where (price > 25)))
   (defvar *widget* (widget contains goods where ,cond))

Второе (без DSL, но с тем же результатом):

(defvar *cond* (lambda (x) (> (price x) 25)))
(defvar *widget* (widget :contains 'goods :where *cond*))

Ты уверен, что без DSL понять сложнее? Но если в DSL мне вдруг понадобятся товары с именами длиннее 50 символов, то придётся искать, сделал ли разработчик DSL нужную функцию. Без DSL доступен весь CL в любой момент.

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

Наоборот в Java для любого изменения намного больше текста править приходится

В Java для любого изменения компилятор проверит его корректность по всем over9000 классам. А IDE, благодаря статической типизации, дает тебе массу возможностей для автоматизации этих изменений. Ну а CL + CLOS, конечно, даст тебе возможность накидать быстро код, без всяких «глупых» ограничений и «лишнего» текста. Вот только дальше %бись с ним как хочешь, когда что-нибудь внезапно не срастется, это уже лично твои проблемы бегать вместо компилятора по всему коду и держать в голове ту информацию, которая выписана в коде на Java.

Причём проблема владельца метода (как правильно Picture.Draw(Screen) или Screen.Draw(Picture) или DrawManger.Draw(Screen, Picture)?) в CLOS вообще не существует

Мне бы такие «проблемы».

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

А можешь привести пример такого dsl'я, чтобы сомневающимся (в необходимости dsl'ей) стало понятно, что дескать, да, тут без dsl'я не обойтись и никакими библиотеками на python'е эту задачу не решить?

Ну как же ты не поймёшь, что писать решение задачи можно на языках разного уровня абстракций? Чтобы писать, и, что важнее, читать программы на Python или на C++ нужно *знать* библиотеки. А чтобы понять, как устроена программа, нужно в мозгу собрать всю низкоуровневую мозайку из дебильных for/while/if/else/do... и т.д. Плюс библиотеки. И, опять же, те же библиотеки состоят из тех же дебильных for/while/if/else/do... и чтобы понять как устроена библиотека (часто нужно даже прикладнику-пользователю библиотеки, чтобы исправить баг в библиотеке), нужно опять же собрать в голове много дебильных низкоуровневых конструкций самого языка, будь то хоть Python, хоть C++, хоть Java, хоть Common Lisp. Опять не понял? :-)

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

Ты уверен, что без DSL понять сложнее?

В том то и дело, что ты написал 2 раза одно и тоже :-). А должен был во втором случае написать код для выборки данных из базы, для создания виджетов с наполнением их данными, выбранными из базы, для добавления виджетов в контейнер и т.д. Спич о том, что в 1-м случае этот код должен сгенерировать компилятор, а во 2-м случае программист его пишет врукопашную (ему же ведь нужен весь Common Lisp для решения прикладной задачи!!1)

Но если в DSL мне вдруг понадобятся товары с именами длиннее 50 символов, то придётся искать, сделал ли разработчик DSL нужную функцию.

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

Без DSL доступен весь CL в любой момент.

Сам подумай, проанализируй, какая часть Common Lisp используется при решении прикладных задач, вроде вышеприведённой. Такой мощный арсенал, как в CL нужен вовсе не для того, чтобы виджетики тасовать, а для того, чтобы писать компиляторы, которые и перетасуют эти самые виджетики. А вы все используете Лисп вообще не так, как следует. :-)

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

Анонимус подразумевает DSL, изменяющий синтаксис: Вышел Racket 6.3 (комментарий)

Причём тут синтаксис? Он в Лиспе фиксированный, если только не пользоваться макрами чтения. Анонимус подразумевает DSL, задающий семантику. :-)

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

В Java для любого изменения компилятор проверит его корректность по всем over9000 классам.

Всё равно нужны модульные тесты. А если они есть, так корректность и в CLOS проверится. И необходимость в рефакторинге (в смысле, переделке внутренней структуры) появляется гораздо реже.

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

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

Ну если второй код тоже считать DSL'ем (семантика-то есть), то Lisp ничем не лучше для написания DSL'ей, чем C++, Java, Haskell, Basic, ... В любом языке можно из имён переменных и функций собрать DSL. Lisp отличается только макросами.

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

А вы все используете Лисп вообще не так, как следует. :-)

Покажи как надо. Ссылку на свой проект дашь?

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

Взгляни на библиотеки Common Lisp. Почти все они написаны на Common Lisp, а не на DSL.

Потому что на common lisp очень трудно писать DSL.

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

Всё равно нужны модульные тесты

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

А если они есть, так корректность и в CLOS проверится.

Это слова теоретика, который никогда не поддерживал серьезный продукт. Верно?

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

Плюс слова теоретика, который не писал серьезный продукт с активным использованием CLOS. Да?

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

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

Тут целую операционную систему с кучей прикладного софта писали и использовали 24/7, а оказавыется анонимус говорит, что лучше так не делать.

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

Тут целую операционную систему с кучей прикладного софта писали и использовали 24/7, а оказавыется анонимус говорит, что лучше так не делать.

Дядя, ты дурак? Тесты нужны без вариантов. Но они дополняют проверки от компилятора, а не заменяют их. И в отличие от проверок компилятора, они не дают никаких гарантий. Даже 100% покрытие всех веток исполнения не дает 100% покрытия всех вариантов использования кода.

П.С. давай ссылку на свою «операционную систему с кучей прикладного софта» на языке с динамической типизацией и с 100% покрытием тестами.

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

man OpenGenera

Ты ядро топика уже покрыл тестами? А ведь «когда на входе и на выходе действительно сложные данные, работа с сетью, тредами, гуем и пр» там тоже есть.

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

man OpenGenera

Дважды дохлая никому ненужная поделка? Не интересно. Да и не имеет отношения к теме.

Ты ядро топика уже покрыл тестами? А ведь «когда на входе и на выходе действительно сложные данные, работа с сетью, тредами, гуем и пр» там тоже есть.

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

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

Но они дополняют проверки от компилятора, а не заменяют их.

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

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

Потому что на common lisp очень трудно писать DSL.

Грэм с Норвигом так не считают. Ну а если вопгосом на вопгос, то на чём тогда не трудно писать DSL? :-)

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

Ну если второй код тоже считать DSL'ем (семантика-то есть), то Lisp ничем не лучше для написания DSL'ей, чем C++, Java, Haskell, Basic, ... В любом языке можно из имён переменных и функций собрать DSL. Lisp отличается только макросами.

Что-то ты пургу стал гнать. Тебя подменили что-ли? «DSL из переменных и функций»? Ты имеешь в виду, придумать очередного выродка с синтаксисом и написать для него тормозной компилятор на C++, Java, Haskell, Basic? Или что такое «DSL из переменных и функций»? Я не понял. :-) Я то думал, что DSL как раз таки только с помощью макросов и делается :-)

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

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

«Хотя бы один тест» проверит только одну ветку исполнения, в других может быть все что угодно, в том числе при разных комбинациях и данных. Это раз. Отработанная ветка тоже ничего не гарантирует, т.к. тест проверит только наличие нужного поведения, а не типа, это два. Например, сравнение 1 и 2, 1 и «2», 1 и что-нибудь вернет одинаковый результат. И тесту все-равно что функция стала возвращать объект вместо числа. Или объект другого класса, где реализовано похожее поведение. Который «говорит», что он равен 1, или имеет размер в 2 элемента.

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

Или что такое «DSL из переменных и функций»? Я не понял.

(defvar *cond* (lambda (x) (> (price x) 25)))
(defvar *widget* (widget :contains 'goods :where *cond*))
cond = [](widget & x){ x.price > 25 };
widget = makeWidget().contains(items.goods).where(cond);
monk ★★★★★ ()
Ответ на: комментарий от monk

cond = [](widget & x){ x.price > 25 };
widget = makeWidget().contains(items.goods).where(cond);

Ну если ты операции присваивания (хотя, в цепепе можно операцией «=» хоть ракеты запускать) называешь DSL, то тогда какой может быть Норвиг? :-)

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

Ну а если вопгосом на вопгос, то на чём тогда не трудно писать DSL? :-)

На Racket, например, очень легко.

Грэм с Норвигом так не считают.

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

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

«Хотя бы один тест» проверит только одну ветку исполнения, в других может быть все что угодно, в том числе при разных комбинациях и данных.

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

Отработанная ветка тоже ничего не гарантирует, т.к. тест проверит только наличие нужного поведения, а не типа, это два.

Нет, для поведения как раз над много тестов. А для проверки типов - достаточно одного.

Например, сравнение 1 и 2, 1 и «2», 1 и что-нибудь вернет одинаковый результат.

Нет, не вернет. Если ф-я ожидает 2, а мы всунем «2» - то сразу убедимся в наличии ошибки.

И тесту все-равно что функция стала возвращать объект вместо числа. Или объект другого класса, где реализовано похожее поведение. Который «говорит», что он равен 1, или имеет размер в 2 элемента.

Что за бред ты несешь?

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