High-level vs low-level overrides / Multi-level overrides

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

High-level vs low-level overrides / Multi-level overrides

Soni "They/Them" L.
Lua 5.2 introduced __ipairs. It's a high-level ipairs() override, as it
overrides ipairs() itself.

Lua 5.3 removed __ipairs and instead added the low-level override
__index. It overrides the primitive (low-level) operations used by
ipairs(), instead of ipairs() itself.

Why can't we have both? I.e. try __ipairs first, if that fails use
__index, etc.

We could also get a __next metamethod and a rawnext() function. pairs()
would then first try __pairs, then try __next.

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: High-level vs low-level overrides / Multi-level overrides

Nagaev Boris
On Mon, Aug 1, 2016 at 8:50 PM, Soni L. <[hidden email]> wrote:

> Lua 5.2 introduced __ipairs. It's a high-level ipairs() override, as it
> overrides ipairs() itself.
>
> Lua 5.3 removed __ipairs and instead added the low-level override __index.
> It overrides the primitive (low-level) operations used by ipairs(), instead
> of ipairs() itself.
>
> Why can't we have both? I.e. try __ipairs first, if that fails use __index,
> etc.
>
> We could also get a __next metamethod and a rawnext() function. pairs()
> would then first try __pairs, then try __next.
>
> --
> Disclaimer: these emails may be made public at any given time, with or
> without reason. If you don't agree with this, DO NOT REPLY.
>
>

What is the motivation behind this proposal? I think the whole idea is
not ideal. It adds to complexity of the language.

PS. Given Lua had __pairs, ipairs (and __ipairs) would be unneeded. To
get current ipairs, one would set __pairs to current ipairs and invoke
pairs.

--


Best regards,
Boris Nagaev

Reply | Threaded
Open this post in threaded view
|

Re: High-level vs low-level overrides / Multi-level overrides

Soni "They/Them" L.


On 01/08/16 04:48 PM, Nagaev Boris wrote:

> On Mon, Aug 1, 2016 at 8:50 PM, Soni L. <[hidden email]> wrote:
>> Lua 5.2 introduced __ipairs. It's a high-level ipairs() override, as it
>> overrides ipairs() itself.
>>
>> Lua 5.3 removed __ipairs and instead added the low-level override __index.
>> It overrides the primitive (low-level) operations used by ipairs(), instead
>> of ipairs() itself.
>>
>> Why can't we have both? I.e. try __ipairs first, if that fails use __index,
>> etc.
>>
>> We could also get a __next metamethod and a rawnext() function. pairs()
>> would then first try __pairs, then try __next.
>>
>> --
>> Disclaimer: these emails may be made public at any given time, with or
>> without reason. If you don't agree with this, DO NOT REPLY.
>>
>>
> What is the motivation behind this proposal? I think the whole idea is
> not ideal. It adds to complexity of the language.

stdlib.

>
> PS. Given Lua had __pairs, ipairs (and __ipairs) would be unneeded. To
> get current ipairs, one would set __pairs to current ipairs and invoke
> pairs.
>

Yeah we don't need ipairs we could just do

local i = 1
local v = t[i]
while v ~= nil do
   i = i + 1
   v = t[i]
end

or

local function ipairs_aux(t, i)
   i = i + 1
   local v = t[i]
   if v then return i, v end
   return nil
end

function ipairs(t)
   return ipairs_aux, t, 1
end

However, we do have ipairs, so it'd be nice to have multi-level
overrides where it makes sense.

__next and __index is consistent.
__pairs and __ipairs is consistent.
__pairs and __index is not consistent.

Having the former 2 gives us the best of both worlds.

--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.


Reply | Threaded
Open this post in threaded view
|

Re: High-level vs low-level overrides / Multi-level overrides

Duane Leslie
> However, we do have ipairs, so it'd be nice to have multi-level overrides where it makes sense.
>
> __next and __index is consistent.
> __pairs and __ipairs is consistent.
> __pairs and __index is not consistent.
>
> Having the former 2 gives us the best of both worlds.

I raised this a month or two ago, and it was pointed out to me that in some cases the __next method may benefit from having a closure constructed when pairs is first called to assist in future processing, and this argument persuaded me.

Despite the similarity of their names and apparent function, the actual underlying behaviour of `pairs` and `ipairs` can be quite different in complexity.  I prefer to think of `ipairs` as syntactic sugar around a for loop, whereas `pairs` is actually building me a custom iterator closure which it returns as its first result.

Now that I think about it this way I am happy with the current arrangement.

While we're wish-listing, I'd rather that the `__eq` metamethod be observed regardless of the underlying type, and I'd rather that the `__le` metamethod devolve to `l == r or l < r` rather than to `not r < l` since the former works with partial orders whereas the latter requires total orders.  These and a `math.to_integer` rounding function based on C99 `lrintl()` are the only simple modifications I currently run Lua with (I have a more complex strict-upval modification but that changes the parser/compiler, not the runtime).
Reply | Threaded
Open this post in threaded view
|

Re: High-level vs low-level overrides / Multi-level overrides

Dirk Laurie-2
2016-08-02 4:37 GMT+02:00 Duane Leslie <[hidden email]>:

> `pairs` is actually building me a custom iterator closure which
> it returns as its first result.

It may feel like that but in fact `pairs` simply returns `next,tbl,nil.`
That is why you don't really need __next.  You can simply say

    for k,v in mynext,tbl do ... end

`io.lines` and `string.gmatch` do make custom closures. You can do
things like

> f = ("The quick brown fox jumps over the lazy dog"):gmatch"%S*"
> repeat word = f() until word=='over'
> for word in f do print(word) end
the
lazy
dog

You can't do that with "pairs".

Reply | Threaded
Open this post in threaded view
|

Re: High-level vs low-level overrides / Multi-level overrides

Duane Leslie


>> `pairs` is actually building me a custom iterator closure which
>> it returns as its first result.
>
> It may feel like that but in fact `pairs` simply returns `next,tbl,nil.`

I wasn't clear, I meant that I feel the purpose of `__pairs` is that it allows me to build a custom iterator.  I know that without a metamethod it just returns the `next` function.  Using the `__pairs` metamethod I can create exactly the examples you give.