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

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

Kergan

Members


Статус

300 сообщений

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

#6637   2012-10-03 17:33 GMT+3 часа(ов)      
Цитата
Оптимизатор кода должен уметь четко вычленять локальные continuations и заменять их на локальные переходы, а иначе циклы будут жутко тормозить.

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

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

> У вас скорее всего будет что-то вроде этого

Если + не переопределен то его вообще должен джит заинлайнить.

misha

Moderators


Статус

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

#6638   2012-10-03 22:58 GMT+3 часа(ов)      
Цитата
что подразумевается под локальными продолжениями и какая связь с циклами? Циклы ведь безо всяких продолжений делаются.
Я неправильно выразился. Хотелось бы улучшить обработку исключений. Например, чтобы оптимизатор в данном фрагменте кода заменил все raise-ы на локальные переходы (на текущий обработчик исключений)
(define (test n)
(let ([foo (lambda(a) (if (zero? a)
(raise a)
(add1 a)))])
(with-handlers ([integer? (lambda(exc) (zero? exc))]
[boolean? (lambda(exc) exc)])
(if (> n 1)
(raise #f)
(test (foo n))))))

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

Kergan

Members


Статус

300 сообщений

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

#6639   2012-10-04 13:51 GMT+3 часа(ов)      
Цитата
Когда у нас аргументы - две константы, то нужно подставить результат вычисления.

это ясно, но понятно же что речь об общем случае.

Цитата
Например, чтобы оптимизатор в данном фрагменте кода заменил все raise-ы на локальные переходы

а стек вам кто размотает если вы локальный переход в этом примере сделаете? дед мороз? а если у вас raise захватит исключение и бросит его в хенлер из которого оно потом будет вызвано (схожий прием как раз делается при реализации рестартов)?

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

metadeus

Members


Статус

89 сообщений

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

#6640   2012-10-04 21:12 GMT+3 часа(ов)      
Цитата
misha :
2) Написать черновой стандарт kernel языка (с примитивными макросами) в общем виде.
3) Запилить транслятор kernel языка на одном из существующих диалектов Лиспа. Пусть пока будет генерировать только код на ассемблере LLVM.
4) Добавление в стандарт FFI.
5) Пересмотреть черновой стандарт kernel языка.
6) Привести транслятор kernel языка в соответствие с текущим стандартом.
7) Повторение 4 и 5 пунктов до тех пор, пока в этом есть необходимость(см. пункт 8 )
8.) Переписать транслятор на kernel языке.
9) Повторить пункты 5 и 6, 7.
и т.д.



Я вижу в таком подходе следующие проблемы:
1) Писать стандарт до реального кода мне кажется пустой затеей, т.к. всего заранее не учтешь, главное иметь общее направление, и предварительный стандарт не избавит от большей части проблем при разработке. Тем более, что стандарт скорее всего будет сильно изменен по результатам предварительного использования языка.
2) Зачем его пилить на динамически-типизированном Лиспе с неотключаемым сборщиком мусора не очень понятно. Что я получу? Макросы, которые мне не пригодятся, т.к. вся система будет переписана на kernel language в последствие? Отсталые и заброшенные байндинги к ЛЛВМ, плюс всю низкоуровневую работу через непрозрачный FFI?

Если я пишу на Сях, то большая часть из того, что я напишу прямиком переезжает в конечный вид системы и переписывать многие вещи в общем совсем не обязательно, их можно просто линковать хоть в динамике (таким, например образом планируется поставлять различные runtime environments + стандартные библиотеки, да и любые другие библиотеки). К тому же, т.к. система типов Си это практически надстройка над системой типов LLVM, то FFI к сишному коду может и должен быть сделан абсолютно прозрачным.

3) Если я использую сишную либу например с реализацией сборщика мусора, хеш таблиц или там веревочных строк, то я могу просто оставить эту библиотеку как есть в kernel language в виде .lib или .so/.dll, в случае же с Лиспом мне придется всё переписывать, т.к. вытащить эти куски из реализации Лиспа не вижу никаких возможностей.

4) Кроме того, разработчиков на Сях найти на порядок проще, а я планирую привлечь кого нибудь к реализации, т.к. своего свободного времени просто не достаточно на такой проект.

Kergan

Members


Статус

300 сообщений

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

#6641   2012-10-05 03:23 GMT+3 часа(ов)      
Речь шла о трансляторе, а не о вм же. В этом плане высокоуровневый язык явно лучше сишки - т.к. никакие причины интероперабельности уже не работают и кроме того все равно в любом случае придется переписывать компилятор, т.к. бутстрап. Так что для до-бутстраповой реализации сишка действительно нафиг и не нужна - это все равно будет прототип, так что надо брать ЯП удобный именно для прототипирования. Лисп в том числе подойдет. А сишка будет явно не лучшим выбором. А статическая типизация уж только помешает.

metadeus

Members


Статус

89 сообщений

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

#6642   2012-10-05 14:42 GMT+3 часа(ов)      
Цитата
Kergan :
Речь шла о трансляторе, а не о вм же. В этом плане высокоуровневый язык явно лучше сишки - т.к. никакие причины интероперабельности уже не работают и кроме того все равно в любом случае придется переписывать компилятор, т.к. бутстрап. Так что для до-бутстраповой реализации сишка действительно нафиг и не нужна - это все равно будет прототип, так что надо брать ЯП удобный именно для прототипирования. Лисп в том числе подойдет. А сишка будет явно не лучшим выбором. А статическая типизация уж только помешает.



Я собственно о компиляторе+ВМ и писал.

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

Да и ещё раз повторюсь: какой прок от высокоуровневого языка, если его возможности не будут использованы практически никак -- какая разница из какого языка дергать LLVM API? Тут даже С++ был бы более предпочтительным, а если байндинги к Окемлу хороши, то он.

Kergan

Members


Статус

300 сообщений

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

#6648   2012-10-09 01:29 GMT+3 часа(ов)      
Цитата
Да и ещё раз повторюсь: какой прок от высокоуровневого языка, если его возможности не будут использованы практически никак

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

Цитата
Бутстрап-бутстрапом, а переписывать все с нуля на kernel language это плохая идея

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

metadeus

Members


Статус

89 сообщений

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

#6649   2012-10-09 03:02 GMT+3 часа(ов)      
Ладно, на чем пишем -- CL, Racket, Haskell, Ocaml, Java, C#, whatever?

Kergan

Members


Статус

300 сообщений

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

#6655   2012-10-10 20:47 GMT+3 часа(ов)      
Я бы выбирал из языков, хороших для быстрого прототипирования (раз это и есть де-факто прототип, который нужен только для того, чтобы забустрапить первый компилятор, написанный на целевом ЯП). То есть из вашего списка, видимо, лучше всего пойдут лиспы. Тем более раз мы пишем лисп, то и перевод с другого лиспа будет выполнен быстрее.

metadeus

Members


Статус

89 сообщений

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

#6656   2012-10-11 01:31 GMT+3 часа(ов)      
Ок. Значит будет CL. Заодно подтяну знание языка.

misha

Moderators


Статус

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

#6678   2012-10-22 19:15 GMT+3 часа(ов)      
Цитата
а стек вам кто размотает если вы локальный переход в этом примере сделаете? дед мороз? а если у вас raise захватит исключение и бросит его в хенлер из которого оно потом будет вызвано (схожий прием как раз делается при реализации рестартов)?
А я и не писал, что это так просто Если бы это было так, то у всех была бы реализована подобная оптимизация. С другой стороны наличие этой оптимизации будет являться большим плюсом для компилятора.

misha

Moderators


Статус

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

#6679   2012-10-22 19:44 GMT+3 часа(ов)      
Цитата
1) Писать стандарт до реального кода мне кажется пустой затеей, т.к. всего заранее не учтешь, главное иметь общее направление, и предварительный стандарт не избавит от большей части проблем при разработке. Тем более, что стандарт скорее всего будет сильно изменен по результатам предварительного использования языка.
А как вы сможете создать вм, если даже не имеете четкого представления о деталях ее реализации (нет чернового стандарта)? Благодаря стандарту вы можете выбрать наиболее подходящее решение конкретной задачи, т.к. на практике обычно существует несколько вариантов ее решения.
Цитата
2) Зачем его пилить на динамически-типизированном Лиспе с неотключаемым сборщиком мусора не очень понятно. Что я получу? Макросы, которые мне не пригодятся, т.к. вся система будет переписана на kernel language в последствие? Отсталые и заброшенные байндинги к ЛЛВМ, плюс всю низкоуровневую работу через непрозрачный FFI?
Ну макросы тоже могут быть написаны на kernel, ведь никто вам не запрещает реализовать транслятор с kernel на лисп. А байндинги к ЛЛВМ вам на этой стадии вообще не нужны. Вам главное научиться создавать правильный код.
Цитата
Если я пишу на Сях, то большая часть из того, что я напишу прямиком переезжает в конечный вид системы и переписывать многие вещи в общем совсем не обязательно, их можно просто линковать хоть в динамике
Без наличия готовой вм про динамику забудьте.
Цитата
3) Если я использую сишную либу например с реализацией сборщика мусора, хеш таблиц или там веревочных строк, то я могу просто оставить эту библиотеку как есть в kernel language в виде .lib или .so/.dll, в случае же с Лиспом мне придется всё переписывать, т.к. вытащить эти куски из реализации Лиспа не вижу никаких возможностей.
А вам это и не потребуется.
Цитата
4) Кроме того, разработчиков на Сях найти на порядок проще, а я планирую привлечь кого нибудь к реализации, т.к. своего свободного времени просто не достаточно на такой проект.
Ну, так он должен к тому же знать лисп, а иначе как он сможет все грамотно реализовать. Иначе будете оба как слепые котята.

misha

Moderators


Статус

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

#6680   2012-10-22 19:55 GMT+3 часа(ов)      
Цитата
Бутстрап-бутстрапом, а переписывать все с нуля на kernel language это плохая идея -- есть сотни уже готовых и проверенных реализаций всего подряд, такие вещи достаточно скомпилировать в LLVM bitcode из Сишечки и использовать их как есть.
А собственно никто вам это и не запрещает. Т.к. для тестирования кода полученного в результате компиляции желательно иметь готовую вм. Т.е. транслятор генерирует LLVM код, который вы компонуете вместе с кодом вашей вм.
Цитата
Да и ещё раз повторюсь: какой прок от высокоуровневого языка, если его возможности не будут использованы практически никак -- какая разница из какого языка дергать LLVM API?
Если поступите как я предлагаю, то вам не придется дергать LLVM API из лиспа.

Kergan

Members


Статус

300 сообщений

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

#6688   2012-10-24 08:45 GMT+3 часа(ов)      
Цитата
А я и не писал, что это так просто

так речь не о том что это просто, а о том, что это невозможно. то есть такую оптимизацию производить запрещено (хоть и не сложно ).

Цитата
Если поступите как я предлагаю, то вам не придется дергать LLVM API из лиспа.

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

misha

Moderators


Статус

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

#6689   2012-10-24 13:22 GMT+3 часа(ов)      
Цитата
так речь не о том что это просто, а о том, что это невозможно. то есть такую оптимизацию производить запрещено (хоть и не сложно ).
Я же не говорю об отказе от базового механизма обработки исключений. Так что мешает компилятору её произвести?
Цитата
так тут суть в том, что дерганье ллвм-апи - это не недостаток, а фича
фактически вм будет некоей надстройкой над ллвм, а дерганье апи позволит тонко работать с вм.
Ну, так я о том, что до бутстрапа этого делать не стоит. А откуда дергать будем? Разрешим пользователю добавлять собственные спецформы? И как это скажется на оптимизаторе кода, т.е. при таком раскладе об оптимизации можно вообще забыть, или как?

metadeus

Members


Статус

89 сообщений

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

#6690   2012-10-24 19:56 GMT+3 часа(ов)      
Я тут наткнулся на интересную мысль:

Цитата
Цитата
Есть еще Nemerle.


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



Кто-нибудь может мне объяснить более доступным языком или на примере -- в чем конкретно состоит противоречие статической типизации и макросов? Или автор бредит?

--

Смотрел недавно ещё раз на язык Julia, и подумал, что в нем есть практически все, что нужно, кроме двух больших различий:
1) В Julia динамическая типизация. Я если честно не понимаю почему они не реализовали статическую? Теперь на динамике они пытаются выжать скорость C++ путем всяких хитрых оптимизаций. Не очень понятно это просто фейл или это осознанное решение, мотивы которого хотелось бы знать.
2) В документации они пишут, что Julia гомоиконна. Тогда зачем было городить синтаксис, чем не устраивали s-exp? Просто прихоть? Или это нашлепка вида макроса чтения, чтобы синтаксис не отпугивал Лиспофобов? Насколько в реальности такая нашлепка необходима (хотя бы в виде тех же Sweet-expressions) для распространения языка за пределы Лисп-комюнити? И чем в реальности отсутствие s-exp осложнит написание макросов, например? В Julia всё выглядит достаточно пристойно.

--

Что-то не ладится у меня с Common Lisp, меня почему-то от него подташнивать начинает, как только начинаю на нем писать. Я просто уже достаточно долго пытаюсь его освоить по-нормальному (с Emacs'ом в нагрузку), но после небольшого перерыва написания на нем постоянно приходится открывать HyperSpec с целью поиска нужной функции в этой адской кипе. Да и байндинги к LLVM'у у него все таки устаревшие -- версия 3.1 не поддерживается.

В общем, остается C++, видимо.

Kergan

Members


Статус

300 сообщений

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

#6695   2012-10-25 05:00 GMT+3 часа(ов)      
Цитата
Я же не говорю об отказе от базового механизма обработки исключений. Так что мешает компилятору её произвести?

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

Цитата
А откуда дергать будем? Разрешим пользователю добавлять собственные спецформы?

Ну естественно. Надо дать возможность пользователю вообще гибко до-переписать всю ВМ.

Цитата
И как это скажется на оптимизаторе кода, т.е. при таком раскладе об оптимизации можно вообще забыть, или как?

так оптимизацию будет делать кодогенератор ллвм.

Kergan

Members


Статус

300 сообщений

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

#6696   2012-10-25 05:05 GMT+3 часа(ов)      
Цитата
Кто-нибудь может мне объяснить более доступным языком или на примере -- в чем конкретно состоит противоречие статической типизации и макросов?

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

Цитата
Смотрел недавно ещё раз на язык Julia

Ну тогда уже mathematica лучше взять - это больше похоже на то, что мы обсуждаем.

Цитата
Да и байндинги к LLVM'у у него все таки устаревшие -- версия 3.1 не поддерживается.

вот кстати есть какие-то для racket:
https://github.com/shekari/racket-llvm

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

а вот даже автор их использует для написания своего компилятора, так что можно посмотреть как оно используется на менее игрушечных задачах, чем в examples:
https://github.com/shekari/tiger

отредактировал(а) Kergan: 2012-10-25 05:24 GMT+3 часа(ов)

Kergan

Members


Статус

300 сообщений

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

#6697   2012-10-25 05:41 GMT+3 часа(ов)      
Цитата
И чем в реальности отсутствие s-exp осложнит написание макросов, например?

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

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

metadeus

Members


Статус

89 сообщений

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

#6698   2012-10-25 15:50 GMT+3 часа(ов)      
Цитата
Kergan :
ну суть в том что либо правила типизации задаются произвольно - тогда компилятор не может проверить их корректность, либо тайпчек надо проводить на раскрытом коде - из-за чего ошибки чекера будут мягко говоря неинтуитивны. и для понимания, чего там чекер наговорил, надо будет знать, во что конкретно и как макрос раскрывается, что, собственно, нарушает модульность.


Ну я так понимаю можно и "отматывать назад" раскрытие макросов (с помощью дополнительных меток выставляемых при раскрытии макросов) с целью представления более внятного сообщения об ошибке, как например делает какой-нибудь clang по отношению к макросам Си?

Цитата
Kergan :
Ну тогда уже mathematica лучше взять - это больше похоже на то, что мы обсуждаем.


Посмотрю.

Цитата
Kergan :
вот кстати есть какие-то для racket:
https://github.com/shekari/racket-llvm

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

а вот даже автор их использует для написания своего компилятора, так что можно посмотреть как оно используется на менее игрушечных задачах, чем в examples:
https://github.com/shekari/tiger



Спасибо, попробую Racket.

Мне тут мысль пришла, что возможно Common Lisp это не локомотив распространенности Лиспов, как его пытаются представить, а собственно его тормоз, т.к. отпугивает своей монструозностью, загораживая элегантность и простоту Лиспов вообще. Читал просто SICP, так все примеры реализации там просты и понятны, то же самое на CL будет выглядеть как Си++ на шаблонах.

metadeus

Members


Статус

89 сообщений

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

#6699   2012-10-25 15:55 GMT+3 часа(ов)      
Цитата
Kergan :
чем реально? ну тем что программисту при написании макроса приется в уме раскрывать сперва код в АСТ, а потом АСТ трансформировать в код. Что, мягко говоря, не сильно удобно. Кроме того, секспры значительно проще как парсить так и генерировать - в результате там где с секспрами все легко парсится и генерится теми же схемными паттернами в не-секспр языке будет ад и содомия.

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



Ну в принципе я так и думал. Получается, что без S-expr'ов гомоиконность в принципе теряет свои преимущества -- чего толку разработчику с доступности AST, если его приходится формировать спец. синтаксисом -- с тем же успехом можно использовать eval для строки с исходным кодом (по типу всех скриптовых языков и всяких D).

Kergan

Members


Статус

300 сообщений

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

#6701   2012-10-26 08:47 GMT+3 часа(ов)      
> Получается, что без S-expr'ов гомоиконность в принципе теряет свои преимущества

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

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

Цитата
Ну я так понимаю можно и "отматывать назад" раскрытие макросов (с помощью дополнительных меток выставляемых при раскрытии макросов)

Не совсем понятно как что отматывать. У нас в макросах могут и сайд-эффекты быть.

Цитата
Посмотрю.

просто mathematica (ее ЯП всмысле) де-факто и есть диалект лиспа

Цитата
Спасибо, попробую Racket.

Ежели будете писать на racket готов помочь в написании

Цитата
Мне тут мысль пришла, что возможно Common Lisp это не локомотив распространенности Лиспов, как его пытаются представить, а собственно его тормоз, т.к. отпугивает своей монструозностью, загораживая элегантность и простоту Лиспов вообще. Читал просто SICP, так все примеры реализации там просты и понятны, то же самое на CL будет выглядеть как Си++ на шаблонах.

Быть может. У CL есть значительное количество хороших и удобных вещей, но стандарт действительно монструозный и устаревший (когда писали стандарт CL то по-другому, правильно, еще и не умели, сделали как смогли), тянет за собой кучу говна, которое уже давно стоило переработать. Однако обратная совместимость же - если в этом стиле стандарт поменять и сделать все правильно, это уже будет совсем не общелисп.

отредактировал(а) Kergan: 2012-10-26 15:46 GMT+3 часа(ов)

metadeus

Members


Статус

89 сообщений

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

#6702   2012-10-26 16:11 GMT+3 часа(ов)      
Цитата
Kergan :
Ну да. Есть правда еще некоторые варианты - ну например гомоиконность ассемблера или конкантенативных языков. Тут тоже ничего в общем-то не потеряем.



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

(+ 1 (apply 'map '+ '(10 20 20)))
10 20 20 list ' + ' map apply 1 +


или нет?

Цитата
Kergan :
Ежели будете писать на racket готов помочь в написании



Присматриваюсь. Пока всё выглядит классно, я даже начал думать, что зря столько времени убил на CL+Emacs. Мне нужнее ваша помощь в стандарте языка, т.к. написать -- это дело сугубо прикладное и решаемое, а вот грамотная проработка стандарта и определение необходимого и достаточного минимума kernel language это более важное в долгосрочной перспективе решение. В любом случае, буду благодарен за любую помощь.

Цитата
Kergan :
Быть может. У CL есть значительное количество хороших и удобных вещей, но стандарт действительно монструозный и устаревший (когда писали стандарт CL то по-другому, правильно, еще и не умели, сделали как смогли), тянет за собой кучу говна, которое уже давно стоило переработать. Однако обратная совместимость же - если в этом стиле стандарт поменять и сделать все правильно, это уже будет совсем не общелисп.


Почему, к примеру, в Racket не сделать что-нибудь типа #lang cl, не так уж и нужно видимо всё, что CL тащит?

Ещё вопрос про Racket: посмотрел бенчмарки SBCL/Racket и обратил внимание, что Racket медленнее. С чем это связано -- это какие-то внутренние особенности ВМ/рантайма/языка или просто не уделяли столько времени оптимизации как в CMUCL/SBCL?

Ещё, правильно ли понимаю, что Typed Racket это динамически типизированный язык, а метки типов служат только для проверки тайп чекером во время компиляции и исполнения? Для генерации оптимизированного кода они используются или ВМ используется та же, что и в языке Racket?

отредактировал(а) metadeus: 2012-10-26 16:27 GMT+3 часа(ов)

Kergan

Members


Статус

300 сообщений

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

#6703   2012-10-26 18:05 GMT+3 часа(ов)      
Цитата
Точно. Форт классная штука. Можем ли мы, вообще говоря, считать, что синтаксис Форта это просто другая запись S-выражений? Точнее, что оба варианта записи позволяют записывать иерархическую структуру? Мы же всегда по идее можем переписать sexp в виде обратной польской записи, типа:

sexpr в обратную польскую нотацию можем, да, но вот наоборот - не всегда, т.к. могут быть слова с динамическим стек-эффектом.Например можно написать слово, которое суммирует то, что лежит на стеке до тех пор, пока сумма не станет больше 10. И если мы напишем 1 2 3 4 5 6 7 sum>10 то перевести в секспр у нас это не выйдет.

Цитата
Присматриваюсь. Пока всё выглядит классно, я даже начал думать, что зря столько времени убил на CL+Emacs.

Вообще racket c emacs тоже можно использовать (geiser), но Dr.Racket и так довольно неплоха, да.

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

Готов помочь и в том и в том.

Цитата
Почему, к примеру, в Racket не сделать что-нибудь типа #lang cl, не так уж и нужно видимо всё, что CL тащит?

Ну тут во-первых да - это просто ненужно. Во-вторых - у CL весьма сильно отличается семантика рантайма. В рамках #lang cl (то есть внутри модуля) ее реализовать нельзя (точнее можно, но по сути мы не сможем реиспользовать уже существующие части рантайма Rakcet, то есть придется практически с нуля реализовать рантайм CL). Короче реализация либо будет неэффективной, либо потребует очень много трудозатрат, либо будет неполной, либо будет плохо вписываться в экосистему Racket (то есть будет висеть в топлевеле, что нехорошо). В общем что называется "овчинка выделки не стоит". Слишком это будет сложно, а необходимости - нет.

> Ещё вопрос про Racket: посмотрел бенчмарки SBCL/Racket и обратил внимание, что Racket медленнее. С чем это связано -- это какие-то внутренние особенности ВМ/рантайма/языка или просто не уделяли столько времени оптимизации как в CMUCL/SBCL?

Ну, во-первых, у Racket не такой уж хороший jit - то есть даже если прикрутить тот же jit от llvm уже будет выигрыш в производительности (и весьма значительный). Во-вторых, в Racket намного более навороченный рантайм - это, естественно, требует определенных накладных расходов. В-третьих, есть какие-то непонятки у меня с производительностью сборки мусора (я не в курсе как конкретно устроен сборщик мусора, но вполне возможно что он иногда тормозит из-за навороченности рантайма в том числе). В-четвертых максимум чем может управлять программист на Racket - это компиляцией в байткод, который очень высокоуровневый (фактически байткод является тем же самым что и full-expanded код, только он закодирован, то есть сделан более компактным). SBCL же предоставляет гораздо более низкоуровневые средства - начиная от деклараций типов и заканчивая генерацией VOP'ов. В результате если сравнивать, скажем так, обычный код (то есть без каких-то хитрых оптимизаций и всего такого), то обычно все идет наравне, а вот если делать жуткие оптимизации то SBCL выигрывает за счет большего потенциала в области этих самых оптимизаций. То есть средств оптимизации больше. Но в этом случае код начинает выглядеть воистину ужасно - проще написать все на плюсах. Будет и понятнее и быстрее. Ну и да, PLT team не уделяет какого-то особого внимания именно скорости работы, они считают что производительность должна быть "достаточной", и в сущности она действительно достаточна для тех задач, где можно применять языки вроде Racket.

Цитата
Ещё, правильно ли понимаю, что Typed Racket это динамически типизированный язык, а метки типов служат только для проверки тайп чекером во время компиляции и исполнения?

Не во время компиляции даже а во время экспанда. После экспанда (во время которого и происходит тайпчек) получается тот же самый динамический full-expanded код. Единственное что чекер при экспанде заменяет там где может safe операции на их unsafe аналог. Например если вы пытаетесь получить значнеие поля структуры то по дефолту надо проверить, а является ли аргумент инстансом соответствующей структуры. Если типизация статическая, то проверку можно опустить - соответственно операция меняется. Ну или если вы складываете два флоата или фикснума, то в статике точно известно что это будут флоаты или фикснумы и можно сразу заинлайнить нужную операцию, а не вызывать полиморфную, которая сперва проверит тип аргументов, а потом вызовет, что надо. Ну и т.д.
Собственно там даже есть такая кнопочка "optimizations coach" - она подсвечивает все места в которых оптимизация такого рода (с заменой на unsafe-операции) выполнена, либо может быть выполнена (и даются подсказки как сузить тип для ее выполнения).

отредактировал(а) Kergan: 2012-10-26 18:17 GMT+3 часа(ов)

metadeus

Members


Статус

89 сообщений

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

#6711   2012-10-29 22:42 GMT+3 часа(ов)      
Что-то я не пойму как работает парсер:
 
#lang racket
 
(require parser-tools/lex
(prefix-in re- parser-tools/lex-sre)
parser-tools/yacc)
 
(provide (all-defined-out))
 
(define-tokens aerylisp-tokens (NUM SYMBOL))
(define-empty-tokens aerylisp-empty-tokens (LPAR RPAR EOF))
 
(define-lex-trans number
(syntax-rules ()
((_ digit)
(re-: (re-? (re-or "-" "+")) (uinteger digit)
(re-? (re-: "." (re-? (uinteger digit))))))))
 
(define-lex-trans uinteger
(syntax-rules ()
((_ digit) (re-+ digit))))
 
(define-lex-abbrevs
(digit10 (char-range "0" "9"))
(number10 (number digit10))
(identifier (re-+ (re-or (char-range "A" "z")
"?" "!" "*" "/" ":" "%" "^" "&" "@" "#" "~" "_" "-" "+"))))
 
(define aerylisp-lexer
(lexer-src-pos
("(" (token-LPAR))
(")" (token-RPAR))
((re-+ number10) (token-NUM (string->number lexeme)))
(identifier (token-SYMBOL (string->symbol lexeme)))
(whitespace (aerylisp-lexer input-port))
((eof) (token-EOF))))
 
(define aerylisp-parser
(parser
(src-pos)
(start expr)
(end EOF)
(error void)
(tokens aerylisp-tokens aerylisp-empty-tokens)
(grammar
(expr-list
[(expr) (cons $ 1 null)]
[(expr expr-list) (cons $ 1 $ 2)])
(expr
[(LPAR RPAR) null]
[(NUM) $ 1]
[(SYMBOL) $ 1]
[(LPAR expr-list RPAR) $ 2]))))
 
(define (eval parsed-expr)
(match parsed-expr
((list-rest head tail) "evaling list")
(a a)))
 
(define (lex-this lexer input) (lambda () (lexer input)))
 
(define (parse-string str)
(let ((input (open-input-string str)))
(eval (aerylisp-parser (lex-this aerylisp-lexer input)))))
 
(parse-string "10")
(parse-string "(10)")
(parse-string "abc")
(parse-string "()")
(parse-string "(10 20 30)")
(parse-string "(abc 10 +43 ecde)")
 


Вывод:
 
Добро пожаловать в DrRacket, версия 5.2.1 [3m].
Язык: racket; memory limit: 256 MB.
10
"evaling list"
'abc
'()
. . parser: expects argument of type <symbol or struct:token>; given #<position-token>
>
 


(src-pos) же указан, в чем проблема?

отредактировал(а) metadeus: 2012-10-30 14:43 GMT+3 часа(ов)

Kergan

Members


Статус

300 сообщений

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

#6712   2012-10-30 11:10 GMT+3 часа(ов)      
2metadeus
Нормальный код дайте, а то у вас там какие-то символы исчезли при вставке.

Kergan

Members


Статус

300 сообщений

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

#6713   2012-10-30 11:21 GMT+3 часа(ов)      
Хотя могу предположить, что надо (whitespace (aerylisp-lexer input-port)) заменить на (whitespace (return-without-pos (aerylisp-lexer input-port))), т.к. в противном случае парсер врапает результат матчинга в source-location дважды - сперва (aerylisp-lexer input-port) возвращает position-token, а потом вокруг этого делается еще один position-token c позицией whitespace.

ЗЫ: да, учитывая, что падает именно на тесте с пробелами, а все остальное отрабатывает нормально, именно в этом ошибка и состоит.
ЗЫЫ: старайтесь не использовать all-defined-out

отредактировал(а) Kergan: 2012-10-30 11:34 GMT+3 часа(ов)

metadeus

Members


Статус

89 сообщений

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

#6714   2012-10-30 14:45 GMT+3 часа(ов)      
Цитата
Kergan :
ЗЫ: да, учитывая, что падает именно на тесте с пробелами, а все остальное отрабатывает нормально, именно в этом ошибка и состоит.


Спасибо, помогло.

Цитата
Kergan :
ЗЫЫ: старайтесь не использовать all-defined-out


Ну это понятно.

--

А в схеме нет простого (return a) или (break a), чтобы из функции выйти? Или надо брать текущее продолжение и его дергать?

Kergan

Members


Статус

300 сообщений

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

#6715   2012-10-30 17:43 GMT+3 часа(ов)      
Цитата
А в схеме нет простого (return a) или (break a)

нет, нету.

Цитата
Или надо брать текущее продолжение и его дергать?

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

ЗЫ: в 3.5.1 для for-ов сделали кейворд #:break.
ЗЫЫ: вообще понятно, что классический return в схеме просто не имеет смысла - циклы делаются через рекурсию, а сквозь рекурсию return возвращать не умеет.
ЗЫЫЫ: вообще если вам хочется сделать break или return - значит что вы делается что-то неправильно.

metadeus

Members


Статус

89 сообщений

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

#6717   2012-10-31 01:42 GMT+3 часа(ов)      
Цитата
Kergan :
нет, нету.

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

ЗЫ: в 3.5.1 для for-ов сделали кейворд #:break.
ЗЫЫ: вообще понятно, что классический return в схеме просто не имеет смысла - циклы делаются через рекурсию, а сквозь рекурсию return возвращать не умеет.
ЗЫЫЫ: вообще если вам хочется сделать break или return - значит что вы делается что-то неправильно.



Ну, если неправильно это значит "не так как у нас принято", то да. Ладно, не суть, я просто не знал, что Racket wanna be pure functional.


Онлайн :

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




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