Skip to content
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

Terser array syntax #2259

Closed
ryanflorence opened this issue Apr 13, 2012 · 15 comments
Closed

Terser array syntax #2259

ryanflorence opened this issue Apr 13, 2012 · 15 comments

Comments

@ryanflorence
Copy link

I couldn't find an issue that already talks about this, so please consider this code:

class
  fn = ->
    # hooray I'm done

  obj:
    hooray: "I'm done"

  arr: [
    'ah man'
    'I have to close this'
  ] # <-- bleh

Wonder if we could do something like:

foo: [] ->
  'hooray'
  "I'm done"

#or

foo :[]
  'hooray'
  'no closing character'

Or anything else that makes sense and doesn't require a closing character.

@xixixao
Copy link
Contributor

xixixao commented Apr 21, 2012

I have read through all three topics and I find rpflorence's solution beautiful:

array = []
  bla
  da
  dee

objectA =
  keyA: []
    elA
    elB
    elC
  keyB: []
  keyC: []


objectA.keyA == [elA, elB, elC]
objectB.keyB == objectB.keyC == []

I can't seem to find any ambiguity. Also, seems to me this is backwards compatible.

@showell
Copy link

showell commented Apr 21, 2012

I'm warming up to it ever so slightly. It seems like we would want this too?:

foo = {}
  name: steve

You wouldn't actually need the {} in most circumstances, but it allows you to be explicit about creating a hash, and it makes it easy to transition from a zero-key hash to a one-key hash.

I'm +0.0000000000001 on this.

@ryanflorence
Copy link
Author

I could dig:

foo = []
  'bar'
  'baz'

foo = {}
  bar: 'baz'

Both of which are parse errors right now (good news).

Or to be more clear, make the [] and {} not look "normal" somehow, maybe like:

foo = []>
  'bar'
  'baz'

foo = {}>
  bar: baz

@xixixao
Copy link
Contributor

xixixao commented Apr 21, 2012

= {}

seems unnecessary. Objects are already easily distinguishable by using key value pairs and there is no "third" type to objects and arrays (in which case it would make sense to unify all of them). Going from zero to one element hash does look great but it also adds two characters to type for each non-empty object ([] doesnt, since now you need brackets anyway).

But I think there would be great use for it in anonymous objects' declaration:

array = []
  {}
    key: value
    bla: da
  {}
    key: value2
    bla: doom

It could also clarify this, which seems to me rather non-obvious (I don't know how popular it is):

array = [
    key: value
    bla: da
]
array == [{key: value, bla: da}]

@ajoslin
Copy link

ajoslin commented Apr 21, 2012

Let's not add more ambiguous stuff. It took me a long time to get used to the return of implicit objects (like below). because it has two of the 'magics' of coffee-script: auto-return and brace-less objects:

returnsAnObject = ->
  key1: value1
  key2: value2

If you add bracket-less arrays, make sure they aren't confusing.

@davidchambers
Copy link
Contributor

Here, the array's items are between the square brackets:

array = ['foo', 'bar', 'baz']

The same is true in this case:

array = [
  'foo'
  'bar'
  'baz'
]

But not in this case:

array = []
  'foo'
  'bar'
  'baz'

I believe an array's items belong between the delimiters ([ and ], in the case of CoffeeScript). For this reason, I'm -1.

@ryanflorence
Copy link
Author

Here the function bodies are between the parens:

foo.then (-> doStuff()), (-> doOtherStuff())

But not in this case:

foo.then ->
  doStuff()
, ->
  doOtherStuff()

Here, the object's items are between the curly brackets:

obj = { foo: 'bar', baz: 'qux' }
obj = {
  foo: 'bar'
  baz: 'qux'
}

But here they are not:

obj = foo: 'bar', baz: 'qux'
obj =
  foo: 'bar'
  baz: 'qux'

I believe a function body, objects' items, and arrays' items belong wherever is the cleanest :)

Perhaps my proposed syntax isn't clean (that's subjective), but this kind of sugar isn't unprecedented in coffeescript.

@davidchambers
Copy link
Contributor

Dropping punctuation is not the same as using punctuation in a new way. I love being able to write obj = foo: 'bar', baz: 'qux' without typing a curly bracket, and bracket-free array literals would be nice also:

array = 'foo', 'bar', 'baz'
array =
  'foo'
  'bar'
  'baz'

I'm not suggesting that this is even a possibility; my point is that the proposed syntax is not a natural extension of CoffeeScript's bracket-free object literal notation.

@vendethiel
Copy link
Collaborator

@davidchambers these are nice, but what happens in a function call? And in a magic return ?

a = ->
 "a"
 "b"

@satyr
Copy link
Collaborator

satyr commented Apr 21, 2012

bracket-free array literals would be nice

Coco enables this by making = and : accept a list block with multiple items.

$ coco -bcs
  array =
    'foo'
    'bar'

var array;
array = ['foo', 'bar'];

This is doable being currently invalid:

$ coffee -bcs
  array =
    'foo'
    'bar'

Error: Parse error on line 3: Unexpected 'TERMINATOR'

unlike the inline version:

$ coffee -bcs
  f array = 'foo', 'bar'

// Generated by CoffeeScript 1.3.1
var array;

f(array = 'foo', 'bar');

@xixixao
Copy link
Contributor

xixixao commented Apr 22, 2012

As rpflorence pointed out, if objects can lose brackets, why arrays couldn't?

Making completely bracket-free arrays has several issues though as was pointed out here and in the other threads.

// new optional way to declare arrays
array = []
  el

// new optional way to declare objects
object = {}
  bla: do

// real uses
object =
  key: value
array = []
  da
  ba
array = []
  {}
    key: value
  {}
    key: value
  []
    doom

// making implicit objects more obvious
f = ->
  {}
    key: value

All backwards compatible (doesn't compile now) and not ambiguous in my opinion.

@vendethiel
Copy link
Collaborator

Yaml-like syntax is also not bad

@jashkenas
Copy link
Owner

So, let's walk through this a bit... First -- Coco's change is the most appealing of these, because it simply allows lists of things as individual lines. All appears well in the obvious case:

array =
  one
  two
  three

... but if you allow that, you also have to allow the single-element array:

array = 
  one

... which is deeply unintuitive, but still perhaps acceptable. Where you really get into trouble is with function calls:

array
  one

if array
  one

... The serious ambiguity of those two is why we aren't going to do it.

As to the proposal to prefix lists of items with [], I agree that it's a mis-use of brackets which are typographically intended to surround their contents, not prefix them. Closing as a dupe.

@tiye
Copy link

tiye commented Jan 6, 2013

To be honest.. I really want some feature because if we can do that,
and what's more, when we have interpolation in of keys,
it would be very nice to generate HTML from CoffeeScript.
I've tried that in LiveScript.. and it's more likely to be an advantage of LiveScript..
https://github.com/jiyinyiyong/live-tmpl
I do hope there's some beautiful solution in CoffeeScript.

dowload-link = "http://jiyinyiyong.github.com/live-tmpl/page/tmpl.js"
page-link = "http://jiyinyiyong.github.com/live-tmpl/page/"
repo-link = "https://github.com/jiyinyiyong/live-tmpl/"

hope-words = '''
  JSON is a build-in type in JavaScript. Hope everyone enjoys it.
  More often, we need to deal with HTML in browsers.
  For Example, the client templating in single-page apps.
  So, why is it ugly and awful to generate HTML with JS?
  Now I'm writting live-tmpl, trying to make it easy in LiveScript.
  '''

hope-html = hope-words.split "\n" .map -> p: it.trim!

demo =
  "/root.main name='top'":
    * "h3": "Home page of Live-tmpl"
    * ".list"
        * ".line":
            * "span.title": "Goal"
            * ".list": hope-html
        * ".line":
            * span: "by"
            * span: "Jiyin Yiyong"
        * ".line":
            * span: "in"
            * span: "LiveScript"
    * ".links":
        * p: "Some links here:"
        * ".line":
            * "a href='#dowload-link'": "Download"
            * "a href='#page-link'": "Demo Page"
            * "a href='#repo-link'": "Github Repo"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants