LiveScript
LiveScript copied to clipboard
Object list literal in a function
[ 1 to 5]
|> map ->
* x: it
y: it * 2
* x: it
y: it * it
Returns:
[{"x":1,"y":1},{"x":2,"y":4},{"x":3,"y":9}]
Expected:
[[{"x":1,"y":2},{"x":1,"y":1}],[{"x":2,"y":4},{"x":2,"y":4}],[{"x":3,"y":6},{"x":3,"y":9}]]
Ugly workaround:
[ 1 to 3]
|> map ->
res =
* x: it
y: it * 2
* x: it
y: it * it
Am I misunderstanding something about the syntax for object list literals? Is it only supported in assignments?
Thanks.
I agree that in both cases your code should compile to an (array of dicts) literal.
Minimal breaking example:
a =
* A: 1
B: 2
* C: 3
D: 4
f = ->
* A: 1
B: 2
* C: 3
D: 4
Seems that lexer returns the same for both, but AST for latter lacks Arr. Looking into AST.
Starting to believe it's fundamental to how current parser is structured.
Meanwhile, a marginally better fix for your code:
[ 1 to 5]
|> map -> return
* x: it
y: it * 2
* x: it
y: it * it
Yeah, it indeed is how the lexer works... A bit subpar but hey...
I realized that function body is an implicit list, so implicit return of last item of the list is actually the correct semantics... Can't really blame lexer for this :wink:
@summivox Thanks for the return hint. Does read better than having an unused assignment as in the original workaround I had used.
Another way:
f = -> []=
* A: 1
B: 2
* C: 3
D: 4
That's what * compiles to
For the record: []= is just a destructuring assignment without stating a variable, i.e. "anonymous assignment". So it's an equivalent to the workaround with a temporary variable from the first post.
I guess this is the same issue I've just come across:
| LiveScript | JavaScript |
|---|---|
table1 =
* id: 1
name: 'george'
* id: 2
name: 'mike'
* id: 3
name: 'donald'
console.log do
* id: 1
name: 'george'
* id: 2
name: 'mike'
* id: 3
name: 'donald'
|
// Generated by LiveScript 1.3.1
(function(){
var table1;
table1 = [
{
id: 1,
name: 'george'
}, {
id: 2,
name: 'mike'
}, {
id: 3,
name: 'donald'
}
];
console.log({
id: 1,
name: 'george'
}, {
id: 2,
name: 'mike'
}, {
id: 3,
name: 'donald'
});
}).call(this);
|
Function calls using the do keyword are not correctly converting arrays.
@johngeorgewright Nothing incorrect about that! do (in this usage) means ‘treat the following as individual arguments’; * means ‘here begins a new structure’. * does not mean ‘I am an item in an array’ (although lots of people seem to assume that is what it means, and perhaps it should change).
Ah. Apologies, so I need to choose 1 of the following:
table1 =
* id: 1
name: 'george'
* id: 2
name: 'mike'
* id: 3
name: 'donald'
console.log table
... or ...
console.log [
{
id: 1
name: 'mike'
},
{
id: 2
name: 'mike'
},
{
id: 3
name: 'donald'
}
]
Or
console.log [
* id: 1
name: 'george'
* id: 2
name: 'mike'
* id: 3
name: 'donald'
]
Or
console.log []=
* id: 1
name: 'george'
* id: 2
name: 'mike'
* id: 3
name: 'donald'
@rhendric I believe that this behavior (func do then (implicit-list)) should not change. It has become a "feature". We need better documentation that explains the semantics of * (hopefully without touching too much compiler internals).