Автор | Сообщение |
Kergan
300 сообщений |
#6637 2012-10-03 17:33 GMT+3 часа(ов) |
Цитата что подразумевается под локальными продолжениями и какая связь с циклами? Циклы ведь безо всяких продолжений делаются. вообще не могу придумать вариант захвата продолжений, который можно было бы заменить локальным переходом. как ни крути - будет изменена семантика, то есть такую оптимизацию проводить никогда нельзя. > У вас скорее всего будет что-то вроде этого Если + не переопределен то его вообще должен джит заинлайнить. |
|
misha![]()
1275 сообщений |
#6638 2012-10-03 22:58 GMT+3 часа(ов) |
ЦитатаЯ неправильно выразился. Хотелось бы улучшить обработку исключений. Например, чтобы оптимизатор в данном фрагменте кода заменил все raise-ы на локальные переходы (на текущий обработчик исключений) (define (test n) ЦитатаКогда у нас аргументы - две константы, то нужно подставить результат вычисления. |
|
Kergan
300 сообщений |
#6639 2012-10-04 13:51 GMT+3 часа(ов) |
Цитата это ясно, но понятно же что речь об общем случае. Цитата а стек вам кто размотает если вы локальный переход в этом примере сделаете? дед мороз? а если у вас raise захватит исключение и бросит его в хенлер из которого оно потом будет вызвано (схожий прием как раз делается при реализации рестартов)? Вообще, конечно, можно завернуть внутренность продолжения в суровый монадический код и гарантировать статически что там у нас выбрасывается и в каком контексте. А потом уже на основе этой информации генерить низкоуровневый код. |
|
metadeus
89 сообщений |
#6640 2012-10-04 21:12 GMT+3 часа(ов) |
Цитата Я вижу в таком подходе следующие проблемы: 1) Писать стандарт до реального кода мне кажется пустой затеей, т.к. всего заранее не учтешь, главное иметь общее направление, и предварительный стандарт не избавит от большей части проблем при разработке. Тем более, что стандарт скорее всего будет сильно изменен по результатам предварительного использования языка. 2) Зачем его пилить на динамически-типизированном Лиспе с неотключаемым сборщиком мусора не очень понятно. Что я получу? Макросы, которые мне не пригодятся, т.к. вся система будет переписана на kernel language в последствие? Отсталые и заброшенные байндинги к ЛЛВМ, плюс всю низкоуровневую работу через непрозрачный FFI? Если я пишу на Сях, то большая часть из того, что я напишу прямиком переезжает в конечный вид системы и переписывать многие вещи в общем совсем не обязательно, их можно просто линковать хоть в динамике (таким, например образом планируется поставлять различные runtime environments + стандартные библиотеки, да и любые другие библиотеки). К тому же, т.к. система типов Си это практически надстройка над системой типов LLVM, то FFI к сишному коду может и должен быть сделан абсолютно прозрачным. 3) Если я использую сишную либу например с реализацией сборщика мусора, хеш таблиц или там веревочных строк, то я могу просто оставить эту библиотеку как есть в kernel language в виде .lib или .so/.dll, в случае же с Лиспом мне придется всё переписывать, т.к. вытащить эти куски из реализации Лиспа не вижу никаких возможностей. 4) Кроме того, разработчиков на Сях найти на порядок проще, а я планирую привлечь кого нибудь к реализации, т.к. своего свободного времени просто не достаточно на такой проект. |
|
Kergan
300 сообщений |
#6641 2012-10-05 03:23 GMT+3 часа(ов) |
Речь шла о трансляторе, а не о вм же. В этом плане высокоуровневый язык явно лучше сишки - т.к. никакие причины интероперабельности уже не работают и кроме того все равно в любом случае придется переписывать компилятор, т.к. бутстрап. Так что для до-бутстраповой реализации сишка действительно нафиг и не нужна - это все равно будет прототип, так что надо брать ЯП удобный именно для прототипирования. Лисп в том числе подойдет. А сишка будет явно не лучшим выбором. А статическая типизация уж только помешает.
|
|
metadeus
89 сообщений |
#6642 2012-10-05 14:42 GMT+3 часа(ов) |
Цитата Я собственно о компиляторе+ВМ и писал. Бутстрап-бутстрапом, а переписывать все с нуля на kernel language это плохая идея -- есть сотни уже готовых и проверенных реализаций всего подряд, такие вещи достаточно скомпилировать в LLVM bitcode из Сишечки и использовать их как есть. Потом, возможно, их и стоит переписать, но далеко не первым пунктом. Да и ещё раз повторюсь: какой прок от высокоуровневого языка, если его возможности не будут использованы практически никак -- какая разница из какого языка дергать LLVM API? Тут даже С++ был бы более предпочтительным, а если байндинги к Окемлу хороши, то он. |
|
Kergan
300 сообщений |
#6648 2012-10-09 01:29 GMT+3 часа(ов) |
Цитата почему не будут? парсинг, статический анализ, оптимизации и кодогенерация - это же как раз пример задач, на которых, как считается, ФП-языки дают наибольший профит. Цитата бутстрап все поголовно делают не просто так - он выполняет роль тестового проекта, который позволит проверить те или иные решения, найти ошибки дизайна ЯП и т.д.. Если смогли написать на ЯП собственный компилятор - ЯП юзабелен. То есть это переписывание выполняет вполне конкретную полезную функцию. |
|
metadeus
89 сообщений |
#6649 2012-10-09 03:02 GMT+3 часа(ов) |
Ладно, на чем пишем -- CL, Racket, Haskell, Ocaml, Java, C#, whatever?
|
|
Kergan
300 сообщений |
#6655 2012-10-10 20:47 GMT+3 часа(ов) |
Я бы выбирал из языков, хороших для быстрого прототипирования (раз это и есть де-факто прототип, который нужен только для того, чтобы забустрапить первый компилятор, написанный на целевом ЯП). То есть из вашего списка, видимо, лучше всего пойдут лиспы. Тем более раз мы пишем лисп, то и перевод с другого лиспа будет выполнен быстрее.
|
|
metadeus
89 сообщений |
#6656 2012-10-11 01:31 GMT+3 часа(ов) |
Ок. Значит будет CL. Заодно подтяну знание языка.
|
|
misha![]()
1275 сообщений |
#6678 2012-10-22 19:15 GMT+3 часа(ов) |
ЦитатаА я и не писал, что это так просто ![]() |
|
misha![]()
1275 сообщений |
#6679 2012-10-22 19:44 GMT+3 часа(ов) |
ЦитатаА как вы сможете создать вм, если даже не имеете четкого представления о деталях ее реализации (нет чернового стандарта)? Благодаря стандарту вы можете выбрать наиболее подходящее решение конкретной задачи, т.к. на практике обычно существует несколько вариантов ее решения. ЦитатаНу макросы тоже могут быть написаны на kernel, ведь никто вам не запрещает реализовать транслятор с kernel на лисп. А байндинги к ЛЛВМ вам на этой стадии вообще не нужны. Вам главное научиться создавать правильный код. ЦитатаБез наличия готовой вм про динамику забудьте. ЦитатаА вам это и не потребуется. ЦитатаНу, так он должен к тому же знать лисп, а иначе как он сможет все грамотно реализовать. Иначе будете оба как слепые котята. |
|
misha![]()
1275 сообщений |
#6680 2012-10-22 19:55 GMT+3 часа(ов) |
ЦитатаА собственно никто вам это и не запрещает. Т.к. для тестирования кода полученного в результате компиляции желательно иметь готовую вм. Т.е. транслятор генерирует LLVM код, который вы компонуете вместе с кодом вашей вм. ЦитатаЕсли поступите как я предлагаю, то вам не придется дергать LLVM API из лиспа. |
|
Kergan
300 сообщений |
#6688 2012-10-24 08:45 GMT+3 часа(ов) |
Цитата так речь не о том что это просто, а о том, что это невозможно. то есть такую оптимизацию производить запрещено (хоть и не сложно ![]() Цитата так тут суть в том, что дерганье ллвм-апи - это не недостаток, а фича ![]() фактически вм будет некоей надстройкой над ллвм, а дерганье апи позволит тонко работать с вм. |
|
misha![]()
1275 сообщений |
#6689 2012-10-24 13:22 GMT+3 часа(ов) |
ЦитатаЯ же не говорю об отказе от базового механизма обработки исключений. Так что мешает компилятору её произвести? ЦитатаНу, так я о том, что до бутстрапа этого делать не стоит. А откуда дергать будем? Разрешим пользователю добавлять собственные спецформы? И как это скажется на оптимизаторе кода, т.е. при таком раскладе об оптимизации можно вообще забыть, или как? |
|
metadeus
89 сообщений |
#6690 2012-10-24 19:56 GMT+3 часа(ов) |
Я тут наткнулся на интересную мысль:
ЦитатаЦитата Кто-нибудь может мне объяснить более доступным языком или на примере -- в чем конкретно состоит противоречие статической типизации и макросов? Или автор бредит? -- Смотрел недавно ещё раз на язык Julia, и подумал, что в нем есть практически все, что нужно, кроме двух больших различий: 1) В Julia динамическая типизация. Я если честно не понимаю почему они не реализовали статическую? Теперь на динамике они пытаются выжать скорость C++ путем всяких хитрых оптимизаций. Не очень понятно это просто фейл или это осознанное решение, мотивы которого хотелось бы знать. 2) В документации они пишут, что Julia гомоиконна. Тогда зачем было городить синтаксис, чем не устраивали s-exp? Просто прихоть? Или это нашлепка вида макроса чтения, чтобы синтаксис не отпугивал Лиспофобов? Насколько в реальности такая нашлепка необходима (хотя бы в виде тех же Sweet-expressions) для распространения языка за пределы Лисп-комюнити? И чем в реальности отсутствие s-exp осложнит написание макросов, например? В Julia всё выглядит достаточно пристойно. -- Что-то не ладится у меня с Common Lisp, меня почему-то от него подташнивать начинает, как только начинаю на нем писать. Я просто уже достаточно долго пытаюсь его освоить по-нормальному (с Emacs'ом в нагрузку), но после небольшого перерыва написания на нем постоянно приходится открывать HyperSpec с целью поиска нужной функции в этой адской кипе. Да и байндинги к LLVM'у у него все таки устаревшие -- версия 3.1 не поддерживается. В общем, остается C++, видимо. |
|
Kergan
300 сообщений |
#6695 2012-10-25 05:00 GMT+3 часа(ов) |
Цитата при базовом механизме стек как раз разматывается и никаких оптимизаций там нет. более того - базовый механизм работает _медленнее_ эксепшенов на продолжениях (если только продолжени реализованы достаточно эффективно. Так что неясно о чем вы вообще. Цитата Ну естественно. Надо дать возможность пользователю вообще гибко до-переписать всю ВМ. Цитата так оптимизацию будет делать кодогенератор ллвм. |
|
Kergan
300 сообщений |
#6696 2012-10-25 05:05 GMT+3 часа(ов) |
Цитата ну суть в том что либо правила типизации задаются произвольно - тогда компилятор не может проверить их корректность, либо тайпчек надо проводить на раскрытом коде - из-за чего ошибки чекера будут мягко говоря неинтуитивны. и для понимания, чего там чекер наговорил, надо будет знать, во что конкретно и как макрос раскрывается, что, собственно, нарушает модульность. Цитата Ну тогда уже mathematica лучше взять - это больше похоже на то, что мы обсуждаем. Цитата вот кстати есть какие-то для racket: https://github.com/shekari/racket-llvm я не в курсе правда, в каком они состоянии, но примеры там забавные. а вот даже автор их использует для написания своего компилятора, так что можно посмотреть как оно используется на менее игрушечных задачах, чем в examples: https://github.com/shekari/tiger отредактировал(а) Kergan: 2012-10-25 05:24 GMT+3 часа(ов) |
|
Kergan
300 сообщений |
#6697 2012-10-25 05:41 GMT+3 часа(ов) |
Цитата чем реально? ну тем что программисту при написании макроса приется в уме раскрывать сперва код в АСТ, а потом АСТ трансформировать в код. Что, мягко говоря, не сильно удобно. Кроме того, секспры значительно проще как парсить так и генерировать - в результате там где с секспрами все легко парсится и генерится теми же схемными паттернами в не-секспр языке будет ад и содомия. то есть если у нас не секспры, а обычный код, то применение макросов с обычного часто используемого инструмента низводится до "в очень редких случаях, если только нет другого выхода бла блабла". |
|
metadeus
89 сообщений |
#6698 2012-10-25 15:50 GMT+3 часа(ов) |
Цитата Ну я так понимаю можно и "отматывать назад" раскрытие макросов (с помощью дополнительных меток выставляемых при раскрытии макросов) с целью представления более внятного сообщения об ошибке, как например делает какой-нибудь clang по отношению к макросам Си? Цитата Посмотрю. Цитата Спасибо, попробую Racket. Мне тут мысль пришла, что возможно Common Lisp это не локомотив распространенности Лиспов, как его пытаются представить, а собственно его тормоз, т.к. отпугивает своей монструозностью, загораживая элегантность и простоту Лиспов вообще. Читал просто SICP, так все примеры реализации там просты и понятны, то же самое на CL будет выглядеть как Си++ на шаблонах. |
|
metadeus
89 сообщений |
#6699 2012-10-25 15:55 GMT+3 часа(ов) |
Цитата Ну в принципе я так и думал. Получается, что без S-expr'ов гомоиконность в принципе теряет свои преимущества -- чего толку разработчику с доступности AST, если его приходится формировать спец. синтаксисом -- с тем же успехом можно использовать eval для строки с исходным кодом (по типу всех скриптовых языков и всяких D). |
|
Kergan
300 сообщений |
#6701 2012-10-26 08:47 GMT+3 часа(ов) |
> Получается, что без S-expr'ов гомоиконность в принципе теряет свои преимущества
Ну да. Есть правда еще некоторые варианты - ну например гомоиконность ассемблера или конкантенативных языков. Тут тоже ничего в общем-то не потеряем. А та "гомоиконность" о которой обычно говорят (возможность квазицитирования и т.п.) она по факту ничего не дает, потому что в этом смысле любой язык гомоиконен (или его можно сделать гомоиконным малым допиливанием). Все это имеет смысл только в том случае, если есть поддержка со стороны синтаксиса. Цитата Не совсем понятно как что отматывать. У нас в макросах могут и сайд-эффекты быть. Цитата просто mathematica (ее ЯП всмысле) де-факто и есть диалект лиспа ![]() Цитата Ежели будете писать на racket готов помочь в написании ![]() Цитата Быть может. У CL есть значительное количество хороших и удобных вещей, но стандарт действительно монструозный и устаревший (когда писали стандарт CL то по-другому, правильно, еще и не умели, сделали как смогли), тянет за собой кучу говна, которое уже давно стоило переработать. Однако обратная совместимость же - если в этом стиле стандарт поменять и сделать все правильно, это уже будет совсем не общелисп. отредактировал(а) Kergan: 2012-10-26 15:46 GMT+3 часа(ов) |
|
metadeus
89 сообщений |
#6702 2012-10-26 16:11 GMT+3 часа(ов) |
Цитата Точно. Форт классная штука. Можем ли мы, вообще говоря, считать, что синтаксис Форта это просто другая запись S-выражений? Точнее, что оба варианта записи позволяют записывать иерархическую структуру? Мы же всегда по идее можем переписать sexp в виде обратной польской записи, типа: Цитата или нет? Цитата Присматриваюсь. Пока всё выглядит классно, я даже начал думать, что зря столько времени убил на CL+Emacs. Мне нужнее ваша помощь в стандарте языка, т.к. написать -- это дело сугубо прикладное и решаемое, а вот грамотная проработка стандарта и определение необходимого и достаточного минимума kernel language это более важное в долгосрочной перспективе решение. В любом случае, буду благодарен за любую помощь. Цитата Почему, к примеру, в Racket не сделать что-нибудь типа #lang cl, не так уж и нужно видимо всё, что CL тащит? Ещё вопрос про Racket: посмотрел бенчмарки SBCL/Racket и обратил внимание, что Racket медленнее. С чем это связано -- это какие-то внутренние особенности ВМ/рантайма/языка или просто не уделяли столько времени оптимизации как в CMUCL/SBCL? Ещё, правильно ли понимаю, что Typed Racket это динамически типизированный язык, а метки типов служат только для проверки тайп чекером во время компиляции и исполнения? Для генерации оптимизированного кода они используются или ВМ используется та же, что и в языке Racket? отредактировал(а) metadeus: 2012-10-26 16:27 GMT+3 часа(ов) |
|
Kergan
300 сообщений |
#6703 2012-10-26 18:05 GMT+3 часа(ов) |
Цитата sexpr в обратную польскую нотацию можем, да, но вот наоборот - не всегда, т.к. могут быть слова с динамическим стек-эффектом.Например можно написать слово, которое суммирует то, что лежит на стеке до тех пор, пока сумма не станет больше 10. И если мы напишем 1 2 3 4 5 6 7 sum>10 то перевести в секспр у нас это не выйдет. Цитата Вообще racket c emacs тоже можно использовать (geiser), но Dr.Racket и так довольно неплоха, да. Цитата Готов помочь и в том и в том. Цитата Ну тут во-первых да - это просто ненужно. Во-вторых - у 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. Цитата Не во время компиляции даже а во время экспанда. После экспанда (во время которого и происходит тайпчек) получается тот же самый динамический full-expanded код. Единственное что чекер при экспанде заменяет там где может safe операции на их unsafe аналог. Например если вы пытаетесь получить значнеие поля структуры то по дефолту надо проверить, а является ли аргумент инстансом соответствующей структуры. Если типизация статическая, то проверку можно опустить - соответственно операция меняется. Ну или если вы складываете два флоата или фикснума, то в статике точно известно что это будут флоаты или фикснумы и можно сразу заинлайнить нужную операцию, а не вызывать полиморфную, которая сперва проверит тип аргументов, а потом вызовет, что надо. Ну и т.д. Собственно там даже есть такая кнопочка "optimizations coach" - она подсвечивает все места в которых оптимизация такого рода (с заменой на unsafe-операции) выполнена, либо может быть выполнена (и даются подсказки как сузить тип для ее выполнения). отредактировал(а) Kergan: 2012-10-26 18:17 GMT+3 часа(ов) |
|
metadeus
89 сообщений |
#6711 2012-10-29 22:42 GMT+3 часа(ов) |
Что-то я не пойму как работает парсер:
Вывод:
(src-pos) же указан, в чем проблема? отредактировал(а) metadeus: 2012-10-30 14:43 GMT+3 часа(ов) |
|
Kergan
300 сообщений |
#6712 2012-10-30 11:10 GMT+3 часа(ов) |
2metadeus
Нормальный код дайте, а то у вас там какие-то символы исчезли при вставке. |
|
Kergan
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
89 сообщений |
#6714 2012-10-30 14:45 GMT+3 часа(ов) |
Цитата Спасибо, помогло. Цитата Ну это понятно. -- А в схеме нет простого (return a) или (break a), чтобы из функции выйти? Или надо брать текущее продолжение и его дергать? |
|
Kergan
300 сообщений |
#6715 2012-10-30 17:43 GMT+3 часа(ов) |
Цитата нет, нету. Цитата это более гибкая вещь, т.к. дает нелокальные переходы. обычно достаточно малых изменений кода чтобы привести все к хвосто-рекурсивному виду, можно узнать конкретный пример? ЗЫ: в 3.5.1 для for-ов сделали кейворд #:break. ЗЫЫ: вообще понятно, что классический return в схеме просто не имеет смысла - циклы делаются через рекурсию, а сквозь рекурсию return возвращать не умеет. ЗЫЫЫ: вообще если вам хочется сделать break или return - значит что вы делается что-то неправильно. |
|
metadeus
89 сообщений |
#6717 2012-10-31 01:42 GMT+3 часа(ов) |
Цитата Ну, если неправильно это значит "не так как у нас принято", то да. Ладно, не суть, я просто не знал, что Racket wanna be pure functional. |
|