5 ms·
I'm way out of my depth here, but interested in trying to understand a few of these things, particularly because I've long wondered how functional programmers r
by ledauphin 6y ago
I'm way out of my depth here, but interested in trying to understand a few of these things, particularly because I've long wondered how functional programmers reason about the "effects" that happen under the hood when dealing with Turing machines which are essentially 100% state.
Specifically:
1) do you consider variable reference to be an effect because you're getting a value from memory/disk/network? Or is it effectful simply because you're replacing a name with a value somehow? I'd love to understand the point of view here.
2) Relatedly, why do you say that creating a lexical closure is effectful (I assume here that we are storing an immutable memory address, or at least a value which represents a way to reliably find another value in the future), but using it (dereferencing that address/value) is not? I can see why you'd say that creating a dynamic closure is not effectful (the code is essentially unattached to anything at the time of creation and can easily be represented by a pure value), but using it is (it now inhabits a scope and will act differently depending on that scope).
Having typed that out, I wonder if what you mean is that creating the lexical closure in a language with immutable data means that at the time of creating the closure, you are (one way or another) making a copy of that data, which is an input "effect" in a sense. That isn't, of course, how things actually work in most non-functional (e.g. OO) languages - the lexical closure only binds the name, but the value represented by the name could in fact change if the data itself is mutable.
Anyway, I'm still curious about #1 above. These are the sorts of comments I come to Hacker News to read, so thank you. :)
- siraben 6y ago> 1) do you consider variable reference to be an effect because you're getting a value from memory/disk/network? Or is it effectful simply because you're replacing a name with a value somehow? I'd love to understand the point of view here. To give an example, say you have int* x. When the expression (*x) is used later on, it is the dereference that is effectful. In other words, the expression lacks referential transparency. Going further, Oleg says that "an expression is effectful if it sends a message to its context". The example he gives is x+1 being impure, since it sends a request to the context to look up the value of x, whereas (λx. x+1) is pure because λ provides a handler for the request to look up the value of x, and the whole expression can be evaluated without sending anything more to the context. > 2) Relatedly, why do you say that creating a lexical closure is effectful (I assume here that we are storing an immutable memory address, or at least a value which represents a way to reliably find another value in the future), but using it (dereferencing that address/value) is not? I can see why you'd say that creating a dynamic closure is not effectful (the code is essentially unattached to anything at the time of creation and can easily be represented by a pure value), but using it is (it now inhabits a scope and will act differently depending on that scope). Creating a lexical closure (see 1:22:30 of the video) involves capturing the environment in which the closure was created. As in #1, the effectful part comes from a request to the context, which is collecting the free variables in the body of the lambda and building the closure. OTOH for dynamic closures you can create them without sending any request to the context, but when you apply it you have to request from the context. The discussion on the Actor model is very relevant to understand what it means for expressions to send requests to contexts.