Показаны сообщения с ярлыком racket. Показать все сообщения
Показаны сообщения с ярлыком racket. Показать все сообщения

вторник, 8 апреля 2014 г.

Альтернативная среда для Racket

Это последний отчёт о моих опытах с Racket и посвящён он сугубо техническому вопросу, а именно среде разработки. По умолчанию новоиспечённому Racket-разработчику предлагается минимальная среда разработки. Она умеет открывать файлы с исходниками, подсвечивать синтаксис, загружать их в простой (ну очень простой) REPL и запускать под отладкой.

В принципе это не так и мало, но хотелось большего. А именно:
  1. Полноценного REPL который бы помнил историю команд и умел подгружать изменения без полного перезапуска.
  2. Быстрой навигации по именам функций и структур.
  3. Богатого функционалом текстового редактора, в частности мультивыделения и быстрого поиска.
  4. Поддержки проектов, по крайней мере коллекций файлов по которым можно искать.
REPL достаточно быстро нашёлся, xrepl. Он прекрасно помнит историю, умеет (пере)загружать файлы, заходить в них чтобы тестировать не экспортированные функции и органично встраивается в shell. Инструкция по установке на сайте хорошо работает, для полного счастья только пришлось добавить в bash_aliases следующую строчку: "xracket="racket -il xrepl"". Она запускает Racket в интерактивном режиме и загружает модуль xrepl. Модуль написан таким образом что сам применяет все необходимые хаки для создания полноценной оболочки.

Однако не сразу всё идеально заработало. Файлы с константами было невозможно перезагружать ,rr - Racket выдавал ошибку переопределения имён. Небольшое исследование вопроса показало что это связано с включенными по умолчанию оптимизациями и легко может быть исправлено одной командой, алиас принял вид "xracket="racket -il xrepl --eval '(compile-enforce-module-constants #f)'"".

Остальные 3 функции поставляет Sublime оставалось только подружить его немного с ЛИСПом, благо я не первый кто этим озадачился. Установка пары плагинов налаживает между крепкую дружбу между Racket и Sublime. Для упрощения жизни я использовал Package Control.

Первый и самый насущный - конечно отступы :) lispindent - отлично справляется с этой задачей и даже не пугается квадратных скобок.

Второй - подсветка синтаксиса. В принципе она уже была, однако некоторые конструкции понимала не корректно. В частности совершенно убивали подсветку литералы #something а также функции и структуры не появлялись в списке символов. За пару дней поправил всё это и даже заслал патч в основную ветку проекта.

Ну и последняя доводка из области эстетства - красивая подсветка скобок и быстрый переход между ними. Делается плагином Bracket Highlighter. Очень удобно показывает границы блока слева, рядом с номерами строк а также позволяет включить "усиленную подсветку" - дополнительно подсветить весь текст принадлежащий выделенному блоку. Плюшки вроде удалить блок или перейти во внешний также присутствуют.

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

Во-первых надо включить lispindent для соответствующего языка следующей настройкой в lispindent.sublime-settings (если используется Package Control то его можно открыть через меню Preferences->Package settings).
{
  "languages": {
    "racket": {
      "syntax": "Racket.tmLanguage"
    }
  }
}
В настройках Bracket Highlighter, которые bh_core.sublime-settings (также легко открываются через меню Preferences->Package settings) надо только найти и настроить под себя параметр high_visibility_style, мне понравился underline. Также удобно повесить переключение этого режима на хоткей, для этого в Default.sublime-keymap надо дописать
{
  "keys": ["ctrl+\\"],
  "command": "bh_toggle_high_visibility"
}
Ну и проверить что файлы .rkt открываются как Racket по умолчанию.

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

понедельник, 17 марта 2014 г.

Land of Lisp

Дочитал сабж. Как можно догадаться книга посвящена языку LISP и выстроена очень своеобразным образом. Основная идея: обучить языку через написание игр. Этот, на первый взгляд направленный на детей, подход в моём случае имел изрядный успех.

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

Скажу честно не все примеры я аккуратно реализовывал и запускал, но примерно 60% задач из книги я выполнил. Что-то расширил, где-то поменял структуру кода - подход с созданием игр в книге даёт читателю очень высокий уровень вовлечённости и это прекрасно.

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

Код примеров на мой вкус немного грязноват. Много где можно радикально улучшить читабельность простыми изменениями вроде добавления структур вместо списков и магических ca*r'ов, заменой анонимных функций на именованные. Стиль который она оставляет после себя как мне кажется нельзя назвать изящным, но это мнение нуба явно тяготеющего к диалектам Scheme-семейства а не Common для которого написана книга.

И да, просто копировать примеры в таком виде было не очень интересно и решение нашлось само собой - я недавно начал ковырять Racket а книжка то написана под Common LISP! Вот и совместил приятное с полезным, транслировал примеры на современный Racket. И я теперь практически лисп-переводчик с опытом работы :) Кстати благодаря этой книжке я сделал и небольшой (и кажется первый сколько-нибудь полезный) вклад в опенсурс: изрядно подвыправил Racket плагин для Sublime.

В общем несмотря на то что книжка вроде не блестящая при должном настрое и желании что-то поделать руками она приночит массу удовольствия. Рекомендую!

четверг, 30 января 2014 г.

Линкопост #2

Пачка ссылок за последние... 4 месяца. Для начала связанное с Racket.

The Racket Way - доклад на strange loop, рассказ о дизайне или даже скорее философии Racket. Несколько наглядных примеров потребности в мета-языках. Достаточно подробно показана возможность плавной эволюции по пути приложение, библиотека, internal DSL, подмножество языка и новый язык со специальным синтаксисом в конце. Полезно посмотреть и как введение в Racket и чтобы понять что можно делать с мета-языками. Мне такая схема показалось существенно более жизнеспособной чем применение MPS или создание external DSL с 0.

Fear of Macros - что-то вроде мини-книги или большого цикла статей о макросах в Racket. Вопрос раскрывается гораздо удачнее чем в основной документации. Автор начинает с простого но низкоуровнего примера и оттуда движется к высокоуровневым pattern-based macros. Оставляет целостное понимание что такое syntax object, expansion и т.д. Интересно будет тем что интересуется мета-программированием или изучает схему.

Frog - аналог Octopress на Racket, вроде попроще в инсталляции. Выглядит симпатично, использует модный Bootstrap. В качестве языка разметки в том числе можно использовать Scribble или Markdown. Код более менее читаемый, в общем неплохой проект для поиграться с языком и посмотреть как на нём пишут реальный софт.

Немного холиваров и вбросов.

We're Doing It All Wrong - доклад от бывшего участника разработки компилятора Scala. Подробно, хотя и крайне эмоционально рассматривает различные проблемы в самом языке и текущей реализации компилятора. Немного сумбурно - неявно мешаются в кучу проблемы дизайна языка,  библиотеки, кода компилятора а в конце вообще выдвигается идея некоего идеального языка не совсем очевидно связанная с озвученными проблемами. Но в любом случае стоит уделить внимание если вы планируете куда-то внедрять скалу.

The Unreasonable Effectiveness of C - наверно одна из самых интересных статей из прочитанных мной за последнее время. Анализируется почему старый, низкоуровневый язык C был и остаётся популярным и весьма успешным. Строго рекомендовано к прочтению фанбоям хаскелей, скал, джаваскриптов, коков и всего остального что конвертирует силу мысли в быстрые и безбажные программы.

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

Хорошие статьи по практике программирования.

Computational Geometry in Python: From Theory to Implementation - понятный и краткий обзор вычислительной геометрии с точки зрения программиста. Хорошо проиллюстрирован кодом на питоне. Очень приятный способ размять мозги в новой области.

How to design and code a complete program - очень хорошая серия статей о дизайне в функциональном стиле. Построена вокруг одного примера - CRUD приложения для веба. Просто и наглядно излагаются некоторые неочевидные концепции. Код на хаскеле.

Ну и немного философии. Why education is so difficult and contentious - большой обзор происхождения и актуальных проблем современного образования. Интересна тем что внятно формулирует цели образования и показывает что они не очень то совпадают с интересами современного индивида, да и во многом общества.

Последняя ссылка на тему личного управления задачами. Bullet Journal - система ведения TODO/календаря в бумажном блокноте. Показалась удобной, сам тестирую.

четверг, 9 января 2014 г.

Clojure vs. Racket - мои наблюдения

Недавно потянуло меня подосвежить в памяти ЛИСП, в качестве учебного пособия и источника игрушечных проектов я без колебаний выбрал LoL. А вот над тем какой диалект выбрать призадумался на пару дней. Вообще сама ситуация довольно примечательна, ЛИСП насколько я понимаю сейчас является единственным языком с несколькими совершенно живыми и здравствующими диалектами. Встраиваемые я сразу отбросил, но и вполне себе самостоятельных осталось порядочно.

В финал вышли два - Clojure и Racket. Common Lisp я отбросил так как в нём многовато на мой вкус специальных форм, макросов и прочих интересных вещей, мне он показался достаточно непоследовательным. Для двух финалистов есть известное и по сути очень хорошее сравнение. Его вывод достаточно однозначен - на практике программировать на Clojure гораздо удобнее, а для учебных целей у диалектов паритет. Однако пост от 2010 года и часть данных там устарели. Ниже я перечислю все устаревшие моменты в том посте ну и приведу пару фактов которые склонили мой выбор в пользу ракеты.

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

Вторая проблема: не консистентная работа со словарями. Она исправлена во-первых ведением протокола для словарей, поддерживаемого из коробки хеш-таблицами и списками пар. Во-вторых богатым семейством функций in-dict* по преобразованию словарей в последовательности.

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

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

Почему я в итоге выбрал Racket? Буквально две причины. Во-первых в Clojure слишком много на мой вкус синтаксических конструкций. Да да, ЛИСП с избытком конструкций, куда мир катится? Куча каких-то скобочек, шапочек, двоеточий и стрелочек... Всякие навороты вроде ключевых слов очень активно используются стандартной библиотекой. Вторая - JVM. Сейчас я уж слишком привязан к ней, надо как-то расширять кругозор.