These are chat archives for ramda/ramda

14th
Mar 2017
Matthew Willhite
@miwillhite
Mar 14 2017 02:28
@piet-v You could use nAry or one of the several arity functions to ensure your spec functions only ask for what they need
Adam Szaraniec
@mimol91
Mar 14 2017 11:20
Is there function that return true if arrray contains one of element passed as argument
R.contains([3,2], [1, 2, 3]); //=> true
R.contains([3], [1, 2, 3]); //=> true
R.contains([4, 2], [1, 2, 3]); //=> true

R.contains([4], [1, 2, 3]); //=> false
Aldwin Vlasblom
@Avaq
Mar 14 2017 11:22
intersection(a, b).length > 0 I guess
Adam Szaraniec
@mimol91
Mar 14 2017 11:23
thx
Bravi
@Bravilogy
Mar 14 2017 16:13
does anyone ever use bitwise operators?
Robert Mennell
@skatcat31
Mar 14 2017 16:14
yes, but not often.
Julio Borja Barra
@juboba
Mar 14 2017 16:24
@Bravilogy same doubt here, I've seen some dumb example use cases, but never a serious one.
@skatcat31 can you give an example?
Rick Medina
@rickmed
Mar 14 2017 16:32
@Bravilogy I haven't seen anyone used them in apps but in libs yes
Robert Mennell
@skatcat31
Mar 14 2017 16:45
https://github.com/shaneGirish/bcrypt-nodejs/blob/master/bCrypt.js is where you'll see more real world use cases. Ciphers.
https://www.reaktor.com/blog/javascript-performance-fundamentals-make-bluebird-fast/ point 2 will explain performance reasons for using it
their code is more generalized than mine was. Mine was for a serial communication in a single byte, allowing me to do bitwise comparisons on it allowed us to fit a large ammount of error codes into a single 3 character transport("[asciiencode]") and just detecting what bit was active allowed us to act on it.
so really where you run into bitwise is in low level encoding, compression, ciphers, and performance management
Robert Mennell
@skatcat31
Mar 14 2017 16:55
// errorcode is a char. We actually contain this in a loop for each character in the string
if(errorcode)
{
  codes.forEach( code => { ( code.code & errorcode ) ? message.push( code.message ) : false ;
}
Robert Mennell
@skatcat31
Mar 14 2017 17:05

as for bitshifts we also used them in a different place for identifying specific events from a serial communication in a custom format

while( i ){
  switch (i >> 1) {
    case 1:
    i = functionCall(i); // more encoding and decoding functions
    break;
    ...
  }
}

When i was consumed we knew transmission was complete and we simply moved onto the next message in the stack

granted you only get two cases there, but we only wanted the first bit.
In a larger application we wanted the first byte so we instead did
i >> 8
unless you're processing data on a low level, or extremely high traffic I severly doubt you'll use techniques like this
Robert Mennell
@skatcat31
Mar 14 2017 17:22
@juboba
Travis LaDuke
@laduke
Mar 14 2017 18:09
Is there an associative binary operation for javascript objects {} ?
.assign I guess
Gabe Johnson
@gabejohnson
Mar 14 2017 18:13
but yeah...Object.assign
Robert Mennell
@skatcat31
Mar 14 2017 18:16
I'd be worried about the deep cloning problem with Object.assign depending on use case...
Travis LaDuke
@laduke
Mar 14 2017 18:19
I was just pondering category stuff, not trying to implement anything🤔
barretron
@barretron
Mar 14 2017 20:16
Is there a shortcut for R.flip(R.contains) ?
Denis Stoyanov
@xgrommx
Mar 14 2017 20:17
What is problem here? This is normal approach
barretron
@barretron
Mar 14 2017 20:18
No problem here, just wondering.
Piet Vandeput
@piet-v
Mar 14 2017 20:30
anyone see a way to make this piece of code clearer?
const isNavBarRoute = R.path(['settings', 'navBar']);
const getPermissions = R.path(['settings', 'permissions']);
const filterByNavBar = (routes, hasSomePermissions) => routes.filter(R.allPass([isNavBarRoute, R.pipe(getPermissions, hasSomePermissions)]));
I feel like the filterByNavBar seems complex :/
what worse is I have a second function which seems to duplicate so much
const isControlPanelRoute = R.path(['settings', 'controlPanel']);
const filterByControlPanel = (routes, hasSomePermissions) => routes.filter(R.allPass([isControlPanelRoute, R.pipe(getPermissions, hasSomePermissions)]));
Robert Mennell
@skatcat31
Mar 14 2017 20:34
try extracting the R.pipe(getPermissions, hasSomePermissions) codeblock into a testPermissions function
const testPermissions = R.pipe(getPermissions, hasSomePermissions);
barretron
@barretron
Mar 14 2017 20:34
maybe R.pathSatisfies instead of piping getPermissions to hasSomePermissions
also what @skatcat31 said
Piet Vandeput
@piet-v
Mar 14 2017 20:34
ah thx :D
Robert Mennell
@skatcat31
Mar 14 2017 20:36
combine my suggestion with barretron and you've got gold
Piet Vandeput
@piet-v
Mar 14 2017 20:38
struggling with the extraction though, mainly due to hasSomePermissions not being known until it's given to `filterByNavBar'
Robert Mennell
@skatcat31
Mar 14 2017 20:39

since then you can have functions like

const isMod = R.pathSatisfies( permissions => permissions.admin || permissions.mod || false, ['settings','permissions']);

which will greatly increase readability in your code

const filterByNaveBar = routes => routes.filter( R.allPass( isControlPanelRoute, isMod ) )
you don't know them before that point?
Piet Vandeput
@piet-v
Mar 14 2017 20:40
it's a dynamically created redux selector being passed in :(
barretron
@barretron
Mar 14 2017 20:40
const testPath = R.flip(R.pathSatisfies);
Robert Mennell
@skatcat31
Mar 14 2017 20:41
flip is your friend.
darnit @barreton XD
barretron
@barretron
Mar 14 2017 20:41
testPath(['foo', 'bar'])(x => x)({ foo: { bar: true } })
lol my bad @skatcat31 ;)
Robert Mennell
@skatcat31
Mar 14 2017 20:43
@barretron nah all good. timing is a thing. But yeah, @piet-v flip is a great utility for those last two arguments. This combines well with pathSatisfies to make a function that first takes a path, and then a tester.
Piet Vandeput
@piet-v
Mar 14 2017 20:43
i see yes, it's already a bit shorter :D
now this remains
(routes, hasSomePermissions) => routes.filter(R.allPass([isNavBarRoute, testPermissions(hasSomePermissions)]))
guess I can try to extract isNavbarRoute next so I can interchange it with another function before passing (routes, hasSomePermissions)
Robert Mennell
@skatcat31
Mar 14 2017 20:51
that hasSomePermissions... is that passed with the routes, or is this the final endpoint function?
Piet Vandeput
@piet-v
Mar 14 2017 20:52
it's part of a redux selector
static getNavBarRoutes = createSelector(
    [
      getRoutes,
      PermissionSelectors.hasSomePermissions
    ],
    filterByNavBar
  );
barretron
@barretron
Mar 14 2017 20:52
If you use R.filter you can probably get rid of the function call altogether (assuming routes is an Array)
oh nvm you'll still need it for the predicate unless you get really fancy
Piet Vandeput
@piet-v
Mar 14 2017 20:53
ye, sadly :D
Robert Mennell
@skatcat31
Mar 14 2017 20:54
you can't avoid the closure in this case without some serioualy... darnit...
barretron
@barretron
Mar 14 2017 20:54
lol
Piet Vandeput
@piet-v
Mar 14 2017 20:56
thinking of flipping the specApply() array [ PermissionSelectors.hasSomePermissions, getRoutes ] so i get (hasSomePermissions, routes) might be able to try some fanciness then x)
Piet Vandeput
@piet-v
Mar 14 2017 21:08
having this atm:
const filterByNavBar = (hasSomePermissions, routes) => R.filter(R.both(isNavBarRoute)(testPermissions(hasSomePermissions)))(routes);
I can feel I'm so close now :o
const filterByNavBar = (hasSomePermissions, routes) => R.compose(R.filter, R.both(isNavBarRoute), testPermissions)(hasSomePermissions)(routes);
Piet Vandeput
@piet-v
Mar 14 2017 21:17
anyone know how to get rid of the arrow function ? Tried curryN(2, isValidNavbarRoute) but didn't work :/
const filterByNavBar = (hasSomePermissions, routes) => isValidNavbarRoute(hasSomePermissions)(routes);
ah it was R.uncurryN(2, isValidNavbarRoute) :D :D
Piet Vandeput
@piet-v
Mar 14 2017 21:35
last hurdle I guess, anyone know how to extract isNavBarRoute from this function so I can pass it as a parameter?
R.compose(R.filter, R.both(isNavBarRoute), testPermissions)
Matthew Willhite
@miwillhite
Mar 14 2017 21:53
What is this function expecting? as-is?
oh…looking at the backlog
Piet Vandeput
@piet-v
Mar 14 2017 21:56
this basically:
(hasPermissions) => (routes) => R.compose(R.filter, R.both(isNavBarRoute), testPermissions)
but I'd like to get it to:
(hasPermissions) => (routes) => (isNavBarRoute) => ???
I'm guessing I'll have to do some kind of R.unapply on R.compose and then use R.adjust on the middle index to supply isNavBarRoute to R.both?
Matthew Willhite
@miwillhite
Mar 14 2017 22:03
does hasPermissions and routes both go to filter?
with routes going to isNavBarRoute first?
Piet Vandeput
@piet-v
Mar 14 2017 22:03
yes
Matthew Willhite
@miwillhite
Mar 14 2017 22:03
@ram-bot converge
Piet Vandeput
@piet-v
Mar 14 2017 22:04
uhm wait
Matthew Willhite
@miwillhite
Mar 14 2017 22:04
ugh, I don’t know how to use ram-bot
Piet Vandeput
@piet-v
Mar 14 2017 22:05
basically hasPermissions is given to testPermissions as a predicate, the result of this is combined with the R.both. The filter uses the result of R.both on routes
Matthew Willhite
@miwillhite
Mar 14 2017 22:06
ok
Piet Vandeput
@piet-v
Mar 14 2017 22:06
I just need to extract isNavBarRoute now so I can replace it with isControlPanelRoute for example :P
maybe R.__ can help; don't know>.<
Matthew Willhite
@miwillhite
Mar 14 2017 22:14
so conceptually you’d end up with something like this, correct?
filter(
  both(
    isNavBarRoute|isControlPaneRoute,
    testPermissions(hasPermissions)
  )
)(routes)
where the first argument in both is going to be some predicate that you can pass in
Piet Vandeput
@piet-v
Mar 14 2017 22:14
yes
ez? :D
Matthew Willhite
@miwillhite
Mar 14 2017 22:15
haha…multitasking right now…but I’ll see if I can come up with something ;)
Piet Vandeput
@piet-v
Mar 14 2017 22:15
thx! x)
Matthew Willhite
@miwillhite
Mar 14 2017 23:02

So… played around with this a little bit.

I think what you were after is something like this (btw none of these are tested):

compose(
  filter,
  apply(both),
  adjust(testPermissions, 1)
)([isNavBarRoute, hasPermissions])

But I personally don’t find that very legible. IMHO you could make some bespoke functions to try to clarify the intent…just off the top of my head:

function bifilter (pred1, pred2, list) {
  return filter(both(pred1, pred2), list);
}

bifilter(isNavBarRoute, testPermissions(hasPermissions), routes);

or

function testRouteTypeAndPermissions (routeT, perms) {
  return both(routeT, testPermissions(perms));
}

compose(
  filter, 
  apply(testRouteTypeAndPermissions)
)
([isNavBarRoute, hasPermissions])
(routes)

I don’t know if this is the best approach, I’m still very much in a paddle boat when it comes to FP (trying to make my way to the :ship:)

…there are downsides to every approach I’ve listed…
I’m curious to see how someone with more experience/practice would approach this problem
Piet Vandeput
@piet-v
Mar 14 2017 23:06
considering I'm trying out point-free style I guess the first one has to be the one
the bifilter one looks nice too though :)
Matthew Willhite
@miwillhite
Mar 14 2017 23:07
There is probably a better way ;)…haha I don’t know if that is a good name…just the first thing that came to me
But I think you’d either need to modify filter or both to get the transform you are looking for