richardhundt / shine

A Shiny Lua Dialect
Other
231 stars 18 forks source link

Consider `func` or `fn` over `function`? #50

Open DAddYE opened 10 years ago

DAddYE commented 10 years ago

I think function is too long and verbose, now the lang is much more succinct so have you considered: func or even fn over function?

richardhundt commented 10 years ago

On 4/3/14 8:03 PM, DAddYE wrote:

I think |function| is too long and verbose, now the lang is much more succinct so have you considered: |func| or even |fn| over |function|?

Well, methods don't need a function prefix:

class Foo
   greet(whom)
      -- no need for function
   end
end

And there's this:

greet = (whom) =>
   -- short function form
end

These already work... except that trunk is currently broken...

— Reply to this email directly or view it on GitHub https://github.com/richardhundt/shine/issues/50.

richardhundt commented 10 years ago

Okay, I've got a bit of headroom now to substantiate my previous response.

In a nut-shell, I'd like Shine to be to Lua what C++ is to C, so I don't want to stray too far from the original syntax. So, while I can't do it everywhere, I'd like Shine to just add to Lua. Exceptions are 4 operators (off the top of my head) which are different:

Shine Lua
. :
:: .
!= ~=
~ ..

~= means concat assign in Shine, and .. is used as range constructors. I think that's it. All the rest are additions.

DAddYE commented 10 years ago

Okay, got it, so you should call it lua++, j/k. Indeed seems very fair. Talking about operators, why ~ for concat and not + ?

richardhundt commented 10 years ago

On 4/3/14 9:55 PM, DAddYE wrote:

Okay, got it, so you should call it |lua++|, j/k. Indeed seems very fair. Talking about operators, why |~|for concat and not |+|?

Performance reasons. Lua and LuaJIT have builtin instructions for string concatenation. These instructions work on ranges of stack slots, so they aren't binary operations like the arithmetic operators. So in Lua if you say a = "foo" .. "bar" .. "baz" it takes one instruction to do the concatenation. Overloading + (which I'd have to do for strings) would be two instructions in this case, one of which creates a temporary string. String interning isn't cheap, so you really want to avoid that where you can.

DAddYE commented 10 years ago

I see the performance reason although I can't (I don't know internals) why they can't infer the string type so + act like ...

Also if we can't use + for string concatenation I suggest to keep .. because is also a common pattern of other languages.

So you can replace range with:

a[1:2] == a[1..2]
a[:2] == a[0..2]
a[2:-2] == a[2..-2]

This is the python way.

Thus for ranges in loop you can add a builtin function like go or python

for a in range(3)
    print(a)
end

What do you think?

richardhundt commented 10 years ago

On 4/4/14 7:52 PM, DAddYE wrote:

I see the performance reason although I can't (I don't know internals) why they can't infer the string type so |+| act like |..|.

It's a register based virtual machine. It has an instruction ADD <dest> <a> <b> which says add a to b and put the result in dest. It has a completely separate VM instruction for concatenation, which is more like CONCAT <dest>, <base>, <count>, which says concatenate from base register base, count stack slots and put the result in dest.

So, because it's a dynamic language, it cannot know the type of the operand at compile-time, so mixing + for both arithmetic as well as concatenation would mean that it would always insert an ADD instruction into the bytecode, the compiler has no way of knowing whether one of the operands is a string (unless its a constant). All this would mean overloading the __add hook for string metatables to make it work. Which, as I mentioned, isn't optimal.

Also if we can't use |+| for string concatenation I suggest to keep |..| because is also a common pattern of other languages.

I know of at least two languages (Perl 6, croc) which use ~. I know of only one which uses .. (Lua). Then again, I don't know that many languages. Both Ruby and Perl use .. for ranges.

So you can replace range with:

a[1:2] == a[1..2] a[:2] == a[0..2] a[2:-2] == a[2..-2]

This is the python way.

Thus for ranges in loop you can add a builtin function like go or python

for a in range(3) print(a) end

What do you think?

I think the distinction here is really the difference between a range and a slice operation. The a[1:2] is a slice. You can't say a[range(1,2)] in Python.

In Shine these two concepts are mixed, which is a short-cut, so ranges really need to be reworked, I'm not all that happy with them as it is. I'd rather add a __slice hook, and keep ranges separate. I'll need to think about it a bit more.

Thanks for the feedback, though.

DAddYE commented 10 years ago

Just quick followup, the dot notation of concatenation is common in php (just one) sql (at least in postgres): echo "qwe" . $a . "rty"; I'm pretty sure there are many others however kind of difficult search for it.

richardhundt commented 10 years ago

On 4/4/14 8:40 PM, DAddYE wrote:

Just quick followup, the dot notation of concatenation is common in php (just one) sql (at least in postgres): |echo "qwe" . $a . "rty";| I'm pretty sure there are many others however kind of difficult search for it.

Yeah, but that's a single . (Perl 5 does that too). Two dots is more commonly a range afaik.

DAddYE commented 10 years ago

So let's try just keeping the single dot? I'm fine with ranges with .. but a bit against to ~ for concatenation, from my background c, go, ruby, js, clojure etc... ~ is for bitwise not or regular expressions like =~ /^\sA/ and sounds a bit awkward to have it for this purpose.

richardhundt commented 10 years ago

On 4/4/14 8:53 PM, DAddYE wrote:

So let's try just keeping the single dot?

What and use -> for property access? You've got to be kidding. How is the parser going the tell the difference between a dot used for property access and a dot used for concatenation. I'm not willing to make whitespace so strict that a.b is property access and a . b is concatenation.

Larry Wall had good reason for switching from . to ~ for concatenation when he designed Perl 6, and that was because Perl 6 was to use . for property and method access, like the rest of the world.

I'm fine with ranges with |..| but a bit against to |~| for concatenation, from my background |c, go, ruby, js, clojure| etc... |~| is for bitwise not or regular expressions like |=~ /^\sA/| and sounds a bit awkward to have it for this purpose

So I suppose the ~= operator in Lua must bother you too.

Shine still has ~ meaning bitwise not as a unary operator. There's no ambiguity there, it's in the prefix position:

a &= ~0

versus:

a ~= b

However, if it really means that much to you, then add this to the top of your program:

function String::__add(a, b) return a ~ b end

And + can be used for concatenation. Just don't expect it to be efficient.

DAddYE commented 10 years ago

I see, to be fair I don't know Perl that much. Just wanted to make sure there is no misunderstanding between operators and yes I don't like ~= so much but I see that you already did 99% of what I consider the right improvement. Anyway, the only thing (if you don't want isn't a big deal) is to use [:] for slice and just range(...) I don't like it either anyway I don't expect many will use loops with those kind of fixed "arrays".