4 ms·
> const y = h(g(f(x))); This notation usually does not reflect how we think about the computational steps. Do others feel this way too? I have to admit I don’t
by CSSer 5y ago
> const y = h(g(f(x)));
This notation usually does not reflect how we think about the computational steps.
Do others feel this way too? I have to admit I don’t really see it. It seems like a very subjective syntactic decision to me. Why not assign each call to a variable for readability? GC overhead? I guess naming things is hard, so sometimes you’re just going to do things like:
halve(double(triple(5)))
But honestly this doesn’t seem that hard to read to me for reasons that are perhaps beyond me. Granted, JS is my mother tongue, so maybe I’m just brainwashed.
I think I’m also hung up on the use of % because it already has the job of being the remainder operator. Are there other examples in the language where operator behavior changes in different contexts that are similar to this I’m missing (aside from the obvious order of operations or operator associativity)?
- oweiler 5y agoPeople read left to right, not inside out. Local vars can make reasoning harder, because they are visible throughout the current scope.
- arnvald 5y ago> Why not assign each call to a variable for readability? The problem is that if you use a variable, you either: - use a new variable each time, therefore you have to think of appropriate name each time (and having a lot of variables does not necessarily make code more readable) - or you have to come up with a rather generic name of variable, like "result" or "output", otherwise the name will not make sense until the very end where the last value is assigned Let's say I want to have a list of active products from some category. With option 1 it would be: const allProducts = Product.all() const activeProducts = allProducts.filterActive() const activeHouseProducts = Category.match(activeProducts, "house") with option 2 you'd do: var activeHouseProducts = Product.all() activeHouseProducts = activeHouseProducts.filterActive() activeHouseProducts= Category.match(activeHouseProducts, "house") and with pipe operator you can do: const activeHouseProducts = Product.all().filterActive() |> Category.match(%, "house")
- magicalist 5y agoFWIW it seems like option 1 should actually be const activeProducts = Product.all().filterActive() const activeHouseProducts = Category.match(activeProducts, "house")
- TedDoesntTalk 5y ago> are there other examples in the language where operator behavior changes in different contexts The newish Elvis operator
- nkozyra 5y agoThe use of the term "pipe" definitely implies a sequential pipeline, and in that sense I agree with the author. But it really only manifests after a few function calls, at which point you're forced to find the initial value and recursively parse the methods. The example is probably unrealistic and not real world, but it's a speed bump I've encountered in real code. Per your example - which is definitely less abstract - it would still feel more intuitive to see 5 | triple() | double() | halve () My issue is the syntax in the proposal, which may feel like another language's implementation, but doesn't really feel like JavaScript. Mentally thinking about JS as an "everything is an object" paradigm, just having a breakout-and-apply chain that looked closer to a dot operator would be more native feeling. ('25').|parseInt(%).|math.Sqrt(%) Other languages imply the pipe "direction" pass-off with syntax like -> but JS has traditionally eschewed that with more apply-transformation-in-place syntax.