-
Notifications
You must be signed in to change notification settings - Fork 32
The object
macro is not ES6-friendly
#23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Valid JSON can be done separately via a |
@IMPinball brought up another issue in the chat:
In total, there are 8 cases in ES6:
|
Yep. I would like to mention that the shorthand method can be done without, and in many different compile-to-JS languages, and even in Lua (another prototype-based language), that functionality simply doesn't exist. [1] That still leaves 4 different versions to cover, including all permutations thereof.
[1] Well, I kinda fibbed a little with ClojureScript, mainly with regards to |
Oh, looks like I missed a bunch other cases:
Note that, unlike shorthand syntax ( |
There are a lot of functions similar to this in Lisp, where you have a bunch of key/value pairs, some of which can have different syntax. They all work by taking a list of lists, like:
This sort of syntax, while it requires a little more typing than the "just pair them off" plist-inspired syntax that
|
That looks way better. On Tue, Oct 6, 2015, 14:14 Tab Atkins Jr. notifications@github.com wrote:
|
Yeah, |
It doesn't need to, necessarily; leaving out the value is equivalent to setting it to |
@tabatkins For multiple declarations, it probably is (see my initial comment on the object shorthand ambiguity). For a single declaration, I would love to see this as a shorthand for a common case:
|
@IMPinball Ambiguity: Does |
@anko I was initially thinking of that, but I decided to not bring it up in the first place, as I already knew about the ambiguity. I was also specifically talking about single declarations, where Or to more directly answer your question, that would compile to |
Yes, that was the ambiguity that I was trying to raise. Personally, I don't really like the idea of special casing Also, it creates inconsistent indentation rules:
But then again, indentation rules can always be enforced at a styleguide level In any case, I think it makes sense to standardize on having each object property /variable declarator in separate forms. ES6 classes will similarly require special subforms as well.
|
I get what you mean. I've just always preferred single declarations instead of multiple in my projects, particularly for initialized variables (less diff noise). var a = 1,
- b = 2,
- c = 3;
+ b = 2; Just personal preference. I know the other is more idiomatic for Lisp dialects, though. (let [a 1
b 2]
(+ a b)) |
Edit: added shorthand. I have an idea for solving the
To show an example with all of them:
// In JS:
const wm = new WeakMap()
const syms = require("./symbols")
{
prop,
_foo: 1,
[Symbol.toStringTag]: "Foo",
get foo() {
return this._foo
},
set foo(value) {
this._foo = value
},
get [syms.Sym]() {
return wm.get(this)
},
set [syms.Sym](value) {
return wm.set(this, value)
},
printFoo() {
console.log(this.foo)
},
concatFoo(value) {
return this.foo + value
},
*values() {
yield this.foo
},
*valuesConcat(value) {
yield this.foo
yield value
},
} And let
@anko @tabatkins @lhorie What do you all think? |
Looks good overall, but your 1-value syntax is wrong. We want it to match So to summarize:
|
|
Also, are you all okay with the implicit lambda? |
Yeah, I got no problems with implicit lambda. |
Looks very similar to what I currently have in that toy compiler I've been working on, except that I use a special form for computed keys instead of non-computed keys. For comparison, here's what some of my tests look like right now: //variable declarations
test('(var (a 1))', 'var a = 1;')
test('(var (a 1) (b 2))', 'var a = 1, b = 2;')
test('(var (a))', 'var a;')
test('(var (a) (b))', 'var a, b;')
test('(let (a 1))', 'let a = 1;')
test('(let (a 1) (b 2))', 'let a = 1, b = 2;')
test('(let (a))', 'let a;')
test('(let (a) (b))', 'let a, b;')
test('(const (a 1))', 'const a = 1;')
test('(const (a 1) (b 2))', 'const a = 1, b = 2;')
test('(const (a))', 'const a;')
test('(const (a) (b))', 'const a, b;')
//object
test('(object (a b))', '({ a: b });')
test('(object (a b) (c d))', '({a: b,c: d});')
test('(object)', '({});')
test('(object (get a () 1))', '({ get a() {1;} });')
test('(object (set a () 1))', '({ set a() {1;} });')
test('(object (get a () 1) (set a () 1))', '({get a() {1;},set a() {1;}});')
test('(object (get a () 1) (b 2) (set a () 1))', '({get a() {1;},b: 2,set a() {1;}});')
test('(object (get a))', '({ get: a });')
test('(object (set a))', '({ set: a });')
test('(object (* a () 1))', '({ *a() {1;} });')
test('(object (a))', '({ a });')
test('(object ((_[] a) 1))', '({ [a]: 1 });')
//class
test('(class a (extends b) (c (d) e))', 'class a extends b {c(d) {e;}}')
test('(class a (extends b) (c (d) e) (f (g) h))', 'class a extends b {c(d) {e;}f(g) {h;}}')
test('(class a (extends b) (static c (d) e))', 'class a extends b {static c(d) {e;}}')
test('(class a (extends b) (get c (d) e))', 'class a extends b {get c(d) {e;}}')
test('(class a (extends b) (set c (d) e))', 'class a extends b {set c(d) {e;}}')
test('(class a (extends b) (* c (d) e))', 'class a extends b {*c(d) {e;}}')
test('(class a (extends b) (static * c (d) e))', 'class a extends b {static *c(d) {e;}}')
test('(class a (extends b) (static get c (d) e))', 'class a extends b {static get c(d) {e;}}')
test('(class a (c (d) e))', 'class a {c(d) {e;}}')
test('(class a (c ()))', 'class a {c() {}}')
test('(class a (static (d) e))', 'class a {static(d) {e;}}')
test('(class a (get (d) e))', 'class a {get(d) {e;}}')
test('(class a (set (d) e))', 'class a {set(d) {e;}}')
test('(class a (static get (d) e))', 'class a {static get(d) {e;}}')
test('(class a (static set (d) e))', 'class a {static set(d) {e;}}')
test('(class a (* get (d) e))', 'class a {*get(d) {e;}}')
test('(class a (* set (d) e))', 'class a {*set(d) {e;}}')
test('(class a (static * get (d) e))', 'class a {static *get(d) {e;}}')
test('(class a (static * set (d) e))', 'class a {static *set(d) {e;}}')
test('(class a ((_[] b) ())', 'class a {[b]() {}}') I'm still toying w/ it and will probably replace the |
Not too sold on that class syntax, though. I'm too busy fixing my computer On Thu, Oct 8, 2015, 21:34 Leo Horie notifications@github.com wrote:
|
@IMPinball both class id and superClass are optional in class expressions, so I'm currently doing it this way to maintain consistency with the keyword verbosity of other constructs, i.e. I have I'm aware that some of my choices are different from current eslisp. For example, I have Regardless, eslisp forms don't need to be the same as my toy compiler, and my code is still heavily in flux and I'm more than happy to hear feedback and suggestions. |
Yeah... They're different languages. And my opinion isn't exactly required On Fri, Oct 9, 2015, 08:58 Leo Horie notifications@github.com wrote:
|
@IMPinball Many thanks for the summary. That'll make a useful base for tests. |
Isn't this inconsistent with the |
No, this is consistent with the planned changes to the In your example, neither atom is quoted, so they shouldn't evaluate to themselves, but rather to the variable they name. |
Ah, of course, my bad! In my example, |
But it will, per #13. The current design is broken, as it's not compatible with computed property names. |
Yes, I see, it makes sense now :) |
☝️ Correct. Sorry, the confusion is my fault. #13 should have been marked open. We had some confusion about the exact nature of the problem. |
Made another edit to the main suggestion, per my comment in #13. |
ES6 introduces dynamic property names in object expressions:
At the moment, eslisp's
object
macro can't unambiguously accommodate that. Given that(object a b)
compiles to{ a : b }
, what should compile to{ [a] : b }
?Similarly to previously in #13, this can't simply be solved by having
(object "a" b)
compile to{ a : b }
instead and(object a b)
to{ [a] : b }
, because it must continue to be possible to express both{ a : b }
and{ "a" : b }
for stuff like Google's closure compiler, and for when it's necessary to ensure that part of the code is also valid JSON.The text was updated successfully, but these errors were encountered: