A Lua utility-belt library for functional programming.
How can I get the sum of all integers between 1 and 100 ?
local sum = M.sum(M.range(100))
print(sum) -- 5050
Say I am looking for the length of the longest word in some array ?
local words = {'some','words','of','different','lengths'}
print(M.max(words, M.op.length)) -- 9 letters
What is the sum of all fibonacci numbers for n below or equal 25 ?
local function fib(n) return n < 2 and n or fib(n - 1) + fib(n - 2) end
local fibsum = M.sum(M.map(M.range(25), fib))
print(fibsum) -- 196417
Or let us do the same, object-oriented style with chaining :
local function fib(n) return n < 2 and n or fib(n - 1) + fib(n - 2) end
local fibsum = M.chain(M.range(25)):map(fib):sum():value()
print(fibsum) -- 196417
Or even shorter :
local fibsum = M(M.range(25)):map(fib):sum():value()
print(fibsum) -- 196417
Feel free to download and try it on your own!
git clone git://github.com/Yonaba/Moses.gitluarocks install moses
moonrocks install moses
local M = require "moses"Note: the full source moses.lua is quite heavy (~92 kiB, 3115 LOC). You can alternatively use the minified version (~35 kiB, 561 LOC).
Find a complete set of code examples in tutorial.md.
- Read it online.
- Jeremy Ashkenas, for the amazing Underscore.js
- Marcus Irven's and JT Archie's 1-to-1 ports that also inspired this
- Matthew Rocklin's Toolz from which I borrowed some ideas
- Steve Donovan's LDoc, used to generate the current HTML documentation.
- Mark Langen's LuaMinify, used to generate a minified version of this library.
Run spec tests from Lua using busted with the following command from the root folder:
busted
This work is under MIT-LICENSE
Copyright (c) 2012-2018 Roland Yonaba.
See LICENSE.
moses's People
Forkers
utkarshkukreti rscdev coolisthename007 jlsandell eitanr jjjesus sportsfeed frqnck jkallunki jaimedp etcdot luiseduardohdbackup inmost-light sandao lowks kul sarayut15511 oskarols b64a0cd5-972d-4e4d-bf03-7b9f44a5e94c clementfarabet antoniomoder takaaptech ignacio evandrolg rockt basiliscos lindianyin aliwangzai sue602 peter-mach vesnica clcarwin personalnadir gjtjx michaeltalyansky dewoller jakesnell cbodenmain elihugarret ryanspeng archenroot russellhaley antirek tst2005 puse caap elikosan melbourne2991 italomaia njligames nomadics ssor kungfoo gcliupeng jeblad exosite-archive prerna13149 murugancmi niorad agui888 hardking dibyendumajumdar cryptkicker turbo samuelbambu carlostg afcarl mrqqeat darkclainer yankunjing greabock quanning diegoalpizar martinklepsch gasmartin malinyuan iiviigames guitarmind hewenning raystudio9236 exositeericlai bogomazon rhaley-starfish yudixiaok zhukaixy loctstrider luningcowboy berkeleytrue lmagic200 malma tourahi lsilent lightsun szy0405 finitestategit jzsst zhu-rengong chinalee-lzh dseeni jiang1027moses's Issues
off-topic: doubt
how produce a minified version of script lua ?
Feature request: unpack()
The global unpack() was deprecated in Lua 5.3, and moved to the table module. Therefore, lots of Lua programs, including Moses, contain a line like this:
local unpack = table.unpack or unpackThis makes it useful to everyone. It'd be nice to not have such lines in my programs, and instead call Moses:
local x,y = moses.unpack(array)Please make moses available for 5.4
According to the luarock webisite, the latest moses library is only available for lua version < 5.4. When I try to install moses for lua 5.4, I got the version 1.6 by default, which is pretty old.
Version 2.1.0-1 of moses was uploaded 2 years ago. For lua >= 5.1, < 5.4
Is there any reason that Moses is not working for 5.4?
Error during installation
sudo luarocks install moses
Installing https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/moses-1.6.0-1.rockspec...
Using https://raw.githubusercontent.com/rocks-moonscript-org/moonrocks-mirror/master/moses-1.6.0-1.rockspec... switching to 'build' mode
Error: Directory Moses-Moses-1.0.0-1 not found inside archive Moses-1.6.0-1.tar.gz
Bug in Intersect, Questions about Difference and Union
Hi!
I'm playing with Penlight and Moses and came across some odd behaviour. I read in two tab separated files using the penlight data module and then run his data.select method that returns an iterator function to the list (script at the bottom).
First, I get an error when I run moses.intersection:
C:\Program Files (x86)\WinLua\Lua\5.3\bin\lua.exe: attempt to index a function value
stack traceback:
[C]: in for iterator 'for iterator'
.\moses.lua:1064: in function <.\moses.lua:1061>
(...tail calls...)
.\compare-projects.lua:33: in main chunk
[C]: in ?
Next I get different behaviour between diff and union. When I run moses.diff, I get back a function. but when I run union, I get back a table that contains a function. Not sure what to make of that?
Anyway, thanks for the great library that makes a someone with grade 11 math feel smart!
The data I am using is here: https://pastebin.com/FBuMcxZe and here https://pastebin.com/swZVC5YB
require('pl')
local m = require('moses')
utils.printf("%s\n","That feels better")
local lfw = data.read('lfw_modules.tab')
local lp = data.read('luaplus_modules.tab')
--intersection to get all matches
-- Union to get duplicate free list
-- difference -- gets the non matchs
local function write(filename, func)
local wt = {}
for i in func do
wt[#wt+1] = i
end
file.write(filename, pretty.write(wt))
end
local W1 = lfw:select('NAME')
local P1 = lp:select('NAME')
local diff = m.difference(W1,P1)
print(type(diff))
local union = m.union(W1,P1)
print(type(union))
print(pretty.write(union))
write('wp_diff.txt', m.difference(W1,P1)) --returns a function
file.write('wp_union.txt', pretty.write(union))
-- This blows up
--write('wp_intersect.txt', m.intersection(W1,P1))
Many functions not chainable because of f(i,k) 1st arg
In lodash/underscore, most functions are chainable because function callbacks are passed a value. That allows constructs such as this in JavaScript:
local positives = _.map({1,-2,3,-4}, math.abs)Such constructs don't work in Moses because some (but not all) functions are passed in index argument before a key argument. This is essential for efficient Lua, but undesirable when function chaining is desired. Here's what you currently have to do in Moses:
positives = moses.map({1,-2,3,-4}, function(i,v) return math.abs(v) end)And because of this, Moses has great function chaining functions like pipe() and compose() that it seems like I never have a chance to use.
Off the top of my head, one idea is to create a new method with an "i" suffix when a callback function will be passed an index before a key. Eg:
positives = moses.mapi({1,-2,3,-4}, function(i,v) return math.abs(v) end)
-- or
positives = moses.map({1,-2,3,-4}, math.abs) uid() alias refers to non-existent uniqueid()
uid() should be an alias for uniqueId(), not uniqueid().
moses = require 'moses'
print(moses.uniqueId())
0
print(moses.uniqueId())
1
print(moses.uniqueId())
2
print(moses.uid())
stdin:1: attempt to call field 'uid' (a nil value)Interview With Moses Author?
Hi Roland!
There is a new Lua forum called... luaforum.com (!) and we have created a section about LuaRocks. The idea is to get LuaRocks authors to write about their libraries. I have had a great deal of success with Moses at various times and wanted to invite you to do an "interview" that will be posted on the Forum?
The idea (at the moment) is to write some questions and you could fill in the answers (I'd be happy doing a skype interview instead if you were interested)? We would also do a mock project to show people how Moses is used. Moses is a little different because you have so much documentation, which makes the mock project a little less necessary. I none the less think it would be a great idea.
Thoughts?
Cheers,
Russ
powerset does not generate a power set
Despite its name, powerset does not actually create a power set. For example, the documentation states when given the set {1,2,3}, returns {{1},{2},{3},{1,2},{2,3},{1,2,3}} however the power set of {1,2,3} is actually {{},{1},{2},{3},{1,2},{1,3},{2,3},{1,2,3}}. Specifically {} and {1,3} are missing in this case.
Using moses without require
Hi there,
I was hoping you could instruct me how to use moses without require.
I would like to use it in a Redis script, so I have to concatenate my script and any additional scripts into a single file, without using additional statements. Also I'd like to use it in repl.it and there is no way to use require there.
TIA
Jan
working with matrix
Hi. I'm new on function programming-like.
moses works fine with array, i.e.
tbl = {id=1, value=12.23};
but with i can work
tbl = {
{id=1, value=12.23},
{id=2, value=32.33
[...]
};
i have to select? or how can process/find/sort using this data movel
sugesstion: add functions to de/serialize using files
Syntax and performance questions?
Hello. This seems great, it is very good to have same syntax as underscore.
- Is syntax different from https://lodash.com that everyone in javascript world is using now?
- Has anyone done performance tests against https://luafun.github.io?
Use of underscore ("_") and "M" from Lua Style Guide
The Lua coding standard designates the underscore (_) as the standard global variable to use in place of an unused variable. Moses uses it as the current-module variable, which is typically represented by a local variable M.
Recommendation:
- Replace
_withMin sources; then - replace
__with_in sources
Static analysis programs such as luacheck make use of the Lua Style Guide conventions.
bug or expected behavior --- _.findWhere x _.select
'the code explict all'
--- src code
-- http://www.gammon.com.au/files/smaug/lua/tprint.lua
-- https://github.com/Yonaba/Moses
_ = require('moses_min')
tprint = require('tprint')
local m = {
{id=1, v='value-1'},
{id=2, v='value-2'},
{id=3, v='value-3'},
{id=1, v='value-1-1'},
{id=1, v='value-1-1'}
};
id = 1;
-- returns the first
x = _.findWhere(m, {id=id} );
tprint(x)
-- return all
x = _.select(m, function(k, v)
return (v.id == id);
end);
tprint(x);
--- output
$ lua findWhere.lua
findWhere
"id"=1
"v"="value-1"
select
1 :
"id"=1
"v"="value-1"
2 :
"id"=1
"v"="value-1-1"
3 :
"id"=1
"v"="value-1-1"
Feature Request: takeWhile, dropWhile
While you're adding features, could you add these too (from Haskell):
takeWhile: alias to selectWhile
dropWhile: as the name suggests, drop elements of array till the condition is met
Very useful lib btw :)
Feature request: unzip
unzip() is the natural complement to zip().
sortBy API doc claims it sorts in-place, but it does not
The only way to capture the results of a sortBy() operation is through its return value.
_=require 'moses'
x={2,1,3}
_.sortBy(x, _.identity)
-- x is still {2,1,3}
x=_.sortBy(x, _.identity)
-- now x is {1,2,3}groupBy does not pass additional arguments
groupBy(t, iter, ...) is supposed to pass extra arguments to iter but it actually does not:
local __ = require "moses"
__.groupBy({"foo"}, function(i, s1, s2) return s1..s2 end, "bar")
Expected result: groupBy returns {["foobar"] = {"foo"}}
Actual result:
attempt to concatenate local 's2' (a nil value)
stack traceback:
testcase.lua:2: in function 'iter'
./moses.lua:470: in function 'f'
./moses.lua:82: in function 'each'
./moses.lua:469: in function <./moses.lua:466>
(...tail calls...)
testcase.lua:2: in main chunk
[C]: in ?
sample() fails when array contains middleclass classes
The sample(array, numSamples) function seems to be sensitive to datatypes allowed in the array argument, and fails to return any array elements when an array contains middleclass class instances.
Test using Busted:
local class = require 'middleclass'
local moses = require 'moses'
describe('moses sample()', function()
it('works when array contains Vector classes', function()
local DenseVector = class('DenseVector')
function DenseVector:initialize(data)
self.data = data
end
local vector1 = DenseVector:new({1,2,3})
local vector2 = DenseVector:new({4,5,6})
local sample = moses.sample({vector1, vector2}, 1)
assert.equal(1, #sample) -- <== fails because #sample is 0
assert.is_true(sample[1]:isInstanceOf(DenseVector)) -- <== never runs
end)
end)How does Moses compare to Lua Fun?
Apart from being more active, how does Moses compare to Lua Fun?
Creating moses debian package
Debian packaging is done. Waiting to be uploaded.
https://github.com/CDLuminate/debian-lua-moses
Moses is used by https://github.com/torch/nn
_.pick does not work as expected with false values
When calling _.pick with a table that has a property with a value of false, it does not include that key in the result.
For example:
_.pick({ saved = false }, "saved") -- returns empty table {}
range(1,1) returns empty array
I'm pretty sure that range(1,1) should return {1}.
Two small spelling mistakes in the tutorials
Two small spelling mistakes in the tutorials:
https://github.com/Yonaba/Moses/blob/master/doc/tutorial.md
pluck (t, property)
Fetches all values indxed with specific key in a table of objects.
indxed ->indexed
constant (value)
Creates a constant function. This function will constinuously yield the same output.
constinuously -> continuously
Cheers,
Russ
_.size behavior
Hi, this behavir is expected on: string and boolean values?
moses-size.lua
print( _VERSION );
print('no args', _.size(), 'nil', _.size(nil), 'false', _.size(false), 'true', _.size(true), 'string empty', _.size(''), '{}', _.size({}), '{{},{}}', _.size( { {}, {} }) );
lua moses-size.lua
Lua 5.1
no args 0 nil 0 false 1 true 1 string empty 1 {} 0 {{},{}} 2
reduce does not work with an array of booleans
reduce fails in the following case:
local b = _.reduce({true, false, true}, function (memo, v)
return memo and v
end)
print(b)
-- => trueFeature request: mapi()
I do miss a mapi() function, it would work like map() but use ipairs() instead of pairs().
Motivation: That are some tables that we are sure that they are just an array and ipairs is much faster on LuaJIT.
2.x is compatible with 1.x ?
Links in documentation not working correctly
Hi,
http://yonaba.github.io/Moses/doc/
From this page if you click on the Tutorial link on the left hand side you are taken to the tutorials page (http://yonaba.github.io/Moses/doc/manual/tutorial.md.html). The Section links in that page don't work. Then, if one goes back to the index on the left and click the moses module, the user gets a 404.
I tested this in both Chrome 69.0.3497.100 and in Edge 42.17134.1.0
Cheers,
Russ
M.compose()
I did some tests with M.compose() and a custom implementation:
function M.compose(...)
local fn = M.reverse {...}
local function exec(i, ...)
if i == #fn then return fn[i](...) end
return exec(i+1, fn[i](...))
end
return function(...) return exec(1, ...) end
end
maybe I'm doing something wrong but this custom function, which uses recursivity, is much faster than the original implementation. FYI, this function passes all the tests.
minor typo in documentation
There is an extra parentheses at the end of the map example
Should read:
_.map({1,2,3},
function(i,v)
return v+10
end)
-- => "{11,12,13}"
What is difference between include (t, value) and contains (t, value)
As title say, i have a bit confuse about two functions above in Table functions (https://github.com/Yonaba/Moses/blob/master/doc/tutorial.md) , are they equal?
Last is different to Rest
We found last recently changed, and it is not aliased to rest. Which version of underscore are you mapping it to? From what I see, Last by counting last n entries and rest is the starting index, so they are different.
By the way, we have been using your script to work in our project, thanks for the effort.
Don't treat io or os modules as mandatory (redis compatibility)
Amalgamated Lua scripts that inline Moses are unable to be loaded by Redis, due to its lack of support for the optional io and os modules, combined with its strict validator which ensures no Lua code is referencing a global that was not implicitly assigned.
Here's an example of a typical error message:
$ redis-cli --eval SparkPi-with-dependencies.lua
(error) ERR Error running script (call to f_9ee542b8c203fc67d9dd0f620ee442e5ea6ecd9e): @user_script:36: user_script:36: attempt to index upvalue 'os' (a nil value)
Lines in Moses like this:
local clock = os.clockMight need to change to something like this:
local clock = os and os.clock or nilFeature request: findWhere(t, f)
Extend findWhere to accept a function as it's second argument instead of a table.
For example, find the first even number in a table:
t = {1, 2, 3}
result = __.findWhere(t, function(value)
return value % 2 == 0
end)
print(result) --> 2_.all is implemented as a array function , but in the tutorial.md , it is in the group of table functions .
the original code is :
function .all(t, f, ...)
return ((#.select(_.map(t,f,...), isTrue)) == (#t))
end
may be
function .all(t, f, ...)
return ((#.select(_.map(t,f,...), isTrue)) == count(t) )
end
is right?
behavior : _.isNumber() _.isInteger()
values with [ "" ], i.e., '0', '1.1', ... are not valid
sugest:
_maybe a flag can 'help' with this .isNumber( value, [true] ) can force a number/integer convert/cast.
$ cat test.moses.isnumber.lua
_ = dofile('moses.lua')
tbl = { 1, 1.99, .99, -1, 0, '', '0', '1', '1.1', '-1', false, nil }
_.eachi( tbl, function(i, v) print( i, tostring(v), _.isNumber(v), _.isInteger(v) ) end)
--- output
1 1 true true
2 1.99 true false
3 0.99 true false
4 -1 true true
5 0 true true
6 false false
7 0 false false
8 1 false false
9 1.1 false false
10 -1 false false
11 false false false
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
OpenClaw
Personal AI Assistant
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
