re: Keeping Your Code Simple VIEW POST

FULL DISCUSSION
 

I don't think your first function is hard to read at all. If anybody finds it unreadable enough to say

that one solution was a mess and that if he had written anything like that he would have gotten chewed out by his boss.

I would chuckle and dismiss their opinion as them probably not being used to working with reduce.

That being said, if I were to improve that code I would probably extract a function that would compare two strings and return the longest, like Nested Software suggests. lenX doesn't really provide more information than x.length.

Regarding short variable names, there is a case for them in certain contexts, and reduce and the like are one of those. Let's consider this.

const pony_names = ponies.map(x => x.name)

Could I write in a way that avoids naming a variable x? Sure.

const pony_names = ponies.map(pony => pony.name)

However, does it add anything? Since I'm mapping over an array named ponies, I know that x is going to refer to a pony, and it works much like a pronoun in a natural language. In natural languages, when the immediate context makes the subject of a sentence clear, it is commonly replaced by a pronoun (or in some languages skipped altogether). So instead of I found a book. The book has a blue cover and the book has 307 pages, we usually say I found a book. It has a blue cover and 307 pages. Naming a variable x would be much like using it in English.

As I've said, to be able to do that effectively, what x refers to needs to be obvious by the immediate context. I still need to give pony_names a sensible name because I'm going to use it in another context detached from the ponies array and then I wouldn't know what x refers to. But for short functions where the immediate context makes it clear what the variable is, longer names are not really a must.

What about reduce then?

ponies.reduce((x, y) => ({ ...x, [y.name]: y }), {})

I agree that x and y might be somewhat confusing here. We have one topic (ponies), but two pronouns (x, y), what do they refer to? We know that reduce passes the element it is iterating over in the second parameter, and the result of the last invocation in the first parameter, so let's give that parameter a more meaningful name.

ponies.reduce((prev, x) => ({ ...prev, [x.name]: x }), {})
// or
ponies.reduce((acc, x) => ({ ...acc, [x.name]: x }), {})

No more having to check the docs again to see which parameter was the accumulated result and which one was the current element of the array.

Let's consider another case, the function that takes two strings and returns the longest.

const longestString = (a, b) => a.length >= b.length ? a : b

Could I have named my variables string_1 and string_2? Sure, but I would argue that those are not meaningful names either, they are just longer. For all I know, a and b could be pony names or science fiction novels. And it's fine, because longestString is a generic function that should work for any kind of string. Do I need to give the variables a name that indicates they are strings? Again, the function name is just a few characters to the left and it already talks about strings, so the immediate context is enough to understand that a and b are strings.

TL;DR

To summarise my point, I think one-character function parameter names are alright when two conditions are fulfilled.

  • The name of the function, or the context where an anonymous functions is invoked, makes the nature of the parameter obvious.
  • The body of the function is short.

And your first code fulfils both conditions. If anything, I would replace your reducer function's signature from (x, y) to (prev, x) or extract it into a named function that takes two strings and returns the longest.

 

I totally agree. I would add that when we do code, we got a semantic, an intention and I think that's the important part. We should use all tools in our arsenal to achieve the goal while letting the semantic be visible.

 

I'm on board with this!

<shares comment with students>

 
code of conduct - report abuse