var localIp = _.chain(os.networkInterfaces())
.values()
.flatten()
.filter(_.partial(supportsProtocol, "IPv4"))
.map("address")
.first()
.value();
``` Program: output = f(input) ```
=> SIMPLICITY
⇧
costs = f exp(complexity)Terms:
In [7]:
var lodash = require('lodash');
var _ = require('lodash-fp');
Out[7]:
In [8]:
lodash.filter([1,2,3,4], function(num) { return _.gte(3, num); })
Out[8]:
In [9]:
_.filter( _.gte(3) )
( [1,2,3,4] )
Out[9]:
In [10]:
// Find obj with variations ∋ key "key1"
(lodash.flow(
_.partialRight(_.result, "variations") // -> {key1: "val1"}
, _.keys // -> [key1]
, _.partialRight(_.includes, "key1") // -> true
))
({variations: {key1: "val1"}})
Out[10]:
⇧
In [11]:
(_.flow(
_.result("variations"),
_.keys,
_.includes("key1")))
({variations: {key1: "val1"}})
Out[11]:
==: filter({age: _.partialRight(_.gt,18)}) // _.flow(_.result('age'),_.gt(18))forEach (_.map is cumbersome){fields: obj, ..} with objpartition-with, nested map (employees.children)[{width:12},{width:6},{width:6},.]lodash & lodash-fp (size?!).See github/jakubholynet/lodash-fp_issues/.../lodash-fp_issues.ipynb.
Due to auto-currying, lodash-fp cannot have vararg functions like lodash has. Some of the existing vararg fns are split into multiple (uniq => uniq + uniqBy) but not all and you thus lose access some functionality.
In my experience you need ot keep lodash for the cases where the func isn't available in lodash-fp. Not sure if including both increases the client-side size / how much.
Examples:
_.assign({}, {a:1}, {b:2}) is wrong - max 2_.result currently doesn't support a default valuezipObject([key, val, key2, val2, ..]) doesn't work, only zipObject(keys, vals)map(Values), find get only value, not the key argument_nofp.max([{n: 3},{n: 4}], \"n\") => { n: 4 }Immutable([1,2,3,4,5])
.skip(2)
.map(n => -n)
.filter(n => n % 2 === 0)
.take(2).reduce((r, n) => r * n, 1);
map.get("prop"))withMutationstoJS()Immutable([1,2,3]).concat([4]).map(double).filter(odd);
Object.freeze (deep); ES5 (IE9+)ImmutableError (push, =, etc.)
<> map, filter, concatflatMap, asObject, asMutable; O: merge, without, asMutableupdateIn(["employee" "salary"], (salary) => salary*1.05, employee). With just the available methods it is cumbersome and requires boilerplate code.i.* callsto/fromJS)updateIn etc.chain)|
You can make JavaScript fly...
|
But why not to use something *designed* for flying?
|
Why? Top-notch data functions and immutable data, core-async, macros, great design.
What about the bytes?
| JS: Nettbutikk | Cljs: Startshop |
|---|---|
| 300 kB | 300 kB |
| React, router, lodash,.. | Om, React, .. |
| No immutable, ... | Immutable, core-async, .. |
| (little own code) | (little own code) |
What about debugging? REPL! (And I live w/o debugger in JS anyway)
ClojureScript gives you
Size: Not really a problem. These two similar web apps, whose size is dominated by their libraries (including the large React), have the same size, even though one uses ClojureScript (and thus has things the other misses) - thanks to the very aggressive Google Closure compiler that can throw away all you actually don't use and the fact that Cljs is optimized for it.
Debugging: Clojure(Script) developers typically don't need it. Interactive, REPL-based development satisfies/prevents most of what debugging does otherwise.
Last: Developers are surprisingly capable of and quick to learn a new language. At least that is the experience of various teams that moved to Clojure.
Extra