LINUX.ORG.RU

а вам кажется странным поведение двойных кавычек в tcl?

 , ,


2

6

Принимая во внимание следующее:

  • списки в tcl не построены из консов
  • списки в tcl на печати изображаются с помощью фигурных скобок
  • при этом внешняя пара фигурных скобок при печати опускается
  • слова можно считать символами
  • {*} по смыслу есть ,@ (см. Википедию)

Получаем следующее:

# присвоим переменной v список из двух символов b и с
> set v {b c} 
b c 
; то же в лиспе
> (setq v '(b c))
(b c)

# построим двухэтажный список
> list a $v
a {b c}
; то же в лиспе 
> (list 'a v)
; то же в лиспе с помощью квазицитирования
> `(a ,v)

# вклеим содержимое v в список
> list a {*}$v
a b c
; то же в лиспе с помощью квазицитирования
> `(a ,@v)

# А вот это что и зачем? 
> puts "a $v"
a b c

# А так не работает:
> puts "a {*}$v"
a {*}b c

Здесь основной вопрос - зачем двойные кавычки ведут себя вот таким образом? Ведь, казалось бы, двойные кавычки по смыслу и являются аналогом квазицитирования, и поэтому должно быть так:

> "a $v"
a {b c}
> "a {*}$v"
a b c

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

★★★★★

Последнее исправление: den73 (всего исправлений: 2)

Ответ на: комментарий от den73

Вопрос в том, как устроен процесс. Допустим, Оустерхаут придумал тикль 1.0.

Выпустил манифест

  • Наш язык расширяемый и состоит из независимых команд написаных на С в вольном стиле
  • Интерфейс расширений стабильный и не будет резко менятся
  • Команды в базовой поставке ничем не отличаются от расширений и их можно складывать в произвольные наборы на усмотрение пользователей

Петя, Вася и Сережа тоже 7 лет ходят за Оустерхаут-ом и нудят. Он посылает всех на **** и указывает что даже им собственноручно написанный Tk это отдельная библиотека. И вообще Tcl не для программирования:( Мойша барыжит tcl-zverpack
Уходит в индустрию и SUN. Все плачут, потом танцуют. SUN это сила, порядок наведет.

Узнав что количество тиклеров превысило 100k Оустерхаут плюет на SUN и основывает стартап где пишет коммерческий Tclpro c отладчиком, линтером и другой фигней. В линуксе как всегда остается бесплатная версия без отладчика, но с кучей расширений и c призраком Столлмана:(

Оустерхаут наконец-то добавляет Tk в коробочную сброрку и вспомнив про Столлмана еще и массивы. Двигает Tcl в ынтерпрайз. Исходники Tclpro по серой схеме утекают в ActivState, который выкинет их в opensource в 2018г когда о бесплатном тикле все забудут:( В промежутке общественность и коммерческие вендоры 3 года мотают нервы основателю что бы встроенный Tk проапгрейдили до стороннего Tile/Ttk. Занавес.

nursik
()
Ответ на: комментарий от nursik
("?" 
  "Считаете" 
  "Вы" 
  "Ошибкой"
  ("Победу" "баша" "над" "лиспом")
  :уточнение ("действительно" :частица "ли")))

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

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

я так понимаю, что меня пытаются убедить, что в тикле «всё нормально» с кавычками и что к этому надо просто привыкнуть.

В тикле так же как «в С». B*sh внезапно первая по древности ide для С :) Если у человека есть опыт програмирования на С в юникс, вот это все «~нормально» становится интуитивно привычным. Если предположить что tcl встраиваемая скриптуха для С-шных приложений и С наше все в никсах, то кого и в чем ты пытаешся убедить?:)

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

Я никого ни в чём не пытаюсь убедить, мне достаточно, чтобы меня не убедили в том, что не является правдой. Я почти никогда не фанател с юникса, разве только в универе, когда сравнивал его с ДОСом. Си тоже никоим образом не есть эталон чего-либо. Если не цепляться за рынки, совместимости, а мыслить стратегически, то всё это не нужно. Другое дело, если мыслить достаточно стратегически, то от компьютеров вообще начинает с души воротить.

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

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

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

«Ошибкой» («Победу» «баша» «над» «лиспом»)

Столманом планировался лисп с ffi и возможностью имитировать другие языки макросами. Bash по сути затычка для тестирования терминала. И со временем должен был уйти на уровень awk для отдельных фанатов.

Более глобальная проблема в том что в середине 90-ых все современные ОС: Mac, OS/2, Unix/CDE даже Amiga и лисп-машины имели хоть и несовместимые варианты шелла, но интегрированные с графикой и которые умели скриптовать запущенные приложения. Фактически Tcl/Tk это наколеночная поделка отдаленно похожая на промышленные образцы, сделанная с основной целью быть переносимой. Линукс&&BSD по непонятным причинам остались с Bash-ем который умеет только командную строку. Ни с чем не связанной графикой. X-овым сервером повисшим в воздухе без виджитов и межпроцессных протоколов. И EmacsLisp-машиной замкнутую внутри себя:(

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

Си тоже никоим образом не есть эталон чего-либо.

Bash -> Tcl ->C не прро эталон, а про то что кавычки и слэши растут из врожденых граничных условий и большинство их принимает. Python и picolisp исходят их других условий, но мы ведь обсуждаем «нормальность» Tcl.

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

Если под врождёнными условиями имеется в виду bash, то это всё же «багосовместимость» на мой взгляд. Не помню, кто здесь писал про особенности bash, как вытекающие из особенностей Си. Не вижу, как это вытекает. Ридер лиспа элементарно пишется на Си, для этого достаточно рекурсии и динамической памяти, сборки мусора не нужно. Сборка мусора в лиспе возникает от других причин, а вовсе не от рекурсивности структур. Гибкости системы типов языка Си тоже вполне себе достаточно для описания лисповых деревьев.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

под врождёнными условиями имеется в виду

Практика использования «сырой» памяти в качестве унивесльной структуры данных и ее обход с помощью зашитой в синтаксис арифметики указателей. Это создает своеобразие plain C :(

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

Я могу предположить что ты зарабатываешь программирование не на С и не в команде?
Это вот все надо просто взять и написать что увидеть проблему. Мне кажется что чтобы засунуть это в изначально С-шный проект будeт нужны предъявить веские причины:( Есть ли у тебя на это причины и время?
У Tcl изначально была задача быть удобным для «любых» С-шников и не было необходимости для сложных структур в ядре. Для его задач они скорее противопоказаны. Долго разъяснять работу с памятью в контексте встроенного языка это печально:(
Баш видимо написали как удобнее, но много кода на С работает именно так «привычно». А для того что бы сходу появилось что-то другое нужен Гвидо как в Питоне или врожденная любовь к Лиспу:)

а вовсе не от рекурсивности структур

Рекурсивное выделение/освобождение и обход это и есть лисп-машина в миниатюре. Из того что я видел это слишком избыточно для произвольного проекта на С. А Tcl можно расширять в стиле Lispy или встроить целый Scheme интерпретатор в качестве команды. Если ты знаешь зачем

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

а вовсе не от рекурсивности структур. Гибкости системы типов языка Си тоже вполне себе достаточно для описания лисповых деревьев.

Ну то есть попробуй С-шнику вслух объяснить в каком виде он получит эту рекурсивную структуру и что ему с ней делать:) Я выше слишком много слов написал:)

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

Неужели же в каком-нибудь K&R в качестве примера не описано создание интерпретатора Си или того же калькулятора, и там нет этой конструкции из вложенных друг в друга динамически создаваемых вариантных структур?

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

и есть лисп-машина в миниатюре

Это вопрос терминологии, но я не вижу настоящего лиспа без сборки мусора. И именно она составляет трудность в Си. Если мы не делаем clone-on-copy, и не позволяем два указателя на одно и то же значение, и у нас нет функций, то у нас есть грабли, но сборка мусора не нужна.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

Структуры можно, кстати, выделять на стеке. Просто будет строка (буфер) и ФВП типа maptree, которая на стеке будет создавать элементы в тот момент, когда они прочитываются.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

и вообще лисп сдулся

Библиотеки пишутся, sbcl отличный компилятор, всех устраивает, на #lisp жизнь кипит. Дай угадаю. Уже выгнали тебя ссаными тапками из всех лисп тусовок?

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

В тикле-таки все нормально с кавычками. Просто не надо использовать кавычки для построения списков. Есть специальные средства (начиная с [list], а потом [linsert], [lappend] и еще кучу всего, ты сам это прекрасно знаешь). Применяй их, и все будет хорошо.

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

То, что тикль можно использовать, я под вопрос не ставлю. Меня не устраивает именно то, что для метапрограммирования, которое нужно часто (иначе - в чём сила тикля?), нужно писать больше букв, чем для непонятной каши, на которую заняты двойные кавычки, и которая не имеет никакого полезного смысла. Хотя можно было бы сделать и вложенные списки, и квазицитирование, и строковую интерполяцию - на всё букв хватило бы. Я уже в самом начале писал, как:

"a $b c" в идеальном тикле должно давать то же, что [list a $b c] в существующем. 
"a ☼b c" в идеальном - то же, что "a $b c" в существующем
Это, правда, не всё из моего списка, квазицитирование я не раскрыл. Но хотя бы так сделать - и уже было бы лучше, чем есть. Не?

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

Жидкий азот тоже кипит. Много ты можешь брехать, но вот то, что sbcl нравится всем - это просто наглейшее враньё, которое доказуемо опровергается на выборке из лисп-тусовки. Насчёт библиотек - и много ты библиотек написал в 2018? У вас даже asdf уже сгнил, вам скоро нечем будет свои программки собирать. Лол :)

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

Хотя не, вру. Наверное нельзя было бы обойтись малой кровью, и букв не хватило бы.

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

Коммон-лисперов у которых пока нет 10k$ на allegro, большинство устраивает, прикинь. Периодически набегают сумасшедшие которым «надо как в scheme/clojure и вообще непойми чего», ручонками размахивают как у вас тут в CL все криво и поломано, такие как ты в общем, так они быстро сваливают и погоды не меняют.

anonymous
()
Ответ на: интересное нашел от anonymous

Ну офигенное новаторство, я шизею! Такое есть в редакторе LW. Нужно быть конченым нищебродом, чтобы не иметь денег даже на LW. Открою тебе тайну, как пока ещё профессиональный лиспер: профессионалы юзают не один лисп, а несколько, и LW среди них первый, благодаря своему уникальному отладчику. Как сказал мой шеф, «каждый лисп не-работает по-своему». Очень точно и красиво подмечено! Но комбинируя несколько лиспов, можно более-менее успешно вести разработку.

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

И я тебе открою ещё одну тайну: распарсить код на Common Lisp вообще невозможно, из-за readmacro. Тот момент, когда я посмотрел на реализацию перехода к определению в Swank, во многом определил мой отход от CL. Это не просто криво, это криво и нельзя исправить. Костыль на костыле.

Чтобы исправить это, нужен отдельный этап чтения, свободный от побочных эффектов, который отвечает за собственно синтаксическое восприятие ридмакросов. Т.е. должно быть сначала преобразование текста в AST, а уже затем обработка побочных эффектов для ридмакросов. Только так можно будет создать парсер для CL хотя бы в теории. Но это невозможно, потому что стандарт CL никто менять не собирается - он «всех устраивает». Равно как нельзя и выкинуть из стандарта те вещи, которые мешают сделать нормальное IDE. Например, puri портит таблицу чтения и это пагубно сказывается на способности емакса читать лисповые файлы. Выкинь её - и у лиспа сразу отвалится применение в вебе. У гугла раньше было руководство по стилю, где явно запрещалось заводить ридмакросы. Но если мы посмотрим реальные (интересные) библиотеки, то их там всегда хватает.

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

Короче говоря, CL - это тоже секта, и я был её прихожанином достаточно долго. Основная догма состоит в том, что в лиспе «можно сделать». Я пребывал в иллюзии, что в лиспе «можно сделать». Более того, я почти сделал кое-что из этого «можно сделать». Но когда пытаешься придти к окончательному и качественному решению, а не к работающему прототипу, то оказывается, что нельзя. В CL «нельзя сделать» IDE. Просто нельзя, и всё.

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

Слушай, не смеши мои тапочки. Работает... Чего стоила только одна недавняя дискуссия про допустимое количество аргументов функции. Которое позволяет написать совершенно элементарный код, который заставляет SBCL падать.

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

Но если тебя устраивает SBCL - бог с тобой. Тема вообще-то про тикль и двойные кавычки :)

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

там как раз и есть частичный reader macro.

более подробно в paper оттуда: 2018.pdf

(оттуда ссылка на ещё один CLimacs: lem : консольный, но с жабохипстерским фронтендом)

В CL «нельзя сделать» IDE. Просто нельзя

ещё доклад индуса интересный. почти смолтоково.

и про контексты про ракетку и BIM любопытно.

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

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

1. сообщество свободных людей, которые всегда друг друга пошлют нахер
2. оно работает - не трогай его
3. лисп же уже совершенен и в нём ничего улучшать не нужно

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

*частичный парсер ридер макро

или, не трогать стандартный reader, а расширить его

2018.pdf, стр. 15-26, особенно приложение B

Incremental Parsing of Common Lisp Code

Irène Durand Robert Strandh irene.durand@u-bordeaux.fr robert.strandh@u-bordeaux.fr LaBRI, University of Bordeaux Talence, France

ABSTRACT

In a text editor for writing Common Lisp [1] source code, it is desirable to have an accurate analysis of the buffer contents, so that the role of the elements of the code can be indicated to the programmer. Furthermore, the buffer contents should preferably be analyzed after each keystroke so that the programmer has upto- date information resulting from the analysis. We describe an incremental parser that can be used as a key component of such an analyzer. The parser, itself written in Common Lisp, uses a special-purpose implementation of the Common Lisp read function in combination with a cache that stores existing results of calling the reader. Since the parser uses the standard Common Lisp reader, the resulting analysis is very accurate. Furthermore, the cache makes the parser very fast in most common cases; re-parsing a buffer in which a single character has been altered takes only a few milliseconds

вообще с кешем Appendix A идея интересная. напоминает Edit decision lists в Xanadu, векторном и гипертекстовом :)

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

Тед Нельсон: Xanadu EDL

WHAT'S IN THE EDL

An EDL contains two types of element--

• SPANS-- portions of content to bring in (currently only from textfiles on the net) • XANALINKS-- tables saying what to connect, etc.

Our EDL samples, for our demonstration document--

• sample Edit Decision List • the same sample, with comments

Robert Strandh:

For the purpose of this paper,we are only interested in the update protocol, because we re-parse the buffer as a result of the update protocol having been invoked.We can think of such an invocation as resulting in a succession of operations, sorted by lines in increasing order.

There can be three different update operations: • Modify. The line has been modified. • Insert. A new line has been inserted. • Delete. An existing line has been deleted.

Although the presence of a delete operation may seem to contradict the fact that no such operation is possible, it is fairly trivial to derive this operation from the ones that are actually supported by the update protocol. Furthermore, this derived set of operations simplifies the presentation of our technique in the rest of the paper.

In order to parse the buffer contents, we use a custom read function. This version of the read function differs from the standard one in the following ways:

• Instead of returning S-expressions, it returns a nested structure of instances of a standard class named parse-result.

These instances contain the corresponding S-expression and the start and end position (line, column) in the buffer of the parse result.

• The parse results returned by the reader also include entities that would normally not be returned by read such as comments and, more generally, results of applying reader macros that return no values.

• Instead of attempting to call intern in order to turn a token into a symbol, the custom reader returns an instance of a standard class named token.

The reader from the SICL project3 was slightly modified to allow this kind of customization, thereby avoiding the necessity of maintaining the code for a completely separate reader.

No changes to the mechanism for handling reader macros is necessary. Therefore, we handle custom reader macros as well.

Whenever a reader macro calls read recursively, a nested parse result is created in the same way as with the standard reader macros. More information about the required modifications to the reader are provided in Appendix B.

неудивительно, что no such operation is possible — у Теда Нельсона вообще буферы немутабельные append-only permadoc

для векторного гипертекстового Xanadu осталось только написать транслятор из Strandh'офских S-выражений the corresponding S-expression and the start and end position (line, column) в Нельсоновские EDL.

инкрементальный и многопотоковый, типа паттерна реактор FRP.

то есть, эти оверлеи EDL могут быть не только файлы текстовые, а любые инкрементальные потоки текста: выхолоп процессов weave/tangle в LitProg, компилятор фронтэнд/бекэнд и т.п.

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

Слушай, ну мы с Монком всё это делали, даже сделали спец. форк eval из SBCL для того, чтобы кеш был общим. Всё это тут даже обсуждалось года два назад. Но, во-первых, всё это абсолютно никому не нужно. Если люди, конечно, получили за это грант - то молодцы. Но не более того.

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

Далее, если читать ридером, будут возникать мусорные символы. Эту проблему я тоже решил лет этак 5 назад, сделав патчи к ридеру (в т.ч. для SBCL). Всем насрать.

Далее, ридер лиспа не может прочитать файл лиспа, поскольку он вернёт не то. Куда запихнуть комментарии, к примеру?

Далее, ридер лиспа контекстно зависим. Что делать хотя бы с тем же *read-base*? Если он неверно настроен, IDE наплодит мусорных символов.

Всё это можно пытаться частично решить, форкнув ридер. Я сделал это лет 7 назад и долго жил с этим ридером, латая его. В лучшие времена он был даже портирован на несколько реализаций CL (последний раз, наверное, я портировал его на ccl в начале сего года). Глядя в исходники Slime/swank, я увидел, что костылей у было меня умеренное количество, т.е. мой код не хуже. Но в целом это всё равно всё большое Г.

САМОЕ ГЛАВНОЕ. set-macro-character может сделать так, что изнутри read будет вызываться абсолютно любой код, который может делать абсолютно что угодно - хоть запускать баллистические ракеты. И это называется «окончательно приехали».

Т.е., не меняя стандарта CL или не меняя требований к оформлению библиотек (которые никто, конечно же, не будет выполнять), невозможно прочитать CL в IDE. Аминь. С учётом этого, все потуги сделать IDE для CL - это не более, чем игры.

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

всё есть гиперстрока.

tcl здесь при том, что вот это вот «всё есть строка», «всё есть текст»  — не только текст , но ещё и гипертекст

вот это tl;dr гениальное прозрение гуманитария. в формате гипертекста «поток сознания и его EDL». инвольтация к эгрегору ТЗ, так сказать.

и вот что получилось в EDL, формализованное.

«всё есть строка» — здесь строки типизированные, span или xanalink

# Moe Juste transclusion
span: http://xanadu.com/xanadox/MoeJuste/sources/0-Moe.pscr.txt,start=7995,length=274
# "Or consider this quote from Darwin--"
span: http://hyperland.com/xuCambDemo/WelcXu-D1y,start=590,length=41
# Actual quote from Darwin
span: http://xanadu.com/xanadox/MoeJuste/sources/2-DarwinDescentOfMan.txt,start=143522,length=213
...
# XANALINKS
# Suppress view of new content
# Don't transclude the recent writing
xanalink: http://perma.pub/links/hide_new.xanalink.txt

# Connection to McKinley Assasination
xanalink: http://hyperland.com/xuCambDemo/rmq41-xanalink.txt

# Connection to scientific article
xanalink: http://hyperland.com/xuCambDemo/mexn86-xanalink.txt

# Connection to original def. of hypertext
xanalink: http://hyperland.com/xuCambDemo/jjq7941-xanalink.txt

вот это контекстно-зависимое span: $url,start=$start,length=$len напоминает tcl с его «команда интерпретирует строку, как хочет»

где ссылки типизированные: ссылка перехода или включения (трансклюзия).

понятное дело, что могут быть и ссылки высшего порядка, ссылки на ссылки (или ссылки на онтологии, классификаторы, типы)

или ссылка-макрос: fexpr на eval, разыменование которой eval запускает

в общем, разные типы ссылок. это всё текст, но разнотиповый.

хотя в лиспе с S-выражениями как-то структурированее получается.

собственно, что tcl что EDL Теда Нельсона пытаются впихнуть невпихуемое: структуры в строки с индексами.

не хватает какой-то эргономичности, наглядности представления.

аналогично тому как DNS на IP отражается, а в Emacs org-mode разные типы ссылок — на конкретное ссылаемое, и без ...,start=NS,length=LN

чего только не делают, лишь бы структурный редактор не писать.

например, любопытно было бы пофантазировать как бы такой Xanadu выглядел в емаксе с текстовыми кнопками-оверлеями (или климаксе с MVP на CLIM с нормальным GUI) — написанный в Literate Programming стиле.

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

в качестве побочного эффекта.

невозбранно достигнув желаемого - векторного гипертекстового Xanadu с инкрементальным парсером.

anonymous
()
Ответ на: всё есть гиперстрока. от anonymous

Записывай видео, что ли. Ты тут много работы накидал, мне лень лично. Хотя понято, что ты очень умный. Насчёт парсеров - есть три (ЕМНИП) подхода к парсингу XML - первый состоит в том, чтобы зачитать весь файл и вернуть вложенную структуру. Второй состоит в вызове callback на каждый элемент. Третий уже не помню. Инкрементность парсера достигается в случае, если состояние вычисления можно записать в переменную и потом вспомнить оттуда. Нечто типа call/cc, но ещё включающее и поток. У нас для этого был «полностью кешированный поток», к-рый делает поток ФП-чистым. И далее механизм инвалидации инстансов потока, который сносит вершину у ФП-чистого мира, когда чел нажал на кнопку. В итоге оказалось, что всё это страшно тормозит, т.к. интерпретатор, и было сделано дуболомное решение парсить весь файл целиком при каждом изменении - оно работало лучше для маленьких файлов, а большие файлы было решено объявить ересью :)

Кроме того, выясняется совершенно страшная вещь: прошлое зависит от будущего. Например, в емаксе нужно раскрасить открывающую скобку, если ты стоишь на закрывающей. Поэтому есть проблема с определением того, по какой границе резать будущее. В худшем случае, мерцание валидности файла, происходящее при вводе с клавиатуры, приводит к мерцанию раскраски во всём файле. Это тоже можно обходить только эвристически.

ЕМНИП мы потратили на это месяца три-четыре и в итоге пришлось остановиться на компромиссной недоделке. Причём не только для CL, но и для языка с нормальным синтаксисом эта задача решается тяжело. И MSVS, и IDEA тоже не видно, чтобы особо преуспели в её решении.

Если бы это был нормальный язык, а не CL (с отсутствием async, call/cc), можно было бы выкрутиться. А в CL выкрутиться не удалось, не выходя за рамки пермиссивно лицензированного кода.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

по-моему, у вас с Робертом подход разный — на протоколах и кеше с каким-то конкретным состоянием и какими-то конкретными контекстами и стандартным, но расширяемым или велосипедить свой контекстно-зависимый велосипед, в твоём случае.

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

Далее, ридер лиспа контекстно зависим. Что делать хотя бы с тем же *read-base*?

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

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

то есть, всю эту контекстную зависимость в состояния/косостояния контекстов и коэффекты, и протокол поверх (=коалгебру) явным образом выделить.

в общем, пробовать надо и тестить. ещё бы понять, как

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

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

Слушай, я ещё в подростковом возрасте почитал про иммунную систему в журнале «Наука и Жизнь» и пришёл к выводу, что утверждения про отсутствие Бога - это скорее всего, ложь. С тех пор узнал о мире много нового и только укрепился в том, что мир и разум были созданы. А следовательно, ничего само собой не самоознается, не жди :)

Тестить не буду, я уже вообще старый, и кодить мне всё труднее и труднее, и морально, и физически :) И самое главное, я делаю по доброй воле только то, что хочу делать сам. А делать IDE и ЯП как-то у меня не стоит на данный момент. Пусть кто-нибудь 22-летний потестит :) Или года через два, если преодолею кризис отношения к компьютерам.

формализовать контекстную зависимость в контексты.

Мы это делали как раз в интерпретаторе. Нужно просто перечислить глобальные переменные, которые входят в понятие контекста, и точка. Ну и иммутабельные структуры данных, конечно. Поскольку в лиспе данные мутабельны, у нас были данные с историей. Консы мы заменили на kons-ы с историей. Таким образом мы погрузили мутабельность в чистое ФП путём запоминания состояния вычисления, это получилось, на мой взгляд, неплохо, хотя пусть лучше скажет Монк - я-то Хаскеля не осилил :)

Да и не знаю, что там тестить. Вот представь себе гипотетический ридмакрос, который читает текст SQL запроса и проверяет его на валидность. Если запрос невалиден, то это ошибка чтения. Здесь используется внешняя СУБД. Её же в do не запихнуть никак :) Потому что рядом сидит Вася и правит схему БД. Через минуту схема поменяется и неверный запрос станет верным. Если отправить Васю в вечность, дав ему по голове, то, конечно, СУБД станет де-факто иммутабельной, но практического смысла в этом никакого нет. Общего механизма отлова изменений схемы СУБД я не видел никогда.

den73 ★★★★★
() автор топика
Ответ на: комментарий от den73

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

TeopeTuK ★★★★★
()
Ответ на: всё есть гиперстрока. от anonymous

А почему бы не пытаться сделать оргмод для Pharo и его точить в указанном направлении? Тоесть емаксоподобный редактор поверх пхаро поверх него оргмод поверх этого ксанаду?

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

тем более что там были какие-то сорцы на смоллток+С++ в старом Xanadu

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

Может и многословный, но при этом компактный и легко читаемый, а слова короткие. На мой субъективный взгляд. Что в нём действительно получается многословно - так это всякие лямбды.

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

по-моему, у вас с Робертом подход разный

Я вспомнил ещё пару тонкостей. Во-первых, в анализе есть несколько отдельных процессов. Следующий возможен в случае, если предыдущий успешно завершён. Например, если в буфере нет читаемых s-выражений, то нельзя и провести смысловой анализ (понять, что означает каждый символ). Но лексический анализ провести можно, т.е. закрыть строки и комментарии. Соответственно, если у меня был файл со смысловым анализом (допустим, подчёркнуты красным неопределённые функции), а потом я нажал кнопку и открыл скобку, то весь этот анализ становится, строго говоря, невалидным. Но если я его при этом сотру, то у меня будет на экране отвратительное мерцание. Т.е. нужна некая эвристика, которая удерживает на экране старую информацию, которая, строго говоря, уже не валидна, только с той лишь целью, чтобы экран не мерцал.

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

special-purpose implementation of the Common Lisp read

There can be three different update operations: • Modify. The line has been modified. • Insert. A new line has been inserted. • Delete. An existing line has been deleted.

Достаточно октрыть хотя бы этот форум, в нём форум комментария и убедиться, что всё по-другому. Учитывается не только состояние буфера, а и история его изменения. И это не сводится к кешированию. Пока я печатал слово «кешировани», оно было некорректным, но браузер подчеркнул мне его только тогда, когда я поставил пробел после этого слова и стало ясно, что больше букв в это слово не поступит. Если я зашёл в это слово снова и хожу по нему стрелками, оно остаётся подчёркнутым. Но как только я нажал на del или на какую-то букву, браузер понял, что я начал менять слово, и стёр красное подчёркивание. Т.е. браузер следит за моим поведением и помнит, что я делал только что.

Функция read принципиально на это неспособна, поскольку она не знает, нажал ли я только что букву, backspace или стрелку. В ней нет соответствующего контекста - он есть только в редакторе, но не в состоянии буфера.

С этой проблемой мы тоже столкнулись, когда делали IDE, и в каком-то виде её решили. С этой же проблемой связана возможность автодополнения.

Допустим, я напиал:

(defu
и нажал «автодополнить». Какой ридер лиспа сможет мне помочь? Да никакой. Любой ридер выдаст ошибку чтения. А автодополнение при этом работает.

В Hemlock есть как минимум три механизма (и три эрзац-ридера лиспа). Первый отвечает за раскраску ключевых слов. Он похож на то, что пишет Роберт - инкрементный (упрощённый) ридер лиспа на базе КА, единицей операции является строка - кешируется состояние чтения в начале каждой строки. Этот ридер неадекватно прост, годится только для лексического анализа.

Другой - для подсветки парных скобок. Не помню, как работает. Третий - для автодополнения и определения текущего символа под курсором. Он анализирует окрестность точки ввода и пытается выкусить из неё символ. Нужно заметить, что синтаксис Лиспа не позволяет решить даже эту задачу! И ещё одна вещь - оказывается, не всегда нужно решать эту задачу. Например, может хотеться, чтобы автодополнение и особенно переход к определению работали бы внутри комментариев, чтобы можно было написать в докстроке «см. также ДРУГОЙ-СИМВОЛ» и можно было бы на него скакнуть. Если определять символы ридером лиспа, то это работать не будет. А hemlock-овский кривой механизм работает. Зато он не сработает, если символ квоченный (не сможет понять, где у него края). На этот случай мы сделали отдельный механизм - в нашей среде можно выделить любой кусок текста и сказать - это символ, перейди к его определению.

Вот сколько подводных камней и тонкостей в задаче создания IDE. Она не может быть решена какой-то одной красивой идеей.

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

Во всяком случае, в синтаксисе Яра было предусмотрено несколько фишек, чтобы обойти разные грабли, которые есть в синтаксисе лиспа и неустранимы. Это, наверное, наболее ценный результат нашей работы. Но он никому не нужен :) А если кому-то нужен, то хрен я его даром отдам, Монк пусть сам думает :)

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

Нет. Всё же неправильные строки в tcl. Вот почему. В лиспе, если я печатаю строку, то я могу обратно получить такую же строку read-om, если я вобью в read буквально то, что было напечатано.

> "asdf"
==> "asdf"
> (read)
"asdf"
==> "asdf"
Там есть нюансы, но это лишь нюансы. То же касается любых сериализуемых в строку данных, т.е. я могу напечатать произвольный связный граф из символов, чисел, строк, списков, нетипизированных массивов и структур (если у них не перешиблен метод печати), и он будет зачитан read-ом из своего печатного представления.

В тикле, для вывода предназначена команда puts. При этом фигурные скобки, защищающие строку с пробелами, концами строки и долларами, не печатаются. Поэтому в тикле нет соответствия print-read, которое есть в лиспе. Может быть puts [list <выражение>] является аналогом лиспового print. Но спрашивается, почему puts по умолчанию не ведёт себя как puts list? В чём смысл? Я не вижу его. Нужно было завести две команды: format (для вывода в красивом виде) и print - для гомоиконного вывода.

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

В тикле, для вывода предназначена команда puts.
Но спрашивается, почему puts по умолчанию не ведёт себя как ... В чём смысл? Я не вижу его.

Смысл в том что puts по основной идее tcl пишет в потоковые дескрипторы юникса: терминалы, сокеты, файлы - взаимодействие с инородными системами где нужен «сырой» поток символов а гомоиконность tcl-объектов будет чаще мешать. Его прямым аналогом в лиспе будет write-line который точно также игнорирует гомоиконность. Только что в лиспе он честно требует приводить символы и деревья к строке для однозначности. Лиспы вобще были исторически более замкнуты на свой REPL чем на общение с другими системами поэтому однообразная гомоиконость для них умолчание, а наоборот делать «клей» на лиспе несколько больше работы чем с помощью shell-like tcl|bash/

нет соответствия print-read, которое есть в лиспе.

Даже в лиспе две параллельные системы ввода-вывода. Отдельно на основе «сырых» байтов|символов и отдельно обобщеный read/print на основе *rеad-table* и *print-всякого Второй в tcl просто не завезли за неопределенностью его статуса. Она и в CL выросла из необходимости различать символы как уникальные объекты и строки в качестве последовательности символов. В tcl не было концепции символов оттуда и пошел разлад.

Может быть puts [list <выражение>] является аналогом лиспового print.

Не должен.

format (для вывода в красивом виде) и print - для гомоиконного вывода.

в хламовнике wiki.tk наверняка есть.

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

Нужно было завести две команды:

Погуглив

«rename puts» site:wiki.tcl.tk
можно узреть много всякого о tcl-way

antares0 ★★★★
()
Ответ на: комментарий от den73

И наутро до меня наконец-то дошло, что если в тикле нужно держать тип в голове, то это относится и к выводу puts. Т.е. ты сам должен понимать, имелась ли в виду строка или список. Выводить a b c фигурными скобками неэкономично. Тикль же интерпретирует команду

команда арг1 арг2 
как список (команда арг1 арг2), и это хорошо. Здесь тикль пишет меньше букв, чем лисп. То же самое происходит и при печати. При этом всё ещё имеется способ, не выходя за рамки тикля, отличать списки от атомов, и тем самым представить дерево:
set дерево {a {под список} б "ат ом"}
И сделать так, чтобы [dict $дерево б ат] не возвращало «ом», а ругалось бы. Но при печати эта информация будет теряться.

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