Следующая страница > 1 < [2] [3] [4]

Автор Сообщение

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6493   2012-09-12 22:36 GMT+3 часа(ов)      
Есть здесь такие люди, кто считает, что %ваш любимый диалект Лиспа% идеален и ничего менять не нужно? Вам не стоит читать дальше.

Я же предлагаю сделать более лучший диалект Лиспа, взяв за основу Scheme/Racket (в части Лисп-1 -- совмещение слотов значений и функций в один для символа, возможно макросов и пр.) и Common Lisp (в части развитого рантайма).

Что планируется сделать:

10) В основу нового Лиспа должна войти LLVM, т.к. это сильно упростит разработку хорошего JIT-компилятора, реализацию кроссплатформенности и предоставит всевозможные оптимизации производительности искаропки. Писаться все это будет на Racket, если не получится с Racket, то на C++, т.к. там наилучшая интероперабельность с LLVM.

20) Часть семантики CL планируется оставить практически без изменений с небольшими коррективами возможно (в том числе CLOS), т.к. она достаточно гибкая и тут особо выдумывать ничего не нужно (может быть только first-class continuations, да оптимизацию хвостовой рекурсии запилить прям в стандарт языка как в Scheme).

30) Система типов планируется в следующем виде: в core lang: статическая типизация с базовыми типами близкими к языку C + какое-то приближение лямбда-исчисления (Хиндли-Милнер); + в standard edition (в виде макросов): ООП с динамической диспетчеризацией по обобщенным функциям как в CLOS, мн. наследованием, а так же оптимизация динамической типизации по type tags.

40) Пакетную систему планируется перепроектировать, т.к. в CL она доставляет множество неудобств, хотя возможно при использовании макросов Racket больших изменений не потребуется.

41) С макросами пока нет определенности, после дополнительного изучения будет определено какой тип макросов оставить (CL или Racket). Скорее всего Racket, т.к. судя по обсуждению ниже мы ничего не теряем и в то же время простые вещи упрощаются.

50) Работу с файловой системой тоже планируется перепроектировать, т.к. в CL это суко говно мамонта какое-то.

60) Необходимо четко разделить рантайм и стандартную библиотеку, которую планируется распихать по пакетам. Кроме того, возможно необходимо сделать стандартные продукты типа Enterprise Edition(включено все, что в основном требуется для больших софтов), Standard Edition(выкинуто то, что не нужно для простых десктоп приложений), Mobile Edition(выкинуто то, что не нужно для мобильных девайсов), Embedded Edition(выкинуто всё, включая стандартный сборщик мусора, осталась только core system из привязок к LLVM и FFI), чтобы была возможность выбирать сборку под задачу и не тащить с собой все подряд и ещё немного.

70) Планируется так же реализация поставки библиотек в виде скомпилированного кроссплатформенного байткода, для быстрой загрузки библиотек и возможно рантайма. Будет ли это байткод LLVM или ещё один сверху пока не ясно. Скорее всего придется городить свой байт-код со своей ВМ поверх LLVM.

80) Поддержка юникода искаропки, внутренняя кодировка только UTF-8, только хардкор.

90) Избавление от не-Лисп-style макросов типа loop, замена их чем-то более дружественным Лиспу (iterate там).

100) Case-sensitive конечно же.

110) Возможность сохранить систему в исполняемый бинарник. Возможно так же с предварительным выкидыванием неких частей инфраструктуры (JIT-компилятора там, ридера, whatever, тут ещё подумать надо насколько это осуществимо).

120) Condition System вероятно будет реализована с помощью макросов поверх continuations. Тут ещё бы неплохо про эффективность подумать.

130) Предполагается возможность отключения сборщика мусора и управления памятью вручную (по типу реализации в D2), а так же возможность переопределения операций выделения/освобождения памяти для реализации своих аллокаторов.

140) Возможности работы с LLVM напрямую -- все необходимые привязки в ядре языка: генерирование функций, блоков и SSA-инструкций в рантайме и их подключение. (Поверх FFI)

150) ОТМЕНЕНО, т.к. противоречит эффективности исполнения и следовательно сужает область применения // Рассматривается возможность реализации принципов языка Kernel с vau и wrap'ом. Если она покажет себя хорошо, то возможно и макросы как таковые не понадобятся.

160) Ещё что-нибудь, буду дописывать по ходу...

Примерный план работ и их очередность:

10) Спроектировать систему типов.
20) Запилить LLVM kernel язык -- без сборки мусора, но с возможностью работать с LLVM и FFI через LLVM.
30) Добавить макросы. (Embedded Edition в принципе готов)
40) Написать стандарт языка в общем виде.
50) Написать на макросах рантайм (динамическая типизация, лямбды, замыкания, ООП, библиотека типов, пакетная система и пр.)
60) Переписать систему на kernel language.
70) Написать стандартную библиотеку. (Standard Edition готов)
80) Написать открытый репозиторий сторонних библиотек.
90) Закончить стандарт языка.
100) Урезать/переписать стандартную библиотеку для мобильных нужд(Mobile Edition готов)
110) Написать стандарты Enterprise инструментов.
120) Написать сами Enterprise инструменты (Enterprise Edition готов).
130) ???
140) PROFIT!

Какими силами планируется это всё сделать:

1) Вообще проект сразу рассчитан на долгий период, так что быстрых результатов ждать однозначно не стоит. Я очень надеюсь, что LLVM ускорит разработку и позволит добиться какого-то осязаемого результата не за 10 лет, допустим, а за 5.

2) Планируется использование собственных сил, но т.к. удается выделять не так уж и много свободного времени на данном этапе, то этого однозначно недостаточно.

3) Есть возможность так же привлечь сторонних разработчиков за деньги из своего личного кармана, т.к. деньги свои, то и разработчиков буду стремиться найти оптимальных по соотношению цена/качество.

4) Возможна попытка привлечь дополнительные средства посредством донейтов или кикстартеров, но я сильно сомневаюсь, что таким образом можно что-то собрать, т.к. никто ессно в результат не верит и никому это не нужно.

5) Ну и если появятся заинтересованные лица, готовые поучаствовать, то это будет большой плюс производительности и мотивации =).

В связи с этим несколько вопросов к сообществу:

1) В каком диалекте или библиотеке вы видели самую лучшую реализацию пакетной системы для Лиспа?

2) Что ещё нужно обязательно исправить, добавить или выкинуть из существующих диалектов?

3) Сколько может стоить достаточной квалификации лиспер на удаленную работу (не обязательно из России)?

4) На какую помощь/содействие от сообщества я могу рассчитывать по вашему мнению: обсуждение стандарта, предложения по функционалу, помощь в реализации, материальное содействие, whatever?

5) Обобщенный true -- это труъ или не труъ? Мне больше импонирует подход Scheme, когда булев тип вынесен отдельным типом, но детального исследования на что влияет это решение я не проводил.

6) Стоит ли идти по пути CL и объединять nil с пустым списком или логичнее сделать nil отдельным значением и типом? Тоже не смотрел пока на что это повлияет.

отредактировал(а) metadeus: 2012-12-07 17:26 GMT+3 часа(ов)

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6494   2012-09-13 05:06 GMT+3 часа(ов)      
А почему за основу общелисп, а не няшная схемка?

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6495   2012-09-13 14:34 GMT+3 часа(ов)      
Вообще говоря, это я опрометчиво заявил, т.к. предполагался именно Лисп-1, а не Лисп-2, т.к. считаю funcall не очень изящным решением. Во многом просто планируется взять проверенные временем решения CL, как то: condition system и CLOS. Сейчас поправлю по этому поводу пост.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6496   2012-09-13 14:54 GMT+3 часа(ов)      
но если будут call/cc, то condition system ненужна. точнее она выражается через продолжения в пару десятков строк.

то есть получаем схему с clos?

вообще было бы интересно сделать максимально низкоуровневый (вплоть до прямой работы с поинтерами) статически типизированный parenthesis core-language на базе system f + call/cc + прозрачный ffi + рантайм, полноценно поддерживающий макросы (адекватная модульность, фазы, гигиена, короче все плюшки) + compile-level macros. упор на производительность всего этого.

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

отредактировал(а) Kergan: 2012-09-13 15:05 GMT+3 часа(ов)

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6497   2012-09-13 16:13 GMT+3 часа(ов)      
Цитата
Kergan :
но если будут call/cc, то condition system ненужна. точнее она выражается через продолжения в пару десятков строк.


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

Цитата
Kergan :
то есть получаем схему с clos?


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

Цитата
Kergan :
вообще было бы интересно сделать максимально низкоуровневый (вплоть до прямой работы с поинтерами) статически типизированный parenthesis core-language на базе system f + call/cc + прозрачный ffi + рантайм, полноценно поддерживающий макросы (адекватная модульность, фазы, гигиена, короче все плюшки) + compile-level macros. упор на производительность всего этого.

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



Меня постоянно мучает вопрос почему тоже самое нельзя получить с помощью привязок к LLVM в Scheme или CL, с последующим выкидыванием всего остального/лишнего из Лисп-рантайма и сохранением этого образа?

Но мне кажется куда важнее стройная семантика самого Лиспа и Лисп-машины, т.к. та же работа с указателями и ffi это вещи сугубо завязанные на платформу, а ограничивать применимость одной платформой или пытаться ещё раз реализовать поддержку кроссплатформенности а-ля SBCL и повторением большей части функциональности LLVM на мой взгляд совсем не айс.

Ещё по поводу сборки мусора -- планирую реализовать отключаемую сборку мусора, то есть позволить вручную освобождать память, как в D.

По поводу макросов, кстати, я планировал оставить CL-style макросы, но, т.к. макросы схемы и их преимущества/недостатки я знаю плохо, то возможно тут стоит ещё подумать.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6498   2012-09-13 16:25 GMT+3 часа(ов)      
Цитата
Но мне кажется куда важнее стройная семантика самого Лиспа и Лисп-машины, т.к. та же работа с указателями и ffi это вещи сугубо завязанные на платформу

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

Цитата
и повторением большей части функциональности LLVM на мой взгляд совсем не айс.

собственно, kernel language можно с llvm и компилировать. Тем более, что в любом случае нужен jit, а не прямая генерация в машкод.

Цитата
Ещё по поводу сборки мусора -- планирую реализовать отключаемую сборку мусора, то есть позволить вручную освобождать память, как в D.

главное предоставить и unsafe низкоуровневые средства, которые позволят хоть свои сборщики/аллокаторы писать.

Цитата
По поводу макросов, кстати, я планировал оставить CL-style макросы, но, т.к. макросы схемы и их преимущества/недостатки я знаю плохо, то возможно тут стоит ещё подумать.

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

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6499   2012-09-13 17:06 GMT+3 часа(ов)      
Цитата
Kergan :
ффи и низкоуровневое ядро нужны за тем, чтобы рантайм лисп-системы не накладывал сильные ограничения. то есть его всегда можно будет прямо находу доработать, используя специально предусмотренные средства.

собственно, kernel language можно с llvm и компилировать. Тем более, что в любом случае нужен jit, а не прямая генерация в машкод.



Ок, только семантику этого ядра, я так понимаю лучше привязать к семантике регистровой машины LLVM, то есть дать возможность разработчику на самом низком уровне генерить функции, блоки и SSA LLVM и подключать все это дело в рантайме к рантайму (лол).

Цитата
главное предоставить и unsafe низкоуровневые средства, которые позволят хоть свои сборщики/аллокаторы писать.


Да, обязательно.

Цитата
макросы схем умеют все, что умеют макросы CL, но проще и надежнее, + умеют еще кое-что, чего макросы CL не могут. по-этому я вообще не вижу ни одной причины по которой можно было бы брать макросистему общелиспа. В 21 веке живем, все-таки.


Спасибо, почитаю, посмотрю, возможно действительно от CL мало что останется =)))

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6500   2012-09-13 18:06 GMT+3 часа(ов)      
Цитата
Kergan :
макросы схем умеют все, что умеют макросы CL, но проще и надежнее, + умеют еще кое-что, чего макросы CL не могут. по-этому я вообще не вижу ни одной причины по которой можно было бы брать макросистему общелиспа. В 21 веке живем, все-таки.



Что-то пишут, что макросы Схемы не могут:
(defmacro aif (test true-branch &optional false-branch)
`(let ((it ,test))
(if it
,true-branch
,false-branch)))


Ещё пишут, что на CL можно написать макросы Схемы http://www.ccs.neu.edu/home/dorai/mbe/mbe-lsp.html, с другой стороны макросы Общелиспа на Схеме тоже вроде как пишут. Единственный аргумент, который у меня остался это то, что макросы Общелиспа более низкоуровневые, поэтому логично именно их включить в kernel языка (в дополнение к арифметике указателей =)). Но тут ещё нет конечного решения.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6501   2012-09-14 06:01 GMT+3 часа(ов)      
> Что-то пишут, что макросы Схемы не могут:

Могут (возьму Racket вместо Scheme):
 
(define-simple-macro (aif cond:expr then:expr else:expr)
#:with it (datum->syntax #'aif 'it)
(let ([it cond]) (if it then else)))
 

но более корректный путь - использовать syntax-patameter:
http://blog.racket-lang.org/2008/02/dirty-looking-hygiene.html

Здесь надо отметить, что обход гигиены нам нужен очень-очень редко. а вот ее ввод - всегда. по-этому вполне логинчо, что автоматом гигиена - есть, а когда надо - ее можно убрать.

> Ещё пишут, что на CL можно написать макросы Схемы

Нет, нельзя (кто так говорит просто не понимает как именно работают гигиенические макросистемы). У того же racket экспандер по сути двухпроходной (искаробки заложена возможность сперва собраь все объявления и выделить из них статическую информацию, а потом уже обрабатывать код, многие макросы даже в стандартной библиотеке завязаны на это поведение), кроме того работа идет не со списками а с синтаксическими объектами - то есть там содержится информация о биндингах, source location, можно добавлять и использовать произвольные свойства к синтаксическим объектам ну и + служебная информация типа syntax arms, expression path и т.п. - ко всему этому, естественно, есть доступ во время экспанда, все эти вещи можно извлекать, модифицировать, етц.
То есть чтобы это работало в общелиспе, надо изменить представление программы и полность переписать экспандер. То есть с нуля написать макросистему Racket

> Общелиспа более низкоуровневые, поэтому логично именно их включить в kernel языка

Наоборот - они с этой точки зрения более высокоуровневые, т.к. мы не можем через них "дотянуться" до более низкоуровневых свойств АСТ (можно считать, что эти детали АСТ от нас скрыты). То есть на самом деле просто в CL этих свойств у АСТ нету и дотягиваться не до чего, но это уже непринципиально.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6502   2012-09-14 06:13 GMT+3 часа(ов)      
Цитата
Ок, только семантику этого ядра, я так понимаю лучше привязать к семантике регистровой машины LLVM, то есть дать возможность разработчику на самом низком уровне генерить функции, блоки и SSA LLVM и подключать все это дело в рантайме к рантайму (лол).

Да, единственное что смущает - тяжеловесность ЛЛВМ. Но в сущности не такая это и проблема. То есть в моих мокрых фантазиях языковой "стек" мне представляется так:
язык - (обработка экспандером) > базовые формы языка - (обработка пост-экспандером) > IR, kernel language - (транслятор в байткод (тривиальный)) > bytecode (полностью повторяет по структуре KL, но более компактен, удобен для обработки) - (хуки к LLVM задающие компиляцию bytecode) > jit/машкод -> рантайм, в котором это все крутится, так же хуки ллвл, позволяющие модифицировать поведение, самый низкий уровень.

и каждый шаг может настраиваться, доопределяться, переопределяться.

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

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6503   2012-09-14 14:52 GMT+3 часа(ов)      
Цитата
Kergan :
 
(define-simple-macro (aif cond:expr then:expr else:expr)
#:with it (datum->syntax #'aif 'it)
(let ([it cond]) (if it then else)))
 




Выглядит немного переусложнённо.

Цитата
Kergan :
Здесь надо отметить, что обход гигиены нам нужен очень-очень редко. а вот ее ввод - всегда. по-этому вполне логинчо, что автоматом гигиена - есть, а когда надо - ее можно убрать.



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

Цитата
Kergan :
У того же racket экспандер по сути двухпроходной (искаробки заложена возможность сперва собраь все объявления и выделить из них статическую информацию, а потом уже обрабатывать код, многие макросы даже в стандартной библиотеке завязаны на это поведение), кроме того работа идет не со списками а с синтаксическими объектами - то есть там содержится информация о биндингах, source location, можно добавлять и использовать произвольные свойства к синтаксическим объектам ну и + служебная информация типа syntax arms, expression path и т.п. - ко всему этому, естественно, есть доступ во время экспанда, все эти вещи можно извлекать, модифицировать, етц.
То есть чтобы это работало в общелиспе, надо изменить представление программы и полность переписать экспандер. То есть с нуля написать макросистему Racket



Звучит как более сложное в реализации решение нежели простые как валенок макросы CL.

Цитата
Kergan :
Наоборот - они с этой точки зрения более высокоуровневые, т.к. мы не можем через них "дотянуться" до более низкоуровневых свойств АСТ (можно считать, что эти детали АСТ от нас скрыты). То есть на самом деле просто в CL этих свойств у АСТ нету и дотягиваться не до чего, но это уже непринципиально.



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

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6504   2012-09-14 19:21 GMT+3 часа(ов)      
Цитата
Звучит как более сложное в реализации решение нежели простые как валенок макросы CL.

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

Цитата
Можешь привести пример, когда это нужно, потому что я не очень понимаю в каких ситуациях эти возможности могут понадобиться?


во-первых, макросистема гарантирует, что у нас не будет весьма широкого класса ошибок (без помощи макросистемы такие гарантии получить очень сложно либо вообще невозможно) - в этом основной смысл именно гигиены (то есть гарантий корректного захвата идентификатором контекста области определения). На схеме я просто пишу макрос - и знаю что он работает, мне даже не надо и задумываться о том, что что-то как-то может не так захватиться. Чем сложнее макрос - тем больше выгоды, то есть там где я в общелиспе начну путаться в пекеджах, генсимах и полностью потеряю контроль над контекстом, с гигиеной все just works с нулевыми затратами с моей стороны. Если говорить о замене списков синтаксическими объектами - ну тут все очень обширно. Зная информацию о source location мы можем очень легко и просто контролировать сообщения об ошибках, (особенный профит за счет интеграции с иде, конечно), это позволяет разработчику макроса эффективно скрыть "внутренности" макроса для пользователя. Добавления произвольных свойств - просто увеличивает гибкость и возможности (например, можно каждому объекту прилепить свойство "тип" и на основе этого делать макросами чекер). Возможности работы с лексическим контекстом позволяют добавлять в контекст произвольную информацию и потом в других макросах эту инофрмацию произвольно преобразовывать или использовать для экспанда - именно так, например, макрос match использует статическую информацию внесенную макросом struct. Причем это все, повторяю, работает корректно, в соответствии со скоупом, никаких проблем, которые бы были при попытке такое реализовать в CL, нет.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6505   2012-09-14 19:30 GMT+3 часа(ов)      
Цитата
Выглядит немного переусложнённо.

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

Цитата
Тут согласен, но нужно ли все что описано дальше, если нам нужна только гигиена? Может быть её можно добиться более простым путем нежели:

гигиены-то можно добиться более простым путем, но именно "то что ниже" делает макросы действительно мощным и удобным инструментом как для макрописателя, так и для пользователя макробиблиотеки. Хотя бы тот же макростепепер ракетовский (который без синтаксических объектов и работы с контекстом не напишешь) уже вы не представляете на сколько упрощает отладку макросов. корректная обработка ошибок, толковая система модулей с фазами исполнения - все это резко повышает юзабельность. я уж не говорю про какие-то конкретные фичи, которых в общелиспе не выразить, но благодаря которым тот же iterate или loop можно реализовать в 10-20 раз короче и при этом понятнее. и гигиена, которая гарантирует, что все just works

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6506   2012-09-14 20:05 GMT+3 часа(ов)      
Цитата
Kergan :
Конечно. Любой лучший инструмент более сложен в реализации
Качественное делат ьвсегда труднее, чем тяп-ляп.



Главное, чтобы не accidental complexity, я вот к чему ;-).


Цитата
Kergan :
во-первых, макросистема гарантирует, что у нас не будет весьма широкого класса ошибок (без помощи макросистемы такие гарантии получить очень сложно либо вообще невозможно) - в этом основной смысл именно гигиены (то есть гарантий корректного захвата идентификатором контекста области определения). На схеме я просто пишу макрос - и знаю что он работает, мне даже не надо и задумываться о том, что что-то как-то может не так захватиться. Чем сложнее макрос - тем больше выгоды, то есть там где я в общелиспе начну путаться в пекеджах, генсимах и полностью потеряю контроль над контекстом, с гигиеной все just works с нулевыми затратами с моей стороны. Если говорить о замене списков синтаксическими объектами - ну тут все очень обширно. Зная информацию о source location мы можем очень легко и просто контролировать сообщения об ошибках, (особенный профит за счет интеграции с иде, конечно), это позволяет разработчику макроса эффективно скрыть "внутренности" макроса для пользователя. Добавления произвольных свойств - просто увеличивает гибкость и возможности (например, можно каждому объекту прилепить свойство "тип" и на основе этого делать макросами чекер). Возможности работы с лексическим контекстом позволяют добавлять в контекст произвольную информацию и потом в других макросах эту инофрмацию произвольно преобразовывать или использовать для экспанда - именно так, например, макрос match использует статическую информацию внесенную макросом struct. Причем это все, повторяю, работает корректно, в соответствии со скоупом, никаких проблем, которые бы были при попытке такое реализовать в CL, нет.


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

Если макросы CL + гигиена по умолчанию + возможности использования рефлексии во время макроэкспанда это и есть макросы Схемы, то я в приницпе за. Почитаю ещё про Схемные макросы.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6507   2012-09-14 20:24 GMT+3 часа(ов)      
Цитата
Главное, чтобы не accidental complexity, я вот к чему ;-).

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

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

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

Цитата
это и есть макросы Схемы

В схеме вообще только гигиена и зоопарк разных ее реализаций. А лучшая макросистема - в Racket.

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6540   2012-09-18 16:56 GMT+3 часа(ов)      
Ещё один большой вопрос: знакомы ли вы с концепциями [url]http://en.wikipedia.org/wiki/Kernel_(programming_language)[/url] (ссылка не вставляется, сорри)? Я долго думал над тем, что в нем предложено и на мой взгляд это большой шаг вперед в части гомоиконности языка и "все есть объекты первого класса".

В кратце, что предлагается в Kernel: разбить создание функции на две части -- одна часть -- функция vau -- создает функцию с невычисляемыми параметрами, а вторая часть wrap -- оборачивает любую функцию вычисляя её параметры перед вызовом.

Зачем это нужно -- а затем, что многие вещи вместо специальных форм становятся простыми функциями, в частности специальный оператор and, становится (из документации):
($define! $and?
($vau x e
($cond ((null? x) #t)
((null? (cdr x)) (eval (car x) e))
((eval (car x) e) (apply (wrap $and?) (cdr x) e))
(#t #f))))


Тогда, например, оператор set! это просто:
(define (set! place value)
(vau place value
(if (symbol? place)
(%symbol-set place (eval value))
(error "Dunno know how to set! to {}" place))))


Который можно легко расширять любыми конструкциями по типу макроса setf CL, но в то же время это просто функция которую можно передать в map, например.

Автор Kernel пишет, что f-expr вообще говоря более мощное средство, чем макросы. Насколько вообще оправдано использование f-expr в современных Лиспах?

P.S. На форум походу накинулись рекламные боты. Кто-нибудь вообще следит за этим форумом или он как бы мертвый и один я тут шатаюсь между могил?

отредактировал(а) metadeus: 2012-09-18 20:36 GMT+3 часа(ов)

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6543   2012-09-19 10:45 GMT+3 часа(ов)      
Цитата
Ещё один большой вопрос: знакомы ли вы с концепциями

да

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

Цитата
это большой шаг вперед в

то есть это шаг назад, в 60е. предложение выбросить нафиг полвека развития лиспов

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6545   2012-09-20 14:45 GMT+3 часа(ов)      
Цитата
Kergan :
собственно, раньше лиспы ведь такие и были, но потом все согалсились, что фекспры - говно.
во-первых, программу с фекспрами можно _только интерпретировать_. никакой тебе компиляции, джита, все будет жутко тормозить и с этим нету никакого способа что-либо сделать. Во-вторых, если у тебя есть фекспры, то нет макросов, что резко ограничивает гибкость и выразительнотсь языка. То есть тут некоторый парадокс - с одной стороны, фекспры вроде более мощны, но с другой, язык с фекспрами проигрывает в выразительности языку с макросами. То есть язык без ничего и с фекспрами позволяет реализовать некие основные формы, а язык без ничего и без фекспров - не позволяет. но если у нас есть язык с основными формами и макросами, то он уже будет более выразителен in practice, в частности, он позволяет реализовать фекспры. а вот макросы через фекспры не реализуешь (и вообще фазы исполнения)...



Все что удалось накопать по этому поводу это странное заявление с http://c2.com/cgi/wiki?RuntimeMacro:
Цитата

The problem with this approach is that it makes compilation essentially impossible. Consider this code:
(define (map fn collection)
(cons (fn (car collection)) (map fn (cdr collection))))
If fn evaluates its argument, map needs to call (car collection) and pass that along. If not, map needs to package up the program fragment (car collection) into a thunk and pass that along. But it can't know which until run time, because fn could be any arbitrary function, even from outside the compilation unit.



В рамках Kernel тут как раз нет никакой неопределенности, в данном случае fn сама должна eval'ить параметры если ей это нужно, а map всегда передает `(car ,collection), причем по идее может сопроводить её скомпилированной функцией (точнее замыканием тогда уж) для быстрого eval'а, а fn может незадумываясь исполнить эту функцию. Хотя, конечно, многие виды оптимизаций и даже простейший inline уже работать не будут и придется компилировать отдельными кусочками чуть ли не каждый S-expr который передается в функцию про которую неизвестно обернута она во wrap или нет. В общем, жаль -- такая красивая и простая концепция.

Хотелось бы ещё по поводу типизации спросить: если core lisp будет иметь семантику C-шную, например, или LLVM (кстати, что лучше предпочесть -- по идее если закладываемся на LLVM, то логичнее и семантику LLVM воплотить?), то и система типов в core lisp будет статическая, а уже поверх неё будет реализована динамика? Мне такой подход очень нравится, т.к. статическая типизация существенно расширяет границы применимости языка -- такой core lisp можно даже для написания ядра ОС использовать.

Насколько системы типов C и LLVM хороши? Не лучше ли тогда попытаться вкорячить ADT и другие возможности того же Haskell, с Хиндли-Милнерами и другими радостями? Или сделать ADT надстройкой над системой типов C/LLVM?

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6546   2012-09-20 15:50 GMT+3 часа(ов)      
Цитата
В рамках Kernel тут как раз нет никакой неопределенности, в данном случае fn сама должна eval'ить параметры если ей это нужно, а map всегда передает `(car ,collection)

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

Цитата
В общем, жаль -- такая красивая и простая концепция.

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

Цитата
Хотелось бы ещё по поводу типизации спросить: если core lisp будет иметь семантику C-шную, например, или LLVM

я бы предпочел некую более мощную систему, ту же system f. А вот это дело уже компилируем с ллвм.

Цитата
то и система типов в core lisp будет статическая, а уже поверх неё будет реализована динамика? Мне такой подход очень нравится, т.к. статическая типизация существенно расширяет границы применимости языка -- такой core lisp можно даже для написания ядра ОС использовать.

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

Цитата
Насколько системы типов C и LLVM хороши? Не лучше ли тогда попытаться вкорячить ADT и другие возможности того же Haskell, с Хиндли-Милнерами и другими радостями?

в том варианте про который я изначально говорил ядро как раз system-f с АДТ, возможно тайпклассами (или любой другой вариант ad-hoc полиморфизма), ну и нативными продолжениями. Через него при желании довольно легко выразить более мощные концепции, с другой стороны, оно само по себе весьма простое. То есть в некоторой степени обладает свойствами минимальности и полноты. Байткод как раз и будет представлять термы этого языка, а дальше уже тот же llvm генерит байткод.

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

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6547   2012-09-20 17:15 GMT+3 часа(ов)      
Цитата
Kergan :
в том варианте про который я изначально говорил ядро как раз system-f с АДТ, возможно тайпклассами (или любой другой вариант ad-hoc полиморфизма), ну и нативными продолжениями. Через него при желании довольно легко выразить более мощные концепции, с другой стороны, оно само по себе весьма простое. То есть в некоторой степени обладает свойствами минимальности и полноты. Байткод как раз и будет представлять термы этого языка, а дальше уже тот же llvm генерит байткод.



А не это ли реализованно в виде Liskell и ему подобных? Сейчас, насколько я понимаю, Haskell компилируется в байткод, который потом как раз может компилироваться в LLVM-биткод, если к этому добавить Haskell FFI, реализовать ридер S-expr с макросами, которые будут раскрываться в Haskell-код, да запилить компилятор самого Haskell в рантайм (тут ещё компайл-тайм информация в рантайме потребуется) + слинковать это всё с LLVM, то не получится ли у нас именно то, что вы хотите?

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6548   2012-09-20 17:57 GMT+3 часа(ов)      
Примерно так, да, но в хаскеле нельзя сделать макросы (только препроцессор), нет возможности работы на действительно низком уровне (хуков к ЛЛВМ, работы с памятья из kernel language), ну и изначальные косяки рантайма типа лени и сломанного ИО.

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6549   2012-09-20 18:47 GMT+3 часа(ов)      
Цитата
Kergan :
Примерно так, да, но в хаскеле нельзя сделать макросы (только препроцессор), нет возможности работы на действительно низком уровне (хуков к ЛЛВМ, работы с памятья из kernel language), ну и изначальные косяки рантайма типа лени и сломанного ИО.



Ок. Буду курить маны по System F, т.к. эта система мне не знакома. Может есть какое-нибудь доступное её описание, желательно с примерами реализации?

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6550   2012-09-20 19:51 GMT+3 часа(ов)      
Цитата
Ок. Буду курить маны по System F, т.к. эта система мне не знакома. Может есть какое-нибудь доступное её описание

TAPL и алгоритм Хиндли-Милнера

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#6618   2012-09-25 16:05 GMT+3 часа(ов)      
А может лучше форкнуть уже готовую реализацию? А то разрабатывать с нуля довольно тяжело физически, а тем более в одиночку.

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6625   2012-09-26 03:10 GMT+3 часа(ов)      
Да я только за. Есть достойные реализации с которых можно начать? Меня сейчас больше всего беспокоит даже не continuations, closures, condition system и прочие низкоуровневые возможности, а реализация нормальной системы типов со всеми возможностями -- выглядит достаточно трудоемко.

Кстати в TAPL написано, что адресная арифметика как бы противоречит типизированному лямбда исчислению. Возможно нужно явно делить весь код на три части: safe, unsafe и trusted в части доступа к низкоуровневым возможностям, которые ломают систему типов.

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6626   2012-09-26 10:47 GMT+3 часа(ов)      
Цитата
Кстати в TAPL написано, что адресная арифметика как бы противоречит типизированному лямбда исчислению.

Противоречит именно адресная арифметика, но не сама работа с памятью.
конкретно проблема в апкастах (void*). Но с монадами это все можно разрулить.

Цитата
реализация нормальной системы типов со всеми возможностями

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

metadeus

Members


Статус

89 сообщений

Где: Russia
Род занятий:
Возраст:

#6631   2012-10-02 19:47 GMT+3 часа(ов)      
Я немного не понимаю сам подход лямбда-исчисления: допустим мне нужно типизировать функцию +, которая используется как (+ 10 20). Я значит приписываю ей тип: int -> int -> int, но таким образом я получаю возможность каррировать её как (+ 10), то есть любая функция использующая более 1 параметра должна конструировать замыкание и возвращать уже его? А возможность компиляции вызова функции в простой PUSH 10, PUSH 20, CALL &PLUS_FUNC должна быть реализована в виде оптимизации или как?

Kergan

Members


Статус

300 сообщений

Где: ---
Род занятий:
Возраст:

#6632   2012-10-02 23:57 GMT+3 часа(ов)      
В лямбда-исчислении каррирование по умолчанию, но переносить это никто не заставляет, оно в лямбда-исчислении лишь из соображений минимальности системы (чтобы не было так сказать лишних аксиом). Тот факт что кроме функций одного аргумента с типом a -> b будут ф-и с n аргументами и типом a1 ... an -> b (равно как и ф-и с типом a1 -> ... -> an -> b и это будут разные типы) ничего в сущности не меняет (с точки зрения системы типов, ее выразительности, алгоритмов тайпчека и тайпинференса), но с точки зрения низкоуровневой реализации это делается проще. Можно, конечно, сделать и как вы в своем посте описали (то есть каррирование и автоматическая оптимизация, как в хаскеле), но имея некаррированный ЯП сделать каррированный довольно просто.
Учитывая что kernel language низкоуровневый, а каррирование нужно только для сокращения записи (то есть возможность писать (+ 10) вместо x ./ x + 10), оно там не надо.

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#6634   2012-10-03 14:59 GMT+3 часа(ов)      
Цитата
120) Condition System вероятно будет реализована с помощью макросов поверх continuations. Тут ещё бы неплохо про эффективность подумать.
Оптимизатор кода должен уметь четко вычленять локальные continuations и заменять их на локальные переходы, а иначе циклы будут жутко тормозить.
Цитата
2) Запилить LLVM kernel язык -- без сборки мусора, но с возможностью работать с LLVM и FFI через LLVM.
3) Добавить макросы. (Embedded Edition в принципе готов)
4) Написать стандарт языка в общем виде.
5) Написать на макросах рантайм (динамическая типизация, лямбды, замыкания, ООП, библиотека типов, пакетная система и пр.) и переписать ридер с C++ на kernel язык.

2) Написать черновой стандарт kernel языка (с примитивными макросами) в общем виде.
3) Запилить транслятор kernel языка на одном из существующих диалектов Лиспа. Пусть пока будет генерировать только код на ассемблере LLVM.
4) Добавление в стандарт FFI.
5) Пересмотреть черновой стандарт kernel языка.
6) Привести транслятор kernel языка в соответствие с текущим стандартом.
7) Повторение 4 и 5 пунктов до тех пор, пока в этом есть необходимость(см. пункт 8 )
8.) Переписать транслятор на kernel языке.
9) Повторить пункты 5 и 6, 7.
и т.д.

отредактировал(а) misha: 2012-10-03 16:08 GMT+3 часа(ов)

misha

Moderators


Статус

1275 сообщений
http://racket-lang.org/
Где: Yemen
Род занятий:
Возраст:

#6635   2012-10-03 15:18 GMT+3 часа(ов)      
Цитата
PUSH 10, PUSH 20, CALL &PLUS_FUNC
У вас скорее всего будет что-то вроде этого
PUSH 10
PUSH 20
LOAD PLUS_FUNC
CALL2
Но если функция "+" не переопределяется, то вы должны оптимизировать этот участок код, т.е. подставить PUSH 30.


Онлайн :

0 пользователь(ей), 37 гость(ей) :




Реклама на сайте: