Re:Crafting Functions
by systemvoltage on Wednesday October 14, 2020 @04:22PM
(#24781125)
Sometimes, I spend a lot of time creating very good abstractions only to find that nothing will make use of it for next 10 years. You'd be better off duplicating some 8 lines of code. It is not ideal but you could be spending your energy elsewhere where it matters and abstractions do actually pay off.
Re:Crafting Functions
by weego on Wednesday October 14, 2020 @02:45PM
(#24780087)
It's also possible that we try to hard to generalise things and for a handful of lines of code it's just as valid to provide different implementations for each rather than spending time evaluating an abstraction that's as likely to only be identical in implementation due to incomplete use case or just the product of the sheer coincidences that appear in immature code.
Re:Crafting Functions
by striking on Wednesday October 14, 2020 @02:49PM
(#24780126)
I think it's worth noting that the examples in the article are the way they are for the sake of demonstration. In that context, I very much appreciated the explanations even as a fairly seasoned programmer; I knew more or less how to do these transformations, but not what they were called and how I might explain in words why I'm doing them.
Re:Crafting Functions
by stopachka on Wednesday October 14, 2020 @02:56PM
(#24780214)
Author here: Indeed, this could be an option right before "Configuration" on the spectrum I shared. For that specific example, I don't think it would make sense to do, but in many cases it can be valid.
I hope the point of the essay came through, that there is an abstraction spectrum, and where certain ideas fall onto that spectrum.
Re:Crafting Functions
by cultus on Wednesday October 14, 2020 @05:00PM
(#24781545)
I really disagree that composition is error prone. It makes it easier to test and isolate errors by easily allowing different implementations along the pipeline. You get abstraction and it's less error-prone. Abstraction usually is a win for reliability, because abstraction means less information and less entropy.
Re:Crafting Functions
by marcosdumay on Wednesday October 14, 2020 @05:28PM
(#24781830)
Notice that the post is written in Javascript.
Abstraction and composition are great to surface the main characteristics of your algorithm. A compiler then can take those characteristics and verify if they make sense. Different compilers can do that in different amounts, and the Javascript one does the absolute minimum possible. On this case, you get no safety, just more complex code.
Go ask a Haskell developer and the first reaction you will get is probably "wait, you were running getData inside the original function?!"
Re:Crafting Functions
by tluyben2 on Thursday October 15, 2020 @10:29AM
(#24788992)
It would be more interesting to see these things in multiple languages so it shows how it would be done (best) in those. Learning things js centered is is not good for everyone.
Re:Crafting Functions
by stopachka on Wednesday October 14, 2020 @08:25PM
(#24783396)
Hey team, author here:
I agree with the statement that composition won't make the code unreliable.
When I wrote mistake, the kind of mistake I was referring too was a mistake in abstraction boundaries, rather than execution. (for an extreme case consider a DSL: if you abstract a DSL from only one example, you'd likely get the core abstractions wrong)
Re:Crafting Functions
by RobKohr on Friday October 16, 2020 @03:26PM
(#24804122)
Keeping it simple until it is needed to expand is the best way forward, and have a little bit of resistance to the expansion.
One issue that comes up is the function arguments can evolve to be a mess over time with this method.
I like to always use a prop object as function arguments, even when it is simple.
function calculateArea({x, y}) rather than (x, y).
This makes it so things can be added, and be optional, and the calling function clearly can see what those values are being assigned to.
This means that the 100 times you called that function don't need to be rewritten with a new parameter added, and you don't have to have a bunch of null values set for unused cases.
I hope the point of the essay came through, that there is an abstraction spectrum, and where certain ideas fall onto that spectrum.
Thanks for reading!
Abstraction and composition are great to surface the main characteristics of your algorithm. A compiler then can take those characteristics and verify if they make sense. Different compilers can do that in different amounts, and the Javascript one does the absolute minimum possible. On this case, you get no safety, just more complex code.
Go ask a Haskell developer and the first reaction you will get is probably "wait, you were running getData inside the original function?!"
Haskell developer here, this was indeed my first reaction :P
I agree with the statement that composition won't make the code unreliable.
When I wrote mistake, the kind of mistake I was referring too was a mistake in abstraction boundaries, rather than execution. (for an extreme case consider a DSL: if you abstract a DSL from only one example, you'd likely get the core abstractions wrong)
But yes more important then just composition is to use combinators and segregate your combinators from IO.
One issue that comes up is the function arguments can evolve to be a mess over time with this method.
I like to always use a prop object as function arguments, even when it is simple.
function calculateArea({x, y}) rather than (x, y).
This makes it so things can be added, and be optional, and the calling function clearly can see what those values are being assigned to.
This means that the 100 times you called that function don't need to be rewritten with a new parameter added, and you don't have to have a bunch of null values set for unused cases.
For example, Go is leaning towards such approaches, and I think should be default for the beginning.
Refactor later, when you will see more cases.
It would be good to have the inversion example for a type-based dispatch language/style, rather than the functional style.
C(...).replace(...).replace(...).replace(...).replace(...).trimStart is not a function