I largely agree with this nodding along to many of the pitfalls presented. Except numbers 2s good refactor. I hope I won’t sound too harsh/picky for an example that perhaps skipped renaming for clarity on the other parts, but I wanted to mention it.
While I don’t use javascript and may be missing some of the norms and context of the lanugage, creating lamda functions (i don’t know the js term) and then hardcoding them into a function is barely an improvement. It’s fine because they work well with
mapandfilter, but it didn’t address the vague naming. Renaming is refactoring too!isAdultis a simple function with a clear name, butformatUserandprocessUsersare surprisingly vague.formatUsergives only adultFormattedUsers, and that should probably be highlighted in the name offormatUsernow that it is a resuable function. To me, it seems ripe for mistaken use given that it is the filter that at a glance handles removing non-adult users before the formatting, whileformatUserdoesn’t appear to exepct only adult users from it’s naming or even use! Ideally,formatUsershould have checked the age on it’s own and set isAdult true/false accordingly, instead of assuming it will be used only on adultUsers.Likewise, the main function is called
processUsersbut could easily have been something more descriptive likeGetAdultFormattedUsersor something similar depending on naming standards in js and the context it is used in. It may make more sense in the actual context, but in the example aFormattedUserdoesn’t have to be an adult, so a function processing users should clarify that it only actually creates adult formatted users since there is a case where aFormattedUseris not an adult.Totally agree. The hardcoded
isAdult: truerepeated in all #2 examples seems like a bug waiting to happen; that should be a property dynamically computed from the age during access time, not a static thing.Or just a function. IMO computer properties are an anti pattern. Just adds complexity and confusion around what is going on - all to what? Save on a
()when you access the value?Properties make semantic sense. Functions do something, while properties are something. IMO if you want to name something lazily evaluated using a noun, it should be a property.
Functions do something, while properties are something.
This is my argument against them. Computed properties do something, they compute a value. This may or may not be cheap and adds surprising behavior to the property. IMO properties should just be cheap accessors to values. If it needs to be computed then seeing a function call can hint the caller may want to cache the value in a variable if they need to use it multiple times. With properties you need to look it up to know it is actually doing work instead of just giving you a value. That is surprising behavior which IMO I dislike in programs.
that we agree on: properties should be cheap to compute.
Making a simple ternary condition as a function instead of property is a wasted opportunity to make its usage cleaner.
Make its usage cleaner? I don’t see how a property does that at all. We are talking about
x.foovsx.foo()really. And IMO the latter tells you this is a function that needs to do some work even if that work is very cheap.x.fooimplies that you might be able to set the value as well. But with computed properties maybe not. Which IMO makes the program a bit harder to read and understand as you cannot simply assume it is a simple assignment or field access. It could be a full function call that does different things depending on other values or even if you are setting vs getting the value. I prefer things being more explicit.Because you’re assuming
foowon’t be renamed when it becomes a function. A function should start with a verb, sayget_foo(), because justfoo()tells me nothing about what the function does (or what to expect as output). If you make it a property,get_is implicit.So if the age is computed from the year of birth for example, it’s really e.g.
thing.ageorthing.get_age()- both of which are fine, but I’d pick the property version.



