
I waffled back and forth about the title of this post, but in the end, I couldn't resist the Hamlet reference.
Today's topic is about writing cle...
For further actions, you may consider blocking this person and/or reporting abuse
As a matter of fact, you can use named functions to create a very useful library to your project. Just use anonymous functions that you certainly know that are very simple or one in a million in your project.
@devpacoluna Thanks for your comment! I hadn't thought of using named functions for building a library, is that something you've done?
yep, I work with react. So i create a folder
lib/
and each file has some functions with the same purpose example date.ts, car.ts, etc...Thanks for sharing this. I like that your version combines arrow functions and semantic naming
Named functions are great when they describe common concepts. E.g., I'd have quite some confidence in how
sum
looks, even if it were declared in a different file:But for functions with different possible implementations (especially the
logRecord
, where log structure shapes the feature's "look and feel"), I'd start with anonymous functions in order to understand the entire logic as I read the code line by line—without the need to scan the file (or even jump between files) for the declaration of a specific function. If the context of a specific piece of code gets too big, I'd look for ways to extract coherent parts. I find it important to let the code and your understanding of it evolve for a while, rather than zealously extract every anonymous function.Thanks for sharing this perspective. That approach makes sense to me and I’ve heard a variation of that quote before but didn’t know the source!
Here are some more variations: martinfowler.com/bliki/TwoHardThin... 🤗
😂 love it!
I like this and agree mostly, but I think the examples you've given add to the confusion rather than making it clearer:
Reading the following, I'd be confused expecting
getStudentRecordById
to take an ID as a parameter and to return arecord
object, when in fact it takes a record object and returns a boolean. That's suitable for use in thefind
method, but it doesn't make sense in itself:If I was reading this one,
printEachRecord
would imply to me that it was a function which took some kind of iterable, rather than a single record:@moopet thanks for your comment. You raise a good point and one that someone in another comment brought up.
Named functions can only provide additional clarity if they are named well. And there is definitely room for improvement for how I named these functions.
Given the simplicity of the functions in your example, I think the anonymous/inline version is significantly more readable. That's partly due to the increased conciseness, which cuts out unnecessary noise, but mostly to do with the reduced indirection compared to the named version. Unnecessary indirection is really bad for readability, because it forces you to jump around instead of reading linearly.
If each step contained more logic, named would probably be better (indirection can be a good thing when dealing with significant chunks of abstraction), but in that case most functions should be defined at the top level rather than nested. That way they can be tested individually.
The exception is where the function depends on variables in the outer scope, which are sometimes better defined nested within that scope. Other options would be refactoring to take all their dependencies as explicit arguments, or using a class with methods and internal state.
@lionelrowe thanks for your comment. I agree the logic is simple enough that it might not be the best example.
My thought was that readers would see the potential in this style of code for larger, more complex code bases, even if the examples were simple.
Although, as others have pointed out, this approach requires the names of the functions to be clear, which I could have done a better job on too.
I appreciate the feedback and perspective!
I personally like to take the approach of bringing the helper functions out of the important business logic while using something like ramda to make that magic possible:
Here the
curry
method will allow us to do some fancy functional programming and not have to resort to something likerecordIsInListOfIds.bind(null, ids)
.@decaf_dev thanks for sharing this method, I’ll have to check out Ramda!
As a software engineer with decades of experience I found the anonymous function version easier to read. I also point out that English has a problems with being imprecise and having different meanings for different people in different contexts. I do appreciate good variable names and comments about why, but somehow shorter is quicker and easier to digest.
@ddfridley Thanks for your comment! You're right, English can be imprecise, and I hadn't considered the confusion that might arise from that. Maybe it's be worth it to let the code, speak for itself.