4 ms·
Function Purity and Immutability in D
- a0 12y agoThere is also a good article about purity in D by David Nadlinger, who is one of the core developers of LDC (LLVM D Compiler): - http://klickverbot.at/blog/2012/05/purity-in-d/ http://klickverbot.at/blog/2012/05/purity-in-d/
- dbaupp 12y ago(For whatever reason HN is nonstandard and includes the trailing >; working link: http://klickverbot.at/blog/2012/05/purity-in-d/ http://klickverbot.at/blog/2012/05/purity-in-d/ )
- wyager 12y ago>A pure function does not read or write any mutable data that is not accessible via the function's arguments [but it can read/write mutable data pointed to by its arguments] That's not a particularly strong or interesting definition of purity. It just means you can't have mutable globals. That is not really powerful or helpful in any way that I can see. I feel like this is a bit of a disingenuous (or perhaps just misunderstanding) attempt to latch onto a buzzword from the functional programming realm that means something almost completely different. Purity has a much stronger definition than "don't mutate global variables". See http://en.wikipedia.org/wiki/Pure_function http://en.wikipedia.org/wiki/Pure_function
- qznc 12y agoA function simply annotated with pure is sometimes called "weakly pure". If its arguments are declared immutable, it is "strongly pure" which essentially matches your definition. All languages I know (e.g. Haskell) make concessions to pragmatism. For example, even pure function can somehow create debug output. Every memory allocation does mutate global state. The weakly pure class of functions is useful. It limits the potential side-effects to stuff reachable from mutable arguments. For example, a image filter function can be weakly pure while it mutates the image provided as an argument. It removes the need allocate a return image or wrap computations in monads and thunks. To get really strong guarantees in D, you declare your functions pure, nothrow, and @safe. The nothrow means no exceptions are thrown and @safe means all the low-level tricks (casts,assembly,etc) to break type safety are disabled.
- T-R 12y agoThat still means the function can't be treated as referentially transparent (whereas a Haskell function with debug output still can be, for the most part). Don't get me wrong, that's still somewhat useful - it tells me "this function doesn't do anything too crazy", but it doesn't tell me "it should be safe to refactor this without having to read the function bodies of the entire call graph below this point", which makes calling it "pure" seem a bit disingenuous.
- qznc 12y agoGiven pure + @safe + immutable arguments, how is it not referentially transparent? (we ignore the practical concessions: debug statements, memory management, termination, floating point hardware state)
- T-R 12y agoI'm not saying it isn't - it's certainly good that it's also possible to declare something as referentially transparent, but defining the keyword "pure" to imply something much less than referential transparency is still a poor choice. Edit: To be clear, I don't really feel too strongly about it. It's still leagues ahead of many other languages - I just think that particular choice of keyword is likely to confuse things a bit.
- sophacles 12y agoIn D, if a function is pure, can it call a function that modifies global state? That is to say (in not necessarily real D, just close enough) given: int global_var void modify_global(int z) { global_var += z; return global_var; } pure int foo(int x) { return x + modify_global(2); } What happens? Does the compiler barf because it causes modification to something not passed? If so, assuming that you can only modify the object passed (via methods of it, and presumably, the things that object points to in its members), then it maintains something much closer to referential transparency than you are implying.
- 2color 12y agoWalter Bright is indeed a really bright mind. Having worked with D recently, I really enjoyed the richness and empowerment the D language offers. I believe the recent rising interest in functional languages is in part due to the elegant blend of expressiveness and performance. Performance is always a delicate topic nevertheless there are some aspects of functional languages which tend to make them more performant.
- deleted 12y ago[deleted]
- smegel 12y ago> This is why a cast to immutable is not allowed in D code marked as @safe. It's an interesting design decision that D code is (presumably) @unsafe by default.
- WalterBright 12y agoYes, although one can explicitly mark code as @system. (I've never liked the "unsafe" attribute, as it implies the code is actually broken.) Safety is something that becomes more desirable the larger and more complex a program is. I wanted D to also be convenient to use for quick, simple programs without burdening the user with having to add annotations.
- bjz_ 12y agoIt is unfortunate that the length of the `immutable` seems to ergonomically discourage its use. I know it's really hard to go back on language design decisions, but have there been any thoughts about providing a shorter alternative?
- WalterBright 12y agoIt used to be called "invariant". We found ourselves constantly explaining to people that "invariant" types were immutable. Bowing to the obvious, we changed it to "immutable". This has been highly successful in that people immediately understand it. Nobody ever found a shorter, equally clear term.
- bjz_ 12y agoYeah - naming things is hard. I agree that `immutable` is clearer than `invariant`. I would suggest `imm`, but that is damn ugly and more opaque. :(
- bibonix 12y agoWhy not get rid of mutable data in the first place? That would make this language (and my others) much cleaner.