lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Lucas Ackerman said:

> The problem with this is that functions have object-like identity.
>
> a = function() end
> b = function() end
> print("a==b :" .. (a==b))	-- a==b : nil

That is true, although it is not insurmountable. Lua functions are
actually mutable objects -- you can call setfenv on them, for example, and
in the case of CFunctions, you can even lua_replace() an upvalue. So they
are not a perfect implementation of tuples. However, they are sufficiently
"function-like" that the core implementation would be trivial. If
necessary, for example, a flag could be added to the function header
information to prevent setfenv; the tuple CFunction would never call
lua_replace(), so that does not actually have to be tested for.

Lua 5.1 allows you to create a __eq metamethod for (all) functions; a
plausible implementation of this would return true if the two functions
were the same object or if they both had the "tuple" CFunction and the
same number of upvalues and the upvalues were equal. That won't capture
the use as table keys, but it would get the equality check right.
>
> Tuples are desirable as higher-order table indices, but need to be indexed
> by value, so they should be immutable and interned like strings!
>
> Interning should also benefit performance due to fewer intermediary table
> constructions.

Possibly, but I kind of doubt it. If most tuples have a very short
lifetime, the interning step requires an expensive hashing operation and
then a lookup in the intern table; I rather suspect this would double the
cost of creating a tuple in the common case. Allocation is not that
expensive.

However, it would need to be done if the tuples were to be usable as table
keys. You might want to have a look at this suggestion:
http://lua-users.org/lists/lua-l/2005-07/msg00016.html

>
> Garbage collection gets more hairy if you have tuples referencing tables,
> but "weak" or "mutable" tuples are a mess that solve nothing.  Weak tables
> already do this job.

I don't think mutable tuples are necessary. There was some discussion
earlier on the list about what a "weak tuple" might be, although I agree
that the semantics are complicated. However, it might be interesting to
implement ephemerons as a form of tuple.

> Tuples could replace the magic expression lists (return values and ...),
> and be implicitly unpacked in useful cases (unless .

I can't see any obvious way to "implictly" unpack a tuple; it is necessary
to distinguish between the tuple-as-an-object and the expansion of the
tuple. However, implementing tuples as functions allows a very simple
syntax for unpacking tuples:
   tup()  <-- returns the values of the tuple
   tup(k) <-- returns the values starting at k
This would be implemented implicitly by the tuple CFunction, and would be
quite efficient.

>
> I don't have any great syntax ideas.  <> are already used in operators,
> and [] in table indexing.  Maybe \{}.

There are several possibilities, but the easiest one is simply:

   tuple("a", 3, function(x) return x + 1 end)

No syntactic ambiguity is introduced by using [val, val, val] as a tuple
constructor provided that you do not allow parenthesis-free function calls
(that is, you would have to say func([2, 3]) rather than func[2, 3]). If
that seemed annoying, you could do what Python and other languages do, and
insist that a tuple constructor be either empty -- [] -- or contain at
least one comma, so that a singleton tuple would be written [2,] rather
than [2]; consequently a tuple constructor could not be confused with a
table index (and a[2,] would compile into a call of 'a' while a[2] would
compile into an index of 'a'). The most annoying part would be the use of
a tuple constructor inside an array constructor:

  t = {[[2,3,4]] = "foo"}  <-- oops, that was a string
  t = {[ [2,3,4] ] = "foo")  <-- verging on C++ template annoyances


>
> Implementation-wise, regular tables with added restrictions could do most
> of the work, and then you borrow interning hash-value from strings (made
> recursive for nested tuples).  Or to look at it another way, strings could
> be a special case of tuple.

I think "restricted tables" is not the way to go. But I don't really think
tuples will happen anyway :) I do agree that strings are effectively a
special case of tuples (as I said before); indeed, I can see the use of
another special case of tuples, where the values are constrained to be
Numbers; but the generalised implementation strikes me as more
interesting.

>
> Lastly, tuples could also solve help the issues of using tables as arrays
> (with holes), since they have fixed length (like strings).  This helps for
> loops too, since loop variables and table indices are already effectively
> unassignable during traversal, since assignment results in undefined
> behavior. Then "for k,v in u do ... end" could be reinstated for tuples.

Or you could just define pairs (or even ipairs) so that it worked with
tuples.