This is almost exactly how my Beads language is designed. It uses a tracked global state, with basically no local state, no NEW, no DISPOSE. Solves a ton of problems. Basically the opposite of OOP.
d
Duncan Cragg
09/11/2019, 8:55 AM
How do you create bits of global state, @Edward de Jong / Beads Project?
Duncan Cragg
09/11/2019, 9:28 AM
And this is also how the Object Net / Onex works.
w
Wouter
09/11/2019, 5:07 PM
dmarbour always appears to be saying very novel and insightful things, but I think I am just lacking something to understand them 😞
Wouter
09/11/2019, 5:13 PM
I'm guessing an important part of what he's saying is that a (properly namespaced) global state is very debuggable, inspectable, loggable, persistable, reversable and many other -ables. Local state is invisible and resists all these -ables. Code without local state is like functional transformers on the global state with predictable outcomes, much like shell pipelines. Is that what he's saying?
d
Duncan Cragg
09/11/2019, 8:47 PM
That's how I understand it (and is the basis for my saying that's how my stuff works).
e
Edward de Jong / Beads Project
09/12/2019, 8:12 AM
OOP creates islands of local invisible state that are not declared in the code, but are created as the instruction pointer traverse through the code. They are a trail of "objects" left behind a bullet, and when perusing the code one cannot see what a common run through the code would produce. Hence the need for evolving massively complex IDE's like Eclipse and Visual Studio whose code bases run in the millions of lines of code. Contrast that with a declarative/deductive system, of which Beads is but one example, you can see all the data structures that will ever exist neatly and concisely specified at the top of the code. It becomes so much easier to predict what happens. I ridiculed COBOL most of my career, but one thing it does fairly well is define the data structures at the top of the program. It has some organizational structure.
❤️ 1
d
Doug Moen
09/12/2019, 10:35 PM
My Curv project embodies a particular approach to state management, but I don't have a buzzword to describe my approach. "The opposite of OOP", like what Edward said, is not very precise. I've been calling Curv a "pure functional" programming language, but it differs from Haskell in some notable ways. You see, Curv also supports imperative programming: it has mutable local variables, an assignment statement, a while statement, a print statement. So what do I call this? Curv does not have "local state", in dmbarbour's sense or the OOP sense, first because it is incompatible with my implementation of live programming and staged programming (which dmbarbour also mentions) and gpu code generation, and second because I want to avoid the incidental complexity created by OOP style local state.
t
taowen
09/14/2019, 12:37 AM
I echo this view as well. Any one can give a explanation why it is easier from cognition perspective?
taowen
09/14/2019, 12:42 AM
Depending on global state or global service (like service locator pattern) is considered a bad practice. The mainstream idea likes clear and explicit "signature" to be able to compose "safely". What is the counter-argument here?
e
Edward de Jong / Beads Project
09/15/2019, 7:47 AM
"is considered a bad practice..." by whom? and why? I am sick and tired of people telling me that global state is bad. If we are talking about a single source of truth from which all conclusions derive, isn't that a mandatory thing? If i have a banking system, and my bank balance says $100, that is global mutable state. If we allow my account to have multiple balance values, that would create chaos, an unworkable situation. So having a bank balance is "bad practice"? This is the absurdity of these dogmatic statements about what is good or bad. I am solely interested in 1) ease of initial programming, 2) ease of fixing errors as reported by customers, 3) ease of transferring the maintenance of the code base to someone other than the author.
None of the goals i hold important have anything directly to do with the details of the programming model. i am interested in the overall results of the technology. And to establish the quality of the results, build test programs, and test them for modification by someone other than the author. Without measurement, you have fad and fashion. I think a lot of FP code is among the least readable i have seen in years. If you are going to go that level of obscurity, just go back to LISP at least the programs will be a lot shorter.
d
Duncan Cragg
09/15/2019, 11:42 AM
😄 👍🏼
Duncan Cragg
09/15/2019, 11:43 AM
I put shared global mutable state at the front and centre of the Object Net - because if you're modelling reality, that's where you have to start!
💯 1
d
Doug Moen
09/15/2019, 1:43 PM
You should respond to what @taowen said instead of attacking a straw man. He mentioned global services and the service locator pattern. If a reusable software component has hard coded dependencies on global mutable state, then it is not very reusable, testable or composable. A very old example of this anti-pattern was the original C library, where many library functions received inputs or returned results via global variables.
t
taowen
09/15/2019, 3:12 PM
The framework I am designing also put global mutable state as the center of architecture, the decesion was made before I found this community. I vaguely feel it to be the right way, but can not articulate a convincing theory from huamn cognition perspective. It would be nice we can come up something to back up our shared design choice, and build a new paradigm on solid ground.
👍 2
taowen
09/15/2019, 3:16 PM
As a ex-thoughtworker, who received professional education from day one on IoC pricinple, I know how OOP runtime polymorphism fail in practice. Nowdays, I would prefer to depending on global service, instead of dependency injection. Here is my answer to the question I was asking:
1. Dependency injection is a overkill, if we only have one impl for that service. There are many ways to change the impl to use, either through configuration file, or make the service a external dependency (lib or rpc). It is like the whole application process is a container, with dependency injected. Fine-grained encapsulation is too idealism, sometimes application process as a encapsulation unit is good enough. Checkout this video:
https://www.youtube.com/watch?v=QM1iUe6IofM▾
2. Runtime polymorphism is hard to reason about, it is better to statically assemble the components than to defer it to runtime. Human cognition has limited working memory budget, it is better spend on the real problem, not on making software "reusable".
3. In terms of having clear component signature to compose safely, I do admit "depending on global service or state" is problematic. But the fault is orignated from limited concept provided from the language we use. Why only input arguments and return value? The dependency on some pre-existing layer should be declared and enforced as contract. We need better language and tools to "make it explicit". Making it explicit does not necessary mean we must make it part of parameter list. We could have a "global dependency list" as part of the signature as well.