3 ms·
so we agree about single-return-pop – it just wouldn't be very useful. what i tried to say is that it's a bit of a strawman – single-return-pop is pretty obviou
by uryga 6y ago
so we agree about single-return-pop – it just wouldn't be very useful. what i tried to say is that it's a bit of a strawman – single-return-pop is pretty obviously useless, so no one would design a pure API like that. so there's no point arguing against it :)
if you want `pop`-like semantics, but also want your operations to be pure, tuples are the only real way to do it. for a real example, see this Haskell implementation of stacks: https://hackage.haskell.org/package/Stack-0.4.0/docs/Data-Stack.html https://hackage.haskell.org/package/Stack-0.4.0/docs/Data-St...
its `pop` has this signature:
stackPop :: Stack a -> Maybe (Stack a, a)
(with a `Maybe` thrown in to account for popping an empty stack)
---
another alternative that works well in some cases is algebraic datatypes and pattern matching:
result = case myList of
[] -> "whoops, empty"
(x : rest) -> (
"the first element is " ++ (show x) ++
", and the rest of the list is: " ++ (show rest)
which is pretty similar to
try:
x = myList.pop(0)
result = "the first element is " + str(x) + " and the rest is " + str(myList)
except IndexError:
result = "whoops, empty"
so that way you can take your structure apart bit by bit like you would with `pop()`. if your container is unordered, you could convert it to a list first.
---
and if wrangling tuples and passing the "state" around like that gets annoying, Haskell has the `State` monad, essentially a wrapper around functions `SomeState -> (X, SomeState)` that eliminates the state-passing boilerplate
- wool_gather 6y agoCurious; why `Maybe (Stack a, a)` rather than `(Stack a, Maybe a)`? The returned stack would be empty like the input.
- uryga 6y agoi guess it's "making illegal states unrepresentable" – with `(Stack a, Maybe a)` you allow an implementation that does stackPop [1,2,3,4] == ([1,2,3], Nothing) which doesn't make sense - `Nothing` is only supposed to happen when the stack is empty, i.e. `([1,2,3], Nothing)` should be impossible. and if `([], Nothing)` is the only "error state", why not just use a `Nothing` for the whole thing instead? and then you can sleep soundly, knowing your pattern-matches are exhaustive :) ergonomically, it's nicer to to test for failure; and you can do "railway-oriented programming", either doing something with the result or quickly bailing out. all that said, there's probably cases where `(Stack a, Maybe a)` is more ergonomic... so you know, this isn't dogma
- wool_gather 6y agoErgonomics could be the reason; good point. I don't think your first point is correct, though; nothing about `Maybe (Stack a, a)` stops me returning `Nothing` incorrectly.
- uryga 6y agoi was going to mention this, but the comment was already long :) of course, this doesn't stop you from implementing it as stackPop _ = Nothing or just doing the wrong thing. but it does prevent you from returning `([1,2,3], Nothing)`, and that's always one less thing to worry about - if not for the implementer, then for the users. and the more the signature constrains possible implementations¹, the better! and this might be subjective, but for me `Maybe (Stack a, a)` results in less cognitive load. with `(Stack a, Maybe a)` if i do case stackPop xs of (_, Nothing) -> ... (xs2, Just x) -> ... in the back of my head i'm going to be thinking "hmm, am i 100% sure i can throw away that first value if i get a Nothing in there? if it's useless, why does the function return it?²" whereas with case stackPop xs of Nothing -> ... Just (xs2, x) -> ... i know for certain there's no new values introduced in Nothing case – great, less things to keep in my head! it's a small thing to be sure, but i like when the types assist me like this :) --- ¹ parametricity is one of my favorite things in pure FP! ² but i hate throwing things away, so it might just be that...
- Dylan16807 6y ago> so we agree about single-return-pop – it just wouldn't be very useful. what i tried to say is that it's a bit of a strawman – single-return-pop is pretty obviously useless, so no one would design a pure API like that. so there's no point arguing against it :) Remember where the conversation started :) It's not a strawman because it's what confused macintux in the first place! I was saying that the thing they expected would be a problem, and we're just discussing how to replace it, not disagreeing with that original idea.
- uryga 6y agogood point, i got a little bit caught up in the argument there :)