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

Ranges don't allow the use of variables in 0.5.4 #65

Closed
ceymard opened this issue Jun 13, 2011 · 12 comments
Closed

Ranges don't allow the use of variables in 0.5.4 #65

ceymard opened this issue Jun 13, 2011 · 12 comments
Labels

Comments

@ceymard
Copy link

ceymard commented Jun 13, 2011

a = [1, 2, 3]
a[1..a.length]
Cannot read property 'length' of undefined

b = a.length
# returns undefined
a[1..b]

a[1 to a.length]
a[1 to b]
SyntaxError: empty range on line 1

So basically there seems to be a problem with using variables in ranges.

@satyr
Copy link
Owner

satyr commented Jun 13, 2011

They are never supposed to work dynamically--the syntax is Number "to"/"til" Number ["by" Number].
Think of them as extended forms of number literal(s), which desugar to comma separated numbers.

$ coco -bpe 'console.log 1 to 3, [4 til 9 by 2]'
console.log(1, 2, 3, [4, 6, 8]);

@satyr satyr closed this as completed Jun 13, 2011
@ceymard
Copy link
Author

ceymard commented Jun 13, 2011

In that case, maybe they should produce a syntax error a little more explicit ? Like "SyntaxError: unexpected identifier 'b'" or something.

Wouldn't that be interesting to add expression support to the ranges ?
Because right now, I suppose I would have to use .slice 1, b
which I find a little sad given that "n to n [by 4]" is way more elegant.

@satyr
Copy link
Owner

satyr commented Jun 13, 2011

maybe they should produce a syntax error a little more explicit ? Like "SyntaxError: unexpected identifier 'b'" or something.

Perhaps. Patches welcome.

I would have to use .slice 1, b

What's wrong with that?

@ceymard
Copy link
Author

ceymard commented Jun 13, 2011

I'll try to find some time to write a patch.

Nothing is wrong with .slice, it's just that it feels kind of sad that we can't use the nice sugar with variables when it seems natural we could. See python's [ ] operator for instance
b[2:len(b)] "feels" right.

Anyway, my idea of implementation is the following :
When we have literals that we can handle at build time, just do like before and generate the array in place.
If there are variables, generate a function like so :

a[1 to b]


function () { var _res = []; for (var i = 0; i < b; i++) _res.push(a[i]); return _res; }()

@satyr
Copy link
Owner

satyr commented Jun 13, 2011

b[2:len(b)] "feels" right

But .slice(2, b.length) is the JS way. You have better choices (scroll down to "Python Ports") if you want Python syntax.

generate a function

Even though .slice accomplish the same?

@ceymard
Copy link
Author

ceymard commented Jun 13, 2011

But .slice(2, b.length) is the JS way. You have better choices (scroll down to "Python Ports") if you want Python syntax.

I like coco better than python :)

Besides, the JS way doesn't matter much here I suppose, since coco and CS exist for the sole purpose of redefining a better way.

Even though .slice accomplish the same?

That's just a matter of "beauty", really. I just find it elegant to be able to do it in a slice directly, rather than calling a function.

I feel it's more "about Arrays". Plus I don't feel it's that complicated to include it in coco, and neither does it revolutionize anything in its use.

IE, I think arr[a to b], or arr[a .. b] is more readable and is more obviously about array manipulation than arr.slice a, b

Just more sugar. Besides, the parsing is already (almost) here !

1 to 4 -> [1, 2, 3, 4]
1 to n or b to n -> .slice b, n
a to b by c -> function ()...

I really think that it would be a worthwile addition. I'll try to provide a patch, whenever I'm done getting used to the Jison syntax :)

@satyr
Copy link
Owner

satyr commented Jun 13, 2011

I just find it elegant to be able to do it in a slice directly, rather than calling a function

I don't get it. You are calling a function either way, and your version is doing it much less efficiently.

I think arr[a to b], or arr[a .. b] is more readable and is more obviously about array manipulation than arr.slice a, b

Disagreed. For reference, see coffee#746 for why they were removed in the first place.

I'll try to provide a patch, whenever I'm done getting used to the Jison syntax

The numeric ranges as we have now don't involve Jison parser. They are expanded within lexer.

@ceymard
Copy link
Author

ceymard commented Jun 13, 2011

You are calling a function either way, and your version is doing it much less efficiently

From my last comment, I would only call the function in the case where it's not possible to be efficient ; that is when using variables.

.slice can be used when it's only .. to .. since it's the same.

I agree with ".." being ambiguous. However, the "from .. to .. by" syntax is not.

Anyway, I know this is subjective, but I think arr[1 to n] is more readable than arr.slice 1, n and shows quicker that this is about arrays.

What I'm proposing is only an addition ; it is perfectly possible to implement it so that the actual implementation is fully preserved in terms of efficiency, and it adds other possibilities.

For exemple, .slice only works for the arr[a to b] case. If I want arr[a to b by c], I can't use anything besides a for loop.

The numeric ranges as we have now don't involve Jison parser. They are expanded within lexer.

Ah well that's a little more complicated then.

@ceymard
Copy link
Author

ceymard commented Jun 13, 2011

Alright, I'll try to summarize in a clearer way what I'm proposing :

the current case is that when I have arr[1 to 4 by 1], this gives me [arr[1], arr[2], arr[3], arr[4]].
This shouldn't change : when having already known numbers, the current method is best.

When having arr[variable1 to variable2], this should compile to arr.slice variable1, variable2

And when having arr[var1 to var2 by var3], compile to

function(){ 
   var _res=[];
   var _rep=null; 
   for(var i=0; i<(_rep = arr).length; ++i) 
        _res.push(_rep[i]); 
   return _res;
}

or desugar to (arr[i] for i from var1 to var2 by var3)

@ceymard
Copy link
Author

ceymard commented Jun 13, 2011

I have to agree that seeing the desugaring method, I can understand that this is not completely essential.

A clearer syntax error would be a perfectly satisfactory solution.

Sorry for spamming !

@satyr
Copy link
Owner

satyr commented Jun 13, 2011

If I want arr[a to b by c], I can't use anything besides a for loop.

Was about to say "that case is rare enough that for-from comprehensions suffice," but looks like you figured it out already. ;-)

or desugar to (arr[i] for i from var1 to var2 by var3)

I have to agree that seeing the desugaring method, I can understand that this is not completely essential.

@ceymard
Copy link
Author

ceymard commented Jun 13, 2011

I've got to say that I still like having the choice between one and another, especially since the proposed syntax is (a little) more concise.

Anyway yeah, it would be nice to see it someday, although really, really not essential.

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

No branches or pull requests

2 participants