These are chat archives for ramda/ramda

26th
May 2016
Christoph Neuroth
@c089
May 26 2016 09:06
I'm wondering about best practices regarding the usage of of compose(a,b,c) vs pipe(c,b,a)? Ramdas compose seems to use pipe internally and I personally find pipe easier to read, but compose seems to be more common in FP in general (e.g. redux uses a compose function)
Julien Goux
@jgoux
May 26 2016 10:36
Hello
is there a function to execute two different functions based on the result of a Maybe in Sanctuary ?
maybeValue.fold(doSomethingIfNothing, doSomethingIfJust) ?
and return an extracted value ?
Scott Christopher
@scott-christopher
May 26 2016 10:41
@jgoux S.maybe is probably the closest to what you want. http://sanctuary.js.org/#maybe
Julien Goux
@jgoux
May 26 2016 10:42
maybeThing <- getThing foo
case maybeThing of
  Nothing -> do
    -- stuff
    pure (result)
 Just v ->
   --stuff
    pure (result)
basically I want to do this (this is PureScript) with Sanctuary
ok I'll look at S.maybe thanks :D
Scott Christopher
@scott-christopher
May 26 2016 10:42
@c089 Use of compose or pipe is primarily a matter of taste.
If you find pipe easier to read, then use pipe :)
@jgoux There's no way to explicitly pattern match, though you could simply check if (maybeThing.isJust) { ... } else { ... }
Julien Goux
@jgoux
May 26 2016 10:44
yes but this is not really functional :(
In fact I need something like bimap or bichain here
Scott Christopher
@scott-christopher
May 26 2016 10:45
Maybe isn't a bifunctor though
Because there is no value in Nothing to map over
Julien Goux
@jgoux
May 26 2016 10:46
true !
Scott Christopher
@scott-christopher
May 26 2016 10:48
If you don't like the idea of using isJust, an equivalent would be S.maybe(whenNothingFn, R.always(whenJustFn), maybeThing)
If you need access to the value in the Just, you could use a curried binary function for whenJustFn, where the first arg will receive the value of the Just
e.g.
@ram-bot
S.maybe(R.add(42), R.add, S.Just(10))(5)
ram-bot
@ram-bot
May 26 2016 10:50
15
Scott Christopher
@scott-christopher
May 26 2016 10:51
@ram-bot
S.maybe(R.add(42), R.add, S.Nothing())(5)
ram-bot
@ram-bot
May 26 2016 10:51
47
Julien Goux
@jgoux
May 26 2016 11:04
@scott-christopher Thanks I like the S.maybe solution !
Scott Christopher
@scott-christopher
May 26 2016 11:04
:thumbsup:
Lewis
@6ewis
May 26 2016 14:28
@ram-bot
const obj = [{id: 1, value: "test 1", label: "AKA"},
             {id: 2, value: "test 2", label: "AKA"}, 
             {id: 3, value: "test 3", label: "AKA"},
             {id: 4, value: "test 4", label: "AKA"}] ;

const arrayOfIds = R.map(R.prop('id'), obj);
R.reduce(R.max, 0, arrayOfIds);
ram-bot
@ram-bot
May 26 2016 14:28
4
Lewis
@6ewis
May 26 2016 14:29
is that the more succinct way?
Scott Sauyet
@CrossEye
May 26 2016 14:38
One possibility: reduce(maxBy(prop('id')), {id: 0}, obj). This should return the object with the max value.
LeonineKing1199
@LeonineKing1199
May 26 2016 15:40
I think CrossEye's implementation is the most succinct, given that you're storing it as a 1d array. But one thing I noticed that's odd isR.map(R.prop('id'), obj). There's R.pluck for this exact reason, I do believe.
Scott Sauyet
@CrossEye
May 26 2016 15:46
Right, so compose(reduce(max, 0), pluck('id')) should be a function to reform the maximum id, if that's what's wanted.
LeonineKing1199
@LeonineKing1199
May 26 2016 15:57
I looked it up and it's so frustrating but yeah, it looks O(n)is the best performance you're gonna get... I was secretly hoping there'd be something fancier out there :laughing:
Scott Sauyet
@CrossEye
May 26 2016 16:03
I may have missed something in the conversation. Are you looking for something faster than O(n) to find the maximum value/object containing the maximum value from an unsorted list? I can't imagine that would exist. Wouldn't you need to at least visit every value? Boom, O(n)!
LeonineKing1199
@LeonineKing1199
May 26 2016 16:04
No, you didn't miss anything. I just like complexity analysis.
Scott Sauyet
@CrossEye
May 26 2016 16:08
Well obviously a sort at best case would bring it down to O(n log n). It's pretty clear that you'll have to end up at least O(n), so I think the most you can do is fiddle with the coefficients.
Lewis
@6ewis
May 26 2016 19:30
R.reduce(R.max, 0, R.pluck('id',obj)); seems to be the most succinct way so far
do we have the equivalent of unshift
array.unshift()
LeonineKing1199
@LeonineKing1199
May 26 2016 19:32
There's prepend and concat
LeonineKing1199
@LeonineKing1199
May 26 2016 19:39
Okay, this is super duper 100% hackish but what about...
const unshift = function(list) {
  return concat(tail(values(arguments)), list)
}

unshift([1337], 0, 1, 2, 3)

// [0, 1, 2, 3, 1337]
Lewis
@6ewis
May 26 2016 19:41
@LeonineKing1199 I'll still to the 0% hackish solution - prepend. thank you :)
LeonineKing1199
@LeonineKing1199
May 26 2016 19:41

Hey, that's not THAT hackish XD

arguments is an object and we care about the values of the keys except for the first one.

The real problem is, prepend works wonderfully but unshift takes a variable amount of arguments. This is my best attempt at emulating that, using the same interface.
Scott Sauyet
@CrossEye
May 26 2016 19:43
Ramda generally tries to avoid that.
LeonineKing1199
@LeonineKing1199
May 26 2016 19:43
Variable numbers of arguments?
Scott Sauyet
@CrossEye
May 26 2016 19:44
Almost no variadic functions left. ...
LeonineKing1199
@LeonineKing1199
May 26 2016 19:44
Yeah, variadics in JS feels dirty.
Scott Sauyet
@CrossEye
May 26 2016 19:44
compose, pipe. What else?
Trouble is that variadic functions don't work well with currying.
LeonineKing1199
@LeonineKing1199
May 26 2016 19:45
Ha, compose so does use arguments!!!
Could we use the spread operator to forward variable numbers of arguments?
I could see the problem with currying being that JS doesn't have any good argument forwarding mechanisms.
Even then, you could only curry based off of non-variable argument lengths. Or is that not true? Ooh, this would be fun to play around with.
Scott Sauyet
@CrossEye
May 26 2016 19:48
Feel free. No one seems to have come up with a palatable solution. But that doesn't mean that you won't. Our that you won't learn something valuable in trying. :smile:
Christian Bongiorno
@chb0github
May 26 2016 19:51
There seems to be a few more people today -- so I will ask a question I asked earlier again. I am trying to create a recursive evolve where in the evolver object is partial and applies to each sub object. I can write the recursion myself, but I thought there might be a clever Ramda way to do it
LeonineKing1199
@LeonineKing1199
May 26 2016 19:51
I feel like it'd be incredibly difficult to implement with Ramda's placeholder mechanism. I'm looking at the implementation details of _curry1 now and it seems like currying acts as a wrapper for function.prototype.apply
Scott Sauyet
@CrossEye
May 26 2016 19:53
Don't try to integrate it with Ramda. Just see if you can build a useful curry that works with variadic functions. That would be quite impressive.
LeonineKing1199
@LeonineKing1199
May 26 2016 19:54
Yeah, this sounds like a fun mental exercise.
Rafe
@rjmk
May 26 2016 21:29
While we're on the topic of variadics, are there any type extensions which can describe a variadic compose? I'm quite happy for it to be 'variadic' in the sense that it takes a list of fns, of course
Incidentally, trying to make a compose that played properly with curry in JS was my intro to FP
LeonineKing1199
@LeonineKing1199
May 26 2016 21:35
What do you mean? Compose is variadic as far as I can tell.
Brad Compton (he/him)
@Bradcomp
May 26 2016 21:40
@rjmk Do you mean a compose where the result is curried to the length of the rightmost function?
LeonineKing1199
@LeonineKing1199
May 26 2016 21:43
Ooh, maybe he means a version of compose that forwards more than one argument through the composition chain. This doesn't make much sense though considering how functions have only one return type so maybe it's not what he meant...
Rafe
@rjmk
May 26 2016 21:51
No, sorry, I mean there is no type for compose (as far as I know). We can handwave it as (b -> a) -> (c -> b) -> ... (n -> m) -> (n -> a), but that's not a real type
Sorry that wasn't particularly clear in my previous comment
Brad Compton (he/him)
@Bradcomp
May 26 2016 21:57
Oh, I see now. It seems like it would be tough to create a precise signature for such a function...
LeonineKing1199
@LeonineKing1199
May 26 2016 22:02

We can handwave it as (b -> a) -> (c -> b) -> ... (n -> m) -> (n -> a), but that's not a real type

Sure, that's a real type! Why would it not be?

Brad Compton (he/him)
@Bradcomp
May 26 2016 22:05
Even with a list of functions, the list wouldn't have a precisely defined type: [(b ->a), (c->b), ...] beyond simply [Function].
Rafe
@rjmk
May 26 2016 22:06
@Bradcomp Agreed, but I imagine it is easier to find a type for the list as that is the standard way for capturing a variadic fn in a well-typed manner. A bit of googling suggests it would be possible with dependent types
@LeonineKing1199 I guess it depends what you mean by a type. I mean roughly a type that exists in System F (I think; I don't have a background in this stuff). Any particular instance of that type is a valid type, but the one with the ... is not
Brad Compton (he/him)
@Bradcomp
May 26 2016 22:19
<- goes and googles system F
Rafe
@rjmk
May 26 2016 22:25
So I think basically the idea is that you start off with some set of types (number, boolean, array, etc; let's ignore more complicated types for now (objects and stuff)). Then you can construct new types from them by creating functions from one to the other. So number -> boolean is a type, and boolean -> array and (number -> boolean) -> boolean -> array. And then (and this is what takes us to System F, we gain the ability to talk about for all types. So when we have a type signature in Ramda that has a variable in it (like a), we're using the power that System F gives us
LeonineKing1199
@LeonineKing1199
May 26 2016 22:27
I think this is starting to veer off of the "practical" part of "Practical functional JavaScript"
Brad Compton (he/him)
@Bradcomp
May 26 2016 22:27
Yeah, it's pretty cool. I had learned about type variables just from Haskell, etc. but I haven't looked too much into the theory behind it. Dependent types (agda?) seem like a really cool concept.
Rafe
@rjmk
May 26 2016 22:30
@LeonineKing1199 Perhaps. Sorry if so; I will stop now
@Bradcomp Yes -- Agda, Coq, Idris are all dependently typed languages
Brad Compton (he/him)
@Bradcomp
May 26 2016 22:31
Idris! That's the one I was thinking of
LeonineKing1199
@LeonineKing1199
May 26 2016 23:24

@rjmk

@LeonineKing1199 Perhaps. Sorry if so; I will stop now

Hey, don't let me discourage you! You do you, man.

Granted, do I think that such abstractions are practical and useful? Heck. No.

But I'm just one person. My opinion is but one of many. So I say, you plug the heck out of it lol.