4 ms·
> That is not the right name to use for returning an element without side effects how do you feel about `str.replace`? i'd say that that name implies side-effe
by uryga 6y ago
> That is not the right name to use for returning an element without side effects
how do you feel about `str.replace`? i'd say that that name implies side-effects too, but everybody's used to the fact that [in python] strings are immutable, so it's no big deal. it's all a matter of expectations and language conventions – e.g. in Haskell, `replace`, `reverse`, `insert` etc. would all be pure functions and no one would think about it twice.
and sure, i'd prefer a "declarative" name if one's available (e.g. `plus` vs `add` on numbers). but if you overdo it you end up naming your functions stuff like `with_inserted` or `with_replaced` and that's just... not up my alley at all (though i'm sure someone likes it)
- Dylan16807 6y ago> how do you feel about `str.replace`? i'd say that that name implies side-effects too, but everybody's used to the fact that [in python] strings are immutable, so it's no big deal. In that case it's returning a modified string, at least. 'pop' and 'replace' both create modifications to the item you feed in. You can return the modified version, or you can mutate it in place, or you can do both. But it makes zero sense to do neither. Why would you make a modified version of an immutable variable, then immediately throw it into the void? So as long as 'pop' is returning the element from the list/map/set/whatever, and nothing else, it is the wrong verb for immutable structures. Also, 'pop' works on unordered data structures too, which makes it fit even less since it's now "pick some arbitrary element".
- uryga 6y ago> So as long as 'pop' is returning the element from the list/map/set/whatever, and nothing else, it is the wrong verb for immutable structures. right, but would anyone really write a functional `pop` like that? that's just `last`. any sensible functional `pop` would return a tuple: (x, new_xs) = pop(xs) so i'm not sure i understand what the problem is tbh. we might be in violent agreement... and re: unordered containers, i'd say it "makes as much sense" for immutable and mutable ones. maybe it returns the most recently inserted element or whatever's convenient/efficient to implement; but it's arbitrary regardless of any (im)mutability.
- Dylan16807 6y ago> so i'm not sure i understand what the problem is tbh. we might be in violent agreement... A two-return pop like that is a little weird, but still basically reasonable. But a one-return pop is a misleading term for immutable data structures. Use list[-1] or last(list) or something. When I say I'd be upset at pop not mutating a list, I'm talking about a one-return pop specifically. > and re: unordered containers, i'd say it "makes as much sense" for immutable and mutable ones. maybe it returns the most recently inserted element or whatever's convenient/efficient to implement; but it's arbitrary regardless of any (im)mutability. If the structure is immutable and unordered, a one-return pop is almost totally useless. You use it, it gives you some element. Then what? You can't meaningfully use it again, because it might give you the same element, or it might not. You can't whittle the structure down one element at a time, processing each element as you go. The only things you can dependably do with it are check if the data structure is empty or not, and get an arbitrary example element.
- uryga 6y agoso 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