Live data from Hacker News

All programming philosophies are about state

worldofbs.com

181–190 of 254 posts

Re: All programming philosophies are about state

#181
post #154

I’ve been a programmer all my life, got first sw job around 2000 in business-oriented area (consulting + programming + “ops”). Before that were 5-7 years of toy programming as a kid. I experimented with tech a lot, got into paradigms early and never restricted myself to a single language/env/os/hw. I haven’t created nothing big, stellar or rocket science, but a couple of my projects lived for 10-17 years and counting…

Maybe you simply gravitated towards sensible ways of dealing with it?

There are quite a bunch of things that are _hard_ (IMO) and related to state management a non-exclusive list of examples:

- GUIs in general, the more interactive they are, the more state you need to manage.

- Caching (at any level) is a form of state. You need to be aware of how and when data changes and who changes it and which parts of the caching are affected, when you care about it etc.

- Memory and disk allocation are state. You need to be aware of what your resources are and when to free them up. You might use locks to make sure your data doesn't get corrupted. At a higher layer you might have authorization models to restrict access.

- TCP is state. What do you do when connections fail or get interrupted? Do you store/buffer messages to be processed at a later time? What does that mean for the receiver?

- SQL databases are stateful. Do you ever need to know what happened when? How do you restore previous state? How do you make that efficient? Are backups/snapshots good enough or can you leverage something more granular?

Re: All programming philosophies are about state

#183

Imperative: modifying state is the point of a bit-flipping machine; get out of my way so I can have fun! OOP: OK, I mostly had enough fun, can we try to tame the bit-flipping chaos with real-world analogies, without deflating all the fun? Functional: Any Monad is by definition an Endofunctor, which also means it's an object in the category of Endofunctors, where the monadic μ(flatMap) and η(unit) operators satisfy th…

...and it's a real shame that Haskell has to be like that. I feel like much of the, sorry, mathematical wankery, is well separable from the stuff that actually makes program behavior more predictable in the functional style. I hear that F# has some success at doing exactly that.

> mathematical wankery

Some blog posts are wankery. Haskell in practice is as separate and separable from it as you want.

I learned what a mathematical monad is out of interest (after using them in practice for years), and my conclusion is that it was a huge waste of time with close to zero use for my programming in Haskell.

Re: All programming philosophies are about state

#185

Earlier quoted context omitted.

There is a bit of categorical mixing going on and the author fails to identify actual hierarchies within the programming styles. But he does see, correctly, that it all has to do with state management. I'll point out what he got mixed up: First OO programming is a specific style of imperative programming. OO is simply imperative programming with state and functions scoped into instances. If you are doing OO, you are…

I think your mistake is that it's not about the "abstract"/academic/philosophical or etymological meaning of those terms (functional, imperative, etc). It's about their meaning (as used for decades) within the developer community at large, as established and commonly understood. And in that, there's absolutely a functional vs OO dichotomy, the first meaning Lisp, Haskell, etc, and the latter meaning Java/C++/Smalltal…

>I think your mistake is that it's not about the "abstract"/academic/philosophical or etymological meaning of those terms (functional, imperative, etc).

No mistake made by me. The popular or even academic usage of the terms isn't relevant to the topic here. The reason is because the way these terms are used are highly inconsistent even in academia. They're not formally defined, they're just used for informal fuzzy communication.

I simply define a hierarchy here that's inline with our intuition to point out things the author and you completely missed.

I'm totally with you in that the popular usage is relevant in MOST cases. But in this specific context it doesn't work because the author attempts to do a very broad isomorphism across terms with fuzzy definitions stating that all of these styles are different forms of managing state and he misses the actual true meaning of what's going on.

Let's not get into language specifics like CLOS for lisp. Let's just focus on the core programming style without considering a specific language. All of these programming styles, more or less can imitate each other when managing state. None of them have a crystal clear way of handling state that's specific to their style. OOP can imitate Imperative and vice versa. In fact I'll list all the connections here:

   OOP -> FP
   OOP -> Imperative
   OOP -> Declarative
   Imperative -> OOP
   Imperative -> FP
   Imperative -> Declarative
   Declarative -> OOP
   Declarative -> FP
   Declarative -> Imperative
An arrow represents "can manage state in the same way as".

Basically almost every programming style listed here is so similar they can practically imitate each other. An isomorphism is obvious and the differences in state management are trivial. However, there is one exception above. You will note FP is not at the left side of the table.

Functional programming Cannot imitate ANY of the other paradigms. Both the author and you completely missed this.

What I am saying is this, there's really only two basic ways of handling state and these two ways are fully exemplified between functional and imperative styles.

All the other styles including the SOA stuff is just fluff. Different ways of doing the same thing. It's like replacing every letter in the alphabet with a different symbol and calling it a new language even though it's still more or less the alphabet.

>Not in any colloquial use of the term. SSA form might be "functional programming", but it's not what 99% of devs (and the author) means by functional programming, which includes the trappings and idioms offered by traditional languages called functional programming languages.

This statement here is categorically wrong even when considering colloquial understanding of THIS concept. It is just factually completely incorrect. Have you tried doing this? map, reduce, recursion, and all FP patterns become your ONLY tools when things become immutable.

Try writing fibonacci with everything immutable in say something simple like JS or python. Good luck doing it without using recursion or reduce.

The isomorphism between FP and imperative programs that use immutable variables is something well known, but apparently, not by you.

Re: All programming philosophies are about state

#187
post #88

Earlier quoted context omitted.

FP is about evaluating expressions and it doesn't have state all over the place. I would also add that statefulness is incredibly hard and complex to get right in complex applications and pure fp languages like haskell lack enough emphasis on runtimes to handle this gracefully.

> FP is about evaluating expressions and it doesn't have state all over the place. FP is all about side effects. Every time you declare something you're effecting a compile time side effect. And then there's monads, which are literally reinventing state with a worse API. I find it odd that no mainstream functional language has an explicit call stack monad and an explicit symbol table monad. Maybe because even the "pu…

> FP is all about side effects.

Every programming language is about side effects.

Computations that don't lead to side effects are useless.

That being said fp splits a core functional part (pure, no side effects of any kind) and the interpreter part where the instructions are run.

The way one should visualize pure functional programming is that functional programs don't _do_ anything. They are equivalent to producing a description of the operation. The actual execution happens when those descriptions (generally encoded in effects or data types such as IO/Task) are interpreted by an external runtime.

Re: All programming philosophies are about state

#188

What happened to good ol' saving state in variables and modifying it using simple operations as needed?

From my experience, most internal business logic is coded using simple imperative style, even if the language used offers object-oriented solution.

Frequently, there are 30+ local variables inside a procedure or a function. It is very rare to even see a class definition. I am talking about mostly financial logic.

Re: All programming philosophies are about state

#189

What happened to good ol' saving state in variables and modifying it using simple operations as needed?

When state is stored simply in variables, especially public fields in a structure, then any code can access them -- even if doing so will violate invariants that the type is expected to uphold.

For example, if I have a `String` whose byte sequences must be valid UTF8 (as in the case of Rust's `String` type), or if I have a `UnitVector3` (which is a `Vector3` that must be of unit length), then allowing direct manipulation of structure fields (X, Y, Z) creates the possibility of instances existing that break the invariant. In the case of Rust `String` that leads to memory unsafety.

Abstractions make it possible to enforce invariants using the type system. If `UnitVector3` provides functions such as a constructor that either (1) takes a valid unit vector as input, or else fails or (2) takes any vector as input, and changes its length to become a unit vector (etc.); and also all of the type's functions return `UnitVector3` (where appropriate, e.g. transformations such as rotation), then it is impossible for an invalid `UnitVector3` to exist!

To continue the example, if I add two vectors together, then their sum will be a `Vector3`, not a `UnitVector3` -- so that operation should have the appropriate return type (`Vector3`). Meanwhile rotating a `UnitVector3` will always return a `UnitVector3`. But translating a `UnitVector3` yields a `Vector3`. And so on. Any code written using these operations can determine from their return type what scenarios it needs to handle (is the return value guaranteed to be another unit vector, or could it be any vector?).

If any code can access and manipulate the X, Y, Z coordinates of `UnitVector3`, then any code that relies upon instances being actual unit vectors has the potential to misbehave. That code is correct -- it's the code that created an invalid `UnitVector3` that's wrong! But the error will show up somewhere else at runtime.

Encapsulating these fields within a type (that provides getter methods), and provides a constructor that validates the input (and fails on invalid), makes this entire class of error impossible.

It is still possible for code to attempt to construct an invalid `UnitVector3`, but the call to the constructor (which validates its input) will fail, thus causing the program to fail as soon as possible, and in the most relevant place!: In the code that's creating an invalid vector -- not some obscure other part of the program that is processing the invalid `UnitVector3`.

Using the type system to enforce soundness properties is impractical to achieve without encapsulation, and the ability to hide data and provide interfaces to it. Structures with public fields, where any code can modify their value, is very high risk by comparison.

Re: All programming philosophies are about state

#190
post #183

Earlier quoted context omitted.

...and it's a real shame that Haskell has to be like that. I feel like much of the, sorry, mathematical wankery, is well separable from the stuff that actually makes program behavior more predictable in the functional style. I hear that F# has some success at doing exactly that.

> mathematical wankery Some blog posts are wankery. Haskell in practice is as separate and separable from it as you want. I learned what a mathematical monad is out of interest (after using them in practice for years), and my conclusion is that it was a huge waste of time with close to zero use for my programming in Haskell.

> I learned what a mathematical monad is out of interest (after using them in practice for years)

Agreed. I regret that I tried to learn what a mathematical monad was before using them, out of a belief that it would help me get started quicker with Haskell. It didn't. It made something confusing that's actually pretty simple.

Post reply on HN