These are chat archives for ramda/ramda

11th
Mar 2015
Jethro Larson
@jethrolarson
Mar 11 2015 01:54
Why _curry1? What's that even do?
Jethro Larson
@jethrolarson
Mar 11 2015 01:59
R.not = (a)=> !a;
R.naught = (fn)=> (args...)=> fn(args...);
Do I go to hell?
David Chambers
@davidchambers
Mar 11 2015 02:01
_curry1 is necessary to ensure consistent handling of R.__.
R.identity(R.__)(R.__)(R.__)(R.__)(R.__)(R.__)(42);  // => 42
Jethro Larson
@jethrolarson
Mar 11 2015 02:02
So outside of the library I might never need to use it?
Scott Sauyet
@CrossEye
Mar 11 2015 02:41
I hope not!!
Hardy Jones
@joneshf
Mar 11 2015 05:21
how does that even work?
hmm, where are the docs for __?
David Chambers
@davidchambers
Mar 11 2015 06:30
ramda/ramda#835 :(
ramda/ramda#856
Ludwig Magnusson
@TheLudd
Mar 11 2015 10:53

Have a question about always. If passed an object, that object can later be mutated and if that is done always will return the mutated object when called afterwards.

var fooBar = { foo: 'bar' };
var afb = R.always(fooBar);
afb() // => { foo: 'bar' }
fooBar.foo = 'baz';
afb() // => { foo: 'baz' }

Is this intentional?

Scott Sauyet
@CrossEye
Mar 11 2015 11:16
@TheLudd: I don't think it was ever considered. It's an interesting point.
Ludwig Magnusson
@TheLudd
Mar 11 2015 11:23
What would you like the behavior to be?
Robin Lambertz
@roblabla
Mar 11 2015 11:27
pretty sure it should be the responsibility of the user to make sure object isn't mutated if he doesn't want it to be.
Scott Sauyet
@CrossEye
Mar 11 2015 11:27
I'd have to think about it a bit. I'm not sure I'd want a change from this, though. Leaving that behavior in the hands of the user might be best.
yes
Robin Lambertz
@roblabla
Mar 11 2015 11:28
mentioning it in the docs might be a good idea though, as to not surprise people ;)
Scott Sauyet
@CrossEye
Mar 11 2015 11:59
Absolutely. And even suggesting a combination with clone for those who want it.
Ludwig Magnusson
@TheLudd
Mar 11 2015 12:04
@roblabla Not always easy to guarantee in JS especially when working with 3rd party libs
but a new function could be added called const which would always return what it was given.
Martin Algesten
@algesten
Mar 11 2015 12:09
var const = function(a) { var _a = clone(a); return function() { return clone(_a) }};
something like this?
clone both in and out to guarantee it’s frozen?
Ludwig Magnusson
@TheLudd
Mar 11 2015 12:11
sounds like a little overkill. Why not just on entry?
Robin Lambertz
@roblabla
Mar 11 2015 12:17
@TheLudd var x = R.always({ obj: "hi"}); x().obj = "ohi"; x();
It does sound overkill but it's the only way I can see to make the function really immutable.
Ludwig Magnusson
@TheLudd
Mar 11 2015 12:25
I stand corrected
Martin Algesten
@algesten
Mar 11 2015 12:27
but then thinking about it, const is probably a really bad name given ES6. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
Ludwig Magnusson
@TheLudd
Mar 11 2015 12:29
constant?
Robin Lambertz
@roblabla
Mar 11 2015 12:30
Are ES6 const immutable ?
Ludwig Magnusson
@TheLudd
Mar 11 2015 12:31
Looking at our code at my company I realize we have been using always as if it did return the exact same thing we gave it. We are not mutating any objects so we haven't run into any trouble but I think I would prefer to have a constant function.
@roblabla I would guess not. In Java, setting something as final does not make it immutable. I think only the reference is constant.
Martin Algesten
@algesten
Mar 11 2015 12:32
yes. it’s like final. just the reference that can’t change.
Robin Lambertz
@roblabla
Mar 11 2015 12:32
Mkay
Danny Fritz
@dannyfritz
Mar 11 2015 14:23
If you clone the object, you will lose referential equality.
Martin Algesten
@algesten
Mar 11 2015 14:32
true that
Hardy Jones
@joneshf
Mar 11 2015 14:48
since when is referential equality a good thing?
Danny Arnold
@despairblue
Mar 11 2015 14:48
why is it a bad thing? oO
Danny Fritz
@dannyfritz
Mar 11 2015 14:51
referential equality is great if your objects are treated as immutable
Ludwig Magnusson
@TheLudd
Mar 11 2015 14:51
If you never mutate objects then in practice o1 === o2 is the same as eqDeep(o1, o2)
Hardy Jones
@joneshf
Mar 11 2015 14:54
referential equality breaks referential transparency
Danny Arnold
@despairblue
Mar 11 2015 14:54
@TheLudd given o1 === o2 I would assume eqDeep(o1, o2) === true even if I mutate it, right?
Martin Algesten
@algesten
Mar 11 2015 14:54
@TheLudd i strugge to see when that can be used. o1 = {}; o2 = {} will never be ===
Danny Arnold
@despairblue
Mar 11 2015 14:55
:D
Martin Algesten
@algesten
Mar 11 2015 14:55
at the most we can use === inside eqDeep to shortcut.
Danny Arnold
@despairblue
Mar 11 2015 14:59
@joneshf so you mean if I mutate an object I can't replace all of its occurrences with an object literal throughout my whole program anymore? I kind of struggle grasp what you're implying. Would you mind giving an example?
Hardy Jones
@joneshf
Mar 11 2015 15:01
@despairblue R.of(1) !== R.of(1) with ref eq.
so using ref eq makes functions not referentially transparent
Ludwig Magnusson
@TheLudd
Mar 11 2015 15:03
@algesten It is the recommended way in react for instance. If you never mutate your state objects then you can know that the state is unchanged by comparing oldState === possiblyNewState
and skip re-rendering if they are equal
Danny Arnold
@despairblue
Mar 11 2015 15:04
Ah, so your saying, one shouldn't use === for comparing complex data. Usually I use it to specifically check if 2 things are the same object, or the same immutable (false, true, a string)
Hardy Jones
@joneshf
Mar 11 2015 15:04
what do you define as a complex data type?
Danny Arnold
@despairblue
Mar 11 2015 15:05
object and array
Hardy Jones
@joneshf
Mar 11 2015 15:05
I don't see array any more complex than say natural numbers, but that's probably hair splitting ;)
I'm just saying that if referential equality is the equality being used (for ANY data type), then it breaks referential transparency.
Danny Arnold
@despairblue
Mar 11 2015 15:07
True, I see === as Is it pointing to the same structure in memory. As long as I use it for this I don't see the harm :)
Martin Algesten
@algesten
Mar 11 2015 15:51
@TheLudd sounds interesting, but is surely only useful in rather limited apps where the one instance of the app is the only one mutating the model. If you have any “shared” models, where say a group of users may alter some common data, you’d always need to do non-referential comparisons somewhere, server or client.
Martin Algesten
@algesten
Mar 11 2015 16:40

I have a bunch of these objects: {code:’FTMAT’, name:’…’} where the code is an identifier. I now want the group objects together on the first two letters in code, .i.e. all objects with FT. There are a few hundred of these in memory, and the user should be able to quickly turn groups off/on for viewing. To speed up viewing I need to preprocess the objects into lists.

I imagine what I want is {FT:[{obj1},{obj2}], TT:[…]} – but that may be my bad procedural habits. And even if that is where I’m aiming, can this be solved in an elegant functional way?

Ludwig Magnusson
@TheLudd
Mar 11 2015 17:12
R.groupBy(R.compose(R.substringTo(2), R.prop('code')))?
Martin Algesten
@algesten
Mar 11 2015 17:20
oooooo :clap:
Ludwig Magnusson
@TheLudd
Mar 11 2015 17:28
Thanks =)
Jethro Larson
@jethrolarson
Mar 11 2015 17:35
var foo = R.memoize(function(a){return { x: a}})
var x = foo(1)
x.x = 2
foo(1) //=> {x:2}
(╯°□°)╯︵ ┻━┻
Martin Algesten
@algesten
Mar 11 2015 17:38
another expected immutable? :)
Ludwig Magnusson
@TheLudd
Mar 11 2015 17:44
People seem happy about the transducers implementation in ramda. I have a question regarding that:
What is a transducer? :smile:
Jethro Larson
@jethrolarson
Mar 11 2015 17:46
Basically it's a generalization over reduce
John-David Dalton
@jdalton
Mar 11 2015 17:46
The word transduce is just a combination of transform and reduce. The reduce function is the base transformation; any other transformation can be expressed in terms of it (map, filter, etc).
Jethro Larson
@jethrolarson
Mar 11 2015 17:46
Yeah, I was just about to link that :)
Ludwig Magnusson
@TheLudd
Mar 11 2015 17:47
Thanks, I'll be readin
Jethro Larson
@jethrolarson
Mar 11 2015 17:49
If you like to learn by video I liked this one https://www.youtube.com/watch?v=6mTbuzafcII
Ludwig Magnusson
@TheLudd
Mar 11 2015 17:49
In my company I am known as the "video guy" :smiley:
John-David Dalton
@jdalton
Mar 11 2015 17:51
his hair is glorious
Scott Sauyet
@CrossEye
Mar 11 2015 17:53
I wouldn't start with the Rich Hickey stuff. Look at a few blog posts first. Then the videos will make a lot more sense. :smile:
Ludwig Magnusson
@TheLudd
Mar 11 2015 17:56
oh yea, almost Stephen Pinker worthy
So this video is neither simple nor easy?
Jethro Larson
@jethrolarson
Mar 11 2015 17:58
I think it's high level and easy to follow...
Though the examples are in clojure so I guess if you're completely unfamiliar with lisp it'll be harder
Ludwig Magnusson
@TheLudd
Mar 11 2015 18:03
ah
Scott Sauyet
@CrossEye
Mar 11 2015 18:03
The video is great. But for me, I learned a lot more from a few posts. Then when I watched the video again it made much more sense.
Ludwig Magnusson
@TheLudd
Mar 11 2015 18:03
Yes I believe so
Scott Sauyet
@CrossEye
Mar 11 2015 18:07
A quick gloss: often when we pipe one functional transformatuon of a data structure into another and then into a third and a fourth, we introduce a lot of overhead in creating intermediate structures. Transducers is a way of composing just the transformations so that we only create the final output data structure.
Graeme Yeates
@megawac
Mar 11 2015 18:53
does substring not support negative indexes :o
R.substring(0, -1, '123') or in my actual case R.substringTo(-3, 'foo.js')
Scott Sauyet
@CrossEye
Mar 11 2015 19:00
It doesn't. Although a PR would be welcome, it would have to be a brand new impl as the current one just delegates to String.prototype.
Graeme Yeates
@megawac
Mar 11 2015 19:03
hmm, @CrossEye you could just change the invoker to use slice isntead of substring
which supports negative indexes
and is otherwise idetnical
I feel thats a minimally breaking change
Scott Sauyet
@CrossEye
Mar 11 2015 19:05
Or you could just use R.slice. But that might be a good idea.
Graeme Yeates
@megawac
Mar 11 2015 19:06
oh is slice implemented via invoker? I thought I saw a pr that changed that
Scott Sauyet
@CrossEye
Mar 11 2015 19:08
There's a very different internal slice.
Might want to change the public one though. Thought I remembered discussions too. Don't know what happened though.
David Chambers
@davidchambers
Mar 11 2015 20:06
I've been thinking of composing another parable for the R.substring issue. It's silly that R.slice is better at taking slices of strings than the function specifically designed for strings. ;)
I'd like to remove R.substring, R.substringTo, and R.substringFrom and have R.slice, R.take, and R.drop support strings, but I know this will be controversial and will thus require a convincing parable. :)
Martin Algesten
@algesten
Mar 11 2015 20:15
functions working on multiple types? heathen! :D
Robin Lambertz
@roblabla
Mar 11 2015 20:16
I like it when my functions are polymorphic...
:<
Martin Algesten
@algesten
Mar 11 2015 20:18
@davidchambers what about R.takeWhile and R.dropWhile?
Kevin Wallace
@kedashoe
Mar 11 2015 20:18
won't R.take and R.drop support strings after transducers?
John-David Dalton
@jdalton
Mar 11 2015 21:34
There's String#slice too.
Jethro Larson
@jethrolarson
Mar 11 2015 21:38
Ramda doesn't treat strings as a list right now, so I don't think transducers will work on them without someone creating an adapter.
John-David Dalton
@jdalton
Mar 11 2015 21:39
treating strings as a list has old browser gotchas too
so if you want to support IE < 9 there's work needed
Jethro Larson
@jethrolarson
Mar 11 2015 21:40
Good news is that the adapter should be pretty easy to write
John-David Dalton
@jdalton
Mar 11 2015 21:41
Ramda doesn't tackle object iteration issues in IE < 9 either (anywhere there's a for-in)
so there's some more work there too
Scott Sauyet
@CrossEye
Mar 11 2015 23:11
@jdalton: Are there specific issues you know of? I would like to address them.
Hardy Jones
@joneshf
Mar 11 2015 23:32
@davidchambers I'd think something involving a fold operation would be the ticket to doing that elegantly