1) Так никто же и не спорит, что именно дерево. Более того — AST как дерево (T — Tree), входит в изначальный дизайн языка. Так действительно, при чем здесь пары? При том, что (если я вас правильно понял) вы противопоставляете свой узел дерева как линейный массив элементов «настоящему» узлу лиспа, как списку, состоящему из пар; под словом «дерево», в данном случае, понимая конечную реализацию языка.
Дебажная инфа в узлах — отличное решение, но к контексту разговора не относящееся. Хотя да, удобно, спорить не буду.
2) В C есть макросы (кодогенерация). С тоже попадает в эту категорию? В С++ есть шаблоны (кодогенерация), то же самое?
3) Конечно разные. Но без первого не будет второго.
4) ff-fold, это специфическая для диалекта свертка — свертка по хеш-таблице (мне кажется, можно было по подсказке «хеш-таблица» догадаться, что если обычный fold в лямбду отдает state и value, то fold с тремя аргументами по хеш-таблице отдает state, key и value).
Вы же понимаете, что я просто выдрал кусочек рабочей программы с целью посмотреть на живом примере, как оно будет на деле в вашем синтаксисе, вместо того, что бы пустопорожне высказывать свой скепсис; а не тщательно готовился выбирая «самый правильный» и «самый r7rs-compliant» вариант? По моему мнению — этот кусочек вполне подходит чтобы оценить.
5) Что значит «дословная калька не покажет»? Вы написали, что используете отступы, а не скобки для гарантированной читаемости кода. Для того, чтобы оценить синтаксис — калька отлично подходит. А если вы собираетесь менять алгоритм — то это уже рефакторинг, а не синтаксические различия.
Я видел тесты, это чуть ли не первое, что я в проекте посмотрел. К сожалению, оценить по ним ничего не выходит — они слишком маленькие и простые. Поэтому и выдал свой пример, снова таки, вполне, по моему мнению, подходящий — там есть аргументы, есть лямбда, есть сложноотформатированный для лучшей читабельности список и условие в одну строку, тоже для лучшей читабельности.
p.s. Что делает этот код — на основании хеш-таблицы с прямой адресацией, в которой хранятся хешированные (как y*65536+x) координаты «живых» клеток, генерирует новую аналогичную хеш-таблицу, проверяя не только текущую клетку (а не должна ли она умереть), но и все 8 соседних (а не должны ли они родится). Результат — новое поколение на зацикленной карте 65536*65536. #empty — пустая таблица, но вроде это и так очевидно.
p.p.s. Ладно, извините за клоуна. Я иногда, возможно, бываю слишком резок, когда кто-то достаточно безапелляционно выдает вполне, на мой взгляд, бредовые вещи. Но консенсус всегда достижим. Продолжаем?
1. А, так вы о конкретной реализации… Но ведь никто не мешает вам реализовать список как линейный массив указателей и/или непосредственных значений; никто вас не заставляет делать пары.
2. Несколько разные вещи, «смотреть что там сгенерировалось» и «программировать на языке», не находите?
3. Вы так и не поняли, о чем я писал; хоть дочитали предложение, или на слове «ребенок» остановились? Попытаюсь объяснить доступнее: шестилетний ребенок способен понять синтаксис языка, его конструкцию, как им пользоваться и базовые примитивы за пару вечеров. Неофит, которому это недоступно и код выглядит как каша — ленивая или глупая скотина, которой место на стройке, а не в программировании.
4. facepalm, у меня нет слов. Ну предложите свои варианты названий, которые будут «самодокументируемые», надеюсь это не будут get-value-by-key-from-hash-table и check-that-cell-is-alive-or-dead-because-i-like-self-describing-functions? И при чем тут экономия байт, это вообще к чему?
И таки да, вы ведете себя как клоун. Я вас попросил привести пример того, как будет выглядеть приведенный код в вашем, «более лучшем» синтаксисе — а вы разводите демагогию «у вас код сам себя не документирует». Неужели боитесь дать конкретный ответ на конкретный вопрос?
1. Разница в синтаксисе — это НЕ разница. Вы написали, что «вместо иерархии списков используется полноценное дерево». Иерархия списков, в данном случае, это и есть полноценное дерево — полноценнее некуда. Может я вас неправильно понял?
2. Вы и C++ код отлаживаете в ассемблерных инструкциях? Зачем вам отлаживать сгенерированный код, если есть возможность читать исходники?
3. Я обучил лиспу за пару вечеров 6-летнего ребенка (точнее научил синтаксису за 10 минут, а остальное время потратил на функции и рекурсию). Если ваши неофиты по уровню развития не превышают дошкольников, то пускай идут работать разнорабочими, а не программистами.
Для сравнения — синтаксис С он так и не смог адекватно понять.
Вы мне все же не ответили на вопрос — покажите, пожалуйста, как вышеприведенный, вполне простой и прозрачный код, будет выглядеть в вашем, более понятном и «гарантированно читабельном» виде? (ff-fold это свертка по хеш таблице, alive — внешняя функция проверки «а жива ли клетка», hash — хеш).
Если вдруг что — стучитесь в личку. Там потом попадутся довольно сложные вещи; например, продолжения (call/cc) — программистов, которые понимают, что это такое, можно по пальцам в своем окружении пересчитать.
Не надо усложнять правила разбора — Lisp потому и великолепен, что прост как бревно, даже Fort сложнее. Скобка — это всегда(!!!) список, первая лексема — всегда(!!!) операция. А для подавляющего большинства извращенцев программистов — существуют макросы.
Присвоение переменной лямбды, как (define (func args) ...) является ничем иным, как обычным макросом (в данном случае — гигиеническим), разворачивающимся в (define func (lambda (args) ...)
Точно так же, как (let ...) спокойно разворачивается тем же способом в набор лямбд, вместо введения новой сущности:
(define-syntax let
(syntax-rules ()
((let ((var val) ...) exp . rest)
((lambda (var ...) exp . rest) val ...))
((let keyword ((var init) ...) exp . rest)
(letrec ((keyword (lambda (var ...) exp . rest))) (keyword init ...)))))
; где
(define-syntax letrec
(syntax-rules (rlambda)
((letrec ((?var ?val) ...) ?body) (rlambda (?var ...) (?val ...) ?body))
((letrec vars body ...) (letrec vars (begin body ...)))))
Или же list:
(define-syntax list
(syntax-rules ()
((list) '())
((list a . b)
(cons a (list . b)))))
То же самое касается cond, case, and, or, begin и остального зоопарка.
Вообще, по минимальному принципу — чтобы сделать Lisp, от ядра языка требуются cons, car, cdr, type, eq?, less?, lambda, quote, define, if, values и define-syntax + syntax-rules. А, да, еще разворачивать ' в quote, а '(...) в (list quote. quote. quote.). Где-то так.
Ну так бы в первом абзаце и написали — «Я пишу цикл статей о формальных языках программирования. Для закрепления знаний на практике мы напишем простой Lisp. В первой части мы напишем парсер, во второй… и т.д.». И кому интересны именно ЯП, а не лишние телодвижения, сразу бы статью скипнули и не выдвигали претензий (а лично я бы вообще сразу перешел к написанию самого ЯП, а на парсер просто дал бы ссылку на гитхаб).
Да, это отличная книга. И в ней рассказывают именно о том, как написать формальный язык. Уж извините за критику, но то, что встатье — это базовые вещи. Это как если бы вы начали с букваря там, я не знаю.
Рекомендую ее почитать. Там нету никаких своих токенизатор/лексер/парсер/транслятор — там сразу берется готовый условный лисп (любой лисп имеет это все из коробки, естественно) и на нем же пишется новый условный лисп. Никакой долгой и муторной подготовки — сразу даются знания о том, как пишутся формальные языки программирования. И, что главное, последовательно и точно описываются все грабли, по которым вы, я так понимаю, намеревались уверенно станцевать.
3. Элементарно решается штатными средствами, вместо изобретения нового компилятора.
(define first car)
(define second cadr)
(define third caddr)
2. ??? Вы серьезно? Как у вас, например, должен выглядеть вот такой код:
; new convey's generation
(ff-fold (lambda (st key value)
(let ((x (mod key 65536))
(y (div key 65536)))
(fold (lambda (st key)
(let ((x (car key))
(y (cdr key)))
(if (alive generation x y) (put st (hash x y) 1) st)))
(if (alive generation x y) (put st (hash x y) 1) st) ; the cell
(list (cons (- x 1) (- y 1)) ; possible cell neighbors
(cons x (- y 1))
(cons (+ x 1) (- y 1))
(cons (- x 1) y )
;cons x y )
(cons (+ x 1) y )
(cons (- x 1) (+ y 1))
(cons x (+ y 1))
(cons (+ x 1) (+ y 1))))))
#empty generation)))
Тем, кому все же интересен лисп, а не очередной (полу)автоматический парсер из готовой тулзени, рекомендую отлично переведенную книгу «Lisp in Small Pieces». Ссылка на хабр же.
«Создано идеальное зеркало, – сказал Дауге, – «абсолютный отражатель». Субстанция, отражающая все виды лучистой энергии любой интенсивности и все виды элементарных частиц с энергиями до ста – ста пятидесяти миллионов электронвольт. Кроме нейтрино, кажется. Волшебная субстанция. Ее теорию разработал институт в Новосибирске. Правда, они не думали о фотонной ракете. Они исследовали возможности идеальной защиты от проникающего излучения ядерного реактора. Но Краюхин сразу понял, в чем дело. – Дауге усмехнулся. – Краюхин – фанатик фотонной ракеты. Это ему принадлежит знаменитый афоризм: «Фотонная ракета – покоренная Вселенная». Краюхин моментально вцепился в «абсолютный отражатель», посадил за его разработку две трети лабораторий комитета, и вот – «Хиус»!»
Меня сильно смущает картинка с иллюстрацией моушен-блюра на lcd.
Заголовок
Вот эта, если что
Смазывание картинки равномерное, без разрывов. Значит объект двигался равномерно. На глазок, смазывание занимает около 25 пикселей. С учетом того, что частота смены кадров заявлена в 60Гц, то время затухания пикселя выходит ~ 400 мс. Что это за антикварная матрица такая?
Нас пытаются на@#ать или это я где-то в расчетах ошибся?
> Что касается спортбайков, там соглашусь, на тех скоростях гироэффект колёс вносит поправки в управление.
Есть использующий гироскопический эффект прием, позволяющий быстро входить в повороты — если надо круто войти в правый (например) поворот, то надо резко толкнуть вперед правый (тот же, что и нужный поворот) грипс. В результате гироскопического эффекта на переднем колесе байк быстро завалится вправо (в сторону поворота), ну а дальше все как обычно в положении «я уже наклонен и в процессе поворачивания».
Вот, как-то так. Трюк после небольшой тренировки получается легко, но насчет объяснения я могу и ошибаться — мне показывали и рассказывали «старшие» велотоварищи, а не академики-физики.
Ну почему подвески нету? Есть. Главная подвеска (с учетом того, что велосипед весит 10кг, а велосипедист — 80кг), это ноги и, извините, задница.
Таким образом, аккумуляторы лучше возить на спине.
Впрочем, можно пересесть на двухподвес и уложить все на багажник.
> Чтобы решить задачу, нужно сначала четко себе ее представить.
Вот-вот.
Рекомендую ознакомится с исходниками давно построенного и проверенного велосипеда под названием "Симулятор Солнечной системы".
А именно, что б долго не искать, с классом Orbit и, например, его использованием в методе Body::getPosition().
p.s. Ваша заметка плохая. Теории нет, решения заявленной задачи нет. То, что вы накодили — кривое и, строго говоря, нерабочее… Вообще оставляет впечатление «нам вчера в классе рассказали про питон и зацените, что я сегодня набросал».
Не надо такую же вторую писать.
Поддерживаю. С уточнением, что парой девайсов владеют 10-летние дети. Девайсы при этом не только живы но и вполне неплохо выглядят. (lbook они же убили за месяц).
Дебажная инфа в узлах — отличное решение, но к контексту разговора не относящееся. Хотя да, удобно, спорить не буду.
2) В C есть макросы (кодогенерация). С тоже попадает в эту категорию? В С++ есть шаблоны (кодогенерация), то же самое?
3) Конечно разные. Но без первого не будет второго.
4) ff-fold, это специфическая для диалекта свертка — свертка по хеш-таблице (мне кажется, можно было по подсказке «хеш-таблица» догадаться, что если обычный fold в лямбду отдает state и value, то fold с тремя аргументами по хеш-таблице отдает state, key и value).
Вы же понимаете, что я просто выдрал кусочек рабочей программы с целью посмотреть на живом примере, как оно будет на деле в вашем синтаксисе, вместо того, что бы пустопорожне высказывать свой скепсис; а не тщательно готовился выбирая «самый правильный» и «самый r7rs-compliant» вариант? По моему мнению — этот кусочек вполне подходит чтобы оценить.
5) Что значит «дословная калька не покажет»? Вы написали, что используете отступы, а не скобки для гарантированной читаемости кода. Для того, чтобы оценить синтаксис — калька отлично подходит. А если вы собираетесь менять алгоритм — то это уже рефакторинг, а не синтаксические различия.
Я видел тесты, это чуть ли не первое, что я в проекте посмотрел. К сожалению, оценить по ним ничего не выходит — они слишком маленькие и простые. Поэтому и выдал свой пример, снова таки, вполне, по моему мнению, подходящий — там есть аргументы, есть лямбда, есть сложноотформатированный для лучшей читабельности список и условие в одну строку, тоже для лучшей читабельности.
p.s. Что делает этот код — на основании хеш-таблицы с прямой адресацией, в которой хранятся хешированные (как y*65536+x) координаты «живых» клеток, генерирует новую аналогичную хеш-таблицу, проверяя не только текущую клетку (а не должна ли она умереть), но и все 8 соседних (а не должны ли они родится). Результат — новое поколение на зацикленной карте 65536*65536. #empty — пустая таблица, но вроде это и так очевидно.
p.p.s. Ладно, извините за клоуна. Я иногда, возможно, бываю слишком резок, когда кто-то достаточно безапелляционно выдает вполне, на мой взгляд, бредовые вещи. Но консенсус всегда достижим. Продолжаем?
Как то слишком пафосно для 179 лет: «В 1837 году установлен в Московском Кремле на постамент, исполненный по проекту Огюста Монферрана.» (с)
2. Несколько разные вещи, «смотреть что там сгенерировалось» и «программировать на языке», не находите?
3. Вы так и не поняли, о чем я писал; хоть дочитали предложение, или на слове «ребенок» остановились? Попытаюсь объяснить доступнее: шестилетний ребенок способен понять синтаксис языка, его конструкцию, как им пользоваться и базовые примитивы за пару вечеров. Неофит, которому это недоступно и код выглядит как каша — ленивая или глупая скотина, которой место на стройке, а не в программировании.
4. facepalm, у меня нет слов. Ну предложите свои варианты названий, которые будут «самодокументируемые», надеюсь это не будут get-value-by-key-from-hash-table и check-that-cell-is-alive-or-dead-because-i-like-self-describing-functions? И при чем тут экономия байт, это вообще к чему?
И таки да, вы ведете себя как клоун. Я вас попросил привести пример того, как будет выглядеть приведенный код в вашем, «более лучшем» синтаксисе — а вы разводите демагогию «у вас код сам себя не документирует». Неужели боитесь дать конкретный ответ на конкретный вопрос?
2. Вы и C++ код отлаживаете в ассемблерных инструкциях? Зачем вам отлаживать сгенерированный код, если есть возможность читать исходники?
3. Я обучил лиспу за пару вечеров 6-летнего ребенка (точнее научил синтаксису за 10 минут, а остальное время потратил на функции и рекурсию). Если ваши неофиты по уровню развития не превышают дошкольников, то пускай идут работать разнорабочими, а не программистами.
Для сравнения — синтаксис С он так и не смог адекватно понять.
Вы мне все же не ответили на вопрос — покажите, пожалуйста, как вышеприведенный, вполне простой и прозрачный код, будет выглядеть в вашем, более понятном и «гарантированно читабельном» виде? (ff-fold это свертка по хеш таблице, alive — внешняя функция проверки «а жива ли клетка», hash — хеш).
Ну а вообще — я за Lisp во всем мире. Удачи!
извращенцевпрограммистов — существуют макросы.Присвоение переменной лямбды, как (define (func args) ...) является ничем иным, как обычным макросом (в данном случае — гигиеническим), разворачивающимся в (define func (lambda (args) ...)
Например, таким:
Точно так же, как (let ...) спокойно разворачивается тем же способом в набор лямбд, вместо введения новой сущности:
Или же list:
То же самое касается cond, case, and, or, begin и остального зоопарка.
Вообще, по минимальному принципу — чтобы сделать Lisp, от ядра языка требуются cons, car, cdr, type, eq?, less?, lambda, quote, define, if, values и define-syntax + syntax-rules. А, да, еще разворачивать ' в quote, а '(...) в (list quote. quote. quote.). Где-то так.
Да, это отличная книга. И в ней рассказывают именно о том, как написать формальный язык. Уж извините за критику, но то, что встатье — это базовые вещи. Это как если бы вы начали с букваря там, я не знаю.
Рекомендую ее почитать. Там нету никаких своих токенизатор/лексер/парсер/транслятор — там сразу берется готовый условный лисп (любой лисп имеет это все из коробки, естественно) и на нем же пишется новый условный лисп. Никакой долгой и муторной подготовки — сразу даются знания о том, как пишутся формальные языки программирования. И, что главное, последовательно и точно описываются все грабли, по которым вы, я так понимаю, намеревались уверенно станцевать.
3. Элементарно решается штатными средствами, вместо изобретения нового компилятора.
2. ??? Вы серьезно? Как у вас, например, должен выглядеть вот такой код:
«Создано идеальное зеркало, – сказал Дауге, – «абсолютный отражатель». Субстанция, отражающая все виды лучистой энергии любой интенсивности и все виды элементарных частиц с энергиями до ста – ста пятидесяти миллионов электронвольт. Кроме нейтрино, кажется. Волшебная субстанция. Ее теорию разработал институт в Новосибирске. Правда, они не думали о фотонной ракете. Они исследовали возможности идеальной защиты от проникающего излучения ядерного реактора. Но Краюхин сразу понял, в чем дело. – Дауге усмехнулся. – Краюхин – фанатик фотонной ракеты. Это ему принадлежит знаменитый афоризм: «Фотонная ракета – покоренная Вселенная». Краюхин моментально вцепился в «абсолютный отражатель», посадил за его разработку две трети лабораторий комитета, и вот – «Хиус»!»
Смазывание картинки равномерное, без разрывов. Значит объект двигался равномерно. На глазок, смазывание занимает около 25 пикселей. С учетом того, что частота смены кадров заявлена в 60Гц, то время затухания пикселя выходит ~ 400 мс. Что это за антикварная матрица такая?
Нас пытаются на@#ать или это я где-то в расчетах ошибся?
Есть использующий гироскопический эффект прием, позволяющий быстро входить в повороты — если надо круто войти в правый (например) поворот, то надо резко толкнуть вперед правый (тот же, что и нужный поворот) грипс. В результате гироскопического эффекта на переднем колесе байк быстро завалится вправо (в сторону поворота), ну а дальше все как обычно в положении «я уже наклонен и в процессе поворачивания».
Вот, как-то так. Трюк после небольшой тренировки получается легко, но насчет объяснения я могу и ошибаться — мне показывали и рассказывали «старшие» велотоварищи, а не академики-физики.
Таким образом, аккумуляторы лучше возить на спине.
Впрочем, можно пересесть на двухподвес и уложить все на багажник.
Начиная со $100.
Вот-вот.
Рекомендую ознакомится с исходниками давно построенного и проверенного велосипеда под названием "Симулятор Солнечной системы".
А именно, что б долго не искать, с классом Orbit и, например, его использованием в методе Body::getPosition().
p.s. Ваша заметка плохая. Теории нет, решения заявленной задачи нет. То, что вы накодили — кривое и, строго говоря, нерабочее… Вообще оставляет впечатление «нам вчера в классе рассказали про питон и зацените, что я сегодня набросал».
Не надо такую же вторую писать.
Инерциоиды?