leafo / moonscript

:crescent_moon: A language that compiles to Lua
https://moonscript.org
3.2k stars 192 forks source link

Slice syntax #104

Open leafo opened 11 years ago

leafo commented 11 years ago

Right now if you want to slice an array table you could do something like this using a comprehension.

list = {1,2,3,4,5}
x = [item for item in *list[2,4]]

It's a bit verbose, I'm considering overloading the [] operator such that if there is a comma in it then it will do a numeric slice:

The example above would be shortened to:

x = list[2,4]

It would work just like slicing with comprehensions, so the following would also be valid:

a = list[,] -- a copy
b = list[,4] -- from the start
c = list[3,] -- to the end
d = items[,,2] -- every other item

The only reason why I might not want to do this would be to use the multi-arg [] syntax for something else. I can't think of anything at the moment.

stevedonovan commented 11 years ago

Some people might prefer to keep [,] for multidimensional arrays? How about : or does that conflict with the rest of the grammar?

leafo commented 11 years ago

The slicing in list comprehensions originally used : but I changed it to , because it was too messy with table literal syntax.

You're saying x[1,2,3,4] should be shorthand for x[1][2][3][4]? I also like that idea.

torhve commented 11 years ago

How about reverse, like python list[-1] for last item?

stevedonovan commented 11 years ago

If people see list[1:-2] then they'll get it, I think. A[1,2] looks too much like a matrix reference.

And A[1][2] is the obvious but not optimal translation. Serious C speed junkies won't use it because of the extra referencing and loss of locality, and will put up with ugly indices like i*N + j. Interesting to consider MS + LuaJIT as a high-performance programming language ;)

leafo commented 11 years ago

True, I tend to put multidimensional data in a 1 dimensional table. It's hard to make assumptions about how the programmer has their multidimensional data setup. I think using the syntax for slicing would have more utility then.

Because the comma is already in use for slicing on comprehensions I don't think it's worthwhile to change it to a colon (plus it's annoying to parse).

@torhve I don't want to break normal table lookups by using the same syntax. I was considering using list[#] for fetching the last item. I could add negative bound support for slices though, so list[-3,] would fetch the last three items. But then you wouldn't be able to iterate over negative indices (which is what happens now)

etandel commented 11 years ago

+1 for list[#] as sugar for list[#list], especially because we can use it in expressions: list[# - get_offset()]

stevedonovan commented 11 years ago

list[# - get_offset()] would be magic, indeed! But could you resolve a no argument # in this general context?

etandel commented 11 years ago

@stevedonovan No idea, but I do hope so! =)

leafo commented 11 years ago

Yeah I can, if # parses as a function call with 1 argument then it will compile normally, otherwise it's a reference to the current table.

leafo commented 11 years ago

For the sake of simplicity I'll probably re-evaluate the list expression when calculating the length, eg.

hello.world[# + 1] --> hello.world[#hello.world + 1]

The expression to get the list can have side effects, which is problematic. I need to start investigating a way to deconstruct expressions into a series of local variable assignments. It's not trivial though because expressions can appear everywhere. (Something like this would probably be easier if I was generating bytecode)

stevedonovan commented 11 years ago

For now, a simple solution would make us happy, I think. Bytecode generation is attractive, but one of MS' strong points is generation of straightforward Lua (which compiles so very fast anyway). Besides, Lua doesn't have a stable byte code format (there are three variants out there currently) and that's the hole that Metalua has dug itself into by only generating 5.1 bytecode.

BTW, is it not time for a point release? The i-1 vs i - 1 issue is a major milestone, I think!

ghost commented 11 years ago

how about ~ [1~5] [~3] [1~] look good to me

weakish commented 11 years ago

What about just using the * operator?

list = {1,2,3,4,5}
x = *list[2,4]
tophf commented 10 years ago

Related: LuaJIT fast slice implementation

Idyllei commented 8 years ago

it seems that the Slice Syntax has been added to the language. @leafo should this issue be closed?

leafo commented 8 years ago

@branefreez where was slicing added?

Idyllei commented 8 years ago

Isn't it already there with *list[start, jump, end]?