lua-users home
lua-l archive

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


> It is reasonably easy though to "remember" all __lt
> methods thusfar created and simply reuse them when possible.  This
applies
> to all your examples.  The "key-comparison" could become something like
the
> following:

This is true. I often use memoisers, and I think I put something on the
Wiki about how easy they are to use, as well.

However, as is the case in general with memoisers using this simple
mechanism, it only works with one argument. That is occasionally a bit of a
limitation.

Anyway, that is no different from an element-by-element comparison of a
closure, and the latter would be more general and faster. Unfortunately, it
depends on syntactic analysis to distinguish constant and mutable closed
variables.

In theory, at least, closures where all the closed variables are actually
constants could be handled the same way as strings: hashed into a
system-wide hash table and then made unique. This is similar to
hash-consing, an idea which has not been demonstrated to be successful in
other languages, but which might have an application here. The advantage of
doing this, as with character strings, is that the resulting objects work
correctly as table indexes (i.e. equal objects are the same key.)

-- by the way, I erred last night in saying that you can still assume that
upvalues in c-closures are immutable. They are not; the api now allows a
c-function to change its upvalues. So implementing the above check on
c-closures would not be possible without an api change.

> Upvalues (v5) only take one extra pointer indirection compared to
constant
> values.  So performance-wise, upvalues are fairly cheap.  (But maybe you
> only mean semantically "better" here.)

Exactly what I meant. (But upvalues (v5) are significantly slower to create
than upvalues (v4) so there is a performance hit, too. I think that the
vast majority of upvalues are immutable, so this is maybe worth looking
at.)

-- Final comment:

I am neutral on the issue of "type" equality checking for __lt but adamant
for __eq: I do not want objects floating around which can defeat __eq and I
think that calling raweq is ugly. (And on a theoretical level, I think that
the operator used for table key comparison should be a language primitive.)

As I have said before, if __eq is generalised enough to allow an object to
hijack it, it should have its own operator and == should go back to being
strict object identity (whatever that might mean in the context of the
above discussion on closure equality.) Object identity and object
"equality" are two different things, and recognising that is important.

In the end, almost all languages end up with two different "==" operators.
(Scheme ended up, bizarrely, with three.) It is, unfortunately, complicated
for both programmers and non-programmers, but I don't think that avoiding
the issue makes it any simpler. I accept that a polymorphic == is easier
for most people to get their heads around and that object identity is a
"more advanced" concept; but "raweq(a,b)" just doesn't do it for me. I like
"is" as in:

if a is nil then ...

I think that captures the idea of what object identity means.

I will put a concrete proposal on the Wiki.

R.