Почему бы не сделать свой Lisp для веба?

Вот есть JavaScript — прекрасная вещь. И прекрасная она на мой взгляд по большей части потому, что дебаггер и отладочные инструменты встроены в каждый Браузер. Без дебаггера и инспектора DOM-дерева было гораздо тяжелее что-либо разрабатывать на JavaScript.


Вот я и решил запилить свой Lisp, но с хорошим дебаггером. Взял маленький, простенький littlelisp и отрефакторил его на 99%. Заточил под пошаговое выполнение и создал свою IDE, простую но работающую.


В итоге получилось следующее.


image

.
Сам язык получился смесью Lisp и JavaScript-a потому, что Lisp я знал плохо, а JavaScript хорошо:)


Далее примеры кода.


(alert document.location.href)

(setq x "ok!") 
(alert (x.substring 0 2))

;; пример с if

(setq x (prompt "Value of X:"))
(if (x == null)
    (setq x "(none)")
    (alert (+ "x = " x))
:else
    (alert (+ "x = " x))
)

;; кстати тела while/if не обязательно оборачивать в свой список

(setq i 0)
(while (i < 10)
    (console.log i)
    (++ i)
)

;; есть синтаксический сахар для арифметических и логических операторов

(x < 2)                ;; -> (< x 2)
((x < 2) && (x > -1))  ;; -> (&& (< x 2) (> x -1))
((x < 2) || (x > -1))  ;; -> (|| (< x 2) (> x -1))
(x + 1 2 3)            ;; -> (+ x 1 2 3) => x+1+2+3
(x ++)                 ;; -> (++ x) 
(++ x y z)             ;; -> увеличит на 1 переменные x, y, z последовательно

;; создание и заполнение JS-объекта

(setq obj1 (new Object))
(setq obj1.a 123 obj1.b "abc") ;; можно за один вызов

(setq name "c")
(setq obj1.@name ())           ;; @ - разыменовывает
(setq obj1.@name.0 111)
(setq obj1.@name.1 222)
(setq obj1.@name.2 333) 

(alert (obj1.c.join " "))      ;; покажет "111 222 333"

;; классы пока-что сделаны по простому

(defclass Трамвай
    :extends Object
    :instvars "из_чего номер"
    :classvars "всего"
    :constructor init
)

(setq Трамвай.всего 0)

;; тела методов и функций тоже не обязательно оборачивать в свой список
(defmeth Трамвай.init (номер основа)
    (setq this.номер номер)
    (setq this.из_чего основа)
    (Трамвай.всего ++)
)

(defmeth Трамвай.поехали ()
    (window.alert (+ " Трамвай №" this.номер " из " this.из_чего " за вами выехал!"))
)

(setq Трамвай1 (new Трамвай 9 "буханки хлеба"))
(Трамвай1.поехали)
(alert (+ "Трамваев всего: " Трамвай.всего))

;; лямбды и функции тоже есть конечно-же

((lambda (x y) (alert (x + y)) "a" "b")

(defun f1 (x) (alert (x + " - ok!")))
(f1 "f1")

;; выполнение произвольного кода пока-что через создание и вызов JS-функции

((new Function "msg" "alert(msg);") document.title)

;; эксепшены тоже можно кидать и отлавливать

(catch (a.b)) ;; вернёт Exception object (Error: "a" is undefined!)
(throw (new Error "Exception!"))

Собственно, сам проект на гитхабе здесь: https://github.com/SaemonZixel/littlelisp.js


Напоследок скажу, что код пока-что в бете (на 17 мая 2020г). Ошибок пока что много и я их потихоньку нахожу и правлю :(


Но зато дебаггер почти как в Smalltalk-средах разработки получилось сделать! :)


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


(Добавлено 30 мая 2020г)
Так же я благодарен изначальному автору Mary Rose Cook за столь замечательную реализацию Lisp-a на JavaScript. Она компактна, мала и очень проста.
Страница на гитхабе: https://github.com/maryrosecook/littlelisp


Но к сожалению от этой красоты ничего не осталось. Я переписал всё под корень :(

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 69

    +5
    Заточил под пошаговое выполнение и создал свою IDE, простую но работающую.

    Почему Вы не рассказали про неё?
      0

      Я хочу про IDE рассказать, но она не достаточно отчищена от багов. А глючная IDE это весьма неудобно)
      Я пока-что оптимизацию хвостовой рекурсии отлаживаю. А там ещё над макросами надо думать...

      +9
      О. вы изобрели ClojureScript. Правда, с IDE.
      +1

      Не хотите попробовать реализовать его в формате tree вместо s-expressions и компилировать в wasm, а не интерпретировать? Тут я рассказывал про эту идею.

        0

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


        setq i 0 id null
        while 
            < i sentence1.length
            setq prev_id id
            setq id 
                    Storage.set 
                         + "string" 
                              Brain.new_id
                         :type 
                         "word" 
                         :value 
                         sentence1.@i 
                         :prev_id
                         prev_id
            if 
                    != prev_id null
                    Storage.set 
                         prev_id 
                         :next id
            ++ i

        Не уверен, что читабельность увеличилась...

          0

          Не очень понял, что делает ваш код. Но как понял переписал в более понятной форме:


          let index 0
          let id null
          
          loop
          
              switch
                  test ordered?
                      index
                      sentence1 .length
                  then break
          
              let prev_id id
          
              put id Storage .set 
                  join
                      \string
                      Brain .new_id
                  object
                      type \word
                      value sentence1 @ index
                      prev_id prev_id
          
              switch 
                  test unique?
                      prev_id
                      null
                  then Storage .set 
                      prev_id
                      object
                          next id
          
              ++ index
            0
            Правда это уже был бы не Лисп

            Это уже( (всё ещё?)) не лисп. Мне кажется, вы слишком буквально поняли акроним как Lots of Irritating Superfluous Parentheses)))
              0
              Согласно википедии: Лисп — это язык обработки списков. Является функциональныйм. И то и то можно делать на этом урезанном искажённом варианте лиспа. Так-что не «в кассу» ваше «ещё не лисп»…
                0
                только что перепроверил, на википедии написано, что лисп мультипарадигмальный. Мы, конечно, можем рассматривать сферический лисп в вакууме, но зачем? К тому же, мировое лисп сообщество давно перешло на common lisp или на scheme
                  0
                  Тем более. Функциональность есть, ООП есть — вот и мультипарадигменность. Согласен, незачем рассматривать сферический лисп в вакууме. Под определения лиспа этот лисп подпадает. Значит просто ещё один диалект лиспа на ряду с common lisp и scheme. Наверное их гораздо больше существует и это хорошо. Каждый выберет то, что ему ближе. Вот автору js-подобный лисп захотелось, вот и запилил. Что теперь гнабить его за это?)
                    0
                    > мировое лисп сообщество давно перешло на common lisp или на scheme

                    Если говорить о языках общего назначения, то да.
                    Но не надо забывать такие встраиваемые языки, как EmacsLisp, которых дофига и больше.
                0

                … И получился недо-Fort, недо-Tcl на питонозакваске...

                  0
                  А в чём оно на Fort похоже то? Где здесь вообще прослеживаются следы с Fort, Tcl и Python? Или вы сами эти языки не знаете, просто видели пару раз и решили сумничать, сравнить?
                0
                чем по вашему tree от s-expr отличается?
                  0

                  Исключительно синтаксисом.

                +1
                Это часом не вы были тем ведущим, который лет 5 назад на одной конференции тоже объединял Lisp и JavaScript?
                  0
                  Нет, не я. А что за ведущий?)
                    0
                    Было видео на Ютубе, к сожалению, не сохранил в закладки, а быстро найти не получается. Один паренек рассказывал, как круто Lisp работал бы во фронтэнде.
                +5
                ;; лямбды и функции тоже есть
                а оптимизация хвостовой рекурсии есть?
                  –2
                  Честно говоря я не встретил случаев когда нужна быль хвостовая рекурсия и соответственно её оптимизация в интерпретаторе. Я предполагаю это из-за того что есть while. Без него циклы пришлось бы организовывать рекурсией.
                  В Erlang нету циклов. Там надо использовать хвостовую рекурсию для организации цикличности. Но там green threads и это как раз выгодно для их функционирования.
                    +10
                    Лисп без TCO, но с циклами, за что вы так…
                    То, что вы написали, это джаваскрипт со скобочками)))) Но никак не лисп, уж извините.
                      0
                      И что, без TCO рекурсия не заработает? и циклы через макросы нельзя организовать?
                      Макросы то есть? Вот если без них, то это очень урезанный извращённый лисп тогда… автор исправляй пожалуйста «это».
                        0
                        Что значит «не заработает»? Рекурсия это когда функция вызывает(прямо или косвенно) себя. ТСО это tail call optimization, оптимизация «хвостового вызова», т.е. вызова, являющегося последним в вычислении этой функции. Её можно оптимизировать в цикл, и это одна из фишек лиспа. Рекурсия без такой оптимизации, конечно, будет работать, но не долго, тк случится Stack Overflow.
                          0

                          У меня Stack overflow не может произойти. Т.к. нету стека вызовов. Используется цепочка контекстов и бесконечный цикл. Т.е. будет работать столько, сколько есть оперативной памяти (миллиард вызовов или более...).
                          Я добавил в beta3 TCO.
                          Пожалуйста не ссортись:)
                          Если есть конструктивные предложения, то скажите. Я постараюсь реализовать их по мере возможности.

                  +1
                  (x + 1 2 3)


                  Подскажите, не возникает ли у вас ощущение диссонанса из-за такой формы записи? Я понимаю, что это выглядит хорошо в случае с (x + y), но когда (x + y z) — лично у меня вызывает недоумение, хотя я, конечно, могу понять о чем идет речь. Не стоит ли в таком случае дополнить до (x + y + z + a + b)? Тем более, что, на сколько мне известно, в common lisp уже есть реализация такой возможности
                    –4
                    Вообще немного коробит)
                    Но честно говоря форма (+ x y z) меня коробит побольше. Lisp для меня пока-что новый язык.
                    Возможно я добавлю такой синтаксис тоже в парсер. Хотя у меня были идеи сделать более сложный механизм арифметики. Например (x + y * z — a) парсилось бы в (+*- x y z a) и интерпретатором вычислялось бы отдельно каждая операция. Т.е. сначала "+", потом "*" и потом "-". Мне кажется это выгоднее было-бы.
                      +4
                      Эта форма специально нужна, чтобы не нужно было ничего добавлять в парсер. Первый элемент списка это функция, остальные — её аргументы.
                        0
                        Ну она и так есть, судя по примерам. Смысл комментария вашего тогда? Кто хочет префиксную нотацию, пусть использует её. Кто привык к js/с/java может заюзать инфиксную, которая ему удобнее и понятнее. Автор молодец, что заранее это предусмотрел и сделал. Чтоб сообщество js-программистов не пугать непривычной для них префиксной нотацией и вызвать у них больше интереса к лиспу.
                          +1
                          так нет тут никакой инфиксной нотации, по крайней мере пока что. Можно только поменять местами первые два элемента списка. Это видно из примеров:
                          (x + 1 2 3)
                          В такой форме записи вообще нет никакого смысла, если только не складывать всегда только два числа
                            –1
                            Для тех кто в танке. Этот яваскрипт-подобный лисп. Этот кастыль (частичная инфиксная запись) добавлен для яваскриптологов. Чтоб им в первое время было удобно всякие (if (a != b)… писать. В этом смысл. Что тут неясного то?
                            Для красноглазых лисперов есть префиксная запись.
                            Или что «ой! мой святой лисп осквернили! фу...»?))
                              +1
                              Так я не про то совсем. Если уж добавлять инфиксную нотацию, то добавлять полностью, а не вот этот вот костыль, который якобы можно оправдать таким образом, каким это сделали вы. При чем тут осквернение лиспа? Это осквернение логики
                                –1
                                А логика здесь причём? Её то как можно осквернить?)) или вашу логику осквернили?

                                Не нравиться — ну допишите функционал сами. В чём проблема? Пул-реквесты к вашим услугам)

                                Или вы только прийти, покритиковать можете: «ой как неправильно, ой как плохо, фу...»?
                                  +1
                                  Спасибо, насмешили. Я уже писал, что… А да пофиг. Дальше смысла продолжать это все я не вижу
                                    0
                                    Согласен. С уважением раскланяюсь.
                        0

                        "Возможно я добавлю такой синтаксис тоже в парсер"


                        Скорее добавляйте, иначе у вас получается странная смесь префиксной и инфиксной нотаций (см Википедию).

                          0
                          Ну синтаксический сахар — это сахар. Для JS-прогаммеров как видно добавлен. Пусть едят. Что тут такого?) Или вы принципиально против сахара в лисп?
                            0
                            Традиционно синтаксический сахар в лисп добавляется через макросы либо через макросы чтения, а их тут ещё нет.
                              0
                              Этот лисп сам по себе нетрадиционен)) Написан больше для привлечения js-программеров в мир лиспа. Макросов нет, зато много похожего, знакомого от js.
                              Будут макросы, наверное будет переделано на них. А сейчас хотябы так. Это вполне разумный шаг.
                          –1
                          Даже не представляю, как вы сможете объяснять компилятору/интерпритатору, как вычислять -+*++-*-+ или что-то подобное, может даже еще страшнее. Тем более, что нельзя вычислять сначала сложение, а потом умножение, существует приоритет выполнения тех или иных математических операций. Именно по этому 2+2*2 = 6, а не 8. В общем, не страдайте фигней, (x + y * z — a) в лиспе раскроется как (- (+ x (* y z)) a)
                            +1
                            Но честно говоря форма (+ x y z) меня коробит побольше.

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


                            сделать более сложный механизм арифметики. Например (x + y z — a) парсилось бы в (+ — x y z a)

                            (Обратную) польскую нотацию переизобретаем? вот на Форте еще попробовать самое то было бы, для прокачки мозга

                              –1
                              В смысле переизобретаем? Это лисп, детка, инфиксная нотация. Всё список, блин.
                          +3
                          Что с поддержкой макросов? В тексте не нашёл.
                            0

                            Макросы будут, когда я пойму как их "подружить" с JavaScript. Не так всё просто к сожалению с ними(

                            +2
                            Lisp без префиксной нотации, макросов и TCO, но зато с while-ом?
                            Спасибо, я лучше в Схему.

                            А почему про Mary Rose Cook в статье ни слова?
                              0
                              Наверное потому-что от изначального проекта Mary Rose Cook осталось «рожки да ножки». Автор написал, что 99% кода переписал.
                              Префиксная нотация есть. Инфексную — переделывает в префиксную парсер. Интерпритатор соответственно работает только с префиксной.
                              У вас проблемы с чтением текстов на русском языке?
                                0
                                Да, особенно когда пишут с опечатками. Неважно сколько осталось рожков в проекте, соавтора (особенно внесшего столь значительный вклад и работавшего над проектом ранее) стоило бы упомянуть. Я конечно не могу на этом настаивать, но как-то это создаёт нехорошее послевкусие. Объём переписанного автором оценить не берусь, поэтому ориентируюсь на историю комиттов. Хардкод типа «переделывает в префиксную парсер» в диалектах Lisp-а, имеющих богатую историю реализации макросов, смотрится как-то бледно. И кстати, забавно что вы отвечаете за автора. Вы как-то с ним связаны? Я смотрю, вы в теме проекта?
                                  0
                                  И какой же там «столь значительный вклад», если переписано 99%?

                                  поэтому ориентируюсь на историю комиттов.

                                  А я вот напрягся и посмотрел:
                                  github.com/maryrosecook/littlelisp/blob/master/littlelisp.js — 138 строк кода.
                                  github.com/SaemonZixel/littlelisp.js/blob/master/littlelisp.js — 2012 строк кода.
                                  И беглым взглядом разница сильно видна.
                                  Изначальный вариант Mary Rose Cook мне кстати понравился больше. Он простой и понятный.
                                  А вот у автора жесть яваскриптовая конечно.

                                  На странице проекта в гитхабе Mary Rose Cook упомянута в первых строках. Так, что уважение проявлено достаточно.

                                  Вы как-то с ним связаны?

                                  Да. Мы вместе говорим на русском языке, знаем js и интересуемся лиспом. Этого достаточно?
                                    0
                                    А вы не по строкам считайте, а по потраченным годам. Я честно не понимаю этого. Это простая норма уважения, просто упомянуть, что проект основан на работе такого-то, такого-то. От этого что-то убудет? А так получается был понятный и компактный проект, на который какой-то человек потратил несколько лет. И тут происходит взрыв на макаронной фабрике. За несколько месяцев проект превращается в непонятного макаронного монстра. Я не отрицаю, SaemonZixel за короткое время написал много строк кода, но вот по делу ли они написаны? Автор сам признаёт, что Lisp знает плохо. Так может стоило поучиться? Понять для чего нужна префиксная нотация? Зачем нужен TCO? Для чего макросы и чем они лучше хардкода в парсере? Но пусть так, пусть будет ещё один диалект Lisp-а. Странный. С инфиксными операторами. Пусть так. Но упомянуть человека, с работы которого начался проект можно было? Не только в тексте лицензии, но и в популяризирующей статье? Это ведь плюс — наличие дополнительного источника. Разве нет? Но больше всего я не понимаю, почему он сейчас молчит. А отвечает за него слабо знакомый с ним человек.
                                      0
                                      Написал автору в личку, чтоб поучаствовал.

                                      И тут происходит взрыв на макаронной фабрике.

                                      Зачётно. Посмеялся)))

                                      Понять для чего нужна префиксная нотация?

                                      Так онаж и так есть? в чём претензия то?)))
                                      Просто добавили немного инфиксной записи для яваскриптологов.

                                      Зачем нужен TCO?

                                      Автор же написал, что не почувствовал нужды в рекурсиях, поскольку добавил while. Только совсем зелёный начинающий программист не знает про TCO. Так, что я думаю автор хорошо знает зачем TCO нужен.

                                      Для чего макросы и чем они лучше хардкода в парсере?

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

                                      … много строк кода, но вот по делу ли они написаны?

                                      Ну вот и выясните. И напишите статью на Хабре в стиле: «Я считаю LittleLisp.js %овно!»)) Получите ещё дополнительные плюсы к карме;)
                                        0
                                        Ну вот и выясните. И напишите статью на Хабре в стиле: «Я считаю LittleLisp.js %овно!»)) Получите ещё дополнительные плюсы к карме;)
                                        Спасибо, не интересно
                                        0

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


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


                                        Еслиб я заранее знал про макросы и многие другие особенности Lisp-a яб не брался за этот проект. Меня привлекла простота Lisp-а на поверхностный взгляд. Сейчас я вижу, что он сложнее чем Smalltalk:(


                                        У меня основной упор был сделан на создание хорошего дебаггера. По этому парсер и интерпретатор были полностью переписаны. И от старого проекта осталось только часть описания Context, пара строк сначала и несколько строк в конце скрипта littlelisp.js. Ну и название частично.
                                        Вобщем-то, весь старый оригинальный функционал был удалён.


                                        В любом случае я признателен Mary Rose Cook за её реализацию Lisp-a. Считаю, что её реализация замечательна и прекрасно. Это меня и вдохновило форкнуть и расширить функционал.
                                        Но пришлось всё переписать по своему чтоб внедрить дебаггинг. И от её красоты, к сожалению, ничего не сохранилось :(


                                        В 1.0beta3 я добавил tail-call optimization для экономии оперативной памяти. Теперь обнаруживается хвостовая рекурсию и переиспользуется текущий контекст функции.


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

                                          0
                                          Будьте художником-пофигистом! А то будет как в стихах Хармса.
                                            0
                                            А вот и автор (магия призыва действует).
                                            Я молчу потому, что я разочарован, что мои разработки были приняты столь негативно и мои комментарии минусуют.
                                            С таким настроением, вы слона не продадите. Понимаете, если критикует и минусует сразу много народу, есть вероятность, что делают они это не по злобе, а по делу.
                                            Если-бы написали конструктивные рекомендации
                                            Уберите хардкод из парсера и сделайте макросы. Как вам такая рекомендация? Достаточно конструктивно?
                                            Еслиб я заранее знал про макросы и многие другие особенности Lisp-a яб не брался за этот проект.
                                            Ну если нет, то конечно нет. Хозяин-барин.
                                            Меня привлекла простота Lisp-а на поверхностный взгляд.
                                            Так вы эту простоту и разрушаете. Lisp прост за счёт того, в частности, что код не отличается от данных (а макросы от программ, просто работают не с данными а с кодом). Или, к примеру, за счёт единообразия всех выражений (парсер получается максимально простым и не надо морочиться с тем, что означают конструкции (1 + 2 3)).
                                            У меня основной упор был сделан на создание хорошего дебаггера.
                                            Это good.
                                            По этому парсер и интерпретатор были полностью переписаны.
                                            Это bad (по хорошему, стоило понять идеологию Lisp и переписывать уже в её рамках). Но опять же, никто не заставляет. Пусть будет ещё один странный Lisp не понятый автором и не принятый общественностью.
                                            я признателен Mary Rose Cook за её реализацию Lisp-a
                                            Это вопрос вашей совести. Признательны — хорошо. Не упомянули — ваше дело.

                                            Успехов вам в дальнейшем творчестве.
                                              0
                                              Пусть будет ещё один странный Lisp не понятый автором и не принятый общественностью.

                                              Какого вы высокого мнения о себе однако! Говорите от лица общественности. Выдаёте разрешение на существование нового лиспа. Берётесь судить всё и вся как будто вы обладаете абсолютной истиной. Прям юношеский максимализм. Не удивлюсь что вы до сих пор в школе учитесь.

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

                                              … и минусует сразу много народу, есть вероятность, что делают они это не по злобе, а по делу.

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

                                              Минусуют красноглазые фанатики и школьники: «фу, мне не нравиться, минусну...».
                                                0
                                                Вы опять ошиблись веткой. Я не с вами общался.
                                                  0
                                                  Опа! Я оказывается прям дурак дураком. В ветках путаюсь и не замечаю этого. Тогда проявите снисхождение, сделайте божескую милость, наставьте на путь праведный, укажите мне дураку, где и что я перепутал?)

                                                  Это Хабр. Здесь все со всеми беседуют. Хотите один на один — личная переписка к вашим услугам.
                                                    +1
                                                    Милейший, я, конечно, прошу прощения, мы с вами в другой ветке уже раскланялись, но я просто не могу смотреть на то, как вы разводите полемику на пустом месте, переворачиваете смысл того, что говорят другие люди, пытаясь выставить их дураками.

                                                    Какого вы высокого мнения о себе однако! Говорите от лица общественности.

                                                    Говорит вполне справедливо, прочитав другие ветки.

                                                    Берётесь судить всё и вся как будто вы обладаете абсолютной истиной. Прям юношеский максимализм.

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

                                                    Взрослые культурные люди избегают минусовать. Вместо этого пишут конструктивно и аргументированно

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

                                                    Опа! Я оказывается прям дурак дураком.

                                                    Перепрочтите, пожалуйста, ветку. Дураком вас никто не называл, это, зачем-то, в своем сообщении сделали вы сами. К слову, скобочка в конце предложения не сделает ваше сообщение смешным.
                                                      0
                                                      Ну там тему закрыли и разошлись. А здесь, в другой беседе, по другой теме, опять встретились. Это нормально. Люди регулярно сталкиваются)

                                                      Говорит вполне справедливо, прочитав другие ветки.

                                                      А я считаю, что нет. Или только вы и он обладаете абсолютной истинной, а я соответственно неправ и заблуждаюсь?

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

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

                                                      Вы, видимо, во вселенной параллельной моей живете.

                                                      Да я живу во вселенной более уважающих и образованных людей, не счищающих, что есть только одна истинна, а всё остальное ложь и ерись И надо им на это указать, убедить для ихнего же блага (принести им «свет истины»). Там много истин и все они истинные. По этому они чужую истину уважают и не критикуют. А свою истину высказывают в виде мнения, начиная словами: «Я так думаю… я считаю… мой опыт говорит… я убеждён… сомневаюсь… и т.д.»
                                                      А не прямо и категорично: «Это никак не характеристика взрослого человека.» Ну да, конечно, вам виднее, вы обладаете истиной, а я нет. Сказанул глупость. Наверное потому, что дурак. И конечно же сейчас вы меня просветите как устроен в реальности мир, мне же во благо…

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

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

                                                      Так поступают уважающие люди. Минуснуть и не объяснить хотябы одной строкой — это неуважительно.
                                                        0
                                                        Что вы все заладили, истина, да истина. Прежде, чем так бросать слова на ветер, надо выяснить что это за вещь такая вообще, «Истина». Ну тут мы с вами ни к чему не придем, слишком много трактовок.
                                                        Значит теперь еще раз, кратко резюмирую смысл своего предыдущего сообщения. Вы, уважаемый, во всем посте только и делаете, что разводите полемику, переходите на личности(хотя достаточно мягко и почти незаметно), ставите себя выше других, оправдывая это тем, что другие ставят себя выше других. Про подмену понятий я уже упоминал. Уважающие люди (хотя кого они должны уважать?) так не поступают.

                                                        А свою истину высказывают в виде мнения, начиная словами: «Я так думаю… я считаю… мой опыт говорит… я убеждён… сомневаюсь… и т.д.»

                                                        Так поступают уважающие люди.

                                                        Считаю, что сказанного уже достаточно.
                                                          –1
                                                          Вы, уважаемый, во всем посте только и делаете, что разводите полемику...

                                                          Ну вы же сами любите полемики!) Иначе чёб вы сюда вклинивались то?)))

                                                          Считаю, что сказанного уже достаточно.

                                                          Уже давно достаточно.
                                                      0
                                                      Так и есть. Это Хабр и здесь не принято разводить ботов для подобного PR-а своих статей. Согласитесь, это довольно подозрительно когда только что созданный аккаунт, без какой либо предыстории, комментирует исключительно автора первой и пока единственной статьи, один одинёшенек (всем остальным на эту статью, в лучшем случае, наплевать). Характерные орфографические ошибки в ваших комментах и исходниках на GitHub-е также намекают. Желаете общаться — выходите из сумрака. Ну, или как вы сами сказали — личная переписка ни для кого не закрыта. Перестаньте работать на публику.
                                                        0
                                                        Согласитесь, это довольно подозрительно когда только что созданный аккаунт, без какой либо предыстории, комментирует исключительно автора первой и пока единственной статьи, один одинёшенек...

                                                        Конечно, а кто захочет с вами общаться? Только троли;)

                                                        ...(всем остальным на эту статью, в лучшем случае, наплевать).

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

                                                        Характерные орфографические ошибки в ваших комментах и исходниках на GitHub-е также намекают.

                                                        Вау! Круто! Новый тип вещдока: характерные орфографические ошибки! О ужос, я ошибаюсь в тех же словах, что и автор! Это провал…

                                                        Желаете общаться — выходите из сумрака.

                                                        Да никому с вами неприятно общаться. Вот все и проходят мимо.

                                                        Перестаньте работать на публику.

                                                        Какая публика, вы чё? Все уже давно перестали читать этот срачь. Остались только красноглазые фонатики, которые воюют за чистоту лисп-мира, и троли))))
                                    0

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


                                    (defmacro with-menu-html (name &body body)
                                      `(with-html-output-to-string (*standard-output* nil :prologue t :indent t)
                                              (:html (:head (:title ,name)
                                              (:link :rel "Stylesheet" :type "text/css" :href "/main.css"))
                                              (:body
                                               (:div :class "allcontainer"
                                              (make-main-menu)
                                              (:div :class "contentcontainer"
                                             ,@body
                                             (:div :class "sourcelink"
                                            (:a :href "/forums.lisp" "source"))))))))
                                    
                                    (defun make-main-menu ()
                                      (with-html-output (*standard-output* nil :indent t)
                                          (:div :class "mainmenucontainer"
                                         (:ul :class "mainmenu"
                                              (dolist (item +all-locations+)
                                         (make-main-menu-item item (string-equal (format nil "/tbnl/~a" item) (script-name))))))))
                                    (defun make-post-row (post)
                                      (with-html-output (*standard-output* nil :indent t)
                                           (:div :class "postcontainer"
                                          (:div :class "postheader"
                                         (:span :class "postname"
                                         (str (gethash "name" post)))
                                         (:span :class "posttime"
                                         (str (gethash "time" post))))
                                          (:div :class "postbody"
                                         (:span :class "postpost"
                                         (str (gethash "post" post)))))))
                                    
                                    (defun make-new-post-form (topicid)
                                      (with-html-output (*standard-output* nil :indent nil)
                                          (:div :class "formcontainer"
                                         (:form :method :post :enctype "multipart/form-data" :action "/tbnl/new-post"
                                         (:div :class "formnamefield"
                                               (:p "Name:" (:input :type :text :name "name")))
                                         (:div :class "formpostfield"
                                               (:p "Body:" (:br) (:textarea :name "post" :rows 10 :cols 30 "")))
                                         (:div :class "formsubmitfield"
                                               (:p (:input :type :hidden :name "topicid" :value topicid)
                                            (:input :type :submit)))))))
                                    
                                    (defun new-post ()
                                      (let ((topicid (parameter "topicid"))
                                     (name (parameter "name"))
                                     (post (parameter "post")))
                                        (when (and topicid name post)
                                          (make-new-post* topicid (make-safe-html-string name) (make-safe-html-string post))
                                          (redirect (format nil "/tbnl/show-topic?topicid=~a" topicid)))
                                        (redirect "/tbnl/index")))

                                    и т.д.

                                      +1
                                      Изящное оружие, для более цивилизованной эпохи.
                                      0
                                      Можно тогда попробовать объединить несколько проектов:
                                      1. http веб-сервер на BASH — habr.com/ru/post/37245
                                      2. к нему Lisp на Python в 90 строк!!! habr.com/ru/post/115206
                                      3. Игрушечная БД на Python dev-gang.ru/article/how-to-write-a-simple-toy-database-in-python-within-minutes-uo1kahsydh
                                      4. Веб сайт с фронтендом на Lisp написанном на JS
                                      И получится отличный минимальный игрушечный веб сервер на котором легко можно будет проследить всё от БД->Lisp->HTTP->(страница на JS-Lisp)

                                      Only users with full accounts can post comments. Log in, please.