Closed ghost closed 12 years ago
for implicit objects or arrays as the first arguments, you need to use do
:
someone do
name: "foo"
age: 20
, callback
someone do
"foo"
20
, callback
That doesn't work.
You can't have ", callback".
That will generate a compilation error.
Sent from my iPad
On 21 jun 2012, at 18:49, Adrian Sinclairreply@reply.github.com wrote:
for implicit objects or arrays as the first arguments, you need to use
do
:someone do name: "foo" age: 20 , callback someone do "foo" 20 , callback
Reply to this email directly or view it on GitHub: https://github.com/gkz/LiveScript/issues/50#issuecomment-6487988
An example of what I dislike:
From this in CoffeeScript:
@add
xtype: "textfield"
itemId: "label-textfield"
name: "filter"
emptyText: "Filter on name"
height: 30
selectOnFocus: true
@on
change: (field, newValue, oldValue) ->
something!
To this in LiveScript:
@add {
xtype: "textfield"
itemId: "label-textfield"
name: "filter"
emptyText: "Filter on name"
height: 30
selectOnFocus: true
}
@on {
change: (field, newValue, oldValue) ->
something!
}
It feels like a major drawback.
I execute functions passing an implicit object everywhere throughout my app and it gives me a bloated feel.
The following compile as you wish. Note that when calling against blocks starting with implicit objects/array you must start off with do
someone do
name: "foo"
age: 20
callback
Notice the indentation - it needs to be correct. Also, you don't need the comma.
someone do
* "foo"
20
callback
Notice the star to show that the first two items are a list, not seperate arguments.
@add do
xtype: "textfield"
itemId: "label-textfield"
name: "filter"
emptyText: "Filter on name"
height: 30
selectOnFocus: true
@on do
change: (field, newValue, oldValue) ->
something!
Why does it force us to use do? Is it to create a new scope?
Also, the 2nd example with the array doesn't work. I have tried it in the compiler on the doc website but it compiles to arguments passed instead of an array.
Johnny
Sent from my iPad
On 21 jun 2012, at 22:59, George Zaharievreply@reply.github.com wrote:
The following compile as you wish. Note that when calling against blocks starting with implicit objects/array you must start off with
do
someone do name: "foo" age: 20 callback
Notice the indentation - it needs to be correct. Also, you don't need the comma.
someone do * "foo" 20 callback
Notice the star to show that the first two items are a list, not seperate arguments.
@add do xtype: "textfield" itemId: "label-textfield" name: "filter" emptyText: "Filter on name" height: 30 selectOnFocus: true
@on do change: (field, newValue, oldValue) -> something!
Reply to this email directly or view it on GitHub: https://github.com/gkz/LiveScript/issues/50#issuecomment-6494292
No new scope is created. Think of do
in these cases as replacing parentheses.
add do
2
3
is the same as
add(
2
3
)
also
someone do
* "foo"
20
callback
compiles for me to
someone(["foo", 20], callback);
Why is the use of do
required? Well that was inherited from Coco, and knowing @satyr, he probably had a very good reason. Take a look at the section 'implicit call/object interaction' in https://github.com/satyr/coco/wiki/improvements
Mostly because it forces to see an implicit call, where coffeescript would fail to read after the implicit object, I think. (but, yeah, @satyr obviously has reasons)
good reason
CoffeeScript's implicit call generally doesn't work against blocks, but has a specialcase for implicit objects:
# f({k: v}, x)
f
k: v
x
which causes problems:
# fails
f
x
k: v
# fails
r = switch
when x
k: v
Coco removed the specialcase and instead made do
block work as multiline arguments.
What are the reasons for:
f 1,
name: "foo"
true
and not
f
name: "foo"
true
I guess it's not that big deal with do. But I think LiveScript should be targeting 0 compromises to create the perfect language.
new Ext.util.KeyMap do
target: Ext.getDoc()
binding:
* key: Ext.EventObject.L
alt: yes
defaultEventAction: "preventDefault"
handler: -> app.sendEvent "changeListView"
* key: Ext.EventObject.UP
defaultEventAction: "preventDefault"
handler: -> app.sendEvent "upKeyIsPressed"
Cons:
Please reopen this issue.
What are the reasons for:
f 1, name: "foo" true
This is an unambiguous case. The 1
indicates the start of an implicit call, and ,
indicates the block after it is part of the arguments.
f name: "foo" true
This is ambiguous due to constructions like if
. Consider:
if f
name: "foo"
true
do
in other places actually creates a new scope in LiveScript
Incorrect.
The if statement was good to describe the problem. But could another word or a symbol perhaps be used?
do -> a = 2
a #=> a is not defined
Doesn't this mean it is creating a new scope?
That scope is from ->
. do
is just calling it. Observe:
$ coco -ps
do
a = 2
a
2
@satyr this is one of my problems with such syntactically stripped-down languages, often consistency is sacrificed for the sake of syntactic unambiguity, where I think the former is more important (obviously unambiguity is required for the compiler to work, but the syntax should not have so few landmarks that it happens often at all)
I mean the language is nice and all, and I plan to use it in the next project that I see fit, but I don't see the point of such a syntax with so few non-whitespace landmarks; I have nothing against parenthesis, coming from lisp and all.
I have nothing against parenthesis, coming from lisp and all.
In that case I'd recommend sticking with lispy variants, in which you have many better choices (ClojureScript, Slip to name a few) with unlimited possibilities via macros.
@adrusi, you can use parentheses instead of do
if you want
new Ext.util.KeyMap(
target: Ext.getDoc()
binding:
* key: Ext.EventObject.L
alt: yes
defaultEventAction: "preventDefault"
handler: -> app.sendEvent "changeListView"
* key: Ext.EventObject.UP
defaultEventAction: "preventDefault"
handler: -> app.sendEvent "upKeyIsPressed"
)
In case of
if f
name: "foo"
true
Perhaps we can do:
if f do
name: "foo"
true
In that way we don't have to be forced typing do everywhere when we don't have to.
Just like executing a function with ! when we have to use it, and ignoring it when we don't.
Even when we have to use do I feel that we can use:
if f \
name: "foo"
true
indicating that it's a new line. Just like in unix.
Having do standing for 2 different things is not good practice.
@johnnywengluu +1 for backslash. As ugly as it is, it's what's used in other languages (python, shell) and is in fact 1 less character
@satyr I tried clojurescript, and I like it. The thing is, I'm also a big javascript fan, and js is my main language, so I also really like these language projects that are closer to js. I'm not saying that clojurescript doesn't have fantastic interop, but coffeescript derivatives don't have a need for interop at all.
@adrusi yes, also, it will only be used when needed, which is perhaps never.
I think people would like to do:
if f name: "foo", true
instead of the earlier mentioned one.
Let our code be cleaner without all these do keywords. It's an downgrade from CoffeeScript in this case
@johnnywengluu:
Perhaps we can do:
if f do name: "foo" true
In that way we don't have to be forced typing do everywhere when we don't have to.
Then we'd have to type do
in most if
though.
if f \ name: "foo" true
\
is taken for unspacing/line-continuing which is more essential.
@adrusi:
I also really like these language projects that are closer to js
Pretty sure there are JS lisps that are. How about Sibilant?
@satyr if the following becomes a legal syntax:
f name: "foo"
other-name: "bar"
(it might already be) then do
is line-continuing. But it's not that big of a deal, as I explain below.
I think do
makes sense in if
more than it does for its current application, but I'm in no way supporting requiring do
for every if
. Perhaps rename do
to begin
to make more sense?
And Sibilant is just bad, at one point I was interested and even forked the project and messed around with the source, but it's really quite bad.
Really, Coffeescript-like languages are fine for me, I'm just saying that it can get frustrating when avoiding parenthesis and braces becomes such a big deal to people that they come up with new syntaxes to avoid them, even when the new syntaxes mean more overall characters. Why can't we just be content with:
if f {
name: "foo"
}, true
which IMO is easier to mentally parse than
if f do
name: "foo"
true
because it provides visual landmarks separating the 2 arguments.
actually, I'd like to point out that:
if f do
name: "foo"
does not compile because the end of the argument list would be ambiguous, for example:
if f do
name: "foo"
a++
a + 2
is that
if (f({name: "foo"}, a++)) { return a + 2; } // however implicit returns are handled in this case, closures, ternaries, whatever
or
if (f({name: "foo"})) { a++; return a + 2; }
I think
do
makes sense inif
more than it does for its current application, but I'm in no way supporting requiringdo
for everyif
. Perhaps renamedo
tobegin
to make more sense?
Python does this with requiring :
for the start of block instead of do
or begin
. Removing this requirement is one of the best aspects of CoffeeScript syntax.
if f do name: "foo"
does not compile
Ritht, that if
lacks the body part. Compare:
if f do
name: "foo"
then
a
@satyr oh, so having a block in the predicate requires then
? that's cool, I hadn't thought of that.
Yeah, since you need to somehow dedent and then indent again. Coco's then
is simply ignored before an indented block for cases like that.
$ coco -bcs
if a then
b
if (a) {
b;
}
$ coffee -bcs
if a then
b
Error: Parse error on line 1: Unexpected 'THEN'
Why isn't it allowed to do:
One of the selling point with LiveScript is that it removes the need for a closing character.
The only exception is:
This makes the code more verbose than the CoffeeScript version (the array syntax stays the same).
Can't we just remove the "pyramid effect" in all eternity just like Jade, Haml and Stylus have done but for HTML and CSS.