[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Microlight
- From: Andres Perera <andres.p@...>
- Date: Thu, 20 Dec 2012 19:13:15 -0430
On Thu, Dec 20, 2012 at 5:42 PM, Jay Carlson <nop@nop.com> wrote:
> On Dec 20, 2012, at 11:02 AM, Philipp Janda wrote:
>
>> And collect/icollect ([1], slightly altered) are actually surprisingly interesting:
>>
>> icollect( {}, 1, pairs( t ) ) --> keys( t )
>> icollect( {}, 2, pairs( t ) ) --> values( t )
>> icollect( {}, 2, ipairs( t ) ) --> shallow_arraycopy( t )
>> icollect( {}, 1, io.lines( fname ) ) --> my @lines = <FILE>;
>> icollect( t1, 2, ipairs( t2 ) ) --> append( t1, t2 )
>>
>> collect( {}, 1, 2, pairs( t ) ) --> shallow_tablecopy( t )
>> collect( {}, 1, 2, ipairs( t ) ) --> shallow_arraycopy( t )
>> collect( {}, 2, 1, ipairs( t ) ) --> invert( t ), makeset( t )
>> collect( t1, 1, 2, pairs( t2 ) ) --> extend( t1, t2 )
>
> I really like this, but I hate numbers. Consider a function swap():
>
> swap(1, 2)
> -> return 2, 1
> swap(1, 2, 3)
> -> return 2, 1, 3
> swap(1, nil)
> -> return nil, 1
>
> -- I'm ultra-paranoid. Would you ever want this to work?
> swap(1)
> -> error()
>
> I thought it was a shame you can't write a no-memory iterator that applies swap() to another iterator's stepping. (You can't because the "next step" function is only called with *first* value it previously returned.) It'd look like a function swap()ing its arguments and its return values.
>
> Perhaps a wrapper calling "swap" per step could be called swaps()--it fits with pairs() and ipairs().
>
> That way those examples could become
>
> icollect({}, pairs( t ) ) -> keys(t)
> icollect({}, swaps( pairs( t ) )) -> values(t)
>
> collect({}, swaps( ipairs( t ) )) -> invert/Set(t)
>
> As a technical matter it would be easy to change the generic-for implementation to pass in two values, and of course we can do whatever we want with collect and icollect.
>
> But after having gone through all that, icollect_2nd() and collect_2nd() would be even easier. swaps() seems like it has very limited utility in the generic-for.
>
> icollect_n and collect_n are a really nice general case.
>
> ...but after all that theory I'm reluctantly walking back to "but would I actually use that with that name". I could write something like table.values(t) but probably just admire icollect_2nd({}, pairs(t)) from afar.
>
> inject_into({}, t) and invert_into({}, t) (whatever their names) are the big ones for me.
>
it's asking for a general rev() function
(collect '() (rev list))
it has plenty uses in lua
for example, instead of the less orthogonal prev() as the converse of next():
for k,v = next(rev(l)) do ...
another one, this time `l' is reversed because it represents each
digit of a bcd number and the implementation happened to store them in
least significant order:
function bcd2str(n) return table.concat(rev(n)) end
rev() can be implemented in terms of swap(), but now we are getting
too Forthy. that concept would hinder, e.g., rev() as a meta method
that spans lists and strings
there could be a (rev! l) that alters in place!