9 ms·
> Mixtures of the two tend to have syntax problems. My gripe isn’t the syntax, it’s the lack of guarantees/constraints. When I’m working in a language with im
by macintux 7y ago
> Mixtures of the two tend to have syntax problems.
My gripe isn’t the syntax, it’s the lack of guarantees/constraints.
When I’m working in a language with immutable data structures, I know what to expect. A language like Python with some added functional sugar is much harder for me because I make stupid assumptions. Spent a half hour once chasing down a bug just because I was carelessly assuming list.pop() didn’t alter the list.
Now I keep a Python shell running all the time so I can see whether various functions have side effects.
- Dylan16807 7y agoYou make a good point in general, but I'd be upset if a function called 'pop' didn't mutate anything. That is not the right name to use for returning an element without side effects.
- macintux 7y agoLike I said, it was stupid. I’d spent a few years working with Erlang and hadn’t yet made the mental switch.
- nonbirithm 7y agoRuby has a nice convention where impure functions like those have a "!" appended to the name. For example String#gsub takes immutable string arguments and returns a new string, but String#gsub! operates on a String instance and mutates it. I guess if you write a new programming language, it would be nice to establish that convention early on, when it's still possible to be done.
- klipt 7y agoThat convention may have originated with Scheme, which has non mutating 'let' vs mutating 'set!'
- macintux 7y agoThe problem with Ruby’s approach, if I recall correctly (been 10 years) is that it’s inconsistent.
- ben-schaaf 7y agoThis is still true. Exclamation mostly means "this is dangerous". Array.push doesn't have an exclamation, and libraries like rails use it to signify that a method will throw an exception instead of return whether it succeeded.
- nonbirithm 7y agoActually I was thinking about how to determine function purity in a static analysis manner for a good while, spurred on by how the Chrome developer console sometimes gives "lazy previews" of typed Javascript statements, but only ones that have no side effects. As it turns out V8 has a feature which can guess if an expression is pure or impure, erring on the side of impure due to undecidability and other random issues. It does this by whitelisting a set of opcodes/built-ins that can potentially mutate state or not and running the statement in a separate VM instance with a debug hook set to throw an exception if an impure opcode/built-in is called. The parent developer tools code then prints the expression if the VM instance returns successfully. https://chromium.googlesource.com/v8/v8.git/+/ba5bac8cebe91c585024c67687ced8fe1baed833/src/debug/debug-evaluate.cc#267 https://chromium.googlesource.com/v8/v8.git/+/ba5bac8cebe91c... I wanted something similar in LuaJIT but it's pretty non-trivial to accomplish. I guess it's one of those mildly useful innovations you can only have with a lot of developer time.
- Animats 7y agoChecking for function purity is easier in some languages than others. It's mostly a transitive closure thing. Pure functions can call only pure functions. It's tough in Javascript, because function declaration is dynamic and you can rebind. It's not that tough in a more static language, where you can tell who calls whom at compile time. Way too many years ago, I did that.[1], starting at line 204. Knowing that a function is pure has many uses. You can optimize, using that x=y => f(x)=f(y). Pure functions can safely be used in assertions and conditional debug code. [1] https://github.com/John-Nagle/pasv/blob/master/src/CPC2/p2trutil.i https://github.com/John-Nagle/pasv/blob/master/src/CPC2/p2tr...
- uryga 7y 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 7y 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 7y 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.
- hcarvalhoalves 7y agoIt's reasonable to expect a `pop` function (in the strict sense) that returns a collection without the last element. The point of `pop` is manipulating the pointer of the top element. We can leave the elements and previous copies of that pointer alone in memory.