love5an: (R)
Собственно, наконец-то у меня дотянулись руки начать писать транслятор лисп-объектов в AST в SLXI.

Для тех кто всё пропустил - SLXI это кросс-интерпретатор моего лиспа, похожего на CL, написанный на C#


Ну так вот, какие TODO:

В SLXI(а конкретно, в классе LispObject) в первую очередь не хватает представлений для функций и для объектов ОО-системы.

Функций пока нет потому, что пока не определился, как они будут представляться, а именно - каким-либо байткодом, либо AST. Скорее всего AST, т.к. у SLXI задача состоит исключительно в том, чтобы забутстраппить будущий компилятор, написанный на самом лиспе, и мне дико лень тратить на сам кросс-интерпретатор излишне много усилий.

ОО-система же, естественно, будет похожа на CLOS, с некоторыми изменениями. В частности все объекты будут т.н. funcallable.
Кстати, в коде на гитхабе можно заметить, что такие вещи, как представление лексического окружения в трансляторе, представление переменных и деклараций, являются internal-объектами, грубо говоря C#-выми штуками. На самом деле, это временная мера; с введением ОО-системы они станут полноценными объектами, которые дадут пользователю лисп-системы возможность достаточно тонко управлять компиляцией на этапе раскрытия макросов.

Еще, как заметно, нету пока что и намека на парсер, т.е. reader. Нету потому, что он будет частью стандартной библиотеки. Считыватель будет очень расширяемым, настраиваемым, и вообще достаточно интересным. Про него подробнее тут: http://love5an.livejournal.com/377367.html

А вообще, есть много things to discuss об этом моем лиспе с представителями лисп-сообщества и интересующимися. В частности, надо будет продумать ОО-систему до конца, надо будет основательно поработать над стандартной библиотекой, ну и вот еще интересный вопрос про модульность - у меня вот уже давно висит идея сделать нормальную модульность лиспу, с блэкджеком и куртизанками, т.е. например наподобие как в .NET - со сборками(assembly), модулями и чем-то типа GAC. Еще интересный вопрос - IO-подсистема в стандартной библиотеке: сейчас мода на асинхронность(я вообще дико влюблен в async await в C#), и надо бы это как-нибудь красиво прикрутить. Вобщем, на одной из встреч надо будет эту тему поднять(ну и в интернете конечно буду писать про это всё).
love5an: (R)

public static void CallWithEscapeContinuation(Action<Action> f)
{
  var escapeTag = new Exception();
  Action escapeProcedure = () => { throw escapeTag; };
  try
  {
    f(escapeProcedure);
  }
  catch (Exception e)
  {
    if (ReferenceEquals(escapeTag, e)) return;
    throw;
  }
}

love5an: (R)
Главная проблема у first-class продолжений в том, что они устраняют понятие dynamic-extent, то есть контекста с динамическим временем жизни, а соответственно:

Во-первых, делают невозможной строгую стековую модель исполнения, а это значит, что никакие формы управления потоком вычислений основанные на оной модели(например все коммонлисповые - tagbody+go, block+return-from, throw+catch, unwind-protect) не могут быть нормально реализованы(они, во-первых, просто теряют смысл, а во-вторых их семантику становится легко, случайно и непреднамеренно даже, сломать, использовав продолжения).

Во-вторых, так как у нас теряется понятие dynamic extent, то все first-class и second-class сущности, включая теперь и собственно поток вычислений, получают unlimited extent, а значит мы теперь не можем детерминированно управлять временем жизни неуправляемых ресурсов, навроде файловых дескрипторов.

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

call/ep

Jan. 5th, 2013 09:31 pm
love5an: (R)
Я тут почитываю Lisp in Small Pieces. Крайне интересная книжка, рекомендую.

Решил поделиться следующим фактом.

Для того, чтобы реализовать всю семантику контроля потоком вычислений Common Lisp, включая в том числе обработку исключений CL, нужно чтобы язык поддерживал Escape Continuations.

А конкретнее, необходимо реализовать процедуру call/ep, или аналогичный макрос let/ep

call/ep имеет тот же интерфейс, как и call/cc, с тем лишь отличием, что процедура-продолжение, передаваемая в параметр функции становится невалидной сразу после выхода из фрейма активации этой функции. То есть, мы можем "выйти" из функции/блока, но зайти в него снова, как мы могли бы это сделать с полноценными продолжениями - мы не можем.

Вот как эта процедура пишется на CL.


(defun call/ep (f)
  (block exit-point
    (labels ((escape-procedure (arg)
               (return-from exit-point arg)))
      (funcall f #'escape-procedure))))

(defmacro let/ep ((var) &body body)
  (let ((block (gensym "EXIT-POINT"))
        (escape-procedure (gensym "ESCAPE-PROC"))
        (arg (gensym "ARG")))
    `(block ,block
       (labels ((,escape-procedure (,arg)
                  (return-from ,block ,arg)))
         (let ((,var #',escape-procedure))
           ,@body))))) 



Фактически, для полноценных escape-продолжений нам необходимо лишь реализовать базис в виде двух операторов/функций - throw и catch(или, что то же самое - block и return-from). Желательно, конечно, чтобы в базисе был еще и unwind-protect, но имея упомянутые два оператора, мы можешь написать его и сами.

Как несложно догадаться, все это вместе поддается реализации на любом языке, поддерживающем замыкания и исключения(или же setjmp+longjmp). Замыкания, впрочем, можно заменить объектами, но в таком случае всё это дело будет смотреться более громоздко.
love5an: (Default)
Как наверное некоторые знают, одной из самых близкий и интересных мне тем в области программирования, и CS вообще, является синтаксический анализ.

В свободное время, как я уже писал, я занимаюсь разработкой своего языка программирования, основанном на Common Lisp, и одна из тем, которая меня очень сильно интересует это расширяемый синтаксис.
Read more... )
love5an: (Default)
Я тут недавно опять думал про неймспейсы, в контексте лиспа, и, внезапно, меня осенило:


(defstruct symbol
  (name     "" :type string)
  (children () :type list)
  ...)

love5an: (Default)
Кстати, тут в Juick напомнили про Си, и я решил написать, что я про Си думаю.
Вообще, получилось не только про Си, но, все таки.

Так вот, то что Си еще жив это, если подумать, вершина идиотизма около-ITшных масс.
Read more... )
love5an: (Default)
Ну и небольшой драфт языка, вообще.

Репозиторий на гитхабе тут(если кто прошлый постинг еще не читал):
https://github.com/Lovesan/Microlisp

Read more... )

Microlisp

Dec. 12th, 2011 07:36 pm
love5an: (Default)
Совершенно от нефиг делать: https://github.com/Lovesan/Microlisp

Буду коммитить на гитхаб по ходу разработки, вобщем. Кому интересно написание интерпретаторов и компиляторов Common Lisp-подобных языков — фоловите.

Планы такие - дописать XI(кросс-интерпретатор, написанный на CL), потом написать компилятор на самом микролиспе, потом им скомпилировать рантайм, стандартную библиотеку и самого себя.
Ну то есть, без всяких там Си.
love5an: (Default)
Сейчас я опишу одну из главных причин по которым я недолюблюваю Ъ ф.п, и люблю CL.

Read more... )

I/O

Oct. 12th, 2011 03:46 pm
love5an: (Default)
Такой вопрос.

В каких языках ввод/вывод в стандартных библиотеках вам кажется наиболее органично устроен, и наиболее удобен в использовании? Как насчет "нестандартных" библиотек? Куда посмотреть в сторону удобных i/o библиотек с продуманной, продвинутой, логичной и прозрачной архитектурой(язык программирования не важен)?

Ко вводу/выводу я тут отношу все связанное с потоками(streams), файлами, сокетами, файловой системой, пайпами, асинхронным i/o и прочим подобным и прилежащим.

Без троллинга, если можно.
Спасибо.

p.s. тэг "lisp" - просто чтобы прочитало больше народу
love5an: (Default)
Продолжаем серию постингов "C++ - говно". На этот раз у нас в гостях C#, а тема - написание COM-компонентов.

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

На самом деле это не так. COM в своей основе крайне прост, и является одной из самых удобных технологий для интероперабельности между различными платформами, рантаймами языков программирования и программами. Для случая RPC же, COM вообще является чуть ли не самой простой и удобной из всех таких технологий, и одной из наименее затратных по памяти и производительности(особенно в сравнении со всякими XML-RPC).
Read more... )
love5an: (Default)
Я на самом деле очень сильно удивлен тем, что очень много людей даже примерно не представляют себе, сколько оверхеда вносят счетчики ссылок, и насколько они менее эффективны, чем нормальный сборщик мусора.

Не перестают меня удивлять и заявления о том, что де, раз в C++ есть boost, с его shared_ptr и прочим, то проблема сборки мусора для C++ фактически решена.

Ладно уж, не будем о том, что счетчики ссылок неспособны разрешить циклические зависимости, просто сравним ту самую производительность, за которую писатели на C++ так трясутся.

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

Заключается он в следующем:
Создаем вектор на 'length' элементов, заполняем его указателями на структуры, подобные лисповым cons-ячейкам, и 'n' раз прогоняем цикл, в котором создаем копию этого вектора, а старый удаляем(элементы при этом мы не копируем, а копируем только указатели на них). Указатели, в C++, естественно, используем "умные".
В качестве противника C++, то есть в качестве языка, в реализациях которого присутствует нормальный GC, я взял Common Lisp, если конкретно - SBCL.

Read more... )
love5an: (Default)
Устал от того, что люди путают динамическую типизацию со слабой или называют лисп бестиповым.
Поэтому нарисовал вот такую картинку.
Виды типизации

(*) Java, C# и Obj-c обладают возможностями динамической типизации. Например, боксинг в Object в Java и C#. Кроме того, в C# 4.0 ввели новое ключевое слово dynamic.
(**) В CL и Clojure присутствуют опциональные декларации типов, так что можно считать, что в них есть немного статической типизации. Современные реализации Common Lisp проводят агрессивный вывод типов при компиляции.
(***) Форт и языки ассемблера принято считать бестиповыми. Но, машинные слова разного размера это ведь тоже типы какие-никакие.

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

Upd: вот еще [livejournal.com profile] jtootf подкинул ссылку: blogs.perl.org/users/ovid/2010/08/what-to-know-before-debating-type-systems.html
love5an: (Default)
Существует замечательный сайт C++ FQA Lite, в котором подробно и обстоятельно объясняются недостатки C++.

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

Поэтому я решил составить свой список, в котором четко и ясно объясняется, почему же все-таки я считаю C++ таким страшным говном, которое надо закопать. В списке всего десять пунктов, все четко, ясно и по делу.

Итак:

Read more... )

По причинам 3, 4, 5, 9 и 10 C++ совершенно неприменим для системного и низкоуровневого программирования.
А по причинами 1, 2, 5, 6, 7, 8, и, опять же, 9 и 10 - и для прикладного.

У C++ нет области применения. C++ протух и умер. Хватит насиловать труп!
love5an: (Default)
Почему мне так активно не нравится питон и люди, его активно защищающие?

Среди прочего, потому, что я часто от них слышу что-то о том, что в современном мире, с современными компьютерами, производительность де совершенно не важна, и поэтому убогие алгоритмы сборки мусора, выделение здоровенных кусков памяти на каждый мелкий инт, интерпретация текста направо и налево это все совершенно неважные мелочи, главное ведь язык то такой "няшный", и код на нем такой то красивый, в противоположность CL с полотнами из declare и declaim.

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

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

Люди, приводящие аргумент о неважности производительности, как по мне, так не только ничего крупного и серьезного не писали(ничего серьезнее мелких веб-поебеней, как минимум), так и вообще даже не читали об этом.

Вот пример - взять компьютерную графику. Существует такая замечательная технология - трассировка лучей(ray tracing). Она позволяет создавать очень реалистичные изображения, потому как позволяет очень просто и естественно рисовать освещение, тени, отражения и сложные поверхности.

Но с ней есть одна такая "небольшая" проблема - эта техника крайне ресурсозатратна. Настолько, что даже крупнейшие студии компьютерной анимации, типа PIXAR, которые могут позволить себе задействовать целый кластер для отрисовки одного кадра, и то используют ее крайне редко и избирательно - а что уж там говорить про реалтайм рендеринг на современных десктопах - разработчики игр тужатся изо всех сил, выдумывая сложнейшие техники с труднопроизносимыми названиями, вроде Parallax Occlusion Mapping или K-буферов, чтобы добиться хоть какой-нибудь фотореалистичности при сохранении приемлимой производительности. И GPU тут не волшебная таблетка - даже в AAA-тайтлах, ориентированных на пользователей high-end видеокарт, многие вещи в графике, например вычисление World/View/Projection матриц или кватернионов, общих для отдельных частей моделей, приходится делать на процессоре, потому что количество матричных преобразований в отдельной вершине, полигоне или, тем более, пикселе, необходимое чтобы снизить FPS до нуля, не так уж высоко даже для суперсовременных графических процессоров.

Другой пример - хранение и обработка данных. Покуда у вас не кластер на тысячи машин, то если вы делаете что-то крупнее статистики по успеваемости в отдельно взятой студенческой группе, вам надо очень много думать над моделью хранения данных в памяти, и над архитектурой доступа к ним - 8-16 гигабайт в 64-битных машинах, или, тем более, 2-4 в 32-битных это совсем не так много, как может показаться на первый взгляд, но вместе с тем, достаточно много для того, чтобы дико тормозить даже на современнейших системах, если у вас доступ к этим 2-4-8-16 гигабайтам не продуман до мельчайших деталей.

Закон Мура никто не отменял, но он совсем не о том, что мы можем растрачивать ресурсы компьютеров на какое-то говно. Одно дело, когда программа на C отрабатывает за 1 миллисекунду, а программа на X - за 300. Но другое дело когда программа на Си выполняется час, а аналогичная на X - две недели.

WPF

Jan. 19th, 2011 12:00 am
love5an: (Default)
WPF охуенно. WPF круто, нереально круто.

GTK+ - говно. Qt - говно. wxWidgets - говно. Tk - говно. Pure Winapi, MFC, ATL, WTL - говно. Windows.Forms - говно. Cocoa - говно. SWT - говно. Swing - говно. Все это блевотное говно.

А WPF пиздато.
Read more... )
love5an: (Default)
Или, "почему Python - говно".
Read more... )

Profile

love5an: (Default)
Dmitry Ignatiev

December 2016

S M T W T F S
    123
45678910
11121314 151617
18192021222324
25262728293031

Syndicate

RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jul. 20th, 2017 12:50 pm
Powered by Dreamwidth Studios