An open API service indexing awesome lists of open source software.

https://github.com/brainrake/fuc

Functional Utilities for Coffeescript and Javascript
https://github.com/brainrake/fuc

Last synced: 8 months ago
JSON representation

Functional Utilities for Coffeescript and Javascript

Awesome Lists containing this project

README

          

Functional Utilities for Coffeescript and Javascript
----------------------------------------------------

`Underscore`/`lodash` too much but never enough?

So you have `async` for breaking all your `Promise`s?

Fuc it all!

```bash
> npm install fuc
```

```coffeescript
require('fuc')._it_all() # fuc the global namespace, fuc prototypes

1 + __ 2 # logs 2, returns 3

unite {a: 1}, {b: 2} # => {a: 1, b: 2}

do thus {a: 1}, -> this.a + 1 # => 2

[1, 2, 4]._fap (it) ->
if it%2 then null else it-2 # => [0, 2]
```

Also, fuc the browser (TODO)

```bash
> bower install fuc
```

```html

Fuc._it_all()
```

If you think that looks dangerous, you can fuc less but stay safe:

```coffeescript
{__, fap, thus, unite} = require 'fuc'
```

Srsly? Why?
-----------

Yes. `lodash` is nice, but functions aren't curried, and some are sorely missing (like `flip`).

So, here's a bundle of functions, in all its 22-line glory, that most of the time obviates the need to include helper libraries, for me at least.

I'll add some `async` helpers as well, I `promise`!

Documentation
-------------

Use [the source](fuc.coffee)!

Also see some [examples](test.coffee).

```coffeescript
curry : (Function) -> Function
function._curry :()-> Function
# takes a function with two or more arguments, returns a function that can
# be called either with two or more arguments (same as the original),
# or with one argument, in which case it returns a function that awaits
# the second argument and possibly more - ultimate flexibility

isO : (value) -> Boolean
value._isO :()-> Boolean
# returns true if value is not a primitive

pp : (value) -> String
value._pp :()-> String
# toString primitives; JSON.stringify and indent objects

__ : (arg [, args...]) -> arg
arg.__ : ([args...]) -> arg
# console.log all arguments, return the first one; uses pp

___ : (prefix, arg [, args...]) -> arg
arg.___ : (prefix [, args...]) -> arg
# console.log prefix and all args, return first arg (after prefix); uses pp

flip : (Function(a, b [, c...])) -> Function(b, a [, c...])
function(a, b [, c...])._flip :()-> Function(b, a [, c...])
# takes a function with two or more arguments, returns it with the first two
# arguments flipped, and curried

flap : (arg, Function [, args...]) -> result
obj._flap : (Function [, args...]) -> result
# applies the function to the argument(s); `flip apply`

dnib : (this_object, Function) -> Function
this_object._dnib : (Function) -> Function
# bind the `this` object in the function body; flipped `Function.bind`

unite : (Object1, Object2 [, Objects...]) -> Object
object1._unite : (Object2 [, Objects...]) -> Object
# create a new object with properties merged from all the arguments

maf : (Function, Array) -> Array
array._maf : (Function) -> Array
# map, then filter out undefineds and nulls (but not `false`s, `0`s or ''s)

zop : (Array) -> Object
array._zop :()-> Object
# create an object from a list of pairs of [key, value]
```

All functions with two or more arguments can be used in a curried fashion: If you call them with only one argument, they will return a function awaiting the other argument (and any optional arguments).

Prototypes of built-in objects like `Object` and `Array` are only extended if you call `Fuc._it_all()`, and the new methods always start with an underscore to avoid name clashes.

Motivating Examples
-------------------

### `__`

I'm not saying we're stuck with `console.log` debugging in javascript. But it's the easiest, and yields the most results for the effort.
Inspecting runtime values is much more important than in static languages: where proper languages throw errors, Javascript does something stupid and moves on like nothing happened. So you need to trace expressions' values to see what's going on. You could do that by setting breakpoints and watches, but that stops program execution and you need to muck about in Developer Tools. It's not so straightforward in `node.js`.

Logging could be more convenient though. When you want to log a subexpression, you have to copy it, since console.log doesn't return anything. Also, it's kind of boring to type it all the time. Well, that's fixed now, just insert `__` wherever, and add parens as needed.

```coffeescript
Array(16).join(__ 'here'-1) + 'Fapman' # logs 'NaN'
```

To log extra information, use `___`

```coffeescript
fs.readFile (___ 'reading') 'file.txt' # logs 'reading file.txt'
```

I used to include the definition for `__` at the top of every single Coffeescript/Javascript source file I wrote, plus usually a few of the other functions here. Now I don't have to.

### `unite`

Lodash and jQuery have `extend`. It's why I include lodash most of the time (along with zipObject). But it mutates the argument. Bleah.

### `flap`

So you want to write the argument first, and then the function you to call with it. Coffeescript has `do` which calls the function immediately after it, and passes the arguments with the same name as the function arguments.

Sometimes you need more though.

### `fap`

Filter map. or `f(x) for x in arr when f(x) not in [null, undefined]`.

License
-------

This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, for any purpose, commercial or non-commercial.