[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Ideas about colon operator syntax (and a patch in the work)
- From: Thomas Jericke <tjericke@...>
- Date: Tue, 29 Apr 2014 14:49:26 +0200
I want to share some thoughts and ideas about a patch I am currently
trying to write.
For now the only reason to use the colon operator is to write less
(syntactic sugar) and to reuse the second last field:
very.deep.table.hierarchy:function()
->
very.deep.table.hierarchy.function(very.deep.table.hierarchy)
were "very.deep.table.hierarchy" is only evaluated once.
This is OK, but I don't think it's very fancy.
My patch idea is to make the colon operator more usable by simply
allowing it in more places/cases.
The first change is simple and I have already a patch for it, I can
release it as single patch if someone is interested.
This change simply makes the function call brackets optional if there is
no argument, other than self which is implicitly added.
This means you can write:
require "string"
local text = "I can shout!"
print(text:upper) --> I CAN SHOUT!
I think this change is quite useful for the following reasons:
- No ambiguity: The : operator outside a function declaration like
"function table:funct() ... end" already defines a function call, no
need to define it twice with empty brackets.
- Backward compatibility: text:upper is so far no valid syntax, so
allowing it doesn't break any existing code.
- Arguably better readability: print(text:upper) looks simpler than
print(text:upper())
The idea is, to use this syntax for type conversion methods as well. The
name would be the "type" of the returned value:
local myDouble = 1.0
local myInt = myDouble : integer -- equals myDouble // 1
local myString = myDouble : string -- equals tostring(myDouble)
The nice thing about this syntax is that it looks very similar to type
definitions in UML notation.
This is actually the reason why I got the idea in the first place. This
can also be used for implicit type conversation to userdata types:
local myDouble = 1.6
local myString = "I SAID, I CAN SHOUT!"
MyFunction(myDouble : fixedPoint, myString : stringBuffer)
MyFunction expects a fixedPoint userdata and a stringBuffer userdata
argument.
Now I can also write this directly as:
MyFunction((1.6) : fixedPoint, ("I SAID I CAN SHOUT!") : stringBuffer)
But that's again not very nice, what I really want to write is:
MyFunction(1.6 : fixedPoint, "I SAID I CAN SHOUT!" : stringBuffer)
This might be just my personal opinion, but I think this is a very clean
and readable way to define custom (userdata) types on the fly if they
are needed.
I am well aware that I can also write:
MyFunction(fixedPoint(1.6), stringBuffer("I SAID I CAN SHOUT!"))
I just don't like that so much, maybe it's just the brackets all over
the place that I dislike.
Anyway, with the first step already done I am now trying to handle the
"hello":function and 1.6:function to work.
I am not sure how much I want to allow. Especially in this case:
print( lower "I'm getting loud with you !" : upper)
What should happen? Synstax error, print "I'M GETTING LOUD WITH YOU!",
or "i'm getting loud with you!"?
Currently I think in this case, syntax error is the right thing, as it
is not obvious in which order "lower" and "upper" are called.
It may be interesting to actually make the colon operator of higher
order than the string call, that would allow one to write:
print "%e, %E" : format(math.pi, math.pi)
But I think this would take things too far.
If anyone has some more ideas or inputs on this style of syntax, I am
open to listen and maybe I will be able to include it into my patch.
So far I am not even sure if I will be able to implement all changes I
thought up myself :-)
--
Thomas