lua-users home
lua-l archive

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


Edgar Toernig escribió:

> IMHO, one should remove as much checks for functions as possible and
> simply assume that one _can_ call the objects.  I.e. in the luaV_gettable
> case, the check "if (ttype(tm) == LUA_TFUNCTION)" should better be
> "if (ttype(tm) != LUA_TTABLE)".

But a table could also have a call method. I continue to think that
overloading the tag methods presents subtle ambiguities.

As an alternative to just assuming that the object could be called, one
could try calling the object with a variety of call that returns a fail
code if the object is not callable; only then would one try an alternative
(if one were convinced that trying an alternative is useful.)

I ran into this same ambiguity, in reverse, with the "extended next" patch:
I wanted to allow the possibility of using generator functions as an
alternative to objects with iterator methods. The right way of doing that
probably would have been to define a next TM for the function type, but I
didn't do that, so I was left with trying for the next method and then
trying to call the object. While that works, it results in an ambiguity if
an object has both a next TM and a call TM. It's not a real ambiguity: the
documentation (almost non-existent, I admit) could specify the order, but I
have the feeling after using the patch for a while that it leads to subtle
bugs, and that it would have been better to make the TM lookup unambiguous
and define functions to have a next TM. The consequence would be that if
you wanted a callable object to also act like a generator function, you
would have to give it a next TM, but in doing so you might notice that the
object already had a next TM and come up with some alternative.

I think this is analogous to the problem -- if it is a problem -- with
gettable and friends.

The implementation of a fast identity function could also provide a
solution to the syntactic ambiguity in Lua 4.1, although some might find it
odd. Nonetheless, replacing an expression with identity(expression) is
obviously a semantic no-op, and it would avoid the problem of:
  (exp)(exp)  (exp)[exp]
being a legitimate function call / table lookup; they could be written as
  identity(exp)(exp)     identity(exp)[exp]
In 4.0, I do this by defining an identity function called Do, because that
seems readable to me, although it does obviously slow things down a bit. (I
usually go for readability over speed.)

R.

> Btw, same thing i.e. in luaD_precall.  Why does the call tag method has
> to be a function?  Or foreach, sort, gsub, ...?

Yes, I agree with that, too.