Repository: rtsisyk/luafun Branch: master Commit: 12837884993a Files: 52 Total size: 132.2 KB Directory structure: gitextract_diaikeab/ ├── .gitignore ├── .travis.yml ├── CONTRIBUTING.md ├── COPYING.md ├── HACKING.md ├── README.md ├── debian/ │ ├── .gitignore │ ├── changelog │ ├── compat │ ├── control │ ├── copyright │ ├── lua-fun.docs │ ├── lua5.1.dh-lua.conf │ ├── patches/ │ │ └── series │ ├── rules │ ├── source/ │ │ └── format │ └── watch ├── doc/ │ ├── .gitignore │ ├── Makefile │ ├── _static/ │ │ └── .keep │ ├── _templates/ │ │ └── layout.html │ ├── about.rst │ ├── basic.rst │ ├── compositions.rst │ ├── conf.py │ ├── filtering.rst │ ├── generators.rst │ ├── getting_started.rst │ ├── index.rst │ ├── indexing.rst │ ├── intro.rst │ ├── operators.rst │ ├── reducing.rst │ ├── reference.rst │ ├── slicing.rst │ ├── transformations.rst │ └── under_the_hood.rst ├── fun-scm-1.rockspec ├── fun.lua ├── rpm/ │ └── lua-fun.spec └── tests/ ├── .gitignore ├── basic.lua ├── compositions.lua ├── filtering.lua ├── generators.lua ├── indexing.lua ├── operators.lua ├── reducing.lua ├── runtest ├── slicing.lua ├── stateful.lua └── transformations.lua ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ *~ temp/ fun.lua.c 5.?-fun/ ================================================ FILE: .travis.yml ================================================ sudo: false language: C services: - docker env: global: - PRODUCT=lua-fun matrix: - OS=el DIST=7 - OS=fedora DIST=24 - OS=fedora DIST=25 - OS=ubuntu DIST=xenial - OS=ubuntu DIST=yakkety - OS=debian DIST=stretch before_deploy: - git clone https://github.com/packpack/packpack.git packpack - ./packpack/packpack deploy: provider: packagecloud username: ${PACKAGECLOUD_USER} repository: ${PACKAGECLOUD_REPO} token: ${PACKAGECLOUD_TOKEN} dist: ${OS}/${DIST} package_glob: build/*.{deb,rpm} skip_cleanup: true on: branch: master condition: -n "${OS}" && -n "${DIST}" && -n "${PACKAGECLOUD_TOKEN}" after_deploy: # Prune old packages from PackageCloud, keep only the last two - pip install -r ./packpack/tools/requirements.txt - python ./packpack/tools/packagecloud prune ${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO} deb ${OS} ${DIST} --keep 2 - python ./packpack/tools/packagecloud prune ${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO} rpm ${OS} ${DIST} --keep 2 cache: directories: - $HOME/lua-5.3.2 addons: apt: packages: - lua5.1 - lua5.2 - luajit # Ubuntu Precise on Travis doesn't have lua5.3 package install: - | [ -e ${HOME}/lua-5.3.2/src/lua ] || (\ wget http://www.lua.org/ftp/lua-5.3.2.tar.gz -c && \ tar xzf lua-5.3.2.tar.gz -C ${HOME} && \ make -j -C ${HOME}/lua-5.3.2 linux \ ) script: - cd tests - LUAJIT=`echo /usr/bin/luajit* | cut -f 1 -d ' '` - ${LUAJIT} -v - ${LUAJIT} runtest *.lua - lua5.1 -v - lua5.1 runtest *.lua - lua5.2 -v - lua5.2 runtest *.lua - LUA53=${HOME}/lua-5.3.2/src/lua - ${LUA53} -v - ${LUA53} runtest *.lua - cd .. notifications: email: true ================================================ FILE: CONTRIBUTING.md ================================================ Contributing ============ We'd love for you to contribute to the project and make **Lua Fun** even better than it is today! Filling Issues --------------- Please file bugs reports and feature requests using [GitHub Issues]. [GitHub Issues]: https://github.com/luafun/luafun/issues Making Changes -------------- If you want to contribute code, please fork the project on [GitHub], make changes in branch and send a pull request. [GitHub]: https://github.com/luafun/luafun ================================================ FILE: COPYING.md ================================================ Copying ======= **Lua Fun** source codes, logo and documentation are distributed under the **[MIT/X11 License]** - same as Lua and LuaJIT. Copyright (c) 2013-2017 Roman Tsisyk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. [MIT/X11 License]: http://www.opensource.org/licenses/mit-license.php ================================================ FILE: HACKING.md ================================================ # Hacking ## Build documentation Build and open in a Web browser: ```sh $ cd doc $ make html $ xdg-open _build/html/index.html ``` It works with Sphinx 4.3.0 and likely will work with newer versions. ================================================ FILE: README.md ================================================ Lua Functional ============== **Lua Fun** is a high-performance functional programming library for [Lua] designed with [LuaJIT's trace compiler][LuaJIT] in mind. Lua Fun provides a set of more than 50 programming primitives typically found in languages like Standard ML, Haskell, Erlang, JavaScript, Python and even Lisp. High-order functions such as ``map``, ``filter``, ``reduce``, ``zip``, etc., make it easy to **write simple and efficient functional code**. Let's see an example: ```lua > -- Functional style > require "fun" () > -- calculate sum(x for x^2 in 1..n) > n = 100 > print(reduce(operator.add, 0, map(function(x) return x^2 end, range(n)))) 328350 > -- Object-oriented style > local fun = require "fun" > -- calculate sum(x for x^2 in 1..n) > print(fun.range(n):map(function(x) return x^2 end):reduce(operator.add, 0)) 328350 ``` **Lua Fun** takes full advantage of the innovative **tracing JIT compiler** to achieve transcendental performance on nested functional expressions. Functional compositions and high-order functions can be translated into **efficient machine code**. Can you believe it? Just try to run the example above with ``luajit -jdump`` and see what happens: ```asm -- skip some initialization code -- ->LOOP: 0bcaffd0 movaps xmm5, xmm7 0bcaffd3 movaps xmm7, xmm1 0bcaffd6 addsd xmm7, xmm5 0bcaffda ucomisd xmm7, xmm0 0bcaffde jnb 0x0bca0024 ->5 0bcaffe4 movaps xmm5, xmm7 0bcaffe7 mulsd xmm5, xmm5 0bcaffeb addsd xmm6, xmm5 0bcaffef jmp 0x0bcaffd0 ->LOOP ---- TRACE 1 stop -> loop ``` The functional chain above was translated by LuaJIT to (!) **one machine loop** containing just 10 CPU assembly instructions without CALL. Unbelievable! Readable? Efficient? Can your Python/Ruby/V8 do better? Status ------ **Lua Fun** is in an early alpha stage. The library fully [documented][Documentation] and covered with unit tests. [![Build Status](https://travis-ci.org/luafun/luafun.png)][Travis] LuaJIT 2.1 alpha is recommended. The library designed in mind of fact that [LuaJIT traces tail-, up- and down-recursion][LuaJIT-Recursion] and has a lot of [byte code optimizations][LuaJIT-Optimizations]. Lua 5.1-5.3 are also supported. This is **master** (development) branch. API may be changed without any special notice. Please use **stable** branch for your production deployments. If you still want to use **master**, please don't forget to grep `git log` for *Incompatible API changes* message. Thanks! Please check out [documentation][Documentation] for more information. Misc ---- **Lua Fun** is distributed under the [MIT/X11 License] - (same as Lua and LuaJIT). The library was written to use with [Tarantool] - an efficient in-memory store and an asynchronous Lua application server. See Also -------- * [Documentation] * [RockSpec] * [RPM/DEB packages](https://packagecloud.io/rtsisyk/master) * [Hacking] * lua-l@lists.lua.org * luajit@freelists.org * roman@tsisyk.com [Lua]: https://www.lua.org/ [LuaJIT]: https://luajit.org/luajit.html [LuaJIT-Recursion]: http://lambda-the-ultimate.org/node/3851#comment-57679 [LuaJIT-Optimizations]: http://wiki.luajit.org/Optimizations [MIT/X11 License]: https://opensource.org/licenses/MIT [Tarantool]: https://github.com/tarantool/tarantool [Getting Started]: https://luafun.github.io/getting_started.html [Documentation]: https://luafun.github.io/ [Travis]: https://travis-ci.org/luafun/luafun [RockSpec]: https://raw.github.com/luafun/luafun/master/fun-scm-1.rockspec [Hacking]: HACKING.md Please **"Star"** the project on GitHub to help it to survive! Thanks! ***** **Lua Fun**. Simple, Efficient and Functional. In Lua. With JIT. ================================================ FILE: debian/.gitignore ================================================ lua-fun/ tmp/ trash files lua_versions *.install *.substvars *.log ================================================ FILE: debian/changelog ================================================ lua-fun (0.1.3-1) unstable; urgency=medium * Initial release. (Closes: #811482) -- Roman Tsisyk Mon, 18 Jan 2016 10:00:00 +0300 ================================================ FILE: debian/compat ================================================ 9 ================================================ FILE: debian/control ================================================ Source: lua-fun Section: interpreters Priority: optional Maintainer: Roman Tsisyk Build-Depends: debhelper (>= 9), dh-lua (>= 19) Standards-Version: 3.9.6 Homepage: https://github.com/luafun/luafun Vcs-Git: git://github.com/luafun/luafun.git Vcs-Browser: https://github.com/luafun/luafun Package: lua-fun Architecture: all Depends: ${misc:Depends} Provides: ${lua:Provides} XB-Lua-Versions: ${lua:Versions} Description: High-performance functional programming library for Lua Lua Fun provides a set of more than 50 programming primitives typically found in languages like Standard ML, Haskell, Erlang, JavaScript, Python and even Lisp. High-order functions such as map, filter, reduce, zip, etc., make it easy to write simple and efficient functional code. ================================================ FILE: debian/copyright ================================================ Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: luafun Upstream-Contact: Roman Tsisyk Source: https://github.com/luafun/luafun Files: * Copyright: 2013-2017 Roman Tsisyk Comment: In the Lua community this license is better known as "MIT". Unfortunately other variants of this license are also known as "MIT". To obtain a machine interpretable copyright file Debian prefers to name this version of the MIT license using the non ambiguous term "Expat". License: Expat Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: . The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. . THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: debian/lua-fun.docs ================================================ README.md ================================================ FILE: debian/lua5.1.dh-lua.conf ================================================ PKG_NAME=fun LUA_MODNAME=fun LUA_SOURCES=fun.lua LUA_TEST=tests/runtest tests/*.lua ================================================ FILE: debian/patches/series ================================================ ================================================ FILE: debian/rules ================================================ #!/usr/bin/make -f VERSION := $(shell dpkg-parsechangelog|grep ^Version|awk '{print $$2}') UVERSION := $(shell echo $(VERSION)|sed 's/-[[:digit:]]\+$$//') %: dh $@ --buildsystem=lua --with lua tarball: clean tar --exclude=.git --exclude=debian --exclude rpm \ --transform='s,^\.,luafun-$(UVERSION),S' \ -czf ../luafun-$(UVERSION).orig.tar.gz . ================================================ FILE: debian/source/format ================================================ 3.0 (quilt) ================================================ FILE: debian/watch ================================================ # test this watch file using: # uscan --watchfile debian/watch --upstream-version 0.0.1 --package lua-fun # https://wiki.debian.org/debian/watch#GitHub version=3 opts=filenamemangle=s/.+\/v?(\d\S*)\.tar\.gz/luafun-$1\.tar\.gz/ \ https://github.com/luafun/luafun/tags .*/v?(\d\S*)\.tar\.gz ================================================ FILE: doc/.gitignore ================================================ _build ================================================ FILE: doc/Makefile ================================================ # Minimal makefile for Sphinx documentation # # You can set these variables from the command line, and also # from the environment for the first two. SPHINXOPTS ?= SPHINXBUILD ?= sphinx-build SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) ================================================ FILE: doc/_static/.keep ================================================ ================================================ FILE: doc/_templates/layout.html ================================================ {% extends "!layout.html" %} {% block footer %} {{ super() }} {% endblock %} ================================================ FILE: doc/about.rst ================================================ About ===== Credits ------- An initial prototype was designed and enginered in one evening by Roman Tsisyk. After that the library was completely rewritten, tested and documented (which took a while). The project exists only thanks to the excellent tracing just-in-time compiler in `LuaJIT `_. The library works best with `Tarantool `_ -- an efficient in-memory database and Lua application server. Copying ------- Lua Fun source codes, logo and documentation are distributed under the `MIT License (MIT) `_ -- same as LuaJIT. Copyright (c) 2013-2017 Roman Tsisyk Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: doc/basic.rst ================================================ Basic Functions =============== .. currentmodule:: fun The section contains functions to create iterators from Lua objects. .. function:: iter(array) iter(map) iter(string) iter(gen, param, state) :returns: ``gen, param, state`` -- :ref:`iterator triplet ` Make ``gen, param, state`` iterator from the iterable object. The function is a generalized version of :func:`pairs` and :func:`ipairs`. The function distinguish between arrays and maps using ``#arg == 0`` check to detect maps. For arrays ``ipairs`` is used. For maps a modified version of ``pairs`` is used that also returns keys. Userdata objects are handled in the same way as tables. If ``LUAJIT_ENABLE_LUA52COMPAT`` [#luajit_lua52compat]_ mode is enabled and argument has metamethods ``__pairs`` (for maps) or ``__ipairs`` for (arrays), call it with the table or userdata as argument and return the first three results from the call [#lua52_ipairs]_. All library iterator are suitable to use with Lua's ``for .. in`` loop. .. code-block:: lua > for _it, a in iter({1, 2, 3}) do print(a) end 1 2 3 > for _it, k, v in iter({ a = 1, b = 2, c = 3}) do print(k, v) end b 2 a 1 c 3 > for _it, a in iter("abcde") do print(a) end a b c d e The first cycle variable *_it* is needed to store an internal state of the iterator. The value must be always ignored in loops: .. code-block:: lua for _it, a, b in iter({ a = 1, b = 2, c = 3}) do print(a, b) end -- _it is some internal iterator state - always ignore it -- a, b are values return from the iterator Simple iterators like ``iter({1, 2, 3})`` have simple states, whereas other iterators like :func:`zip` or :func:`chain` have complicated internal states which values senseless for the end user. Check out :doc:`under_the_hood` section for more details. There is also the possibility to supply custom iterators to the function: .. code-block:: lua > local function mypairs_gen(max, state) if (state >= max) then return nil end return state + 1, state + 1 end > local function mypairs(max) return mypairs_gen, max, 0 end > for _it, a in iter(mypairs(10)) do print(a) end 1 2 3 4 5 6 7 8 9 10 Iterators can return multiple values. Check out :doc:`under_the_hood` section for more details. .. [#luajit_lua52compat] http://luajit.org/extensions.html .. [#lua52_ipairs] http://www.lua.org/manual/5.2/manual.html#pdf-ipairs .. function:: each(fun, gen, param, state) iterator:each(fun) :returns: none Execute the *fun* for each iteration value. The function is equivalent to the code below: .. code-block:: lua for _it, ... in iter(gen, param, state) do fun(...) end Examples: .. code-block:: lua > each(print, { a = 1, b = 2, c = 3}) b 2 a 1 c 3 > each(print, {1, 2, 3}) 1 2 3 The function is used for its side effects. Implementation directly applies *fun* to all iteration values without returning a new iterator, in contrast to functions like :func:`map`. .. seealso:: :func:`map`, :func:`reduce` .. function:: for_each(fun, gen, param, state) iterator:for_each(fun) An alias for :func:`each`. .. function:: foreach(fun, gen, param, state) iterator:foreach(fun) An alias for :func:`each`. ================================================ FILE: doc/compositions.rst ================================================ Compositions ============ .. currentmodule:: fun .. function:: zip(...) iterator1:zip(iterator2, iterator3, ...) :param ...: iterators to "zip" :type ...: iterator :returns: an iterator Return a new iterator where i-th return value contains the i-th element from each of the iterators. The returned iterator is truncated in length to the length of the shortest iterator. For multi-return iterators only the first variable is used. Examples: .. code-block:: lua > dump(zip({"a", "b", "c", "d"}, {"one", "two", "three"})) a one b two c three > each(print, zip()) > each(print, zip(range(5), {'a', 'b', 'c'}, rands())) 1 a 0.57514179487402 2 b 0.79693061238668 3 c 0.45174307459403 > each(print, zip(partition(function(x) return x > 7 end, range(1, 15, 1)))) 8 1 9 2 10 3 11 4 12 5 13 6 14 7 .. function:: cycle(gen, param, state) iterator:cycle() :returns: a cycled version of ``{gen, param, state}`` iterator Make a new iterator that returns elements from ``{gen, param, state}`` iterator until the end and then "restart" iteration using a saved clone of ``{gen, param, state}``. The returned iterator is constant space and no return values are buffered. Instead of that the function make a clone of the source ``{gen, param, state}`` iterator. Therefore, the source iterator must be pure functional to make an identical clone. Infinity iterators are supported, but are not recommended. .. note:: ``{gen, param, state}`` must be pure functional to work properly with the function. Examples: .. code-block:: lua > each(print, take(15, cycle(range(5)))) 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 > each(print, take(15, cycle(zip(range(5), {"a", "b", "c", "d", "e"})))) 1 a 2 b 3 c 4 d 5 e 1 a 2 b 3 c 4 d 5 e 1 a 2 b 3 c 4 d 5 e .. function:: chain(...) iterator1:chain(iterator2, iterator3, ...) :param ...: iterators to chain :type ...: iterator :returns: a consecutive iterator from sources (left from right) Make an iterator that returns elements from the first iterator until it is exhausted, then proceeds to the next iterator, until all of the iterators are exhausted. Used for treating consecutive iterators as a single iterator. Infinity iterators are supported, but are not recommended. Examples: .. code-block:: lua > each(print, chain(range(2), {"a", "b", "c"}, {"one", "two", "three"})) 1 2 a b c one two three > each(print, take(15, cycle(chain(enumerate({"a", "b", "c"}), {"one", "two", "three"})))) 1 a 2 b 3 c one two three 1 a 2 b 3 c one two three 1 a 2 b 3 c ================================================ FILE: doc/conf.py ================================================ # Configuration file for the Sphinx documentation builder. # # This file only contains a selection of the most common options. For a full # list see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html # -- Path setup -------------------------------------------------------------- # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) # -- Project information ----------------------------------------------------- project = 'Lua Functional' copyright = '2013-2021, Roman Tsisyk' author = 'Roman Tsisyk' # The short X.Y version version = '0.1' # The full version, including alpha/beta/rc tags release = '0.1.3' # -- General configuration --------------------------------------------------- # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [ ] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = 'en' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # -- Options for HTML output ------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'haiku' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # The name of an image file (relative to this directory) to place at the top # of the sidebar. html_logo = 'logo.png' # If true, the reST sources are included in the HTML build as _sources/name. # The default is True. html_copy_source = False ================================================ FILE: doc/filtering.rst ================================================ Filtering ========= .. currentmodule:: fun This section contains functions to filter values during iteration. .. function:: filter(predicate, gen, param, state) iterator:filter(predicate) :param param: an predicate to filter the iterator :type param: (function(...) -> bool) Return a new iterator of those elements that satisfy the **predicate**. Examples: .. code-block:: lua > each(print, filter(function(x) return x % 3 == 0 end, range(10))) 3 6 9 > each(print, take(5, filter(function(i, x) return i % 3 == 0 end, enumerate(duplicate('x'))))) 3 x 6 x 9 x 12 x 15 x .. note:: Multireturn iterators are supported but can cause performance regressions. .. seealso:: :func:`take_while` and :func:`drop_while`. .. function:: remove_if(predicate, gen, param, state) iterator:remove_if(predicate) An alias for :func:`filter`. .. function:: grep(regexp_or_predicate, gen, param, state) iterator:grep(regexp_or_predicate) If **regexp_or_predicate** is string then the parameter is used as a regular expression to build filtering predicate. Otherwise the function is just an alias for :func:`filter`. Equivalent to: .. code-block:: lua local fun = regexp_or_predicate if type(regexp_or_predicate) == "string" then fun = function(x) return string.find(x, regexp_or_predicate) ~= nil end end return filter(fun, gen, param, state) Examples: .. code-block:: lua lines_to_grep = { [[Emily]], [[Chloe]], [[Megan]], [[Jessica]], [[Emma]], [[Sarah]], [[Elizabeth]], [[Sophie]], [[Olivia]], [[Lauren]] } each(print, grep("^Em", lines_to_grep)) --[[test Emily Emma --test]] each(print, grep("^P", lines_to_grep)) --[[test --test]] > each(print, grep(function(x) return x % 3 == 0 end, range(10))) 3 6 9 .. function:: partition(predicate, gen, param, state) iterator:partition(predicate) :param x: a value to find :returns: {gen1, param1, state1}, {gen2, param2, state2} The function returns two iterators where elements do and do not satisfy the prediucate. Equivalent to: .. code-block:: lua return filter(predicate, gen', param', state'), filter(function(...) return not predicate(...) end, gen, param, state); The function make a clone of the source iterator. Iterators especially returned in tables to work with :func:`zip` and other functions. Examples: .. code-block:: lua > each(print, zip(partition(function(i, x) return i % 3 == 0 end, range(10)))) 3 1 6 2 9 4 .. note:: ``gen, param, state`` must be pure functional to work properly with the function. .. seealso:: :func:`span` ================================================ FILE: doc/generators.rst ================================================ Generators ========== .. currentmodule:: fun This section contains a number of useful generators modeled after Standard ML, Haskell, Python, Ruby, JavaScript and other languages. Finite Generators ----------------- .. function:: range([start,] stop[, step]) :param start: an endpoint of the interval (see below) :type start: number :param stop: an endpoint of the interval (see below) :type stop: number :param step: a step :type step: number :returns: an iterator The iterator to create arithmetic progressions. Iteration values are generated within closed interval ``[start, stop]`` (i.e. *stop* is included). If the *start* argument is omitted, it defaults to ``1`` (*stop* > 0) or to ``-1`` (*stop* < 0). If the *step* argument is omitted, it defaults to ``1`` (*start* <= *stop*) or to ``-1`` (*start* > *stop*). If *step* is positive, the last element is the largest ``start + i * step`` less than or equal to *stop*; if *step* is negative, the last element is the smallest ``start + i * step`` greater than or equal to *stop*. *step* must not be zero (or else an error is raised). ``range(0)`` returns empty iterator. Examples: .. code-block:: lua > for _it, v in range(5) do print(v) end 1 2 3 4 5 > for _it, v in range(-5) do print(v) end -1 -2 -3 -4 -5 > for _it, v in range(1, 6) do print(v) end 1 2 3 4 5 6 > for _it, v in range(0, 20, 5) do print(v) end 0 5 10 15 20 > for _it, v in range(0, 10, 3) do print(v) end 0 3 6 9 > for _it, v in range(0, 1.5, 0.2) do print(v) end 0 0.2 0.4 0.6 0.8 1 1.2 1.4 > for _it, v in range(0) do print(v) end > for _it, v in range(1) do print(v) end 1 > for _it, v in range(1, 0) do print(v) end 1 0 > for _it, v in range(0, 10, 0) do print(v) end error: step must not be zero Infinity Generators ------------------- .. function:: duplicate(...) :param ...: objects to duplicate :type ...: non nil :returns: an iterator The iterator returns values over and over again indefinitely. All values that passed to the iterator are returned as-is during the iteration. Examples: .. code-block:: lua > each(print, take(3, duplicate('a', 'b', 'c'))) a b c a b c > each(print, take(3, duplicate('x'))) x x x > for _it, a, b, c, d, e in take(3, duplicate(1, 2, 'a', 3, 'b')) do print(a, b, c, d, e) >> end 1 2 a 3 b 1 2 a 3 b 1 2 a 3 b .. function:: xrepeat(...) An alias for :func:`duplicate`. .. function:: replicate(...) An alias for :func:`duplicate`. .. function:: tabulate(fun) :param fun: an unary generating function :type fun: function(n: uint) -> ... :returns: an iterator The iterator that returns ``fun(0)``, ``fun(1)``, ``fun(2)``, ``...`` values indefinitely. Examples: .. code-block:: lua > each(print, take(5, tabulate(function(x) return 'a', 'b', 2*x end))) a b 0 a b 2 a b 4 a b 6 a b 8 > each(print, take(5, tabulate(function(x) return x^2 end))) 0 1 4 9 16 .. function:: zeros() :returns: an iterator The iterator returns ``0`` indefinitely. Examples: .. code-block:: lua > each(print, take(5, zeros())) 0 0 0 0 0 .. function:: ones() :returns: an iterator The iterator that returns ``1`` indefinitely. Example:: > each(print, take(5, ones())) 1 1 1 1 1 Random sampling --------------- .. function:: rands([n[, m]]) :param n: an endpoint of the interval (see below) :type n: uint :param m: an endpoint of the interval (see below) :type m: uint :returns: an iterator The iterator returns random values using :func:`math.random`. If the **n** and **m** are set then the iterator returns pseudo-random integers in the ``[n, m)`` interval (i.e. **m** is not included). If the **m** is not set then the iterator generates pseudo-random integers in the ``[0, n)`` interval. When called without arguments returns pseudo-random real numbers with uniform distribution in the interval ``[0, 1)``. .. warning:: This iterator is not pure-functional and may not work as expected with some library functions. Examples: .. code-block:: lua > each(print, take(10, rands(10, 20))) 19 17 11 19 12 13 14 16 10 11 > each(print, take(5, rands(10))) 7 6 5 9 0 > each(print, take(5, rands())) 0.79420629243124 0.69885246563716 0.5901037417281 0.7532286166836 0.080971251199854 ================================================ FILE: doc/getting_started.rst ================================================ Getting Started =============== Please jump to `Using the Library`_ section if you are familiar with Lua and LuaJIT. .. contents:: Prerequisites ------------- The library is designed for LuaJIT_. **LuaJIT 2.1 alpha** is high^W **Highly** recommended for performance reasons. Lua 5.1--5.3 are also supported. The library is platform-independent and expected to work on all platforms that supported by Lua(JIT). It can be also used in any Lua(JIT) based applications, e.g. Tarantool_ or OpenResty_. You might need diff_ tool to run test system and sphinx_ to regenerate the documentation from source files. .. _LuaJIT: http://luajit.org/ .. _Tarantool: http://tarantool.org/ .. _OpenResty: http://openresty.org/ .. _diff: http://en.wikipedia.org/wiki/Diff .. _sphinx: http://sphinx-doc.org/ Installing LuaJIT ----------------- You can build LuaJIT from sources or install it from a binary archive. From Sources ```````````` 1. Clone LuaJIT git repository. Please note that **v2.1** branch is needed. You can always select this branch using ``git checkout v2.1``. .. code-block:: bash $ git clone http://luajit.org/git/luajit-2.0.git -b v2.1 luajit-2.1 Cloning into 'luajit-2.1'... 2. Compile LuaJIT .. code-block:: bash $ cd luajit-2.1/ luajit-2.1 $ make -j8 3. Install LuaJIT .. code-block:: bash luajit-2.1 $ make install luajit-2.1 $ ln -s /usr/local/bin/luajit-2.1.0-alpha /usr/local/bin/luajit Install operation might require root permissions. However, you can install LuaJIT into your home directory. From a Binary Archive ````````````````````` If operations above look too complicated for you, you always can download a binary archive from http://luajit.org/download.html page. Your favorite package manager may also have LuaJIT packages. Running LuaJIT `````````````` Ensure that freshly installed LuaJIT works: .. code-block:: bash $ luajit LuaJIT 2.1.0-alpha -- Copyright (C) 2005-2013 Mike Pall. http://luajit.org/ JIT: ON SSE2 SSE3 SSE4.1 fold cse dce fwd dse narrow loop abc sink fuse > = 2 + 2 4 It is good idea to use LuaJIT CLI under ``rlwrap`` (on nix platforms): .. code-block:: bash alias luajit="rlwrap luajit" $ luajit LuaJIT 2.1.0-alpha -- Copyright (C) 2005-2013 Mike Pall. http://luajit.org/ JIT: ON SSE2 SSE3 SSE4.1 fold cse dce fwd dse narrow loop abc sink fuse > = 2 + 2 4 > = 2 + 2