Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

96
Visualizações
Readability for function composition

I'm trying to practice function composition using Ramda but wondering if it's overkilled and needed some advice on this.

Given the object below

const articles = [
  {
    title: 'Everything Sucks',
    url: 'http://do.wn/sucks.html',
    author: {
      name: 'Debbie Downer',
      email: 'debbie@do.wn'
    }
  },
  {
    title: 'If You Please',
    url: 'http://www.geocities.com/milq',
    author: {
      name: 'Caspar Milquetoast',
      email: 'hello@me.com'
    }
  }
];

Make a boolean function that says whether a given person wrote any of the articles.

Sample function invocation

isAuthor('New Guy', articles) // should return false
isAuthor('Debbie Downer', articles) // should return true

My Solution

First I create a function to grab the author name as below

const get = _.curry(function(x, obj) { return obj[x]; });

const names = _.map(_.compose(get('name'), get('author'))); // ['Debbie Downer', 'Caspar Milquetoast']

Now that I have a function names ready to be used, I will try to construct isAuthor function and below is two of my attempts

Attempt 1: without composition

const isAuthor = function(name, articles) {
  return _.contains(name, names(articles))
};

Attempt 2 with composition

const isAuthor = function(name, articles) {
  return _.compose(
    _.contains(name), names
  )(articles);
}

Both attempts works with correct results, this question is asking solely from functional programming perspective as I'm totally new to this domain and wondering which attempt is favourable than the other, and hopefully this question will not get closed as opinion based, I sincerely thinks that this is not opinion based but seeking industrial practice in FP world.

Also feel free to provide any alternatives than the two attempts I've made, thanks!

about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Ramda has a set of functions to work with nested properties. In your case we could combine pathEq and any:

  1. pathEq returns true if a property at given path is equal to given value.
  2. any applies a predicate function to each element of a list until it is satisfied.

The isAuthor function takes a name first then returns a function that takes a list:

const {compose, any, pathEq} = R;

const isAuthor = compose(any, pathEq(['author', 'name']));

isAuthor('Debbie Downer')(articles);
//=> true

isAuthor('John Doe')(articles);
//=> false

But this isn't necessarily better than:

const {curry} = R;

const isAuthor = curry((x, xs) => xs.some(y => y?.author?.name === x));
                                  
isAuthor('Debbie Downer')(articles);
//=> true

isAuthor('John Doe')(articles);
//=> false
about 4 years ago · Juan Pablo Isaza Relatório

0

Think of Ramda as a tool that helps you write in a certain way, and not something that dictates how you write your code. Ramda (disclaimer: I'm one of the founders) allows you to write in a more declarative fashion, using nice compositions and pipelines. But that doesn't mean that you need to use it everywhere you could.

The simple vanilla JS answer from tuomokar is probably all you need, but Ramda does have tools that might make that seem more readable to some.

So we could write something like this:

const isAuthor = (name) => (articles) => 
  includes (name) (map (path (['author', 'name'])) (articles))

const articles = [{title: 'Everything Sucks',url: 'http://do.wn/sucks.html', author: {name: 'Debbie Downer',email: 'debbie@do.wn'}}, {title: 'If You Please', url: 'http://www.geocities.com/milq', author: {name: 'Caspar Milquetoast', email: 'hello@me.com'}}]

console .log (isAuthor ('New Guy') (articles))
console .log (isAuthor ('Debbie Downer') (articles))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>
<script>const {includes, map, path} = R                                  </script>

Note that your get is built in to Ramda as prop, and that your names can be written as map (path (['author', 'name'])).

We could make this point-free, on our own, or using a tool like http://pointfree.io/. It might look like this:

const isAuthor = compose ((o (__, map (path (['author', 'name'])))), contains)

But I find that far less readable than any of the other suggestions. I wouldn't bother.

about 4 years ago · Juan Pablo Isaza Relatório

0

Both of your solutions seem like an overkill at least in my opinion.

Without using any libraries, a solution could be as simple as this for example:

 const isAuthor = (name, articles) => articles.some((article) => article.author.name === name)

Functional programming is cool, but it doesn't mean you should make things unnecessarily complex.

From your proposals the first one seems a lot more readable than the second one.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda