Thanks Richard for your work and the article. It was a good read!
Given the current good results, what is the likelihood we will see this
feature in R16?
On Mon, Apr 30, 2012 at 3:09 AM, Richard O'Keefe <o...@cs.otago.ac.nz> wrote:
> There is a new version of
> http://www.cs.otago.ac.nz/staffpriv/ok/frames.pdf > up. This one has some encouraging experimental results.
> Thanks Richard for your work and the article. It was a good read!
> Given the current good results, what is the likelihood we will see this
> feature in R16?
Maybe it possible to add JSON notation to frame handling?
It would be very convenient, because {id : 4135, title : "title2"} is
mapped to [{id, 4135}, {title, "title2"}].
The only difference is that in all external format handlers binaries
are used to represent external strings.
_______________________________________________
erlang-questions mailing list
erlang-questi...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
> Maybe it possible to add JSON notation to frame handling?
> It would be very convenient, because {id : 4135, title : "title2"} is
> mapped to [{id, 4135}, {title, "title2"}].
> The only difference is that in all external format handlers binaries
> are used to represent external strings.
I don't quite understand this question.
There is a section in the frames proposal titled "Frames and JSON"
which mainly just presents a table
JSON Erlang
null null
false false
true true
numbers numbers, but JSON has no integers
strings binaries
arrays lists or tuples
dictionaries frames
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.
function({type : <<"article">>, title : Title, id : Id} = Object) ->
Object{id : make_permalink(Id, Title)}.
or
Article = {id : 523, title : proplists:get_value(<<"title">>, Params)}
I mean this. Your syntax may have some historical roots, but they are
too ancient. Nowadays such syntax <{key ~ value>} look like inventing
bicycle with square wheels.
_______________________________________________
erlang-questions mailing list
erlang-questi...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
> function({type : <<"article">>, title : Title, id : Id} = Object) ->
> Object{id : make_permalink(Id, Title)}.
> or
> Article = {id : 523, title : proplists:get_value(<<"title">>, Params)}
> I mean this. Your syntax may have some historical roots, but they are
> too ancient. Nowadays such syntax <{key ~ value>} look like inventing
> bicycle with square wheels.
JSON syntax is ***Javascript*** syntax.
The frames proposal has always made it very clear why we cannot
copy JSON syntax.
{} is already an empty TUPLE,
it cannot also be an empty 'dictionary'.
We cannot reasonably use unadorned curly
braces for frames.
{a:f()} already means a tuple whose one element
is the value of a call to the f() function
in module a. We *CANNOT* even unreasonably
use a colon in maplets; it is just not going
to work.
If there's any parallel to the ideal-square-wheel special environment,
here, it's existing Erlang syntax, which is so weird and annoying that
even some ardent fans of the language can't refrain from open
criticism. Richard is looking for what would be the "smoothest ride"
given what can't be changed. I think he's made the best of some
not-very-satisfactory choices. And it's not like he and I exactly
agree on syntax issues (but let's not go there again. Ever.)
Richard: "Have a lollipop."
Curmudgeon points for that one.
This proposal is almost 10 years old. Is it really so radical that we
couldn't have it in beta within three months?
On Tue, May 1, 2012 at 2:27 PM, Richard O'Keefe <o...@cs.otago.ac.nz> wrote:
> On 1/05/2012, at 3:38 PM, Max Lapshin wrote:
>> I mean using JSON directly inside Erlang:
>> function({type : <<"article">>, title : Title, id : Id} = Object) ->
>> Object{id : make_permalink(Id, Title)}.
>> or
>> Article = {id : 523, title : proplists:get_value(<<"title">>, Params)}
>> I mean this. Your syntax may have some historical roots, but they are
>> too ancient. Nowadays such syntax <{key ~ value>} look like inventing
>> bicycle with square wheels.
> JSON syntax is ***Javascript*** syntax.
> The frames proposal has always made it very clear why we cannot
> copy JSON syntax.
> {} is already an empty TUPLE,
> it cannot also be an empty 'dictionary'.
> We cannot reasonably use unadorned curly
> braces for frames.
> {a:f()} already means a tuple whose one element
> is the value of a call to the f() function
> in module a. We *CANNOT* even unreasonably
> use a colon in maplets; it is just not going
> to work.
> 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.
Exactly. In Ruby, for example, since atoms aren't garbage
collected, converting a JSON from an external source to a hash using atoms
as keys represents a security vulnerability in a web service, as someone
could force the "atom table" to fill in completely, so we simply don't.
So until the atom limitation is fixed, we would be better on handling JSONs
as a dict or something else.
I have read the proposal completely and I think everything is well
explained and defined. Even though I am not a huge fan of the syntax, I
think it fits Erlang well. One option that I haven't seen considered is
still using curly brackets as delimiters and use `{~}` to specify an empty
frame. This would make the common case (a frame with at least one element)
easier on the eyes by sacrificing a bit the not so common case (empty
frame). But again, we are in good hands with whatever the Erlang and OTP
team decide.
On Tue, May 1, 2012 at 11:37 AM, José Valim <jose.va...@gmail.com> wrote:
> 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.
> Exactly. In Ruby, for example, since atoms aren't garbage
> collected, converting a JSON from an external source to a hash using atoms
> as keys represents a security vulnerability in a web service, as someone
> could force the "atom table" to fill in completely, so we simply don't.
> So until the atom limitation is fixed, we would be better on handling
> JSONs as a dict or something else.
> I have read the proposal completely and I think everything is well
> explained and defined. Even though I am not a huge fan of the syntax, I
> think it fits Erlang well. One option that I haven't seen considered is
> still using curly brackets as delimiters and use `{~}` to specify an empty
> frame. This would make the common case (a frame with at least one element)
> easier on the eyes by sacrificing a bit the not so common case (empty
> frame). But again, we are in good hands with whatever the Erlang and OTP
> team decide.
On Tue, May 1, 2012 at 11:28 PM, Max Bourinov <bouri...@gmail.com> wrote:
> Hi Richard,
> Thank you very much for posting your great work!
> But the title scared me. "Getting rid of records" - what should I do with
> all my code that uses records?
> I like the idea of frames a lot. It would significantly simplify my code and
> I love this idea.
> Best regards,
> Max
> On Tue, May 1, 2012 at 11:37 AM, José Valim <jose.va...@gmail.com> wrote:
>>> 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.
>> Exactly. In Ruby, for example, since atoms aren't garbage
>> collected, converting a JSON from an external source to a hash using atoms
>> as keys represents a security vulnerability in a web service, as someone
>> could force the "atom table" to fill in completely, so we simply don't.
>> So until the atom limitation is fixed, we would be better on handling
>> JSONs as a dict or something else.
>> I have read the proposal completely and I think everything is well
>> explained and defined. Even though I am not a huge fan of the syntax, I
>> think it fits Erlang well. One option that I haven't seen considered is
>> still using curly brackets as delimiters and use `{~}` to specify an empty
>> frame. This would make the common case (a frame with at least one element)
>> easier on the eyes by sacrificing a bit the not so common case (empty
>> frame). But again, we are in good hands with whatever the Erlang and OTP
>> team decide.
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.
> > I mean this. Your syntax may have some historical roots, but they are
> > too ancient. Nowadays such syntax <{key ~ value>} look like inventing
> > bicycle with square wheels.
> JSON syntax is ***Javascript*** syntax.
> The frames proposal has always made it very clear why we cannot
> copy JSON syntax.
> {} is already an empty TUPLE,
> it cannot also be an empty 'dictionary'.
> We cannot reasonably use unadorned curly
> braces for frames.
> {a:f()} already means a tuple whose one element
> is the value of a call to the f() function
> in module a. We *CANNOT* even unreasonably
> use a colon in maplets; it is just not going
> to work.
I really dream about plain and simple 0 = D1.baz.fum.i, =)
_______________________________________________
erlang-questions mailing list
erlang-questi...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
> 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.
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*
At first I didn't like the syntax at all, but after playing around with it
for a couple of hours it kind of grows on you. #{ } vs <{ }>, the second
one only uses a single character more. I think we could live with that one.
I still don't like ~ .. and I definitely don't like lollipops.
Lavriks syntax proposal is very clean and seems like an obvious fit to the
current Erlang syntax. However, if I read #{ k = value }, and I know how
R#{k = value } works, it feels like the two should have some sort of
connection. They would't have one. It is entirely possible we are fooling
ourselves with a similar syntax and would be better off with a completely
different syntax.
Syntax is perhaps the most fun to discuss since it is our interface. It is
important to get it right since it hard to change it once implemented. But,
It is of minor concern to me.
What guarantees should we leave? The underlying implementation of a Hashmap
has enormous consequences on the guarantees we can promise. Speed, memory
consumption and functionality are all trade offs. From a memory / speed
perspective I really like a HAMT-implementation. Very compact, simple
garbage collector, persistent and all around nice properties (except
ordering). Doing something more fancy complicates the gc which is not
unsolvable but irritating.
Richard, is the "beam"-implementation for frames around to look at?
On 1 May 2012, at 19:19, Björn-Egil Dahlberg wrote:
> It is entirely possible we are fooling ourselves with a similar syntax and would be better off with a completely different syntax.
I'm in the camp of
- similar syntax indicates similar semantics
- different syntax indicates different semantics
…or something to that effect. Most importantly, I definitely agree that borrowing a syntax just because it's well-established, is a very bad idea if your intention is to give it different semantics from what one would expect.
> I have read the proposal completely and I think everything is well explained and defined. Even though I am not a huge fan of the syntax, I think it fits Erlang well. One option that I haven't seen considered is still using curly brackets as delimiters and use `{~}` to specify an empty frame. This would make the common case (a frame with at least one element) easier on the eyes by sacrificing a bit the not so common case (empty frame). But again, we are in good hands with whatever the Erlang and OTP team decide.
The relevant concept here is *uniformity*: are all cases of a construct
generated by the *same* rule(s)? {a~1, b~2}, {a~1}, and {~} are *not*
generated by the same rule. The bare ~ in {~} has no counterpart in the
others. As I understand it, Joe Armstrong's current proposed syntax is
'#{' [maplet {, maplet}...] '}'
so you would have #{a~1, b~2}, #{a~1}, and #{} (using ~ for maplets
where Joe would actually use =). I prefer symmetric fences, not least
because it helps tools to help me get my brackets to match properly.
But I could live with Joe's syntax.
I have been toying with the idea of a revision to my proposal, namely
that
<open> <maplet> {',' <maplet>}... '|' <expression> <close>
should only be allowed to replace slots that already exist in the
base frame, and not to add new slots. Functional support for adding
new slots would remain, but this way we would *know* that the new
frame could always share the descriptor of the old one, and it would
provide a "safety" assurance to the programmer: if you *intend* to
write 'a copy of F except that the ~count slot is zero'
then <{ count ~ 0 | F }> would faithfully check your assumption that
F _has_ a count slot. This is just like the way records are now, after
all.
> Thank you very much for posting your great work!
> But the title scared me. "Getting rid of records" - what should I do with all my code that uses records?
> I like the idea of frames a lot. It would significantly simplify my code and I love this idea.
There are several answers to 'what should I do'.
(1) If it ain't broke, don't fix it.
Records are NOT going to go away.
There's an analogy from Fortran. Fortran 66 had so-called
'Hollerith literals', where you would write e.g., 4HFRED
to get a string "FRED". That's right, the length as a
decimal integer, the letter capital H, and then that many
characters. With the advent of proper character data in
Fortran 77, Hollerith literals were not needed any more.
They had always been clumsy and error-prone. But they
stayed. I can't remember if they were still there in
Fortran 90 or not, but by Fortran 95 they were gone.
Well, I just tried a Hollerith literal in a tiny program
and while the Fortran 95 compiler *complained*, the
program *worked*.
The Erlang community isn't quite _that_ committed to
backwards compatibility, but it's not too far off...
(2) Frames are almost drop-in replacements for records.
The major exception is default initial values for fields,
which have problems anyway.
Years ago I wrote a paper 'Delenda est preprocessor'.
Abstract patterns and frames are all part of a long-time
project to make the preprocessor unnecessary.
On 2/05/2012, at 3:48 AM, Juan Jose Comellas wrote:
> 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.
The frames proposal was written long before erlson was a twinkle in its author's
eye. Indeed, it was originally drafted in the year that JSON was invented (2001),
so JSON was not an influence.
The frames proposal explains why using '=' in maplets is a bad idea.
Basically, it is HARDER to read because it makes '=' locally ambiguous.
You go searching through a file and hit the line
foo = bar(),
and you have NO IDEA whether this is a maplet or a matching. BAD!
As for #{...} vs <{...}>, it's in one way harder to write
(to get <{, press SHIFT with left hand, and then < and { are close
for two-fingered right hand typing; the same is true of }>,
but #{ requires me to hold down the shift key with my left hand
AND press the # key with my left hand at the same time, and while
there is a shift key on the right, { requires the use of the right
hand). Brackets really ought to be mirror symmetric, but I could
live with #{...}.
There's a section in the proposal titled
"The Colour of the paint on the Ark."
why do we find it easier to argue about the colour
of the paint on the Ark than to climb aboard?
That is the section that provides the reasons for the syntax.
Now Jan Burse and I have been arguing with each other about frames,
but actually, that was a *lot* more useful, because he focussed on
semantics.
But here's the most important thing, which appears in the next draft
of the frames proposal:
This would have been a workable syntax for frames
before erlson used it. Now, it is important that the syntax
should be distinct from erlson syntax, so that frames can be
added to Erlang without breaking erlson. There is also an
important pragmatic difference between frames and erlson.
Frames are new built in data type with a good deal of thought
put into making them economical in memory and time.
``At runtime, Erlson dictionaries are represented as a list
of {Name, Value} tuples ordered by Name. This way, each Erlson
dictionary is a valid proplist and orddict in terms of the
correspond[ing] stdlib modules.''
An entry in an Erlson dictionary thus takes 4 words for the
{Name,Value} tuple plus 2 words for the list cell pointing to
it, or 6 words compared with a frame's 1 or 2.
It therefore matters which one you are using: a programmer
needs to be able to tell at a glance whether an expression
deals with a frame or with an erlson dictionary.
That is, we shouldn't copy Erlson syntax, BECAUSE Erlson IS ALREADY
USING IT and we must not break Erlson.
> As for #{...} vs<{...}>, it's in one way harder to write
> (to get<{, press SHIFT with left hand, and then< and { are close
> for two-fingered right hand typing; the same is true of }>,
> but #{ requires me to hold down the shift key with my left hand
> AND press the # key with my left hand at the same time, and while
> there is a shift key on the right, { requires the use of the right
> hand). Brackets really ought to be mirror symmetric, but I could
> live with #{...}.
Only true for a range of QWERTY keyboards. There's a lot more layouts in the world. Incidentaly on my keyboard writing <{}> is insanely difficult (takes a minimum of 2 seconds when trying to go fast), while #{} is not perfect but a lot easier (maybe half a second, hard to measure at this point). This is because the former requires me to press the sequence "<, ALT GR {, ALT GR }, SHIFT >", while the latter only requires "ALT GR #, ALT GR {, ALT GR }". The keys for # and { are also right next to the other, which isn't true for < and {.
So in my case at least it's not only 1 key less, it's also a lot simpler to type.
It's also a lot simpler to type = instead of ALT GR ~, regardless of other considerations.
> Only true for a range of QWERTY keyboards. There's a lot more layouts in the world.
Indeed. It is impossible to optimise for all of them.
> Incidentaly on my keyboard writing <{}> is insanely difficult (takes a minimum of 2 seconds when trying to go fast), while #{} is not perfect but a lot easier (maybe half a second, hard to measure at this point). This is because the former requires me to press the sequence "<, ALT GR {, ALT GR }, SHIFT >", while the latter only requires "ALT GR #, ALT GR {, ALT GR }". The keys for # and { are also right next to the other, which isn't true for < and {.
You don't say which keyboard. The frames proposal document notes a similar
issue for Swedish keyboards, and suggests allowing *both* <{...}> *and* <(...)>
as a way of coping with the problem.
However, since the problem with <{...}> appears to be due to the use of
the curly braces, surely this must make tuples and records already 'insanely
difficult'.
As for the difficulty of typing ~, code is READ more often than it is WRITTEN,
so the readability advantage much outweighs the typing disadvantage.
Modern text editors have abbreviation features which mean that you *should* be
able to set your text editor up so that (, expands to <{}> with the cursor in the middle
=, expands to ~ with the cursor after it
so that typing "<{a ~ 1, b ~ 2}>" requires the keystrokes
"(,a=,1, b=,2<fwd><fwd>"
It took me five minutes to write this code for my home-brew text editor:
void comma(void) {
if (argvalue != implicit) { putin();
} else
switch (fetch(here)) {
case ')': /* For Erlang expressions */
case ']': /* For Erlang lists */
here++;
break;
case '}': /* For Erlang tuples and frames */
case '>': /* For Erlang binaries */
here += fetch(here+1) == '>' ? 2 : 1;
break;
default:
switch (fprev(here)) {
case '(': /* For Erlang frames */
delete(NORM, here-1);
strinsert(1, 4, "<{}>");
here -= 2;
break;
case '[': /* For Erlang tuples */
delete(NORM, here-1);
strinsert(1, 2, "{}");
here--;
break;
case ':': /* For Erlang records */
delete(NORM, here-1);
insert(1, '#');
break;
case '=': /* For Erlang frames */
delete(NORM, here-1);
strinsert(1, 3, " ~ ");
break; case ' ': here--;
insert(-1, ',');
here++;
break;
default:
putin();
}
}
}
After which it's just "(,a=,1, b=,2," which can't be _that_ hard to type.
On Tue, May 1, 2012 at 7:22 PM, Richard O'Keefe <o...@cs.otago.ac.nz> wrote:
> That is, we shouldn't copy Erlson syntax, BECAUSE Erlson IS ALREADY
> USING IT and we must not break Erlson.
I'm not sure if you are serious, but here's my comment to that anyway.
To me, the benefits of using Erlson syntax for a native implementation
of name-value dictionaries in Erlang outweigh the broken compatibility
with Erlson runtime data representation.
One of the reasons why I created Erlson was to prove that it is
possible to have a nice syntax for Erlang dictionaries that fits with
the language (*). While Erlson syntax is similar to records, it is
still different enough to avoid confusion and it is compatible with
the rest of Erlang's syntax.
So, for those who actually consider implementing a native dictionary
data type in Erlang and using Erlson syntax for that, please feel free
to break Erlson.
Anton
(*) I realize that this is a highly subjective statement, but it is no
worse than any of the purely theoretic arguments about syntax I read
in this thread. Language design is not a science, for better or worse.
_______________________________________________
erlang-questions mailing list
erlang-questi...@erlang.org
http://erlang.org/mailman/listinfo/erlang-questions
come on, we can't start inventing new syntax only from 'editor' perspective, otherwise we could go to "brainfuck" syntax, which is so compact and easy to write ;), but in 100% is not readable at all
> On 05/02/2012 02:22 AM, Richard O'Keefe wrote:
>> As for #{...} vs<{...}>, it's in one way harder to write
>> (to get<{, press SHIFT with left hand, and then< and { are close
>> for two-fingered right hand typing; the same is true of }>,
>> but #{ requires me to hold down the shift key with my left hand
>> AND press the # key with my left hand at the same time, and while
>> there is a shift key on the right, { requires the use of the right
>> hand). Brackets really ought to be mirror symmetric, but I could
>> live with #{...}.
> Only true for a range of QWERTY keyboards. There's a lot more layouts in the world. Incidentaly on my keyboard writing <{}> is insanely difficult (takes a minimum of 2 seconds when trying to go fast), while #{} is not perfect but a lot easier (maybe half a second, hard to measure at this point). This is because the former requires me to press the sequence "<, ALT GR {, ALT GR }, SHIFT >", while the latter only requires "ALT GR #, ALT GR {, ALT GR }". The keys for # and { are also right next to the other, which isn't true for < and {.
> So in my case at least it's not only 1 key less, it's also a lot simpler to type.
> It's also a lot simpler to type = instead of ALT GR ~, regardless of other considerations.
> Now Jan Burse and I have been arguing with each other about frames,
> but actually, that was a*lot* more useful, because he focussed on
> semantics.
No I didn't care about semantics. The semantics is trivial since
as I interpret Erlang it does do some flow analysis of the given
code and sees to it that everything is ground, compared to normal
Prolog.
The flow analysis happens mostly implicit by having turned the
relation semantics of Prolog into a functional semantics. With
the sad result that one way to implement relation semantics in
Erlang is via continuation.
I was more concerned with usage and complexity. Your frames have
been invented many many times. 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.
I guess one way to implement real feature structures in a logic
programming language would be to extend the unification so
that it works on feature terms with tail features. Feature
structures are very fashion in certain attribute grammar
formalism. Besides unification there can be further operations
between feature structures.
The simple syntax there for feature structures is [k1:v1,
k2:vn|F]. And it seems to be rather the rule than the exception
that a feature structure is open. This stems from the relation
ship of feature structures to equations, so the following
equations
G:k1 === v1,
G:k2 === v2
would correspond to the following feature structure relation:
G===[k1:v1,k2:v2|_]
The (===)/2 in the two equations can be viewed as a
declarative combined setter/getter. So setter/getter
are by no way alien to logic programming and it is not
mandatory to go with a feature structure on the
surface of a language.
What seems to be a problem in the grammar domain is that
then practically highly recursive feature structures are
used. But some compilation techniques are able to flatten
them straight the way to records and removing all open
parts that are never closed. So that a feature
structure (*):
In certain circumstances it can be also benefitial to turn
open parts into record positions. Maybe the grammar application
domain can provide further ideas for representing and optimizing
frame terms in Erlang, and vice versa. Most probably the
referenced paper below is already hopelessly outdated, and
people do even more clever things today. But anyway.
> The implied mapping takes JSON {id: 4135, title: "title2"}
I'd just like to chime in that this is not actually valid JSON. In valid
JSON, all keys are quoted strings. Thus, this would be:
{"id": 4135, "title": "title2"}
Which is not at all as good a match with Erlang idioms, unless you want
more magic to turn strings into atoms, only when used as keys...
Sincerely,
jw
Sincerely,
Jon Watte
--
"I pledge allegiance to the flag of the United States of America, and to
the republic for which it stands, one nation indivisible, with liberty and
justice for all."
~ Adopted by U.S. Congress, June 22, 1942