Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.javascript > #24448

ANN: Ramda, a new functional programming library

Newsgroups comp.lang.javascript
Date 2014-05-27 20:13 -0700
Message-ID <da2909bd-58cc-4183-8b3c-167039985491@googlegroups.com> (permalink)
Subject ANN: Ramda, a new functional programming library
From Scott Sauyet <scott.sauyet@gmail.com>

Show all headers | View raw


I've been away from this group a while, and probably will not be 
around for long this time, as I'm pretty buried in several projects 
that haven't left me much spare time.  But I wanted to announce my 
current project.  I'll check in regularly for a while to read responses.

I'm looking for feedback on a new functional programming library for 
Javascript that I've been developing with a friend.  This may seem 
very familiar to those who saw a similar request a year ago.  That was 
for a different library, which turned out to be more of academic 
interest.  This one was originally based on that project, eweda, but 
with a more practical bent.

The library is called "ramda", which is just a silly pun on "lambda".

My co-author has just published a brief introduction at

    <http://buzzdecafe.github.io/code/2014/05/16/introducing-ramda/>

The project is on Github, at 

    <https://github.com/CrossEye/ramda> 

and the library is (temporarily, at least) in a single source file: 

    <https://github.com/CrossEye/ramda/blob/master/ramda.js> 

You can install it for a Node.js project with

    npm install ramda

------------------------------ 

The API has a sizable overlap with Underscore [1] and LoDash [2].  But 
its motivations are closer to allong.es [3] or Lemonad [4] or 
Functional Javascript [5].  It's an attempt to do in Javascript 
something more akin to normal functional programming, as would be 
found in Haskell, ML, Scheme, or LISP. 

The library's functions are available as properties on the main 
object, `ramda`: 

    var square = function(x) {return x * x;}; 
    var nbrs = ramda.range(1, 5); // => [1, 2, 3, 4] 
    var squares = ramda.map(square, nbrs); // => [1, 4, 9, 16] 

But they can be attached to any object, including the global object 
via `ramda.installTo()`.  This will pollute the global namespace with 
a number of functions, but is one possible means of using the library. 
After that, you could just call 

    var squares2 = map(square, range(1, 5)); // => [1, 4, 9, 16] 

You might note something surprising here.  Even when it has the same 
functions as Underscore/LoDash, its parameter order often differs. 
This is intentional.  Underscore's API was built out of the native, 
OO- first functions on `Array.prototype` and other similar structures. 
Ramda's API, on the other hand is designed around composition and 
partial application (or currying.)  You can create new functions 
easily by not passing all the arguments to something like `map`: 

    var squareAll = map(square); 
    squareAll(range(1, 6)); // => [1, 4, 9, 16, 25] 

In all cases, functions that take one list as a parameter, have it as 
their last parameter.  And those that take one function as a parameter 
have it as their first one.  The API should be internally consistent, 
even if it's a bit different from other libraries. 

------------------------------ 

There is a fairly large set of tests (using Mocha), but they are by no 
means comprehensive, serving more as an API guide than as an 
exhaustive analysis of edge cases.  They are in the folder `tests`, 
and can be run in a modern browser at 

    <https://rawgit.com/CrossEye/ramda/master/test/index.html> 

The only documentation beyond the test suite is a Docco-annotated 
version of the source, available at 

    <https://rawgit.com/CrossEye/ramda/master/docs/ramda.html> 

------------------------------ 

The functions we include are mostly standard functional library list 
functions, ones like `map`, `foldl`, `foldr`, `filter`, `take`, 
`skip`, some object-based ones like `prop`and `func`, plain function 
manipulations like `compose`, `flip`, `memoize` and various partials, 
as well as a few arithmetic and logic functions.  There are over 100 
functions now, with some dozen aliases. (`reduce` is the same as 
`foldl`.)  

I'd love for experienced people to look at the functions and see what 
is missing, what is totally unnecessary, and what could use a better 
name or at least an alias.  In the latter category, I really would 
like to find a better name for `foldl1`, whose name was borrowed from 
Haskell.  It's the difference between a left fold with an explicit 
accumulator supplied: 

    var total = foldl(add, 0, range(1, 11)) // => 55 

and one where the first value of the (non-empty) list is taken as the 
accumulator: 

    var total2 = foldl1(add, range(1, 11)); // => 55 

With the automatic partial application of functions, there is no good 
way to allow for dynamic functions signatures, so I can't simply 
assume that `foldl` with two parameters means something different from 
`foldl` with one.  So a good name to replace `foldl1` would be very 
helpful.  Similarly, of course, for `foldr1`. 

------------------------------ 

We also have a few functions that we think are unique to Ramda.  Two 
examples are:

  - `when` is similar to functions in other libraries that accept an 
    object specification and return a predicate that can be used to 
    test additional objects.  Ramda's `when` takes more than just 
    individual values for specification, though; it can also take 
    functions:

        isTriangular = where({
          sides: 3,
          a: function(a, t) {return a < t.b + t.c;},
          b: function(b, t) {return b < t.a + t.c;},
          c: function(c, t) {return c < t.a + t.b;}
        });

        isTriangular({sides: 5}); //=> false
        isTriangular({sides: 3, a: 2, b: 1, c: 7}); //=> false
        isTriangular({sides: 3, a: 3, b: 4, c: 5}); //=> true

  - `useWith`.  We still haven't decided which of the two APIs 
    for this function we prefer, and for the moment are including     
    both.  This function combines a number of configuration functions 
    with a single gathering function and returns a new function.  When 
    the resulting function is called, the arguments are supplied, 
    respectively, to each of the configuration functions, and the 
    results of these functions are all passed to the gathering 
    function.  This allows us to define Codd's `project` (similar to 
    SQL `select`) for lists of objects with quite simple code:

        project = useWith(map, pickAll, identity); // OR (other API)
        project = use(map).over(pickAll, identity);

    This would get used like this:

        var kids = [
          {name: 'Abby', age: 7, hair: 'blond'},
          {name: 'Fred', age: 12, hair: 'brown'},
          {name: 'Rusty', age: 10, hair: 'brown'},
          {name: 'Alois', age: 15, disposition: 'surly'}
        ];
        filter(propEq("hair", "brown"), kids);
        //=> Fred and Rusty

------------------------------ 

The library has a facility for creating lazy infinite lists; we're in 
the process of pulling that out of the core and making it a separate 
extension.  In fact we want to have a bundle-building mechanism to 
allow you to create your own package, the way Modernizr and David 
Mark's MyLibrary (is that still around?) do.

But that infrastructure work has never really made it to the top of 
our list of priorities.  We've just picked up a volunteer to help with 
documentation, so soon the library might be better documented.

But we're still mostly focused on code.  And perhaps the biggest thing 
left is to implement some of the standard algebraic types, such as 
Functor, Applicative, Monoid, and Monad, as well as some standard 
objects implementing those, such as Maybe, Either, and IO.  This is 
well underway, and will probably be ready within weeks.

------------------------------ 

In any case, this is a very long post.  I'd love to hear any feedback 
you have to offer.  I'd especially love to hear suggestions about the 
API design. 

Thanks,

  -- Scott,

_____ 
[1] http://underscorejs.org/ 
[2] http://lodash.com/ 
[3] https://github.com/raganwald/allong.es 
[4] http://fogus.github.io/lemonad/ 
[5] http://osteele.com/posts/2007/07/functional-javascript 

Back to comp.lang.javascript | Previous | NextNext in thread | Find similar | Unroll thread


Thread

ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-27 20:13 -0700
  Re: ANN: Ramda, a new functional programming library John C <rescattered@gmail.com> - 2014-05-27 21:00 -0700
    Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-28 04:37 -0700
  Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-28 04:36 -0700
  Re: ANN: Ramda, a new functional programming library "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2014-05-28 08:49 -0700
    Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-28 15:59 -0700
      Re: ANN: Ramda, a new functional programming library "Michael Haufe (TNO)" <tno@thenewobjective.com> - 2014-05-28 16:15 -0700
        Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-28 17:05 -0700
          Re: ANN: Ramda, a new functional programming library Christoph Michael Becker <cmbecker69@arcor.de> - 2014-05-30 14:53 +0200
            Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-30 11:14 -0700
  Re: ANN: Ramda, a new functional programming library Dr J R Stockton <reply1400@merlyn.demon.co.uk.invalid> - 2014-05-29 19:40 +0100
    Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-29 17:55 -0700
      Re: ANN: Ramda, a new functional programming library Christoph Michael Becker <cmbecker69@arcor.de> - 2014-05-30 14:05 +0200
        Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-30 11:10 -0700
  Re: ANN: Ramda, a new functional programming library John C <rescattered@gmail.com> - 2014-05-30 06:25 -0700
    Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-30 11:23 -0700
      Re: ANN: Ramda, a new functional programming library John C <rescattered@gmail.com> - 2014-05-30 12:44 -0700
        Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-30 13:39 -0700
          Re: ANN: Ramda, a new functional programming library John C <rescattered@gmail.com> - 2014-05-30 19:17 -0700
            Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-05-31 09:52 -0700
              Re: ANN: Ramda, a new functional programming library Christoph Michael Becker <cmbecker69@arcor.de> - 2014-05-31 22:24 +0200
                Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-06-01 06:55 -0700
      Re: ANN: Ramda, a new functional programming library Christoph Michael Becker <cmbecker69@arcor.de> - 2014-05-31 21:00 +0200
        Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-06-01 06:54 -0700
  Re: ANN: Ramda, a new functional programming library Dr J R Stockton <reply1400@merlyn.demon.co.uk.invalid> - 2014-06-01 19:05 +0100
    Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-06-01 19:28 -0700
      Re: ANN: Ramda, a new functional programming library Dr J R Stockton <reply1400@merlyn.demon.co.uk.invalid> - 2014-06-03 22:01 +0100
        Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-06-03 19:15 -0700
          Re: ANN: Ramda, a new functional programming library Dr J R Stockton <reply1400@merlyn.demon.co.uk.invalid> - 2014-06-05 23:41 +0100
            Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2014-06-06 11:36 -0700
          Re: ANN: Ramda, a new functional programming library Dr J R Stockton <reply1400@merlyn.demon.co.uk.invalid> - 2014-06-07 23:13 +0100
  Re: ANN: Ramda, a new functional programming library billyroberts111@gmail.com - 2016-03-06 10:22 -0800
    Re: ANN: Ramda, a new functional programming library Scott Sauyet <scott.sauyet@gmail.com> - 2016-03-06 17:52 -0800
      Re: ANN: Ramda, a new functional programming library "Evertjan." <exxjxw.hannivoort@inter.nl.net> - 2016-03-07 10:50 +0100

csiph-web