These are chat archives for ramda/ramda

25th
Jan 2017
Rick Medina
@rickmed
Jan 25 2017 03:41
people! do you annotate your functions in functional style code? do you use HM-ish? jsdoc-ish...?
Brad Compton (he/him)
@Bradcomp
Jan 25 2017 03:43
If it's a public function (exported from the module) I'll use jsdoc for the IDE help. If it's internal to the module I'll use HM because it provides a visual helper when I'm building compositions
Rick Medina
@rickmed
Jan 25 2017 03:47
internal: just HM or +comments as needed?
eg: when you are returning an object of some shape
or do you use tagged types or something like that?
Brad Compton (he/him)
@Bradcomp
Jan 25 2017 04:01

We have a utility to define a POJO structure, so the HM can be

getUser:: userId -> Maybe(User)

where User is either defined in the file or just understood

Usually that's enough, but of course if it isn't obvious what the function is doing I'll comment
Rick Medina
@rickmed
Jan 25 2017 04:06
awesome! @Bradcomp
another one...
do you prefer to pass through needed data to external functions or use closures ?
or other option
Brad Compton (he/him)
@Bradcomp
Jan 25 2017 04:11
Generally (though not always), I will define curried functions at the top level, then partially apply them as I go (does that make sense?)
Rick Medina
@rickmed
Jan 25 2017 04:18
@Bradcomp mmm sort of...(I guess this question is not specific to fp), on a big function do you prefer the logic within to separated by internal sub functions or extract them (with the additional boilerplate of passing the params)?
Brad Compton (he/him)
@Bradcomp
Jan 25 2017 04:21
Personally I hate long functions. I try to break out as much as I can, give the helper functions descriptive names, and see what specific parameters each one needs to take.
Rick Medina
@rickmed
Jan 25 2017 04:26
what would you define as long function? :)
Generally (though not always), I will define curried functions at the top level, then partially apply them as I go (does that make sense?)
something like this? (pseudo code)
const uno = p1 => p2 =>
   const j = p1 + p2
   return j

const dos = p2 => j =>
  p3

const longFunc = (p1, p2, p3) =>
  return pipe(
    uno(p1),
    dos(p2)
  )
Brad Compton (he/him)
@Bradcomp
Jan 25 2017 04:39
:point_up: yeah, like that
Long depends on the context, but if it doesn't fit on the screen it's hard to keep in your head ;)
Rick Medina
@rickmed
Jan 25 2017 04:44
cool, gotcha! ...what's your monitor size btw??? (j/k :))
thanks!
Brad Compton (he/him)
@Bradcomp
Jan 25 2017 04:44
If you have to ask you should split it up :stuck_out_tongue:
Rick Medina
@rickmed
Jan 25 2017 04:45
actually, I asked bc I think I'm on the other extreme (writing lots of many 2/3 line functions with 2+ params)
Marcus Nielsen
@marcusnielsen
Jan 25 2017 06:26
This message was deleted

hi there, i'm have this function

 function applyMask(mask, value) {
   var result = "";
   var offset = 0;
   for(var i=0; i < mask.length; i++) {
     var mch = mask.charAt(i);
     var v = value.length > i + offset ? value.charAt(i + offset) : ' ';

      if(mch === 'd') {
        result = result + v           
      } else {
        result = result + mch; 
        offset--;
      } 
   }

  return result;
}

and i try rewrite it to functional analogue. How do that?

usage:
> applyMask("dd/dd/dddd", "25012017")
'25/01/2017'
Alex Deas
@alex-deas
Jan 25 2017 11:24
If you're trying to use functional programming, starting with a functional library isn't really the best place to start; as you should ensure you can implement the same functions without the library first. Otherwise you're relying on abstractions you don't understand. I'd suggest checking out:
http://eloquentjavascript.net/1st_edition/chapter6.html and https://github.com/getify/Functional-Light-JS for good articles on functional programming in addition to checking out https://wiki.haskell.org/Functional_programming and https://github.com/fantasyland/fantasy-land for more general principles.
Denis Stoyanov
@xgrommx
Jan 25 2017 12:37
James Forbes
@JAForbes
Jan 25 2017 15:49
@Myp maybe try breaking each operation into individual functions, and then see if you can easily compose them. E.g. the string formatting, the iteration / aggregation
@Myp any further questions, ask away
Jack Leigh
@leighman
Jan 25 2017 16:21
I'm trying to use ramda sequence with fluture but I get Future#ap expects its first argument to be a Future of a Function
any idea what I can do?
sequence(Future.of, [Future.of(4), Future.of(5)])
Think it's because ramda uses of([]) which doesn't have typeof 'function'?
sequence(Either.of, [Either.of(4), Either.of(5)]) gives Right([4,5]) with Either from sanctuary
Aldwin Vlasblom
@Avaq
Jan 25 2017 16:25
@leighman That happens because Ramda's ap is compatible with FantasyLand 1.0, whereas Fluture follows 3.0.
The argument order of ap was flipped in FL 2.0
Brad Compton (he/him)
@Bradcomp
Jan 25 2017 16:26
@leighman I think Sanctuary Type Classes has a compatible ap function.
Aldwin Vlasblom
@Avaq
Jan 25 2017 16:27
:point_up: That.
Jack Leigh
@leighman
Jan 25 2017 16:28
Is the ramda one going to be updated?
Brad Compton (he/him)
@Bradcomp
Jan 25 2017 16:30
It was begun a while ago but stalled: ramda/ramda#1900
ramda/ramda#1938
ramda/ramda#1950
Jack Leigh
@leighman
Jan 25 2017 16:37
how come the sanctuary Either is working?
Brad Compton (he/him)
@Bradcomp
Jan 25 2017 16:40
Sanctuary v 0.11 is compatible with the old FL spec. The next release won't be
Jack Leigh
@leighman
Jan 25 2017 16:42
Okay, I see
Thanks
Matt Ross
@amsross
Jan 25 2017 18:16
Can I get a little advice on whether or not I’m doing this a little wonky:
h(teams)
  .tap(log)
  .map(R.over(R.lensProp("team-split"), R.compose(
          R.map(R.map(R.head)),
          R.map(R.groupBy(R.prop("stats"))),
          R.groupBy(R.prop("split")))))
  .tap(log)
  .map(R.over(R.lensProp("team-split"), R.compose(
          R.flatten,
          R.values,
          R.lift(R.values))))
  .each(log)
at the start, teams is an array of objects like this:
{ teamId: 1,
  'team-split':
   [ { split: 'Total', stats: 'own', games: 1 },
     { split: 'Total', stats: 'opponent', games: 1 } ] }
after the first map, I’ve turned them into objects based on grouped stats:
{ teamId: 1,
  'team-split':
   { Total:
      { own: { split: 'Total', stats: 'own', games: 1 },
        opponent: { split: 'Total', stats: 'opponent', games: 1 } } } }
and then turn them back into the original structure
basically turning the array team-split into an object with nested properties according to the values in the array members (only one will ever match both groupBy statements)
Matt Ross
@amsross
Jan 25 2017 18:28
I feel like there has got to be a cleaner/smarter way to compose(map(groupBy(fn), groupBy(fn))