3 ms·
If one was well-versed in memory management and how the stack would blow up in production one would not have to repeat them here. Also, if you have to justify
by reactordev 3y ago
If one was well-versed in memory management and how the stack would blow up in production one would not have to repeat them here.
Also, if you have to justify cleverness, it’s not clever. Don’t defend the style by grandstanding on “functional is better” or “you don’t know func bro”, how about ask why I feel the imperative style is more legible? Why would this not be the best way to write this? Where can I write this way? Or even “I find this style to be legible to me, but I’m curious about why you think it’s not”.
- satvikpendem 3y agoIt's not "clever" though, it's simply how functional programming languages like OCaml and Haskell work. You think imperative is more legible because you learned primarily from imperative languages, I'm assuming. If you had learned functional programming from the start of your programming life, then you'd find it perfectly legible.
- reactordev 3y agoYou don’t know me or what I’ve learned or know so why presume? The clever bit is the recursive nature of it in addition that it’s functional. I’m pretty sure monads have existed longer than JavaScript and I’m perfectly comfortable reading functional code. The code in the example hides several onion layers of inefficiencies I think need/should/deserve to be called out. I’m not saying everything should be a class man. I’m saying not everything should be a clever one liner.
- trealira 3y agoI think there are cases where the functional style is more legible, but also cases where imperative style is more legible. I really think the imperative style is more legible in this particular case. This is why Haskell and OCaml allow imperative constructs when they're more legible. I'll take an example from Learn You a Haskell[1]. In Haskell, one can implement a quick and dirty stack like this: type Stack = [Int] -- Throws exception on empty list/Stack pop :: Stack -> (Int, Stack) pop (x:xs) = (x, xs) push :: Int -> Stack -> ((), Stack) push a xs = ((), a:xs) You can then write a function to push 3 onto the stack, then pop two items off the stack, returning the second popped item—this is equivalent to just popping an item from the stack and returning it, but the point is to show off the stack manipulation. stackManip :: Stack -> (Int, Stack) stackManip stack = let ((), newStack1) = push 3 stack (_, newStack2) = pop newStack1 in pop newStack2 But using the state monad, it is more legibly written like this: import Control.Monad.State stackManip :: State Stack Int stackManip = do push 3 _ <- pop pop [1]: http://learnyouahaskell.com/for-a-few-monads-more http://learnyouahaskell.com/for-a-few-monads-more
- hajile 3y agoIn this case, imperative with spread would be just as slow and no more readable. The real issue is that this should have been wired up with an iterator. At that point, you aren’t using a for loop and your iterator might actually be faster with property tail calls.