[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] Penlight Lua Libraries
- From: David Manura <dm.lua@...>
- Date: Sat, 25 Apr 2009 15:23:32 -0400
On Sat, Apr 25, 2009 at 4:00 AM, steve donovan wrote:
> On Sat, Apr 25, 2009 at 9:17 AM, David Manura wrote:
>> for k in pl.list.iter(List(tablex.keys(t)):sort()) do
>> print(k,t[k])
>> end
>> That's a bit ugly.
That would be nicer if the API allowed method call chaining:
for k in List.keys(t):sort():iter() do
print(k,t[k])
end
That would follow a useful pattern of
(1) wrap a table into a list ... e.g. List(t) or List.keys(t)
(2) chain any number of list operations ....
e.g. :sort(f):map(g):filter(h)
(3) convert to a sequence to iterate over
(It would be preferable if this could be avoided as in Python,
defaulting to the type of iteration we usually want.
An __iter metamethod has been proposed:
http://lua-users.org/wiki/GeneralizedPairsAndIpairs )
>> If the sort didn't have to be in-place, we could chain the
>> transformations on a single line:
In-place v.s. non-in-place operations...Penlight currently departs
from its Python inspiration in that it provides additional List
methods like "map/filter" that are not in-place like its methods
"sort/reverse". This feels inconsistent/arbitrary. Python
not-in-place operations are separated out as standalone functions:
"sorted/map/filter".
However, consider the approach in Chapter 16 of Lua Programming Gems
used to implement a matrix type (p.180). All operations (even map)
are in-place, like Python list methods. However, there is an explicit
copy() method, and all operations return the object itself to allow
chaining.
-- two different uses
return a:copy():emwul(b):linfold()
return a:emwul(b):linfold()
This is flexible and avoids excessive temporary copies.
In fact, Penlight already does the copy when constructing a list from a table.
> Python makes the consequence of sequence
> more explicit, whereas it isn't really a native Lua concept. There is
> for instance both seq.reduce and tablex.reduce
Shouldn't there also be a List:reduce?
> whereas a smart reduce
> could work out from its arguments what operation was required.
Perhaps.
>> I'm not certain I like your argument order for functions though.
>
> Yes, I was being deliberately backwards. But if we are _mostly_ using
> prepackaged functions, then the argument is moot. The concern was that
> when using the traditional order, the actual
> table/sequence/list/whatever ends up at the end of a potentially long
> anonymous function definition.
>
> t1 = map(function(x)
> return x*(x-1)
> end,t1)
The problem I think is when we chain these operations together:
t1 = sort(map(filter(t1, f), g), h)
Now, "h" modifies the verb "sort", "g" modifies "map", and "f"
modifies "filter". These are farther apart and read less naturally
than if we had written
t1 = sort(h, map(g, filter(f, t1)))
We can also compose and curry them:
t1 = compose(curry(sort,h), curry(map,g), curry(filter,f))(t1)
On the other hand, the form map(t, f) is useful when map a method of
list, list:map(f), rather than a standalone function.