These are chat archives for ramda/ramda

19th
Mar 2017
Vijay
@vijaytv
Mar 19 2017 00:00
@dskelton-r7 . Thanks. FYI, I was trying to convert the following (largest rectangle in a histogram) into ramda as an exercise. - https://gist.github.com/vijaytv/b8d132be01ecb29c4929a0ec78d4fa02
Matthew Willhite
@miwillhite
Mar 19 2017 01:39

@vijaytv

function f (ls) {
  if (isEmpty(ls)) return [];
  var ts = splitWhen(equals(0), ls);
  return concat(ts[0], f(tail(ts[1])));
}

Not the prettiest, but it should work…

er maybe not concat, but you could do whatever you want with ts at the end to build up the structure you want
gmunguia
@gmunguia
Mar 19 2017 08:56
@vijaytv
First time I use Ramda, so I felt I might as well share my attempt:
const isntEmpty = compose(not, isEmpty)
const splitZero = compose( zipWith(call, [identity, tail])
                         , splitWhen(equals(0)))    

unfold(both(isntEmpty, splitZero))([2, 3, 4, 0, 3, 4, 0, 2])
Stefano Vozza
@svozza
Mar 19 2017 11:14
Nice. You can do complements(isEmpty)
For your first function
gmunguia
@gmunguia
Mar 19 2017 11:15
Oh, nice. Thanks for the feedback!
Johnny Hauser
@m59peacemaker
Mar 19 2017 18:58
This is all good:
var fn = (data, options) => {}
var f = R.compose(R.curry, R.flip)(fn)
but
what about:
var fn = (data, somethingElse, options) => {}
var f = R.compose(R.curry, R.flip)(fn) // not going to work because `flip` only works on the first two arguments
I need flipN, right?
Josep M Sobrepere
@josepot
Mar 19 2017 19:38
I'm not sure what you are trying to do there @m59peacemaker , but perhaps nthArg could be useful too
Johnny Hauser
@m59peacemaker
Mar 19 2017 19:38
@josepot JOSEP! HEY MAN!
Josep M Sobrepere
@josepot
Mar 19 2017 19:38
oh, no, NVM
Johnny Hauser
@m59peacemaker
Mar 19 2017 19:38
Dunno if you remember me
Josep M Sobrepere
@josepot
Mar 19 2017 19:39
of course I do :)
Johnny Hauser
@m59peacemaker
Mar 19 2017 19:39
It's a small and JavaScript-y world!
Josep M Sobrepere
@josepot
Mar 19 2017 19:39
yep, it is! are you still working with angular these days?
Johnny Hauser
@m59peacemaker
Mar 19 2017 19:40
kinda. I have a React app also
How about you?
Josep M Sobrepere
@josepot
Mar 19 2017 19:40
I've been working with React-Redux for the last 18 months or so
Johnny Hauser
@m59peacemaker
Mar 19 2017 19:40
neat
It's cool that you're in the functional world =D
Josep M Sobrepere
@josepot
Mar 19 2017 19:42
yep, I've been very focused into FP for the last 2 years approximately
Johnny Hauser
@m59peacemaker
Mar 19 2017 19:42
I'm such a rabid functional advocate
I'm not great at it
but soooooo can't stand everything else these days
Josep M Sobrepere
@josepot
Mar 19 2017 19:43
It's funny, it looks like we've gone through very similar paths :smile:
BTW, I just published a small silly library for react-redux apps
I would appreciate some honest feedback
Johnny Hauser
@m59peacemaker
Mar 19 2017 19:43
I am not so great at front-end. I can get the job done, but I've never found an approach I'm very happy with.
Piet Vandeput
@piet-v
Mar 19 2017 19:44
can I ask a redux-ramda related question to one of u both? :D
(or both) lol
Johnny Hauser
@m59peacemaker
Mar 19 2017 19:44
sure, but I probably can't answer it =D
My react/redux code is terri-bad-awful
I think it's worse than my Angular code somehow!
Piet Vandeput
@piet-v
Mar 19 2017 19:45
assuming I only have one store, I'll only have one dispatcher right?
Josep M Sobrepere
@josepot
Mar 19 2017 19:45
yes
in redux there is only one store
so, yep, just one dispatcher
@m59peacemaker have a look at this please and tell me what you think https://github.com/josepot/react-redux-scroll
^^ anyone else is welcomed too, of course
Piet Vandeput
@piet-v
Mar 19 2017 19:46
Ok, my situation then: I'm using Aurelia and learning redux while I'm at it. sadly there isn't really a good plugin yet so I'm trying to get rid of as much boilerplate as I can
so on many place I get the following silly code:
    return this.store.dispatch(this.permissionsActions.addPermission(role));
assuming there's only one dispatch anyways I'm using ramda to wrap all my actions in the action class to automatically dispatch themselves lol
Josep M Sobrepere
@josepot
Mar 19 2017 19:48
I have never heard of Aurelia before, sorry.

assuming there's only one dispatch anyways I'm using ramda to wrap all my actions in the action class to automatically dispatch themselves lol

Another way to do it, maybe better (maybe not), is to use bindActionCreators to keep things decoupled.

Piet Vandeput
@piet-v
Mar 19 2017 19:50
mmm, that's awkward, so I basically wrote that manually lololol
aha, first tip on that page gives me my answer as to why redux doesn't do this by default x)
thx!
writing the ramda function for it was fun though :o
Josep M Sobrepere
@josepot
Mar 19 2017 19:52
In react it's easier, because the react-redux connector accepts an object with action creators as the second argument
Piet Vandeput
@piet-v
Mar 19 2017 19:52
y
I wrote my own connector
x)
first wrote a connector for reselect
Josep M Sobrepere
@josepot
Mar 19 2017 19:53
nice
Piet Vandeput
@piet-v
Mar 19 2017 19:53
then i wrote one for dispatchers
but was wondering why all my action files are being connected when they don't use this approach in any react-redux exampls
guess I now know why
but considering I'm not gnna make a serverside app, full speed ahead (and hopefully not regret it in the futureà
the ramda code for wrapping the dispatchers btw:
// wrapPairValue :: (c => d) => ([a, b => c] => [a, b => d])
const wrapPairValue = R.useWith(R.adjust(R.__, 1), [R.map]);
// wrapObjectValues :: (c => d) => {a: b => c} => [[a,b => d]]
const wrapObjectValues = R.useWith(R.map, [wrapPairValue, R.toPairs]);
// applyWrapper :: (c => d) => {a: b => c} => {a: b => d}
export const applyWrapper = R.pipe(wrapObjectValues, R.fromPairs);
feedback is appreciated, was my first time abusing map to chain functions
Johnny Hauser
@m59peacemaker
Mar 19 2017 19:57
@josepot looks quite well done
Josep M Sobrepere
@josepot
Mar 19 2017 20:01
thanks @m59peacemaker
Johnny Hauser
@m59peacemaker
Mar 19 2017 20:21
I suppose there are a zillion takes on curryN. I made one for fun. How did I do?
var _curN = function (n, fn) {
  return function () {
    if (arguments.length >= n) { return fn.apply(this, arguments) }
    return Function.bind.bind(fn, this).apply(this, arguments)
  }
}
var curN = _curN(2, _curN)
Josep M Sobrepere
@josepot
Mar 19 2017 20:39

@m59peacemaker I would expect the following to return a function:

const test = (a, b, c, d, e) => a + b + c + d + e;
curN(3)(test)(1)(2);

But it doesn't.

Johnny Hauser
@m59peacemaker
Mar 19 2017 20:39
:'(
Josep M Sobrepere
@josepot
Mar 19 2017 20:40
Do you know what I mean?
Johnny Hauser
@m59peacemaker
Mar 19 2017 20:41
hmm. It does for me!
Just tested it
Josep M Sobrepere
@josepot
Mar 19 2017 20:41
really?
Johnny Hauser
@m59peacemaker
Mar 19 2017 20:42
@ram-bot
var _curN = function (n, fn) {
  return function () {
    if (arguments.length >= n) { return fn.apply(this, arguments) }
    return Function.bind.bind(fn, this).apply(this, arguments)
  }
}
var curN = _curN(2, _curN)
const test = (a, b, c, d, e) => a + b + c + d + e;
curN(3)(test)(1)(2)
maybe the bot won't do that :/
Piet Vandeput
@piet-v
Mar 19 2017 20:42
it returns NaN in REPL?
Johnny Hauser
@m59peacemaker
Mar 19 2017 20:43
hmm, indeed
Josep M Sobrepere
@josepot
Mar 19 2017 20:51
I think that the implementation of a curry function is very tricky because it has a lot of edge cases.
Johnny Hauser
@m59peacemaker
Mar 19 2017 20:51
I thought I had it working. I didn't write tests. So...that's how it goes.
Josep M Sobrepere
@josepot
Mar 19 2017 20:52
Now, you made me try to write my own... :smile:
Piet Vandeput
@piet-v
Mar 19 2017 20:52
possible to test it using jsVerify?
Johnny Hauser
@m59peacemaker
Mar 19 2017 20:53
oh! I see what happened. I messed it up when refactoring to make it look nicer
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:00
var _curN = function (n, fn) {
  var f = function () {
    if (arguments.length >= n) { return fn.apply(this, arguments) } 
    return Function.bind.bind(f, this).apply(this, arguments)
  }
  return f
}
var curN = _curN(2, _curN)
@josepot ^
var f = ...
return f
somehow tempted me into removing it and replacing the usage of f with fn
oops!
Josep M Sobrepere
@josepot
Mar 19 2017 21:00
lets me see if I can break it :smile:
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:01
this is why f is a bad var name!
the brain says "aaahhh the only difference between f and fn is a single n. Just change it. Won't break a thing."
despite logic...
Josep M Sobrepere
@josepot
Mar 19 2017 21:03
Sorry @m59peacemaker
var _curN = function (n, fn) {
  var f = function () {
    if (arguments.length >= n) { return fn.apply(this, arguments) } 
    return Function.bind.bind(f, this).apply(this, arguments)
  }
  return f
}
var curN = _curN(2, _curN);
const test = (a, b, c, d, e) => a + b + c + d + e;
curN(3)(test)(1)(2)(3)(4, 5);
Piet Vandeput
@piet-v
Mar 19 2017 21:03
so mean
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:03
oh snap. That's supposed to work?
Josep M Sobrepere
@josepot
Mar 19 2017 21:03
yep
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:03
I don't get the logic there
Josep M Sobrepere
@josepot
Mar 19 2017 21:05
wait
no, my bad
Piet Vandeput
@piet-v
Mar 19 2017 21:05
that doesn't work
with R.curryN either
lol
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:05
:)
Josep M Sobrepere
@josepot
Mar 19 2017 21:05
right, right, I'm sorry
stupid of me
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:05
man you wrecked my world for a moment haha
Josep M Sobrepere
@josepot
Mar 19 2017 21:05
I cheated, I thought that I did curN(4)
sorry
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:06
one of us was messing up good =D
Josep M Sobrepere
@josepot
Mar 19 2017 21:06
it looks great, sorry @m59peacemaker
I honestly thought that I had done curN(4), sorry
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:07
It's all good!
Josep M Sobrepere
@josepot
Mar 19 2017 21:07
it's pretty cool
thanks for sharing that
Piet Vandeput
@piet-v
Mar 19 2017 21:07

alternativeFacts

Johnny Hauser
@m59peacemaker
Mar 19 2017 21:07
I was happy about the bind.bind usage =D
lol piet
Josep M Sobrepere
@josepot
Mar 19 2017 21:07
:joy:
The Function.bind.bind is pretty sick. Very clever :clap:
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:08
Since you fellows are quite awesome, I could use an opinion about https://github.com/m59peacemaker/js-optional-args
You can't call R.curry on the result of it because the returned function has no length
I imagine that is a common problem
I don't know the answer to it
Josep M Sobrepere
@josepot
Mar 19 2017 21:09
(It seems like I will be the last one in the industry to give up on the usage of semicolons :disappointed: )
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:10
I'm this close to adding Object.define(newfn, 'length', {get: () => oldFn.length})
DO IT NOW
It's so liberating
Piet Vandeput
@piet-v
Mar 19 2017 21:11
how do handle the usecase of: happyFunction(optional, optional, required) ?
Josep M Sobrepere
@josepot
Mar 19 2017 21:11
I can't man... I'm 36 years old, I started programming when I was 12, I started with C... All the languages that I've worked with they use semicolons... They come out so naturally that... I don't know, I know that it's silly, but I can't help it.
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:11
optionalArgs(2, 3, yourFn)
Piet Vandeput
@piet-v
Mar 19 2017 21:11
but what if u then call it with one of the two optionals?
no way to know which one it is?
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:12
yeah, it's the first one
put them in order haha
Piet Vandeput
@piet-v
Mar 19 2017 21:12
:D
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:12
That API is wrong enough anyway, but it's common in JS and I see the appeal in some cases
but if you seriously have optional args that you might pass out of order....
Piet Vandeput
@piet-v
Mar 19 2017 21:12
would kinda expect optionals to be last
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:12
just...stop
Piet Vandeput
@piet-v
Mar 19 2017 21:13
or to be config obj :D
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:13
Yeah, but you know, the node.js convention is data, [options], cb
That's the main purpose of my module, but it's general enough for worse APIs if you want to be more evil
Piet Vandeput
@piet-v
Mar 19 2017 21:15
or wrap the function so u flip last two params :D
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:15
The reason people like that API is because it is more readable and avoids putting undefined or null there for 99% of use cases
But the main thing is
doThisThing('for-real', {really: true, seriously: false}, (didNot, did) => {
   // buncha stuff
})
I agree that is more readable than putting the options at the end
Josep M Sobrepere
@josepot
Mar 19 2017 21:18

Hey @m59peacemaker a couple of questions about that:

1) is argCount needed, can't you grab it from the length of the 3rd argument?

maybe is that I
m not understanding this very well, sorry
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:18
length of the 3rd argument?
You mean the fn.length ?
Josep M Sobrepere
@josepot
Mar 19 2017 21:18
yep
and the 3rd argument is the function, no?
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:19
Nope, because of es6 default parameters
fn.length isn't reliable
Josep M Sobrepere
@josepot
Mar 19 2017 21:19
right
I think that it's cool
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:21
function foo (input, optional = 123, optional = 456, cb) {}
foo('abc', () => {})
foo.length === 1
so, it's all just bad.
Josep M Sobrepere
@josepot
Mar 19 2017 21:21
right, right
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:21
optional-args used to look at fn.length and you could optionally pass the length
Piet Vandeput
@piet-v
Mar 19 2017 21:22
any reason for optionalArgCount > argCount - 1 over optionalArgCount >= argCount ?
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:22
and it was module.exports = optionalArgs(optionalArgs) to make that happen lol
Yeah, it is more semantic with the issue
Piet Vandeput
@piet-v
Mar 19 2017 21:22
k :)
looks good ^^
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:24
any thoughts about the fn.length issue, tho?
Piet Vandeput
@piet-v
Mar 19 2017 21:25
can't add anything about it, didn't know about the ES6 issue for example
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:26
var foo = function foo(a, b) {}
var food = optionalArgs(1, 2, foo)
foo.length !== food.length
I mean that ^
R.curry(food) <-- doesn't work
Piet Vandeput
@piet-v
Mar 19 2017 21:26
can u return the function with modified .length?
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:27
Yep
Piet Vandeput
@piet-v
Mar 19 2017 21:27
any issue with forcing output function to have same .length as input function?
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:27
That's what I was saying about Object.define(newfn, 'length', {get: () => oldFn.length})
I don't think it would be bad, I'm just not sure I should do it
Do people do this kinda thing?
You probably want to curryN a function like that anyway
Piet Vandeput
@piet-v
Mar 19 2017 21:31
the times I've encountered this problem I just passed {} or undefined like a good (naive? xD) boy. No clue what others do as far as this is concerned
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:54
btw, one of MANY example where this module is useful https://github.com/substack/node-mkdirp/blob/master/index.js#L8-L14
Piet Vandeput
@piet-v
Mar 19 2017 21:55
lol @ the comment in the code file
Johnny Hauser
@m59peacemaker
Mar 19 2017 21:56
oops, I meant to link more. The cb check is further down. It's just ugly.