···11+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
22+# yarn lockfile v1
33+44+55+ramda@^0.25.0:
66+ version "0.25.0"
77+ resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.25.0.tgz#8fdf68231cffa90bc2f9460390a0cb74a29b29a9"
88+99+sanctuary-def@0.14.0:
1010+ version "0.14.0"
1111+ resolved "https://registry.yarnpkg.com/sanctuary-def/-/sanctuary-def-0.14.0.tgz#cebbec591f5a9b211b34b4b942999d6534010fa8"
1212+ dependencies:
1313+ sanctuary-type-classes "7.1.x"
1414+ sanctuary-type-identifiers "2.0.x"
1515+1616+sanctuary-type-classes@7.1.1, sanctuary-type-classes@7.1.x:
1717+ version "7.1.1"
1818+ resolved "https://registry.yarnpkg.com/sanctuary-type-classes/-/sanctuary-type-classes-7.1.1.tgz#084bbd3168d72e60a059f6f78f5b7e391e68ffbb"
1919+ dependencies:
2020+ sanctuary-type-identifiers "1.0.x"
2121+2222+sanctuary-type-identifiers@1.0.x:
2323+ version "1.0.0"
2424+ resolved "https://registry.yarnpkg.com/sanctuary-type-identifiers/-/sanctuary-type-identifiers-1.0.0.tgz#e8f359f006cb5e624cfb8464603fc114608bde9f"
2525+2626+sanctuary-type-identifiers@2.0.1, sanctuary-type-identifiers@2.0.x:
2727+ version "2.0.1"
2828+ resolved "https://registry.yarnpkg.com/sanctuary-type-identifiers/-/sanctuary-type-identifiers-2.0.1.tgz#fc524cf6dd92cebfcbb0dd9509eff193159a20ed"
2929+3030+sanctuary@^0.14.1:
3131+ version "0.14.1"
3232+ resolved "https://registry.yarnpkg.com/sanctuary/-/sanctuary-0.14.1.tgz#3bf7613ec79ad28e5997b2901992e5992d3a047b"
3333+ dependencies:
3434+ sanctuary-def "0.14.0"
3535+ sanctuary-type-classes "7.1.1"
3636+ sanctuary-type-identifiers "2.0.1"
+84
talk01/01_first-class-functions.md
···11+Functions in JavaScript are declared this way:
22+33+```js
44+function fn(arg1, arg2, ...spread) {
55+ return value;
66+}
77+```
88+99+Functions can be stored in a variable/constant so they can also be declared this way:
1010+1111+```js
1212+const fn = function(arg1, arg2, ...spread) {
1313+ return value;
1414+};
1515+```
1616+1717+Or you can use arrow functions. This is nice and helps with JS context issues:
1818+1919+```js
2020+const fn = (arg1, arg2, ...spread) => value;
2121+```
2222+2323+Functions also have methods on them, because they're javascript objects!
2424+2525+```js
2626+const fn = function(arg) {
2727+ return [this, arg];
2828+};
2929+const fnBounded = fn.bind("a", "hey");
3030+console.log(fnBounded());
3131+```
3232+3333+We can even extend the functionalities by extending `Function.prototype` but we won't do it right now
3434+3535+Because all the above, functions can be arguments as well (callbacks)
3636+3737+```js
3838+const apply = (fn, value) => fn(value);
3939+const result = apply(x => x + 1, 2);
4040+console.log({ result });
4141+4242+// You can pass functions without initiating them on the spot
4343+const increment = x => x + 1;
4444+const result2 = apply(increment, 2);
4545+console.log({ result2 });
4646+```
4747+4848+And you can even return a function from your function!
4949+5050+This is called "HoF" or "Higher order function":
5151+5252+> Higher order function: a function that receives or returns a function
5353+5454+```js
5555+const map = fn => array => array.map(fn);
5656+const incrementAll = map(x => x + 1);
5757+const result = incrementAll([1, 2, 3]);
5858+console.log(result);
5959+```
6060+6161+The `map` method that recieves the function and then the data, is called _currying_ or _partial application_. It is also
6262+called point-free, because after we make this function we can use `map` without using `.map`, and with the right
6363+modifications it can work on _any_ type (`NodeList`!)
6464+6565+There are libraries to use currying without headaches, like `Ramda`. `Ramda`'s `curry` function gets one argument - a
6666+function with some arity, and understands how many arguments left to provide to the given function on any invocation.
6767+6868+> ProTip: When using curried functions, we're most likely to take the data as the last argument.
6969+7070+```js
7171+const { curry } = require("ramda");
7272+const map = curry((fn, array) => array.map(fn));
7373+const result1 = map(x => x + 1, [1, 2, 3]);
7474+console.log({ result1 });
7575+7676+const incrementAll = map(x => x + 1);
7777+const result2 = incrementAll([1, 2, 3]);
7878+console.log({ result2 });
7979+```
8080+8181+For React developers, partial applications and higher order functions should sound very odd. `Redux` is doing it too.
8282+When using `redux`, you use the `connect` function, that has the signature `connect :: config -> Component ->
8383+ConnectedComponent` - gets a config, then a React component, and provides you a new component that may or may not use
8484+your original component.
+41
talk01/02_purity.md
···11+When we talk about "function purity", it means one thing and one thing only: Every time that we call the function with
22+the same arguments, the same result comes out. That means - no side effects. No DB calls, no exceptions, no mutations of
33+any kind outside the function scope.
44+55+```js
66+const pure = x => x + 1;
77+const pure = x => Promise.resolve(x);
88+const impure = x => db.getValueFor(x);
99+1010+const pure = xs => xs.map(x => x + 1);
1111+const pure = xs => {
1212+ const result = [];
1313+ xs.forEach(x => result.push(x + 1));
1414+ return results; // mutation but inside this scope
1515+};
1616+const impure = xs =>
1717+ xs.forEach(x => {
1818+ x.y += "hey"; // mutation!
1919+ });
2020+```
2121+2222+Think about `React.Component#render`. You can't make HTTP calls there, you can't do anything but to provide the
2323+components based on `this.state` and `this.props`. This is the restriction React's API have to maintain your DOM tree.
2424+Mutations are fine! _React itself does mutations and side effects_, but these should be VERY managed and well tested.
2525+2626+This is why I love 2 ways of making HTTP calls in React - HoCs and Render props:
2727+2828+```js
2929+const ComponentWithData = withFetch("https://app.keywee.co/...", MyComponent);
3030+3131+// or
3232+function render() {
3333+ return (
3434+ <Fetch url={url} onLoading={() => "Loading"} onError={(error, retry) => "Error!"}>
3535+ {value => JSON.stringify(value)}
3636+ </Fetch>
3737+ );
3838+}
3939+```
4040+4141+But this is for another talk.
+95
talk01/03_lenses.md
···11+# Lenses
22+33+Lenses are a pattern in functional programming to "see" the "world". Lenses can show you the world as it is, you can
44+focus on whatever you want to see, and you can manipulate everything.
55+66+Lenses have 3 methods: `view`, `over` and `set`.
77+88+```js
99+const user = {
1010+ name: "gal",
1111+ nickname: "schniz"
1212+};
1313+1414+const { lensProp, view, over, set } = require("ramda");
1515+const $name = lensProp("name");
1616+1717+const userName = view($name, user);
1818+console.log(userName);
1919+```
2020+2121+You can say that it isn't impressive. It's just like using `user.name`. But lenses give more than just that. They're
2222+composable.
2323+2424+```js
2525+const user = {
2626+ name: "gal",
2727+ nickname: "schniz",
2828+ hobby: {
2929+ name: "talking"
3030+ }
3131+};
3232+3333+const { lensProp, view, over, set, compose } = require("ramda");
3434+const $name = lensProp("name");
3535+const $hobby = lensProp("hobby");
3636+3737+const hobbyName = view(compose($hobby, $name), user);
3838+console.log(hobbyName);
3939+```
4040+4141+Still not impressive? yes, still like `user.hobby.name`. Let's see the most powerful thing about lenses.
4242+4343+```js
4444+const { lensProp, view, over, set, compose } = require("ramda");
4545+const $name = lensProp("name");
4646+const $hobby = lensProp("hobby");
4747+4848+const user = {
4949+ name: "gal",
5050+ nickname: "schniz",
5151+ hobby: {
5252+ name: "talking",
5353+ lovedSince: "forever"
5454+ }
5555+};
5656+5757+const userHagever = set($name, "hagever", user);
5858+const userDifferentHobby = set(compose($hobby, $name), "javascripting", user);
5959+console.log({ user, userHagever, userDifferentHobby });
6060+6161+// in plain javascript, using shallow copying, it would be like
6262+6363+const userDifferentHobbyJS = Object.assign({}, user, {
6464+ hobby: Object.assign({}, user.hobby, {
6565+ name: "javascripting"
6666+ })
6767+});
6868+6969+console.log({ userDifferentHobbyJS });
7070+```
7171+7272+Which one is better?
7373+7474+The last function I need to show you is `over`. Well, `over` is like `set`, but more flexible. You can implement `set` with `over`.
7575+`over` takes a function (instead of a new plain value) to apply on the old value - it is something between `view` and `set`.
7676+7777+```js
7878+const { lensProp, view, over, set, compose } = require("ramda");
7979+const $nickname = lensProp("name");
8080+8181+const user = {
8282+ name: "gal",
8383+ nickname: "schniz",
8484+};
8585+8686+const addHandleIfMissing = nickname => nickname.charAt(0) == '@' ? nickname : `@${nickname}`
8787+const userWithHandle = over($nickname, addHandleIfMissing, user)
8888+console.log({ user, userWithHandle });
8989+9090+// implementing set is easy -
9191+9292+const setWithOver = (lens, value, obj) => over(lens, () => value, obj)
9393+const userWithNewNick = setWithOver($nickname, 'new nick', user)
9494+console.log({ user, userWithNewNick })
9595+```