These are chat archives for ramda/ramda

4th
Oct 2017
James Forbes
@JAForbes
Oct 04 2017 00:27
@skatcat31 :smile:
Kurt Milam
@kurtmilam
Oct 04 2017 07:46
It's my understanding that a language-level compose would make some optimization options possible that a user-land compose doesn't.
@skatcat31 and here's my missyElliot with the operator:
const missyElliot =
  reverseIt
  +> flipIt
  +> bringItdown
James Forbes
@JAForbes
Oct 04 2017 08:16
yeah inlining would definitely be possible
but also source transforms in build tools
"compile" time inlining
in babel or what have you
Vladimir Kapustin
@kapooostin
Oct 04 2017 08:32

Got stuck with curry and converge. Here is a test that makes me feel I do not understand something essential:

const data = {
  collection: [
    1, 3, 5
  ],
  multiplier: 10
};

const mapper = curry( ( data, multiplee ) => data.multiplier * multiplee );
const mapperManuallyCarried = data => multiplee => data.multiplier * multiplee;

const mapped = data => data.collection;

const fnConverge = converge( map, [ mapper, mapped ] );
const fnConvergeManuallyCarried = converge( map, [ mapperManuallyCarried, mapped ] );
const fn = data => map( mapper( data ), mapped( data ) );

const result = fn( data );

const expected = [ 10, 30, 50 ];

fnConvergeManuallyCarried and fn work just fine.
fnConverge fails returning [ Function anonymous ] instead of [ 10, 30, 50 ]. Why?

Denis Stoyanov
@xgrommx
Oct 04 2017 08:41
@kapooostin lift(o(map, multiply))(prop('multiplier'), prop('collection'))(data)
Vladimir Kapustin
@kapooostin
Oct 04 2017 08:56
Ok, I'll try it. But why converge doesn't behave here as I expect it.
Vladimir Kapustin
@kapooostin
Oct 04 2017 09:09
@xgrommx Thanks, it works! But I still want to make sure, that I understand converge correctly. What was wrong with fnConverge.
Rolf Strijdhorst
@rolfst
Oct 04 2017 12:23
@kurtmilam I agree. look at elixir for example. there they have the |> as a pipe, definitely a language construct. I also look at python for language constructs like list comprehensions definitely a language construct or generator comprehensions. lots of optimisation possible. It's not for nothing that a lot of patterns that jQuery brought us are now merged into the language. user-land is fine to experiment but when a pattern gets so valuable it often gets promoted to the language so all kinds of optimisations can be applied
Alastair Hole
@afhole
Oct 04 2017 12:31
Hey all I was just looking at ramda/ramda@f494250 and I wondered what "side-effects": false, in the package.json is doing? Is it related to babel-plugin-annotate-pure-calls?
Dylan Taylor
@dylanjt
Oct 04 2017 15:13
hey, a coworker and I are experimenting with implementing ramda in our codebase and trying to write functionally. I was wondering - it has been a little difficult to find examples - is it possible to compose functions such that R.compose(mappingFunc, networkCallDependentOnFirstNetworkCall, mappingFunc, NetworkCall) ?
if it's not, what is the best practice for dealing with sequential network calls / async functions?
and apologies if this is not a good forum for these kinds of questions.. has not been easy to find knowledgeable ramda users in the general js/node irc channels, etc
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 15:27

@dylanjt A lot of people will tell you to use a library like fluture for handling async calls. We've also had pretty good luck using Ramda to work with promises.

One way is to use functions like pipeP or composeP, but be wary that in that case the first function you pass through must return a Promise. Another option is to construct a then function:

const then = (f) => (p) => p.then(f);

You can then use compose or pipe or whatever to compose functions, just wrap the ones dealing with Promises in then

Dylan Taylor
@dylanjt
Oct 04 2017 15:34
@Bradcomp thanks :) so my coworker (supervisor actually) is partial to figuring out fluture. but we're having a hard time finding examples of fluture incorporated in Ramda, preferably in Ramda compositions. is that possible, in more or less the form I described at the end of my first message?
of course, too, i understand this is ramda channel and not fluture channel. will ask around there too.
Dylan Taylor
@dylanjt
Oct 04 2017 15:41
and good to know that there are solid options for working with promises.
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 15:48
Let's assume that the network calls are callback based. You can use Future.node to convert them to return Futures. Then your example would look like this:
const result = R.compose(R.map(mappingFunc), R.chain(networkCallDependentOnFirstNetworkCall), R.map(mappingFunc), NetworkCall) (stuff);

result.fork(errHandler, successHandler); //The future won't actually run until you call `fork` on it.
Aaron Mc Adam
@aaronmcadam
Oct 04 2017 15:50
does anybody have a good example of a simple natural sort of an array of strings?
Dylan Taylor
@dylanjt
Oct 04 2017 15:50
thank you again - I'm going to play around with that in runkit
Robert Mennell
@skatcat31
Oct 04 2017 15:58
@kurtmilam I'm curious what optomizations you mean?
@JAForbes inlining in build tools would be nice. At that point I still have a problem with +> being confusing. I'd rather have it be a function of native code, and at that point a compiler would still be able to inline it(or at least should be able too... If they don't I'd be very sad)
Kevin Wallace
@kedashoe
Oct 04 2017 16:36
@afhole see webpack/webpack#5435
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 16:44
@aaronmcadam What do you mean?
@ram-bot
const ls = ['c', 'C', 'a', 'bet', 'zed'];

sortBy(toLowerCase)(ls);
ram-bot
@ram-bot
Oct 04 2017 16:45
toLowerCase is not defined
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 16:45
@ram-bot
const ls = ['c', 'C', 'a', 'bet', 'zed'];

sortBy(toLower)(ls);
ram-bot
@ram-bot
Oct 04 2017 16:45
[ 'a', 'bet', 'c', 'C', 'zed' ]
Robert Mennell
@skatcat31
Oct 04 2017 16:57

@JAForbes with your decorator, wouldn't it be nice to just have a single : to the left so you can

f +> : g +> h;
// versus

f +> :g: +> :h:;
//or
 f +> : g +> h :;

Assuming something interim returns another promise it's then just another : instead of a pair enclosing

Alec
@alavkx
Oct 04 2017 18:44
What would be the appropriate construct to use for..
When true, append, else nothing
I'm trying to use
map(when(predicate, o(append, x => ({...})), but when returns identity when false.
I'm assuming I should be using something other than map here
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 18:50
Can you give an example, it sounds like you want filter
Alec
@alavkx
Oct 04 2017 20:22

This is my best effort so far, still broken. It will pollute the list with key value pairs returned by the identity when R.when is false
I've been kind of boggled on how to handle branching logic in this scenario

o is compose, and pairKey and pairValue are x => x[0] and x => x[1] respectively

Brad Compton (he/him)
@Bradcomp
Oct 04 2017 20:22
Sorry, I was out for a bit
looking now
Alec
@alavkx
Oct 04 2017 20:22
No worries
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 20:26

So you have an object, and you break it into pairs. For each pair you are creating this object:

{
      id: val.measureId,
      displayName: val.displayString,
      parentId: val.length >= 2 || existsIn("nonVariableGroup", key)
        ? val.variableGroup + "dg" : null,
    }

and also you want to create a list of these:

{
            id: x + "dg",
            displayName: x,
            parentId: null,
         }

for each item that has a value with a length less than or equal to 1, and then you want to concat those two lists together>

Alec
@alavkx
Oct 04 2017 20:26
correct
I think my issue stems from me not understanding how to use reduce in a point free fashion
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 20:32
One thing to note is that you can't use o to compose 3 functions
R.o
Alec
@alavkx
Oct 04 2017 20:33
o woops
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 20:37
R.propSatisfies
Alec
@alavkx
Oct 04 2017 20:40
fixed :)
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 20:43
Nicely done
here is what I was working on
I like to break things apart into atoms I can put together
that way it's easier to see what's going on at each layer of abstraction
Alec
@alavkx
Oct 04 2017 20:44
Ah that's quite a bit easier to read
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 20:44
So I have functions like mapper and createItem (both terrible names) that work on the data, and then the others work on the structures
Alec
@alavkx
Oct 04 2017 20:47
The mapAndFilter helper is the bit I was missing. Curious if there is a name for this abstraction. I figured there was some dusty function in the corner of Ramda I couldn't put my finger on
Brad Compton (he/him)
@Bradcomp
Oct 04 2017 20:49
I mean, I am sure there is a name for it in haskell :stuck_out_tongue:
Alec
@alavkx
Oct 04 2017 20:51
Ha, like most things. Came across "Zygohistomorphic Prepromorphism" the other day. Quite a trip
Thanks for the help :D
Jason Shin
@JasonShin
Oct 04 2017 22:16
guys
do you think Async/Await is monadic?
or in otherword
can you write pure functions using it?
James Forbes
@JAForbes
Oct 04 2017 23:29

@skatcat31 I've advocated for your exact position before, e.g. "why couldn't the compose function be inlined?" It definitely could but with less guarantees than syntax provides simply because syntax focuses on one thing. That means implementer's do not need to consider cross cutting concerns. Build tools I think can take a lot more risk than engines because you can configure them to meet your intent instead of globally configure them for every developers intent.

As for the :x: syntax, I wasn't even really proposing that :D that was just to demonstrate that we could easily add async function support later with a lift operator, so there's no reason to complicate +>. But... maybe it's a good idea I'm not sure. I think a single : on the left could work but might be confusing because of ternaries.