Lists of objects not being constructed

23 views
Skip to first unread message

Mark Green

unread,
Aug 5, 2014, 1:46:13 PM8/5/14
to lives...@googlegroups.com
Well, I hope this doesn't turn out to be a silly mistake like my last question *blush*

class Sheep
 
(x) ->
   
@test = x
    console
.log @test.length
   
for s in @test
      console
.log s

class Moose
 
(n) ->
   
@name = n

new Sheep [new Moose "Sid", new Moose "Bob"]

The output from the console.log command is 1 and only "Sid" is listed. "Bob" seems to vanish into the either. Putting brackets around "new Moose 'Sid'" makes it work, which seems to be a bug since it should be clear that the constructor to Moose takes only one argument. Is this a bug or something I'm doing wrong?

Matt Brennan

unread,
Aug 5, 2014, 3:42:08 PM8/5/14
to lives...@googlegroups.com
ls -bc> new Sheep [new Moose "Sid", new Moose "Bob"]
new Sheep([new Moose("Sid", new Moose("Bob"))]);

The second Moose is being passed as a parameter to the first, rather than as a second array element. If you wrap the Mooses in parentheses, or put one on each line, it will work as you expect.

And there's no such thing as a silly mistake. We were all beginners once :) 

Piotr Klibert

unread,
Aug 5, 2014, 3:44:44 PM8/5/14
to lives...@googlegroups.com
Hello,

in CoffeeScript implicit parens are opened just after an identifier
and always closed at the end of line. I think it's the same in
LiveScript in your case - with explicit parens your example would look
like this:

new Sheep( [new Moose( "Sid", new Moose "Bob" ) ] )

which is clearly not what you want. To make it work you need to make
sure the list has two elements - this can be done in many different
ways, for example:

# the obvious
new Sheep [ new Moose("Sid"), new Moose("Bob") ] # you could leave the
second set of parens out, but don't ;)

# another obvious fix
new Sheep [ (new Moose "Sid"), (new Moose "Bob") ]

# less obvious fix
new Sheep [
    new Moose "Sid"    # note: no comma
    new Moose "Bob"
]

etc.

So, in short, I think this is expected behaviour and not a bug.

Also note that in JavaScript you can never be sure how many arguments
a function, or a constructor, takes. Even if a function declares only
one formal parameter it's still possible to pass any number of
arguments to it and it still can access all arguments, even those
which are not declared. In other words:

f = (x) -> [x, &1, &2]
f 1, 2, 3 # returns [1, 2, 3]

This makes inferring the "correct" number of arguments during parsing
impossible in general.

Mark Green

unread,
Aug 6, 2014, 1:26:24 PM8/6/14
to lives...@googlegroups.com
Ok, thanks. Is there any way to suppress this, ie, to specify that a livescript function definitely will not have extra undeclared parameters?

While I'm asking that question, is there either of the following in livescript:
  - An equivalent to Oxygene's colon operator, where c:field++; is equivalent to if c.field? then c.field++;
  - A "don't care" value in destructuring as in Haskell, for example, first = (x,_) -> x ?

Piotr Klibert

unread,
Aug 6, 2014, 3:32:16 PM8/6/14
to lives...@googlegroups.com
Ok, thanks. Is there any way to suppress this, ie, to specify that a livescript function definitely will not have extra undeclared parameters?

Not that I know of, at least not during compilation. 

- An equivalent to Oxygene's colon operator, where c:field++; is equivalent to if c.field? then c.field++;

No, I don't think so. You have to write: 

c.field? and c.field++

or something similar.
 
- A "don't care" value in destructuring as in Haskell, for example, first = (x,_) -> x ?

You can use underscore just fine for this as it's a valid identifier, but it will introduce `_` as a binding with some value in current context.

Depending on the context I use `_`, `nvm` or `ignored` for this.


Matt Brennan

unread,
Aug 8, 2014, 4:39:40 PM8/8/14
to lives...@googlegroups.com
void acts as a parameter that doesn't bind anything:

ls -bc> (a, void)-> a
(function(a){
  return a;
});
Reply all
Reply to author
Forward
0 new messages