lua-users home
lua-l archive

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


On Sun, Feb 19, 2012 at 3:14 AM, Miles Bader <miles@gnu.org> wrote:
> "llib" and "lualib" are wayyyyyyyyyyyyyyyyyyyyyyyyyy too generic.
> I think only the real Lua team has the moral authority to get away with
> using names like that.

Very true; the name is not important, anyway.

If nothing else, tostring = ml.tstring gives a person a nicer
interactive experience with default table dumping.

I had some fun with 'mlx' where the X stands for
'Extension/Experiment/Evil'. The extension part is a List class
(although perhaps  a better word is Array, since the adjective I
associate with 'List' is 'linked'). A common enough refrain is that
tables do not have a default metatable, so we're forced to spell out
table.sort, table.concat etc.  List provides a suitable metatable for
table's array-like operations, plus the ml ones.

    > import(_G,"mlx")
    > words = List{'frodo','bilbo','sam'}
    > = words:sub(2)
    {"bilbo","sam"}
    > words:sort()
    > = words
    {"bilbo","frodo","sam"}
    > = words:concat ','
    "bilbo,frodo,sam"
    > = words:filter(string.match,'o$'):map(string.upper)
    {"BILBO","FRODO"}
    > l = List.range(10,50,10)
    > = l:indexof(30)
    3
    > = l:indexby {1,3,5}
    {10,30,50}

Personally I prefer method chaining (left-to-right) to functional
composition (right-to-left) with its implicit namespacing.

The experiment part is accessed with 'mlx.string_operators()' which
provides the standard binary operators like '+','*','[]' and some
synthetic ones like '{}' for table construction and '~' for
string.match.

    > = l:map('+',1)
    {11,21,31,41,51}
    > = l:map2('+',{1,2})
    {11,22}

The evil bit is giving all functions a metatable that provides
operators for functional expressions:

   debug.setmetatable(print,{__concat=ml.compose,__mul=ml.bind1,__div=ml.bind2})

(Again, not automatic, have to say 'mlx.function_operators()')

    > printf = io.write .. string.format
    > ewrite = io.stderr.write*io.stderr
    > zip = imap2 / '{}'
    > = zip(l,{'one','two','three'},{1,2,3})
    {{10,"one"},{20,"two"},{30,"three"}}
    > isspace = string.match/'^s*$'
    > = isspace '', isspace 'boo'
    ""      nil

Note how easy it is to build useful functions!  My favourite is

     triml = string.gsub/^%s+'/''

which is a very suggestive notation, at least for gsub.

However, at this point I realized I was mostly just entertaining
myself, and getting away from the Serious Business of defining a
little library ;)

Another candidate function which could be generally useful is sfilter,
which consumes and creates sequences generated by iterators.

    for x,y in sfilter(io.lines(),string.match,'(%a+)=(.+)') do ... end

steve d.