Поругайте недоязычок описания и преобразования данных
средства декомпозиции где?
средства декомпозиции где?Вот же:
include{ext:htmling3}
9001st Tree Markup Language?
Питон-вариант вызывает дискомфорт без двоеточия в конце строки перед новым блоком отступа.
средства декомпозиции где?декомпозиции чего? и по какому принципу?
Можно комментарий по поводу круглых скобок после version? В остальных местах фигурные.Фигурные скобки и круглые скобки, при использовании в качестве выделения блока - взаимозаменяемые.
Отчасти это сделано для удобства, чтобы можно было одни блоки отделять от других.
Отчасти из-за того, что у меня пока не сформировалось хорошего принципа по которому можно блоки разделить на несколько видов.
Питон-вариант вызывает дискомфорт без двоеточия в конце строки перед новым блоком отступа.если хочется, то двоеточие можно там указывать для эстетики - парсер это пережует. Но, вообще, как раз хотелось сделать максимально "чистое" представление, чтобы глаз не мылился лишними символами.
декомпозиции чего? и по какому принципу?предположу, что имеются в виду переменные\константы, функции\процедуры, модули. есть ли возможность их использовать?
9001st Tree Markup Language?это тоже есть, но в большей степени это 9001st Tree Processing Language.
еще он язык вида "давайте опишем мир в виде дерева" (в очень сыром виде когда ФС, БД, интернет, произвольный объектный граф внешним образом описывается как ориентированный граф без циклов, что позволяет над миром делать всякие преобразования через единый синтаксис.
предположу, что имеются в виду переменные\константы, функции\процедуры, модули. есть ли возможность их использовать?переменные есть.
Из вышеприведенного кода, это, например, объявление двух переменных
#versions %version.?;
#description %description;
или маркировка "на лету"
.family.? #family
функции тоже есть (из-за конвейерного подхода считается, что у функции всегда есть один параметр, который "пришел слева", и внутри функции он текущий)
#module-view=>(text:(.changed -> '+' (.main -> style:background-color:lightgray;
функцию можно запихнуть в узел дерева - будет недо-объект
модули есть, но халявные.
не говоря уж о семантике?
---
"История не учительница, она классная дама: сама она никого
и ничему не учит, но больно наказывает за невыученные уроки."
1. Деление на элемент, аттрибут, значение (при этом один вид не может быть заменен на другой) В xml - есть все три. В универсальных ЯП обычно сведено до двух: элемент(объект) и аттрибут(свойство).
Здесь принято решение, что всё есть элемент.
2. Деление: структура, коллекция, атомарное значение.
Решение: всё есть дерево(лес).
4. Литерал или терминальный символ?
Решение: всё и то, и другое одновременное. Кавычки имеют смысл только для синтаксического парсера, чтобы можно было строку с произвольными символами представить в виде единого литерала.
5. Терминальный символ или переменная?
Решение: Если не указано явно, то, по умолчанию, терминальный символ. Обращение к переменной явно выделяется символом '@' спереди.
6. При обращении к элементу дерева выбирается сам элемент или его внутреннее содержимое?
В ФС, xml принято, что выбирается сам элемент. В ЯП выбирается содержимое при обращение к свойству, и сам элемент при обращени к коллекции.
Решение: всегда выбирается сам элемент
a{b:1, c:2} -> .b ==> b:1
a{b:1, c:2} -> .b.? ==> 1
7. Выбор идет на текущем уровне, или на уровень ниже?
Решение: на уровень ниже через символ '.', на том же уровне через символ '%'
(a{b:1, c:2}, a2{b:21}) -> .b ==> (b:1, b:21)
(a{b:1, c:2}, a2{b:21}) -> %a2 ==> a2{b:21}
8. Дерево целиком или только значение узла?
Решение: дерево целиком - символ '$", значение узла - '%$'
a{b:1, c:2} -> $ ==> a{b:1, c:2}
a{b:1, c:2} -> %$ ==> a
9. Конкретный элемент или произвольный?
Решение: конкретный элемент - через имя, мультивыбор - через список, произвольный - через '?'
(a{b:1, c:2}, a2{b:21, d:4}) -> .b ==> (b:1, b:21)
(a{b:1, c:2}, a2{b:21, d:4}) -> .(c,d,e) ==> (c:2, d:4)
(a{b:1, c:2}, a2{b:21, d:4}) -> .? ==> (b:1, c:2, b:21, d:4)
формальной грамматики,какой-то вариант грамматики
query := expression;
expression := S* semicolon-expression S*;
semicolon-expression := comma-expression ( S* ';' S* comma-expression)* (S* ';')?;
comma-expression := (match-expression ( S* ',' S* match-expression)* (S* ',')?);
match-expression := (switch-expression / or-expression) ( S* match-op S* match-expression) *;
or-expression := and-expression ( S* or-op S* and-expression) *;
and-expression := equal-expression ( S* and-op S* equal-expression) *;
equal-expression := sum-expression ( S+ equal-op S+ sum-expression) *;
sum-expression := multiply-expression ( S+ sum-op S+ multiply-expression)*;
multiply-expression := not-or-else-expression ( S+ multiply-op S+ not-or-else-expression) *;
not-or-else-expression := not-expression / colon-expression;
not-expression := ('!' S* colon-expression);
colon-expression := query-expression (S*':' S* colon-expression)?;
query-expression := (atom-expression (S* (check-expression / function-expression / property-expression / axis-expression / square-expression / named-expression*);
atom-expression := var-expression / lambda-expression / declare-expression / construct-expression / check-expression / function-expression / property-expression / axis-expression / round-expression / figure-expression/ square-expression / lexem;
var-expression := '@' identifier;
declare-expression := '#' identifier S* match-expression;
lambda-expression := (identifier / round-expression) S* '=>' S* match-expression;
construct-expression := (lexem / round-expression) (S* named-expression)? (S* figure-expression)+;
named-expression := '#' (identifier / spec-identifier);
switch-expression := ( S* '|' S* match-expression)+;
function-expression := '.' lexem S* round-expression;
check-expression := '%' condition;
axis-expression := '^' condition;
property-expression := '.' condition;
condition := switch-condition / lexem;
switch-condition := '(' S* lexem (S* ',' S* lexem S*)* S* (',' S*)? ')';
round-expression := '(' (expression / S*) ')';
square-expression := '[' expression ']';
figure-expression := '{' (expression / S*) '}';
lexem := (command-identifier / number / literal / identifier / spec-identifier);
and-op := '&&';
or-op := '||';
equal-op := !'<-' ('*==*' / '*=*' / '*=' / '=*' / '==' / '!=' / '<=' / '>=' / '<' / '>' );
multiply-op := '*' / '/';
sum-op := '+' / '-';
match-op := '->' / '<-' / ':=' / '-=' / '+=';
identifier := [a-zA-Z_]([a-zA-Z0-9-_]*);
command-identifier := '::'[a-zA-Z_]([a-zA-Z0-9-_]*);
spec-identifier := '$' / '?' / '~' / '^';
number := [0-9][0-9]*;
literal := ('""' ('""""' / (!'""' .* '""') / (""'"" (""''"" / (!""'"" .* ""'"");
S := comment / [ \t] / line-break;
comment := '//' (!line-break .)* line-break;
line-break := ([\r][\n]) / [\r] / [\n];
в формальной записи семантики я не силен. Могу своими словами рассказать при наличии примера, что и как стоит рассказать.
еще он язык вида "давайте опишем мир в виде дерева" (в очень сыром виде когда ФС, БД, интернет, произвольный объектный граф внешним образом описывается как ориентированный граф без циклов, что позволяет над миром делать всякие преобразования через единый синтаксис.Спасибо, но Лисп давно уже изобрели.
Спасибо, но Лисп давно уже изобрели.он под списки заточен. Деревья на нем не удобно записываются
Вот и разберись с этим, чтобы не надо было "при наличии примера."
И, кстати, если ты используешь очень новый и не до конца
разработанный способ записи грамматики, надо это указывать,
так как не всегда очевидно, что обозначается знаком "/":
толи это обычный выбор, толи зависимый.
А ещё, это, конечно, круто, что ты закодировал приоритеты операций
в грамматике, но грамматика от этого становится очень тяжеловесной.
Если ты хочешь, чтобы что-либо "покритиковали," не надо этого делать.
---
"История не учительница, она классная дама: сама она никого
и ничему не учит, но больно наказывает за невыученные уроки."
> он под списки заточен. Деревья на нем не удобно записываются
Гон.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."
Гон.как минимум их надо во что-то преобразовывать, или делать какие-то дополнительные допущения, чтобы был возможен быстрый поиск конкретного элемента по именованому пути (быстрее, чем full-scan в глубину)
декомпозиции чего?больших задач
и по какому принципу?
это уже ты должен придумать.
понятно что должно быть аналоги передачи параметра и колбеки.
колбекиэто зачем? ужасный же вариант декомпозиции.
это зачем? ужасный же вариант декомпозиции.как ты будешь делать общую конву на сайте — частный случай колбеков
делать общую конвув смысле, переиспользуемый каркас?
Отдаленный аналог: jsont, s-expression, sql-я, xquery, linqопечатка?
получается аналог и того, и другого
Паттерн-матчинг? Ветвления? Циклы? Абстрагирование генерации схожих деревьев в функции?
Я бы даже сказал, что пять страниц кода, пестрящего $$$, <<<, >>>, и т.п.
было более осмысленно критиковать, чем то, что выше.
---
"Это проявление Аль-Хагг.
Те, кто знают это, знают..."
Паттерн-матчинг?полноценного нет. я не определился с базовым набором примитивов и функционала под это.
Паттерн-матчинг? Ветвления?есть конструкция вида
| <condition1> -> <code1>
| <condition2> -> <code2>
...
| <conditionN> -> <codeN>
condition-ы проверяются последовательно,
если <condition-i> не пустой, то в, качестве, результата всего выражения берется результат <code-i>,
иначе (если пустой то проверяется следующее условие
примитивный паттерн-матчинг на такой конструкции получается организовать.
Циклы?нет, и не будет.
есть, возможность, сгенерить бесконечный список, и есть понятие волны, которая движется по списку и на каждой итерации вызывает обработчик, передавая текущий элемент. Обработчик на каждой итерации может вернуть произвольный лес и/или передать произвольный лес на следующую итерацию. Этакая помесь: map и aggregate.
Абстрагирование генерации схожих деревьев в функции?что имеется ввиду?
А ещё, это, конечно, круто, что ты закодировал приоритеты операцийсогласен.
в грамматике, но грамматика от этого становится очень тяжеловесной.
К сожалению, под вариант грамматики с отдельным описанием приоритетов у меня не получилось сходу сделать универсальный парсер.
что имеется ввиду?
Когда есть <code1> и <code2>, совпадающие по большей части, но имеющие некоторые отличия, и хочется DRY.
как минимум их надо во что-то преобразовывать, или делать какие-то дополнительные допущения, чтобы был возможен быстрый поиск конкретного элемента по именованому пути (быстрее, чем full-scan в глубину)а разве по твоей записи можно сделать поиск быстрее, чем прочитать всё дерево?
чтоб было быстрее, нужен бинарный формат типа как в базах данных
И, кстати, если ты используешь очень новый и не до концаМне показалось, это обыкновенный PEG, он в 21 веке ни у кого вопросов вызывать не должен.
разработанный способ записи грамматики, надо это указывать
Мне тоже так показалось, но у меня они всё равно вызывают некоторые вопросы.
(Кстати, про 21-й век не надо, они и появились, емнип, только в 21-м веке.)
---
"Математика --- лучший способ водить самого себя за нос."
а разве по твоей записи можно сделать поиск быстрее, чем прочитать всё дерево?Если дерево уже прочитано, и при наличии условия, что узлы на одном уровне отсортированы, то можно быстрее.
на списках, конечно, можно тоже самое (изоморфные преобразования никто не отменял но придется тогда в список вложить ту же самую семантику, что есть у дерева.
есть следующее дерево (сортированность узлов есть изначально, или делается при прочтении)
a
b1 x
c2
fa
fr 5
d
e 1
..
b
..
тогда следующее выражение %a.c2.fr.? с помощью бинарного поиска отрабатывается за O(log N)
тоже самое, конечно, можно сделать и на списках
(a, (b1, (x (c2, (fa (fr, (5 (d (e, (1 (b, ..)
но тогда появляется много скобок, и нарушается взаимооднозначность: всякая "хорошая" структура может быть представлена в виде списков, но не всякий вариант списков является "хорошим".
также для эффективного поиска требуется другой способ хранения списков, чем универсальный готовый, и другой способ записи запроса, чем универсальный к спискам.
Если дерево уже прочитано, и при наличии условия, что узлы на одном уровне отсортированыто есть преобразовать в бинарный формат таки надо
то есть преобразовать в бинарный формат таки надода, надо
ps
если говорить аккуратнее, то требуется преобразование во внутренний формат, потому что этот внутренний формат можно хранить и в виде текста при очень большом желании
Когда есть <code1> и <code2>, совпадающие по большей части, но имеющие некоторые отличия, и хочется DRY.можно применить общий подход:
- либо делается "жирная" функция, которая принимает флажок "первый вариант это, или второй", и в места различий вставляются if-ы на основе флажка
- либо делается "каркасная" функция, которая принимает в качестве параметров набор отличий и их расставляет по "местам".
ps
чтобы привести более конкретные инструменты необходима более конкретная задача.
разве k8{changed} это не то же самое что k8:'changed' ?
.(c,d,e)
О! Давно ждал такой язык А там что-нибудь позабористее можно?
.(c.d, e {f.g, h})
> О! Давно ждал такой язык
Пролог, что ли?
---
...Я работаю антинаучным аферистом...
Да при чем тут пролог =) просто синтаксическая возможность писать после точки что угодно. Вместо [x.a, x.b, x.c.d] ты пишешь x.[a, b, c.d] и т.п. Особенно это удобно, когда x не переменная, а временные данные. Вместо x=f(y); x.a+x.b ты просто пишешь f(y).(a+b)
Вот так в D работает:
struct S { int a, b; }
S f(int x) { return S(x, x+1); }
int g(int x) { with(f(x return a + b; } // <---
f(x).(a+b)*f(y).(a+b)
он под списки заточен. Деревья на нем не удобно записываютсяWAT
(define omg '(1 2 3 (4 5 (6 7) (8 9) 10) 11
Лиспосписок это и есть дерево.
Что-то я не догоняю, чем отличается ; от , и зачем нужно :для отделения выражения друг от друга - ';' тоже самое, что и ','. внутри точки работает только ','
разве k8{changed} это не то же самое что k8:'changed' ?
k8:changed тоже самое, что k8{changed}
первое сделано для того, чтобы скобок было как можно меньше.
что-нибудь позабористее можноможно.
#f=>p{x:10, y:4};
.f -> .x+.y
выдаст 14
Язык, по умолчанию, иммутабельный.
Каждая конструкция языка на вход принимает лес и на выход возвращает лес.
1. одиночный терм или литерал
вход игнорируется. на выходе - лес из одного узла, содержащего терм
tr ==> tr
1 ==> 1
'tr' ==> tr
'1 2' ==> '1 2'
1.1. блок (список выражений, склейка в длину)
expr1; expr2; ..; exprN.
может заключаться в круглые или фигурные скобки. вместо ';' может использоваться ','. Сепаратор после последнего выражения может ставиться, а может не ставиться.
каждое из expr-i принимает на вход тот же лес, что и весь блок. Результат блока есть склейка результатов expr-i
2. декларация переменной отдельным выражением внутри блока
#name expr;
expr вычисляется и присваивается переменной name
переменная видна до конца блока.
имя переменной может переиспользоваться, но физически это будет новая переменная.
2.1. переменная (обращение к переменной)
вход игнорируется. на выходе - содержимое переменной
(#x 1;@x; @x;) ==> (1, 1)
3. дерево (склейка в глубину)
expr1 {expr2}.
также возможен вариант записи expr1:expr2.
запись expr1:expr2:expr3 раскрывается как expr1{expr2{expr3}}
оба выражения на вход принимают то же, что всё выражение в целом.
результат expr2 вклеивается на один уровень ниже в результат выражения expr1
div{text{1}} ==> div:text:1
(div:text:1){text:2} ==> div{text:1, text:2}
(div, div){text:1} ==> (div:text:1, div:text:1)
{1, 2} ==>
4. выбор по имени
%<term>
из входного леса выбираются деревья у которых головной терм совпадает с term
(a, b, c, b:2) %b ==> (b, b:2)
(a, b, c, 'b 1':2) %'b 1' ==> 'b 1':2
5. выбор по имени на уровень ниже
.<term>
из входного леса из всех поддеревьев уровнем ниже выбираются такие у которых головной терм совпадает с term
p{x:1, y:2}.x ==> x:1
(div:text:1, p{text:2, br, text:3}).text ==> (text:1, text:2, text:3)
6. выбор головного узла
%$
из входного леса выбирает только головные узлы
p{text:1} %$ ==> p
(div, p:text:2) %$ ==> (div, p)
7. выбор всех элементов на уровень ниже
.?
выбираются все поддеревья на уровень ниже
p{text:1} .? ==> text:1
(div, p:text:2) .? ==> text:2
8. конвейер
->
фактически ничего не делает. используется для ввода блока в выражение, или для визуального отделения
p{text:1} -> .? <==> p{text:1} .? ==> text:1
p{text:1} -> (%$, .?) ==> (p, text:1)
(div:text:1, p:div:text:2) -> (.text, .?.text) ==> (text:1, text:2)
8.1 текущий лес
$
результат равен входу.
1 -> $ ==> 1
div{text:1} -> $:text:2 ==> div{text:1, text:2}
9. where
[<cond>]
из входных деревьев выбираются такие для которых <cond> не пустой
(div:text:1, div, p:text:2) [.text] ==> (div:text:1, p:text:2)
10. switch
| <condition1> -> <expr1>
| <condition2> -> <expr2>
...
| <conditionN> -> <exprN>
condition-ы проверяются последовательно,
если <condition-i> не пустой, то результат <condition-i> передается в <expr-i> и в, качестве, результата всего выражения берется результат <expr-i>,
иначе (если пустой то проверяется следующее условие
11. декларация функции
#<name>(<args>) => <expr>;
у функции есть один неявный аргумент, значение которого передается на вход <expr>
12. вызов функции
.<name>(<expr-s>)
в функцию передается значение входа и значения выражений <expr-s>
(
#add-text(text)=> $ {text:@text};
div.add-text(1).add-text(2 p.add-text(3);
) ==> (div{text:1, text:2}, p:text:3)
навигация по коду есть?
навигация по коду есть?нет, нету
нет, нетуи нельзя сделать?
и нельзя сделать?сделать можно.
открытый вопрос - насколько часто он будет ошибаться.
открытый вопрос - насколько часто он будет ошибаться.так не пойдет, должна быть 100% верность, хотя бы теоретическая
так не пойдет, должна быть 100% верность, хотя бы теоретическаяЧто выдавать, например, для следующего кода?:
#author author{id: 1, Fio:'И.И. Карнаух'};
#book book {id:1, name:'Bla-bla'};
#item |[.rand < 0.5] -> @author | @book;
@item.id;
что должна делать навигация при нажатии на id в последней строке?
ps
Данный код может быть статически-типизирован, при этом тип переменной item: некая структура, имеющая поле id.
про edn вспоминали? http://github.com/edn-format/edn
что должна делать навигация при нажатии на id в последней строке?список из двух элементов. При этом про каждый элемент выдается инфа: какой проект, неймспейс, класс, файл, метод, строка.
Оставить комментарий
Dasar
Назначение языка:Описание деревьев данных и преобразование одних деревьев в другие. Аналог xml-я и xslt в одном флаконе. Отдаленный аналог: json, s-expression, sql-я, xquery, linq(и его аналогов в других языках).
Объектные графы тоже описываются и преобразуются, но требуют нормализации в деревянный вид: обратные ссылки, приводящие к циклам, оформляются по особому.
Основные принципы:
- лаконичность
- единообразие (унификация)
- конвейерная запись преобразований
- текстовая сериализуемость: произвольные данные или код должны уметь преобразоваться в текстовое представление (максимально приближенное к коду, который пишет программист) для передачи по произвольному каналу
- толерантность к неполноте информации: код может обработать дерево, имея лишь частичное представление о его структуре и смысле
- заточенность под исполнение O(1)/O(log n)
- гибкость
Пример описания данных
тоже самое, но с использованием идеи питона, что отступы используются для описания структуры.
оба синтаксиса взаимозаменяемые и могут использоваться вперемешку.
преобразование приведенных данных в html-вид
выходной html