LINUX.ORG.RU

ЯП dao


0

6

http://daovm.org/
llvm, скорость, простые биндинги, наращивают крит. массу либ
синтаксис си образный, впервые вижу чтобы для мотодов применяли ключевое слово routine
ну еще макросы, yield на закуску
наткнулся тут https://github.com/strangeloop/StrangeLoop2013/blob/master/slides/elc/Fu-DaoP...

★★★★

Последнее исправление: bga_ (всего исправлений: 1)
Ответ на: комментарий от anonymous

А я где говорил, что я сторонник CL? Я люблю Схему, но не люблю гигиену. В CL меня бесит то, что он LISP-2.

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

Надо, чтобы на Паскале можно было описывать макросы.

Так об этом речь и шла

Задача-минимум - для самого Паскаля, максимум - для хост-языка тоже.

Это одно и то же.

anonymous
()
Ответ на: комментарий от anonymous

Это одно и то же.

С какой радости? Если внутри компилятора Паскаля свой macroexpand, то host-язык об этом и знать-то ничего не будет.

anonymous
()
Ответ на: комментарий от anonymous

С какой радости? Если внутри компилятора Паскаля свой macroexpand

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

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

anonymous
()
Ответ на: комментарий от anonymous

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

Это с твоей, убогой точки зрения так. Моя позиция в том, что экспандер должен быть туп, как пробка (как в Common Lisp), без всякой гнилой гигиены, так что внутри DSLей могут быть свои собственные экспандеры.

anonymous
()
Ответ на: комментарий от anonymous

паскаль это слишком просто

С интересом посмотрю, как в твоей реализации этого слишком простого языка обрабатывается goto. Особенно интересен случай irreducible control flow.

Да, важная деталь - реализация должна быть эффективной.

anonymous
()
Ответ на: комментарий от anonymous

Моя позиция в том, что экспандер должен быть туп, как пробка (как в Common Lisp), без всякой гнилой гигиены, так что внутри DSLей могут быть свои собственные экспандеры.

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

anonymous
()
Ответ на: комментарий от anonymous

С интересом посмотрю, как в твоей реализации этого слишком простого языка обрабатывается goto. Особенно интересен случай irreducible control flow.

Тривиально раскрывается в letrec. Это классическая реализация goto в схемке.

Да, важная деталь - реализация должна быть эффективной.

Более эффективной реализации в схемке не существует. Но вобщем сделанный на таком goto цикл будет работать ровно с той же скоростью, что и обычный луп, например. То есть схемка в принципе не умеет делать переход быстрее чем так.

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous

Тривиально раскрывается в letrec. Это классическая реализация goto в схемке.

Для начала тебе придется код на Паскале перевести в SSA, и затем в CPS. Причем, делать это только для тех под-графов, в которых есть irreducible control flow. Если делать это для всех, то будет неэффективно.

Все еще «проще, чем loop»?

Но вобщем сделанный на таком goto цикл будет работать ровно с той же скоростью, что и обычный луп, например.

Ага, только тебе надо это делать только для goto, причем не всех. Ты же не хочешь так же обрабатывать control flow внутри, например, if?

anonymous
()
Ответ на: комментарий от anonymous

реализация чего действительно может вызвать проблемы (тайпчекер тот же).

Что с тайпчекером-то сложного? Там банальный type propagation, делается в один проход переписыванием дерева depth-first. Исходный AST без типов, целевой AST с каждым expression и lvalue узлом, аннотированным его типом (или идентификатором типа). Правила тривиальны.

Для ML даже проще - дерево переписывается два раза, первый раз каждый expression аннотирован уникальным идентификатором, второй раз создается плоский список уравнений с этими идентификаторами (там четыре правила переписывания выходит). Дальше тупо применяешь к уравнениям унификацию, и подставляешь полученные типы на место идентификаторов. Скукота.

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

anonymous
()
Ответ на: комментарий от anonymous

Что с тайпчекером-то сложного? Там банальный type propagation, делается в один проход переписыванием дерева depth-first.

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

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

Для ML даже проще

В ML есть полиморфизм - это сильно усложняет представление типизированного дерева и вообще control-flow тайпчека.

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

Это как раз элементарные вещи для реализации которых даже задумываться не нужно.

anonymous
()
Ответ на: комментарий от anonymous

Если делать это для всех, то будет неэффективно.

Да нет, вполне эффективно.

Для начала тебе придется код на Паскале перевести в SSA, и затем в CPS.

Ты совсем дурак чтоли? Надо быть полным ебланом, чтобы переводить код в SSA, чтобы потом переводить его в CPS.

Все еще «проще, чем loop»?

Конечно. Метки лупа в схеме вообще в отличии от паскалевского goto только через продолжения реализовать можно.

anonymous
()
Ответ на: комментарий от anonymous

То есть следует алгоритм тайпчека реализовать как частный случай алгоритма экспанда

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

и проход, конечно же, один - тайпчек должен идти синхронно с экспандорм

Ты уже заведомо обосрался делать оптимизации. Научись мыслить чуть шире чем твой убогий и кривой гигиенический экспанд.

т.к. макры не смогут взаимодействовать с типами и макросистемой хост-языка

Идиот. Какие такие типы хост-языка?!? Это ж говносхемка!

В ML есть полиморфизм - это сильно усложняет представление типизированного дерева и вообще control-flow тайпчека.

Весь этот «полиморфизм» - это тупо узел «variable» в AST типа. Который по сути ничем от других не отличается.

Это как раз элементарные вещи для реализации которых даже задумываться не нужно.

Ну рассказывай, как ты irreducible control flow будешь «не задумываясь» транслировать. И так, чтоб letrec получался только для него, а чисто структурный код (пусть даже реализованный на goto) транслировался бы в структурные конструкции.

anonymous
()
Ответ на: комментарий от anonymous

Ты вообще не способен мыслить в более удобных и высокоуровневых абстракциях

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

Затраты на «синхронность» с экспандом на самом деле минимальны, зато искаробки получаем кучу вещей, делать которые ты будешь до старости.

Ты уже заведомо обосрался делать оптимизации.

При чем тут оптимизации, дурашка?

Какие такие типы хост-языка?!?

Не знаю. При чем тут типы хост-языка?

И так, чтоб letrec получался только для него, а чисто структурный код (пусть даже реализованный на goto) транслировался бы в структурные конструкции.

Не понял, ты подумал, что я собираюсь бранчи ифа в летрек пихать или что?

anonymous
()
Ответ на: комментарий от anonymous

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

То, что ты выше написал для with - это как раз говнокод.

Затраты на «синхронность» с экспандом на самом деле минимальны,

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

При чем тут оптимизации, дурашка?

При том, что ты их будешь делать между тайпчеком и экспандом.

Не знаю. При чем тут типы хост-языка?

Ты сам это вякнул. Тебе и объяснять.

Не понял, ты подумал, что я собираюсь бранчи ифа в летрек пихать или что?

Как ты будешь бранчи ифа не пихать, а irreducible goto пихать? Как ты их отличишь, да еще и в один проход с тайпчеком?!?

anonymous
()
Ответ на: комментарий от anonymous

То, что ты выше написал для with - это как раз говнокод.

Замечательно. Я с нетерпением ожидаю твоего решения. Правда, не думаю, что мы его увидим.

за счет отсутствия разделения таких абсолютно разных частей трансляции, как тайпчек и собственно экспанд.

С чего же это отсутствие?

Ты сам это вякнул.

Нет, я ничего такого не говорил.

Как ты будешь бранчи ифа не пихать, а irreducible goto пихать? Как ты их отличишь, да еще и в один проход с тайпчеком?!?

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

А ты, еблан, какие-то SSA зачем-то притащил, CPS, пиздец - заставь дурака богу молиться, что называется.

anonymous
()
Ответ на: комментарий от anonymous

С чего же это отсутствие?

Ты ж сам собрался въебать все в макроэкспанд, без разделения на фазы.

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

Код с goto, который в принципе транслируется в loop, должен транслироваться в loop, а не letrec, придурок. Код с irreducible cfg только и должен в letrec транслироваться. Иначе неэффективно.

А ты, еблан, какие-то SSA зачем-то притащил, CPS, пиздец - заставь дурака богу молиться, что называется.

Ну а как ты анализировать cfg на наличие irreducible flow будешь?

anonymous
()
Ответ на: комментарий от anonymous

какие-то SSA зачем-то притащил

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

anonymous
()
Ответ на: комментарий от anonymous

Ты ж сам собрался въебать все в макроэкспанд

Да. Но как это связано с разделением кода?

Код с goto, который в принципе транслируется в loop, должен транслироваться в loop, а не letrec

Конечно же не должен.

Иначе неэффективно.

Это твои ебанутые фантазии. В схеме все циклы - это летрек. Как думаешь, форма (let loop (bindings) ... blah blah ... (loop args ...)) во что транслируется? Так что толку от твоих «оптимизаций» чуть менее чем никакого - один хуй твой луп, в который ты оттранслируешь reducible, потом преобразуется в летрек.

Ну а как ты анализировать cfg на наличие irreducible flow будешь?

Ты совсем тупой? Я вообще не буду этого делать. Это не нужно. Нужно только побить код на куски и засунуть каждый в свою лямбду в летреке. Да собсно не надо даже в лямбды в летреке - удобнее дефайнов внутрь лета налепить.

anonymous
()
Ответ на: комментарий от anonymous

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

Это ты чего под этим подразумеваешь?

anonymous
()
Ответ на: комментарий от anonymous

Конечно же не должен.

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

В схеме все циклы - это летрек.

Только вот схема тупая и loop оптимизировать внутри умеет, а с letrec никто ничего не гарантирует.

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

Так делать нельзя. Это неэффективно. А если на самом деле бить ничего не надо, и control flow в обычные структурные конструкции впишется (и вообще не содержит циклов)?

anonymous
()
Ответ на: комментарий от anonymous

Это ты чего под этим подразумеваешь?

Вместо:

(let ((a 1))
  (define label1 ()
      (set! a (+ a 1))
      (label2))
  (define label2 ()
      (if (> a 10) a (label1)))
  (label1))

Писать так:

(begin
   (define (label1 a)
       (label2 (+ a 1)))
   (define (label2 a)
       (if (> a 10) a (label1 a)))
   (label1 1))

Читай про эквивалентность SSA и CPS, ламер.

anonymous
()
Ответ на: комментарий от anonymous

ЗЫ: обрати внимание, что при этом преобразовании императивный код стал функциональным. Причем, этот трюк возможен даже с массивами и структурами (см. Array SSA).

anonymous
()
Ответ на: комментарий от anonymous

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

Нет, именно нормальный компилятор.

Только вот схема тупая и loop оптимизировать внутри умеет, а с letrec никто ничего не гарантирует.

Ты что, совсем тупой? Еще раз, для особо одаренных - В СХЕМЕ НЕТУ НИКАКОГО ЛУПА. Твой луп в тот самый летрек и переводится.

Так делать нельзя. Это неэффективно.

Это максимально эффективно.

А если на самом деле бить ничего не надо, и control flow в обычные структурные конструкции впишется (и вообще не содержит циклов)?

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

(letrec ([start (lambda () (foo) (next))]
         [next (lambda () (bar) (exit))]
         [exit (lambda () (void))])
  (start))
скомпилируется в банальное (begin (foo) (bar) (void))

anonymous
()
Ответ на: комментарий от anonymous

Писать так:

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

Читай про эквивалентность SSA и CPS

Я прекрасно знаю про эквивалентность SSA и CPS.

anonymous
()
Ответ на: комментарий от anonymous

А, я понял, ты дуцмаешь что вот это ты показал пример SSA? Нет, это не SSA.

Ну и я все еще жду от тебя блестящей реализации with.

anonymous
()
Ответ на: комментарий от anonymous

Я уж не говорю про то, что это преобразование существенно меняет семантику и потому его применять просто нельзя.

Дебил. Невменяемый дебил. Семантика не изменилась, недоумок.

anonymous
()
Ответ на: комментарий от anonymous

А, я понял, ты дуцмаешь что вот это ты показал пример SSA? Нет, это не SSA.

Ты конченный недоумок. Это пример того, как выглядит CPS после SSA (если до уебана не дошло, то поясню - a была мутабельной переменной, а была promoted до регистра).

anonymous
()
Ответ на: комментарий от anonymous

Семантика не изменилась

Изменилась. При чем ощутимо. Потому никто таких преобразований и не выполняет.

anonymous
()
Ответ на: комментарий от anonymous

Это пример того, как выглядит CPS

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

anonymous
()
Ответ на: комментарий от anonymous

Потому никто таких преобразований и не выполняет.

Расскажи это любому компилятору, где есть mem2reg pass, сосунок.

anonymous
()
Ответ на: комментарий от anonymous

Ты совсем конченая ебанашка. Еще раз - написанная твоей поебота не имеет никакого отношения ни к SSA, ни к CPS. И, соответственно, к mem2reg pass тоже. Я уж не говорю о том, что в чуть менее тривиальных случаях эта твоя «оптимизация» только замедлит работу программы.

anonymous
()
Ответ на: комментарий от anonymous

Не, ну ты пиздюк невменяемый! Был alloca, стал виртуальный регистр (мутабельная переменная с set! и аргумент функции).

Если ты настолько опизденевшая школолятина, что не в состоянии понять эквивалентности, то тебе пора вешаться.

anonymous
()
Ответ на: комментарий от anonymous

У CPS и SSA есть вполне четкое определение и все, что ему не удволетворяет - не имеет отношения к CPS и SSA.

не в состоянии понять эквивалентности

Код до преобразования в CPS/SSA эквивалентен коду после этого преобразования. От этого оригинальный код ближе к SSA/CPS не становится ни на грамм. И я все еще жду with.

anonymous
()
Ответ на: комментарий от anonymous

После паскаля с тебя паскаль, а не with. with - сейчас.

Хотя мы от тебя, конечно, никогда и ничего не ддождемся, ты только пиздеть горазд.

anonymous
()
Ответ на: комментарий от anonymous

Один только with без паскаля бесполезен. Для Схемы такая конструкция не нужна, ибо динамически типизированное говно.

anonymous
()
Ответ на: комментарий от anonymous

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

но когда ты не покажешь, конечно

anonymous
()
Ответ на: комментарий от anonymous

Никто не мешает указать тип структуры в форме макровызова, как у меня сделано. Тем более что реализация будет точно такая же, как и в случае с типами. Я все еще жду реализации.

anonymous
()
Ответ на: комментарий от anonymous

У тебя пиздня, а не реализация.

Без типов with невозможен. Такое работать не будет:

(define-record Eblo (integer Pizdnia) (real Mudotnia))

(define (foo x)
  (with (x)
     (set! Pizdnia (* Modutnia 2))))

(foo (new Eblo 0 0.0))
anonymous
()
Ответ на: комментарий от anonymous

Без типов with невозможен. Такое работать не будет:

У меня все прекрасно работает:

(define (foo x)
  (with x Eblo
     (set! Pizdnia (* Modutnia 2))))

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

anonymous
()
Ответ на: комментарий от anonymous

Ты пиздюк, а твоя мамка - блядина.

Семантика with не предполагает явного именования типов, сучка ты рваная. Он к хуям не нужен, если еще и типы писать надо.

anonymous
()
Ответ на: комментарий от anonymous

Оять жалкие отговорки.

Реализация с явным/неявным именованием типов различается в одной единственной строке, в остальном - все в точности одно и тоже.

Так ты напишешь with или и дальше будешь придумывать жалкие отмазки, признавая, раз за разом, что неспособен жалких 20 строк кода родить?

Он к хуям не нужен, если еще и типы писать надо

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

anonymous
()
Ответ на: комментарий от anonymous

Сделай с неявными типами (и не как в какашкелях с какамликами, с общим пространством имен для полей структур). Или иди на хуй, школоло.

anonymous
()
Ответ на: комментарий от anonymous

Да без проблем, собственно, с неявными типами это даже проще:

(begin-for-syntax
  (define (id-transformer getter setter tmp)
     (syntax-parser [id:id #`(#,getter #,tmp)]
                    [((~literal set!) id:id e:expr) #`(#,setter #,tmp e)])))

(define-simple-macro (with e:expr body:expr ...+)
  #:do ([type (type-of #'e)])
  #:fail-unless (record? type) (~a "missed record in" type)
  #:with (getter ...) #`#,(record-getters type)
  #:with (setter ...) #`#,(record-setter type)
  (let* ([tmp e]) 
    (define-syntax transformed
      (make-set!-transformer (id-transformer #'getter #'setter #'tmp))) ...
    body ...))
давай тебе свой охуенный код

anonymous
()
Ответ на: комментарий от anonymous

#:do ([type (type-of #'e)])

#:do ([define type (type-of #'e)]) ofc

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.