1

I use the following function to send some data to a React component by wrapping it in a higher-order component:

import { equals, filter, isNil, prop, where } from 'ramda'

const example = getChapter => ownProps =>
  filter(
    where({
      sectionId: equals(prop('section', ownProps)),
      subsectionId: isNil,
      sub2sectionId: isNil,
      sub3sectionId: isNil
    }),
    prop('getContents', getChapter)
  )

I’m familiar with the concepts of functional programming, but still relatively new to the Ramda library. Now I’d like to rewrite this code using Ramda so that ownProps and getChapter can get eliminated, if only as an academic exercise.

It seems like I should eliminate ownProps first because of the order of the arguments? Although I’m not even sure of that.

Any help would be greatly appreciated!

PS. I’m aware that in the code above ownProps.section would be more readable and preferred to prop('section', ownProps), ceteri paribus, but I expect that the prop function lies on the path to a point-free equivalent of the code above, hence their inclusion.

Bart
  • 1,600
  • 1
  • 13
  • 29
  • point-free style doesn't increase reusability. `x => f (x)` and point-free `f` are equivalent, but expressed with a different *style*. one is not "more reusable" than the other. – Mulan Jan 14 '18 at 17:38
  • Thanks for the clarification, I updated the question. – Bart Jan 14 '18 at 17:45
  • Can you explain what the _purpose_ of this function is? I think that would be important to clarify. What is `ownProps`? – JLRishe Jan 14 '18 at 17:53
  • `ownProps` is an object containing the props supplied to a react component, for example for `` it would be `{ section: 8 }`. In this case, the `Content` component gets wrapped in a higher-order component which supplies its data. Because the `Content` component is used in multiple places, the data supplied to it differ, and the criteria for this are in the `where` function in the code given above. Thanks in advance! – Bart Jan 14 '18 at 17:59
  • 1
    I think that it will look quite bad and would be very far from best practices to make it entirely point-free. It will have to involve a number of steps. One step would be to _create_ the object you send into _where_ with R.assoc. – fredrik.hjarner Jan 14 '18 at 18:48
  • 1
    What do you mean with _because the functions are not commutative_? If you mean that you can't change the order of getChapter and ownProps in `example = getChapter => ownProps => ...` I think it is incorrect. I don't see why you would not be able to change it into `example = ownProps => getChapter => ...` – fredrik.hjarner Jan 14 '18 at 19:34
  • 1
    Whoops, my bad, you are correct! – Bart Jan 14 '18 at 19:44

2 Answers2

3

Could this be done? Sure. Here's one version:

const example2 = useWith(flip(filter), [prop('getContents'), pipe(
  prop('section'),
  equals,
  objOf('sectionId'),
  where,
  both(where({
    subsectionId: isNil,
    sub2sectionId: isNil,
    sub3sectionId: isNil
  }))
)])

The most unusual function in there is Ramda's useWith, which acts approximately like useWith(f, [g, h])(x, y) ~> f(g(x, y), h(x, y)). This is not a standard functional language construct, only one that helped make point-free some functions that were difficult to do so. It was mostly useful, though, before ES6/ES2015 became ubiquitous.

You can see this in action on the Ramda REPL.


Should you do this? Well, you said it's an academic exercise, so perhaps. But I find this much less readable than the original. This seems to me useful only as a way to learn some of the features of Ramda. I wouldn't put it into production.

Scott Sauyet
  • 49,207
  • 4
  • 49
  • 103
3

In addition to Scott's answer this is another possible variant:

useWith(
  flip(filter),
  [
    prop('getContents'),
    pipe(
      prop('section'),
      equals,
      assoc('sectionId', R.__, {
        subsectionId: isNil,
        sub2sectionId: isNil,
        sub3sectionId: isNil
      }),
      where
    )
  ])

And if you call it with the order of the arguments reversed you don't need the flip on the filter.

fredrik.hjarner
  • 715
  • 8
  • 22