lua-users home
lua-l archive

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


Hi,

--[[Feature suggestion:  drop the "equal type" rule for order operators.
Rationale:  I want to be able to implement arithmetic types that extend Lua
numbers.]]

I will not dig too deep into the "order operator" issue (I wrote some time
ago that I still do not have an "optimal" Lua solution), but just make some
comments.

First of all, I'm not in favor of an "equal __lt method" rule.  If you allow
different __lt methods then you can implement many sensible operators by
double dispatching (pass control to second operand if the first one cannot
handle comparison.)  Secondly, such a rule would more or less call for
implied coercion, which is difficult in a dynamically typed language, to say
the least.

> Now, 'a' and 'b' have different metatables. But that should be
> ok because they have the same __lt metamethod, right? Wrong!
> Every time compare_by_id runs, it returns a different "closure".

Yes, you're right.  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:

do
    local key_lt_table = {}

    local function make_key_lt(key)
        local lt = key_lt_table[key]
        if not lt then
            lt = function(a, b) return a[key] < b[key] end
            key_lt_table[key] = lt
        end
        return lt
    end

    function compare_by_named_key(key, self)
        local lt = make_key_lt(key)
        local meta = getmetatable(self)
        if meta then
            meta.__lt = lt
        else
            setmetatable(self, {__lt = lt}
        end
    end
end

So, if you know there is an "equal __lt rule" then it is not much trouble to
make your code "compatible."

> It is clear from a syntactic analysis of the code in Snippet 2
> that 'key' is a constant, but Lua does not (currently) do this
> analysis.
[... snip snip ...]
> Furthermore, Code Snippet 2 is (at least theoretically) better
> because it makes it clear that the comparison key is fixed.

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.)

Bye,
Wim