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 ()
Последнее исправление: maxcom (всего исправлений: 2)

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

Common Lisp уступает Racket в плане надёжной работы в Windows

Что понимать под надёжной? В SBCL в Windows нестабильная многопоточность. В остальном примерно равно (если в Common Lisp не злоупотреблять (optimze (safety 0)).

Программы на Common Lisp уступает программам на Racket в плане надёжной работы в целом из-за наличия в Racket контрактов на функции.

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

Стабильность на винде — это Corman Lisp, LispWorks или Allegro CL.

Это всё за деньги. И достаточно тормозное к тому же (медленнее, чем Racket, не говоря уж о SBCL).

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

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

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

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

1. более удобную запись субмодулей,

определяешь для ридера в some-extension ридер-макрос #module(+), который работает в соответствии с нужной тебе семантикой.

2. субмодули для языков с произвольным синтаксисом.

Тоже можно, однако, надо понимать, что ридер в ракетке ассоциируется с входным портом, с-но, в данном случае твой ридер не будет меняться, на весь файл будет использован ридер от some-extention, просто он будет сам себя переопределять при виде соответствующих форм (#module). Если же рассовать тот же код по отдельным файлам, то для каждого будет свой собственный ридер, соответствующий #lang'у. В некоторых случаях, возможно, это может оказать какой-то эффект. Но, наверное, в очень необычных и нетривиальных, мне в голову сейчас примера не приходит.

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

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

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

CCL на Windows работает полноценно (с потоками) стабильно

Да. Если писать в основном под Windows, то это лучший выбор. Под Linux у SBCL выше производительсность.

monk ★★★★★
()

Как переводится название сего языка программирования? Интересует обоснование, что переводится именно так, а не иначе.

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

Как переводится название сего языка программирования?

Racket (англ. racket — рэкет) (c) wikipedia

Интересует обоснование, что переводится именно так, а не иначе.

Сайт про Racket: http://macrologist.blogspot.ru/ . Называется «one racketeer»

Также в официальной документации (http://docs.racket-lang.org/quick/):

«More typically, Racketeers use the let or let* form for local binding.»

«Most Racketeers prefer to use the shorthand function form with define instead of expanding to lambda.»

А racketeer переводится только как «рэкетир», если брать слова производные от racket (http://lingvolive.ru/translate/en-ru/Racketeer).

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

Чо-то Вы сложное сказали :)

Что сложного в лексическом связывании? Гигиеническое связывание отличается от негигиенического в точности так же как лексическое от динамического. То есть макросы ведут себя как функции.

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

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

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

racket scheme

Не совсем: Racket is a descendant of Scheme, just like PLT Scheme was. ... The name Racket meets some basic criteria: it isn't used already, it's easy to pronounce and spell, and it has a vague connection to the word “scheme.” Mostly, though, we just like it. http://racket-lang.org/new-name.html

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

А всетаки, в чем разница между conditions комона и continuations ракета в плане практического использования? Если мне, например, надо в функции прочитать значение из файла и, если чтение не удалось, вернуть управление выше по стеку вызовов и там решить, как продолжать выполнение функции: либо заюзать дефолтное значение, либо считать из другого файла, либо плюнуть на выполнение задачи, либо переспросить у своего «хозяина» итп. Кажется так выглядит типичный юзкейс кондишенов. Так вот, с помощью продолжений, такое наверно записываеться выкидыванием исключения со значением продолжения или как? И как в таком случае работает управление ресурсами?

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

А всетаки, в чем разница между conditions комона и continuations ракета в плане практического использования?

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

Так вот, с помощью продолжений, такое наверно записываеться выкидыванием исключения со значением продолжения или как?

Можно сделать на продолжениях кондишены. Можно обычные исключения. Можно еще что-нибудь, что тебе нравится.

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

dynamic-wind

Дак эта скотина перевходит в инициализатор. Не ну я понимаю, что так проще реализовать, но блин, заново ресурсы выделять неприятно. Эх, жаль нельзя считать ссылки на продолжение и финализировать только когда все ссылки на него сдохнут. Или можно?

q0tw4 ★★★★
()

Еще клёво было бы иметь возможность сериализации произвольного объекта втч continuation, чтоб можно было сохранять состояние проги на диск в середине вычислений или поддерживать работу с миллионами клиентов на нескольких машинах, сохраняя продолжения в бд в ожидании действий клиентов и продолжая их не обязательно на той же машине, где они начинались (типа эрланг).

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

можно использовать delimited continuations и высвобождать ресурсы по выходу из твоего with-resource-do-smth блока

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

высвобождать ресурсы по выходу из твоего with-resource-do-smth блока

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

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

в чем разница между conditions комона и continuations ракета в плане практического использования?

Можно писать web server в стиле:

(define (make-main-page)
  (define-values (user password) (make-auth-page))
  (if (user-ok? user password)
      (template-main-page)
      (error page "Incorrect password")))

где make-auth-page рисует страницу с запросом имени и пароля и возвращает имя и пароль (эдакий диалог, но на http/html)

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

Эх, жаль нельзя считать ссылки на продолжение и финализировать только когда все ссылки на него сдохнут. Или можно?

Легко (с пакетом finalizer):

(require finalizer)
(define file (open-input-file "myfile"))
(register-finalizer file close-input-port)

Стандартными средствами:

(require ffi/unsafe)
(define file (open-input-file "myfile"))
(register-finalizer file close-input-port)

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

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

Такие вещи лучше делать через Custodian: http://docs.racket-lang.org/reference/custodians.html?q=custodian#(def._((quo...

Тогда можно одной командой закрыть как поток вызванной функции, так и её ресурсы.

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

где make-auth-page рисует страницу с запросом имени и пароля и возвращает имя и пароль (эдакий диалог, но на http/html)

В теории красиво. Но возникает вопрос: насколько хватит такого web-сервера, если, например, злоумышленник откроет сотни тысяч диалогов, которые будут ждать ввода имени/пароля?

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

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

Ну будут висеть (до таймаута) сотня тысяч ссылок на продолжения (указатель + стек). Займут пару мегабайт и сотню тысяч тактов на проход GC.

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

Примерно так (это полный работающий код):

#lang web-server/insta
; start: request -> response
(define (start request)
  (show-counter 0 request))
 
; show-counter: number request -> doesn't return
; Displays a number that's hyperlinked: when the link is pressed,
; returns a new page with the incremented number.
(define (show-counter n request)
  (define (response-generator embed/url)
    (response/xexpr
     `(html (head (title "Counting example"))
            (body
             (a ((href ,(embed/url next-number-handler)))
                ,(number->string n))))))
 
  (define (next-number-handler request)
    (show-counter (+ n 1) request))
  (send/suspend/dispatch response-generator))

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

Ну будут висеть (до таймаута) сотня тысяч ссылок на продолжения (указатель + стек). Займут пару мегабайт и сотню тысяч тактов на проход GC.

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

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

можно, но неудобно

Вот именно. По той же причине нет смысла реализовывать кондишены через delimited continuations. Почти так же неудобно выйдет наверно.

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

ограничить количество продолжений, очевидно

Не совсем очевидно как это будет выглядеть в реальности. (Просто далеко не все знакомы с этой темой.) Насколько усложнится реальный код?

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

А можешь какой-нибудь url dispatcher посоветовать

Именно по url есть такой: http://docs.racket-lang.org/web-server/dispatch.html . Только он с продолжениями плохо дружит (в смысле, транслировать url<->продолжение приходится вручную).

Или стандартный вариант:

(define (make-servlet path start)
  (define servlet (make-v2.servlet (current-directory)
                                   (make-threshold-LRU-manager #f (* 1024 1024 64))
                                   start))
  (λ (url)
    (match (url-path url)
      [(list (path/param (? (and/c path)) _) _ ...) servlet]
      [else (next-dispatcher)])))

(serve
 #:dispatch (seq:make
             (servlet:make (make-servlet "news" news))
             (servlet:make (make-servlet "jobs" jobs))
             (servlet:make (make-servlet "helpdesk" helpdesk-handler))
             (files:make #:url->path (make-url->path "/var/www/")))
 #:listen-ip #f
 #:port port)

monk ★★★★★
()

Подмодули теперь полностью поддерживаются в Typed Racket.

Прикольно, когда-то это было одной из причин, по которым язык отложил.

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

Ни на сколько, это вопрос настроек сервера, фактически.

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

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

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

Помимо учебной цели аргументов было 4

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

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

Какой стиль стимулирует ракет в реальных программах - больше императивный или больше функциональный?

Больше функциональный. В том смысле, что если у тебя в коде есть set!, который на является сохранением продолжения, то, скорее всего, этот код можно переписать лучше. Списки по-умолчанию immutable. Есть immutable варианты для string, byte string, vector, hash table и box.

никто там особо по идеологической чистоте не загоняется

Особо нет. Но есть рекомендованный стиль (использовать define вместо let, cond вместо if+begin, использовать match, избегать использования без необходимости set!, макросов, продолжений). Так-то и в haskell можно писать всё внутри IO и не заморачиваться.

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

избегать использования без необходимости set!, макросов, продолжений

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

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

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

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

Т.е. избегать писать свои небольшие компиляторы.

Ты пропустил «без необходимости». То есть DSL — это нормально, продолжения для web сервера — нормально. set! внутри замыкания (для изменения связанной переменной) — тоже нормально.

А макросы типа unwind-protect, with-open-file, — не надо, так как вместо них достаточно функций.

Также не надо писать в стиле

(define (func ...)
   (call/cc
     (lambda (return)
        (when ....
           (return 'fail1))
        (unless ....
           (return 'fail2))
        ...)))     
Так как то же самое делается или через match или через error.

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

Ты пропустил «без необходимости».

Это ты верно заметил, пропустил. В подобных рекомендациях это незаметно, зато заметная суть. Без макросов никакие Лиспы не нужны. (Если у вас не IBM 704 или иже с ним.) Прямое назначение Лиспа как раз в написании компиляторов. Если этого не делать, то есть огромная куча других языков, на которых можно описывать программы через невзрачную обойму for/while/if/else... и считать себя программистом :-) PS. Почти все т.н. лисперы Лиспом пользоваться не умеют.

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

Прямое назначение Лиспа как раз в написании компиляторов.

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

В Scheme (и Racket) считается, что если что-то можно описать декларативно, то это нужно описать декларативно (и здесь нужны макросы). Но если что-то нельзя описать декларативно, то делать макросы для «красоты синтаксиса» очень плохой тон.

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

Именно из-за этой идеи сообщество Common Lisp такое раздробленное.

А я думаю, что именно из-за не(до-)понимания этой идеи, сообщество Common Lisp такое, каким оно сейчас является.

Каждый придумал себе по языку

Взгляни на библиотеки Common Lisp. Почти все они написаны на Common Lisp, а не на DSL. Так что почти все или Common лисперов пишут на Common Lisp. Любят использовать всякие там CLOS, т.е. кодят как на цепепе.

если что-то нельзя описать декларативно, то делать макросы для «красоты синтаксиса» очень плохой тон.

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

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