[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Syntax lollipops
- From: Dirk Laurie <dirk.laurie@...>
- Date: Thu, 28 Feb 2013 09:14:00 +0200
A lollipop is a kind of sugar that is specially designed to suck.
C++ is full of it. Python is full of it. Ruby is full of it. Perl has
nothing but. Even C cannot be excused (you_agree? great : get_stuffed).
Lua does not have much.
- `table.name` for `table["name"]` is not a lollipop: it is compact
as well as intuitive.
- `object:method(x,y)` for `object.method(object,x,y)` is not
a lollipop when used as a function call: it allows chained
invocation avoiding short-lived local variables.
But there are two kinds of sugar I find myself using less and less.
When I do (usually while debugging), I kick myself.
Both deal with function definition.
Object-oriented definition
--------------------------
You think it looks like the call. So it does, but it hides too much.
function prototype:func(x,y)
-- self, self, self, self, ...
end
This is only convenient if you write objects that have only one instance
(in which case why bother?) Otherwise you don't want the methods in
the object among the instance-dependent fields; they should go into
a method table accessed via the `__index` metamethod, which normally
is not a function but simply the method table itself.
`object:func(x,y)` is invariably used to mean `object["func"](object,x,y),
never `rawget(object)(object,x,y)`. The latter is what you are going to
get, though, if you forget
getmetatable(object).__newindex={}
before unwrapping the lollipop. In which case you must not forget
getmetatable(object).__index = getmetatable(object).__newindex
getmetatable(object).__newindex=nil
when you're done, otherwise all the fields of the object will also
go into the method table.
Much more readable is to make the method table explicit.
object_method={}
object_method.func(object,x,y) = ...
None of this self, self, self (which even Python does not inflict
on you, even if most Python programmers do it regardless). You can,
earlier or later, even just in time, decide whether your
object-oriented style requires your methods in the metatable
itself or in its `__index`.
Any function definition with 'function' before the name
-------------------------------------------------------
How many characters do you save?
local function func(x,y)
local func=function(x,y)
Zero. That's right, nada, nichts, rien, zilch.
So why push the name 'func' even further from the left margin?
Moreover, you may need a forward definition occasionally.
local func, another_func
another_func = function
-- that refers to 'func'
end
func=function(x,y)
-- which refers to 'another_func'
end
In which case the lollipop is available for `another_func` but
not for `func`. Why submit to such asymmetry?
Recognize these lollipops for what they are: atavistic remnants
of some non-Lua language that crept into the design at a stage
when it seemed like a good idea. Recognize them, but don't use them.
Your programs will read better and require less debugging.