Я когда-то подобную штуку писал на коленке и наугад (без матана) для своей парсилки тайского языка. Там решение выглядело так, что кроме результата вычисления, тянулся еще description и дерево лемм.
Начало я понял, это ж типичная проблема, сплошь и рядом возникает при кодировании. Но вот потом я уперся в то, что если у нас есть строго последовательность вычислений (вот там, где на 12/13-м слайде про DOB), то чаще всего дальнейшие вычисления не имеют смысла.
А значит, надо останавливаться и сообщать об ошибке. Одной! Потому что следующее вычисление почти всегда зависит от предыдущих.
А если не зависит, то речь идет о concurrent tasks, и программист должен был бы это разделить средствами языка. А если не разделил, то бить по рукам, потому что он подложил мину под будущее scalability.
Тайский. Парсить. Parsec'ом. Точнее, его FSharp'овым клоном, FParsec. Собственно, автор ФПарсека меня на StackOverflow и пригласил.
Он потом еще где-то в блоге писал, что это единственный известный ему случай, где монадическим парсером парсится natural human language; он-то привык к DSL'ям. :))
Точнее, не сегментации, а syllabification. Потому там и FParsec, что накопительно парсим и, в случае чего, rollback.
rather, the piece that produces x: {y:..., z:...} now needs to be aware of where in the resulting structure it is. And the piece producing y:... needs to be aware where in the x:... it is. Etc.
Right. So how does one produce a flat structure from a tree?
function* toJSON(x) {
if (typeof x === 'string') {
yield '"';
yield escape(x);
yield '"';
return;
}
if (typeof x === 'number') {
... }
if (typeof x === 'boolean'
...
}
yield '{';
let first = true;
for (let k in x) {
if (!first) yield ',';
first = false;
yield '"' + k + '": ';
yield* toJSON(x[k]);
}
yield '}';
}
Straightforward streaming of keys, values, delimiters. No one is aware of anyone's parents or children.
If we were to flatten it first, then somewhere need to distinguish that they are part of objects, so the correct keys can be produced in the output.
function* toJSON(k, x) {
if (typeof x === 'object') {
for (let k1 in x) {
yield* toJSON(k? k + '.' + k1: k1, x[k1]);
}
return;
}
if (k) {
yield '"';
yield k;
yield '":';
}
if (typeof x === 'string') {
yield '"';
yield escape(x);
yield '"';
return;
}
if (typeof x === 'number') {
... }
if (typeof x === 'boolean'
...
}
}
[{"a": 1}, {"b": 2}] JSON has a corresponding flat structure of ....?
ok, then: {"a":[{"b": 1}, {"c": 2}]} JSON has a corresponding flat structure of "a.0.b: 1", "a.1.c: 2". But what JSON does the flat structure "a.0.b: 1", "a.2.c: 2" correspond to?
That's because of types are ascribed to the values. If we could pass around [1,,3] as Json, then the mapping can be improved; but in "regular languages" having arrays with holes is questionable.
It's not about arrays with holes. JSON for them will have null instead of a hole. That's not the same as {0: 1, 2: 3}. Arrays have length and order of elements.
Maybe I am a bit slow, but yes, we can ascribe properties to certain objects. But you need to encode those properties so that you can restore them upon decoding. Like in JSON those properties are encoded by using square brackets. In a flat structure everything looks the same, so you need to invent markers, like extra constructed fields (length? plus _isArray?).
I recall what stunts people adopt to read a list of properties from Java's .properties files, which _are_ flat. :-)
no subject
Date: 2017-04-05 11:20 pm (UTC)Вот хорошие слайды, очень близко к вашей лекции: Railway Oriented Programming
Я когда-то подобную штуку писал на коленке и наугад (без матана) для своей парсилки тайского языка. Там решение выглядело так, что кроме результата вычисления, тянулся еще description и дерево лемм.
no subject
Date: 2017-04-05 11:25 pm (UTC)Тайский парсить! Там задача сегментации...
no subject
Date: 2017-04-05 11:35 pm (UTC)А значит, надо останавливаться и сообщать об ошибке.
Одной! Потому что следующее вычисление почти всегда зависит от предыдущих.
А если не зависит, то речь идет о concurrent tasks, и программист должен был бы это разделить средствами языка. А если не разделил, то бить по рукам, потому что он подложил мину под будущее scalability.
Разве нет?
no subject
Date: 2017-04-05 11:39 pm (UTC)Он потом еще где-то в блоге писал, что это единственный известный ему случай, где монадическим парсером парсится natural human language; он-то привык к DSL'ям. :))
Точнее, не сегментации, а syllabification. Потому там и FParsec, что накопительно парсим и, в случае чего, rollback.
no subject
Date: 2017-04-06 07:35 am (UTC)was: {x: {y: z, s: t}} - missing x means both y and s are also missing
flat: {x.y: z} - is x missing or not?
no subject
Date: 2017-04-06 07:39 am (UTC)no subject
Date: 2017-04-06 02:50 pm (UTC)no subject
Date: 2017-04-06 07:27 pm (UTC)Straightforward streaming of keys, values, delimiters. No one is aware of anyone's parents or children.
If we were to flatten it first, then somewhere need to distinguish that they are part of objects, so the correct keys can be produced in the output.
no subject
Date: 2017-04-06 02:50 pm (UTC)no subject
Date: 2017-04-06 07:33 pm (UTC)[{"a": 1}, {"b": 2}] JSON has a corresponding flat structure of ....?
ok, then:
{"a":[{"b": 1}, {"c": 2}]} JSON has a corresponding flat structure of "a.0.b: 1", "a.1.c: 2". But what JSON does the flat structure "a.0.b: 1", "a.2.c: 2" correspond to?
no subject
Date: 2017-04-06 08:02 pm (UTC)2. 1.0.b -> 1, a.1.c -> 2
3. ("a.0.b: 1", "a.2.c: 2") ===> {"a":{"0":{"b":"1"}, "2":{"c":"2"}}
Remember, we are dealing with JavaScript object notation.
no subject
Date: 2017-04-06 08:27 pm (UTC)> x = {0:1, 2:3}
{ '0': 1, '2': 3 }
> x.length
undefined
> [1,,3]
[ 1, , 3 ]
> [1,,3].length
3
no subject
Date: 2017-04-06 08:40 pm (UTC)If we could pass around [1,,3] as Json, then the mapping can be improved; but in "regular languages" having arrays with holes is questionable.
no subject
Date: 2017-04-06 09:14 pm (UTC)Maybe I am a bit slow, but yes, we can ascribe properties to certain objects. But you need to encode those properties so that you can restore them upon decoding. Like in JSON those properties are encoded by using square brackets. In a flat structure everything looks the same, so you need to invent markers, like extra constructed fields (length? plus _isArray?).
I recall what stunts people adopt to read a list of properties from Java's .properties files, which _are_ flat. :-)
no subject
Date: 2017-04-06 03:48 pm (UTC)