4 ms·
I think he's getting lost in the complexity of infrastructure. Not realizing the true key of what modularity is. The truth is we don't fully have a theory aroun
by corethree 3y ago
I think he's getting lost in the complexity of infrastructure. Not realizing the true key of what modularity is. The truth is we don't fully have a theory around all of it yet but we have a good idea about parts of it and how to maximize modularity of certain aspects of your program.
The segregation of state away from pure functions is the "state" of the art right now in terms of modularity. By doing this you are maximizing modularity of your program to the greatest extent that we know of in theory.
The segregation of computer logic into containers, servers, files, folders and all that other stuff are just illusions and arbitrary boxes that serve only to confuse. The most modular abstraction is the pure combinator. Once your program is in itself a combinator composed from other combinators, then and you can arbitrarily choose where you want to put them. Put one set of combinators in a container on one server or another set in a folder split among arbitrary files. Put em in libraries or don't... up to you. Again it doesn't matter... because your combinators flexible enough that you can move your combinators anywhere.
The infrastructure is irrelevant and an arbitrary choice in terms of the initial design. You must choose your code abstractions such that you have the flexibility to make ANY arbitrary infra choice and the pure combinator is the one such abstraction that maximizes the amount of choices you have.
The flaw with this pattern is that it doesn't include state. Hence why you need to segregate it away using a pattern called: functional core, imperative shell. The IO monad in haskell actually forces you to program with the pattern.
We don't fully know how to maximize modularity when we have state and functions working together so what we do is we just try to segregate the two concepts as much as possible. By doing this we have large sections of the program that are extremely modular and small singularities of the program where we have to combine state and function.
This is the front line in the quest for modularity. All the infra stuff is just fluff.
What the author talks about is largely inline with what I'm saying here but he's getting a bit lost and not driving home to the key insight here that's been formalized by languages like haskell.
- lioeters 3y ago> The segregation of state away from pure functions is the "state" of the art right now in terms of modularity. I've heard pure functions described as "having no side effects". So "being pure" means having no state of its own, as well as not having an effect, changing the state of anything anywhere else. > We don't fully know how to maximize modularity when we have state and functions working together.. Doesn't that describe Object-Oriented Programming, at least some aspect of it, like classes which bind state and methods together? The difficulty, in my experience, is that there can be many, many objects with their own state, affecting each other's state in a complicated web/graph of effects. > functional core, imperative shell This approach of "pushing state up" to the surface, I think is the way to keep all states in one place, with every change under control. Better yet, to have immutable state, with every effect/change producing a new state. > Once your program is in itself a combinator composed from other combinators In this context, does a combinator mean something similar to a pure function? I see on Wikipedia: > Combinatory logic can be viewed as a variant of the lambda calculus, in which lambda expressions (representing functional abstraction) are replaced by a limited set of combinators, primitive functions without free variables. And the meaning of "free variables": > In computer programming, the term free variable refers to variables used in a function that are neither local variables nor parameters of that function. The term non-local variable is often a synonym in this context. Aha, non-local variables. That smells like global or external state. Right, I think years of programming have taught me to intuitively notice mutable state, especially when a function is trying to reach out and make an effect on some state outside itself. That goes against modularity, unless it's managed intentionally.
- corethree 3y ago>I've heard pure functions described as "having no side effects". So "being pure" means having no state of its own, as well as not having an effect, changing the state of anything anywhere else. This is correct. The "state" part of the equation is equivalent to IO. You either manipulate state, or you manipulate the state of the real world (aka IO). The key is to segregate state and IO away from purity. >Doesn't that describe Object-Oriented Programming, at least some aspect of it, like classes which bind state and methods together? The difficulty, in my experience, is that there can be many, many objects with their own state, affecting each other's state in a complicated web/graph of effects. Yes. OOP by nature unionizes state and method. That is the very definition of an object. But this is not exclusive to OOP. You can do this with any programming paradigm except for strictly functional programs that force you to segregate mutating state and function. >This approach of "pushing state up" to the surface, I think is the way to keep all states in one place, with every change under control. Better yet, to have immutable state, with every effect/change producing a new state. Yes. But the problem is If we truly had immutable state and we produced new state every time this will in the most practical cases lead to a OOM error. We must at some point change state in order to save memory. >In this context, does a combinator mean something similar to a pure function? I see on Wikipedia: Similar. The free variable restricts modularity of the function. x = 5 f(n) = n + x vs. g(n) = n + 5 g is more modular then f because f cannot be moved out of the context of x. g is the combinator while f having a free variable x is not a combinator. This is why the combinator is the most modular primitive. >Right, I think years of programming have taught me to intuitively notice mutable state, especially when a function is trying to reach out and make an effect on some state outside itself. That goes against modularity, unless it's managed intentionally. Exactly and the way to manage it intentionally is to minimize the need for management as much as possible. Remove all logic away from mutations. Mutation is division by zero. Minimize this action as much as possible. Additionally treat mutation and IO as the same thing. You are either mutating state or mutating the world.