Yes, I see. It is a pity =(
The implied mapping takes JSON {id: 4135, title: "title2"}
to <{id ~ 4135, title ~ <<"title2">>}>.
The bounded size of the Erlang atom table is a vulnerability
but there is an EEP to address that; that in itself is a much
more urgent issue than frames.
And what about borrowing the syntax that Anton Lavrik used for erlson [1]? That syntax looks similar to the one used for records and is much easier to read/write.
It is entirely possible we are fooling ourselves with a similar syntax and would be better off with a completely different syntax.
The implied mapping takes JSON {id: 4135, title: "title2"}
- a couple of diagrams
- some new material, including a description of what
is wrong with using X.y to access a field
- a new section 2 apologising for the rewrite this
needs and hasn't had yet
- a new section 15 (starting on page 41)
which describes in some detail how it works
with new BEAM(-ish) instructions
put_frame allocate a frame
is_frame give true/false result
test_frame used in clause heads
check_frame used in expressions
load_slot load a slot (with inline cache)
copy_frame copy a frame for updating
store_slot store a slot (with inline cache)
On 2/05/2012, at 5:19 AM, Björn-Egil Dahlberg wrote:
> Syntax is more than just finding which characters our parser can identify, like in the frames proposals where ~ is our separator. When I read <{ k ~ value | Is }> it says cons "k is like a value" to Is. *brr*
In fact the semantics very closely related to the semantics of
`((k ,@value) ,@Is) considered as an association list in Scheme,
which really does involve a cons. Let's face it, Is#{k=value}
says that k *equals* value, which it doesn't. There is a uniquely
right character for the job, and that's ↦ .
> What guarantees should we leave?
Any data structure associated with Phil Bagwell is likely to repay study.
I do hope there is no patent on "Cache-Aware Lock-Free Concurrent Hash Tries"
by Aleksandar Prokopec, Phil Bagwell, and Martin Odersky, because that's
_exactly_ what I want for storing frame descriptors. However, the
frame implementation described in the frames proposal is meant as a
replacement for records, and however good HAMTs are at other things,
frames should leave them in the dust *when used as record replacements*.
I know that. The frames proposal SAYS that with specifics.
I haven't seen this particular implementation used for this
particular purpose, but it's not novel either.
> I remember also some proposals
> that retain the relational character, so that a pattern <{k1~v1,
> k2~vn|F}> with a tail frame would become a first class citizen
> of the language. These are then not called frames but rather
> feature structures.
Actually, they're called ψ-terms.
>
> I guess one way to implement real feature structures in a logic
> programming language
It has been done in at least two different ways.
LIFE (Logic, Inheritance, Functions, and Equations)
was described by Hassan Aït-Kaci and Patrick Lincoln
in 1989. It was based on LOGIN, described in
3. A ̈ıt-Kaci, H. and Nasr, R., “LOGIN: A Logic Programming Language
with Built-in Inheritance.” Journal of Logic Programming 3(3), pp. 187–215. 1986.
(Bob Carpenter's "The Logic of Typed Feature Structures:
With Applications to Unification Grammars, Logic Programs And Constraint Resolution)
was published nearly 20 years later.
There was an interpreter for LIFE written in C called Wild LIFE
which can still be downloaded if you search for it (the link on
Peter van Roy's page appears to be dead). I found it at
http://rapidlibrary.com/files/life1-01-tar-z_ulzttmxtv8i89on.html
I was very unhappy when I learned that LIFE was dead.
The Wild LIFE system can't be compiled by an ANSI C compiler. One
can figure out by reading the source code that it uses binary trees
to represent ψ-terms.
The other way that I know of is what Michael Covington did in his
book about natural language processing in Prolog, which is what I
did independently, and which I *suspect* but don't know that
Pl-PATR did as well, which is to use equations on paths rather than
displaying feature structures as ψ-terms, and precompiling the
grammar so that the paths work on plain on Prolog terms. >>Feature
structures<< may be open, but the set of >>feature names<< is closed.
>
> The simple syntax there for feature structures is [k1:v1,
> k2:vn|F].
The syntax for ψ-terms looks like label(a => U, b => V) with
the 'tail' implied.
> And it seems to be rather the rule than the exception
> that a feature structure is open.
Yes. But this is >>Erlang<< we are talking about, not Prolog,
and not LIFE, and not linguistics. Erlang does not use unification.
> (*)
> Compiling Feature Structures into Terms:
> an Empirical Study in Prolog (1993)
> by Andreas Schöter , Buccleuch Place
> http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.24.8407
You will note that this comes two years _after_ WildLIFE was released
and at least seven years after Aït-Kaci's work.
"Compiling to flat terms" is the technique I mentioned using above;
it is so obvious, so easy, and so effective that it's a wonder to me
that anyone ever used anything else. In fact it was SO obvious and
SO easy that it never occurred to me that it was worth a publication.
(Erlang readers: this is actually very very close in spirit to the
way -record declarations are implemented now. Savour the irony!)
Anyway, the *POINT* of the frames proposal is not to innovate but to
take a well established idea and adapt the details to make it suitable
for >>>replacing records<<< in a distributed functional language.
It's like a mouse's nest in a cat's ear: only the location is new.
I don't understand this example [p16]
foo:bar(Ugh),
How is this ambiguous? Are you trying to set the bar element from the
foo frame? Your next line is unclear.
These two poins are very interesting to discuss.
Problem is with handling external data. After frames will be added,
webservers will change their API to represent user query string as a
frame.
There have been done a lot in Ruby world, because Ruby also have atoms
and it has the same problem with their non-GC behaviour. So appeared
extension to Hash class, called HashWithIndifferentAccess
http_params[:key] is translated to http_params["key"] and strings are
used internally to store keys.
This is safe in terms of atom table overload and convenient.
We will not be able to use frames for handling user data if only atoms
can be keys, but if we allow to store atoms, binaries and strings as
keys, we will get a mess with different ways to introduce keys.
Ah, understood. There is certainly an opportunity for error here.
Could {:} represent the empty frame?
>
> <{ foo: bar(Ugh) }> could work because there would be no ambiguity for
> the compiler, but it would be still ambiguous for humans (damn you, humans).
> I would shrug if I read a code like <{ foo:bar(Ugh) }> that actually means
> <{ foo: bar(Ugh) }>.
FWIW, I think this is probably acceptable. If <{ }> was accepted, it
implies an intent on the programmer's behalf that they wanted to
create a frame, which requires a key and a value.
{
quix
% some comment or some more code
, <{ a:1
% some comment or some more code
, foo:bar(Ugh)
, baz:quux(Eh)
% some comment or some more code
}>
% some comment or some more code
, [ ...]
% some comment or some more code
}
When you see code snippet/line with foo:bar(Ugh) you have to very
carefully scan surrounding code when you are willing to know what the
hell is going on and above example is relatively pretty formatted and
indented. It can be far worse in real world application and with
little bit more levels as
{ok, <{ foo:{bar, baz, <{foo:bar(Ugh), baz:quux(Eh)}>, foo:bar(Och)}, a:2 }>}
Good luck with this syntax.
--
Hynek Vychodil
BI consultant
GoodData
náměstí 28. října 1104/17, 602 00, Brno - Černá Pole
Office: +420 530 50 7704
E-mail: hy...@gooddata.com
Web: www.gooddata.com