Is there ever a time when it makes sense to choose Go over OCaml?

I just finished reading the linked docs and TIL on the last bit about matching host machine. Wow the process is quite involved

Recursion? Who the hell uses recursion [outside of algorithmic code]? But yes, downcast is evil, I agree.

But:

There are no such things as inheritance or casting in Go

:face_with_spiral_eyes:

AFAIK, there’s no empirical evidence that immutable data-structures lead to lower fault density. Maybe especially when compared to things that we know matter - like age of code (older = less bugs; in fact higher correlation than cyclomatic complexity according to one metastudy [ask me for source]), and perhaps social issues like stress and company culture/structure.

I’d actually argue that Java’s package private properties are superior to immutability. Both would be nice to have, tho… :crossed_fingers:

1 Like

Now you got me curious. Pointer please?

These two threads summarize two metastudies I read, about fault density and maintainability metrics.

The missing piece is that no metric is compared to social and environmental factors of the devs. Or skill level of devs, however you’d measure that… :skull:

I don’t need any empirical evidence when I have experience myself how immutable data structures have reduced the amount of bugs in my code base. I can not probably be considered a valid sadistic marker, but it’s good enough for me

That’s what they call “clinical experience” in the medical field, but it’s not science… It’s kinda at the bottom of the knowledge production scale.

1 Like

I mean determination of whether sharing/“modifying” is problematic with immutable data structure is vastly easier than with mutable data structure. I don’t know what an argument to the contrary would look like.

A simple counterargument is that you don’t know how much it matters compared to other factors, both code- and non-code-related (social environment of the company etc). Maybe we’re focusing on completely wrong aspects to reduce bug density? It’s anyone’s guess. :slight_smile:

2 Likes

Yeah well, it’s also called a “red herring” to divert a conversation with an unrelated argument. Your meta-studies provide nothing on how-to-program, programming languages or paradigms, and they carefully conclude that the best metrics are actually the least worst they could find in a sea of contradictory papers. “Code that no-one needed to update in a long time” seems to have less bugs than “Code that is actively being developed”. Cool cool. It’s trolling to dismiss all practical opinions on such ground!

“AFAIK there’s no empirical evidence that GOTO lead to higher fault density than structured programming, especially when compared to things that we know matter - the amount of caffeine in your bloodstream. But according to one study, tea might be even better if you are working on procedural code. (Also the most influential softwares were written under LSD, but since then, failure to reproduce has shed some doubts on their methodology.)”

2 Likes

Three thoughts:

  1. I looked at your emiprical studies, and they appeared to all be for O-O languages? Which … aren’t either functional, nor focused on immutable data, in any meaningful sense.

  2. It’s rare that anybody studies ML-family languages for these sorts of things, eh?

  3. But conveniently, we’re starting to get a real-world test of all this: the rise of Rust. B/c immutability is a key part of what makes Rust work. So hey, maybe in a few years … decades … we’ll have answers.

2 Likes

There’s also the real world example of Erlang/Elixir, for network-heavy
programs. They deal only with immutable structure and share-nothing
communications. Apparently erlang-based services have had crazy high
reliability numbers for decades, and more recent products like Whatsapp
managed large services with very few engineers.

I find these intriguing, especially with the recent announcement of
research on adding types to
Elixir
.

5 Likes

I’ve been a fan of Erlang for a long time (from afar). And yes, it’s produced some very reliable systems. But I think it’s a little to generous to say that it’s due to immutability, per se. Erlang has something that I’ve seen in no other system: fault containment boundaries at smaller-than-process scope.

That is to say (and this is important): in an Erlang address-space (they use “process” to mean “thread”) when a thread faults, that fault can be received by a “supervisor” process, which can deal with it, typically by ripping-down-and-restarting an entire collection of threads. Since all mutable data (and yes, lots of mutable data in Erlang) is associated (== “owned in a strong sense”) with individual threads, this means that you’re ripping down entire subsystems, and cleanly.

In software fault-tolerance, this ability to identify a strong fault-containment boundary within which a full restart can occur, is the sine qua non of high quality fault-tolerance.

As I alluded to earlier, data that is passed between Erlang threads is immutable, and this is also important, b/c no thread<-> interference is possible.

Here’s the one big caveat: it doesn’t mean you get fault-tolerance for any C/C++ code you linked-into your Erlang address-space. It’s just for Erlang code, and just for Erlang-level faults.

But it’s still a big deal, and I cannot emphasize enough just how unique and revolutionary Erlang’s fault-tolerance approach is.

I found the presentation by Rick Harper from the 90s (that introduced me to this concept) about this: https://www.fastonline.it/sites/default/files/2019-06/RobustProgramming.pdf

Page 31 is where the specific approach of error-containment is presented.

5 Likes

In Erlang, immutability is a quite essential part of the fault-tolerance story. Remove it, and it mostly collapses.

1 Like

Immutability is essential for their approach to “smaller than UNIX process” fault containment regions. But there are many languages that focus on immutable data, and yet don’t enjoy the fault-tolerance that Erlang enjoys.

I’m also an acolyte of the church of functional programming, so I also value enormously being able to compute over immutable data. And I can tell you that, having spent nearly two decades living with fault-intolerant systems, and debugging them, discovering Joe Armstrong’s thesis, and reading his words on fault-containment, were like … “oh my god, he did it! he did it!”

But it’s all good: we focus on different parts of the (extremely lovely) elephant.

3 Likes
  1. Oh yeah, this was just an example of metrics that I know have been studied. Searching for “immutability fault density” gives nothing. Everyone’s free to guess. :slight_smile: Or make arguments and pretend it’s knowledge [when in fact it’s rather a hypothesis that needs to be tested].

  2. Didn’t look for it, but I assume most research related to FP is theoretical and type-system related? I’m not sure we have big enough code-bases in FP langs yet.

  3. Isn’t the point of Rust that it can make immutability safe? Similar to Clean.

If Erlang had mutability but enforced values are only copied when shared between processes, perhaps it’d be enough to still let its OTP libs achieve its current levels of fault tolerance and self-healing.

Assuming I never need hot code reloading of any kind, I’d still take static types with an actor based system with basic supervisors any day!

IIRC, Erlang already copies values, except for strings (which can get large). This is the reason that Erlang doesn’t need a global GC, even though it’s a heavily multithreaded system, and exhibits such excellent scalability. Or at least, that’s what I remember from the last time I looked.

And you’re absolutely right about the value of “process supervision”.

1 Like

Back when I debugged Websphere (and J2EE servers generally), I used to make the cynical observation that “there is only one viable application lifecycle: it starts with fork/exec(2) and ends with exit(2).” By which I was casting scorn at the way that J2EE did hot code-reload and such, and pretended that somehow this allowed for application lifecycle management, without actually, y’know, restarting processes.

Needless to say, none of that shit worked, but hey, a buncha “architects” got fat paychecks for it.

2 Likes

I don’t know what the intent is, but I’d rather think that the point of Rust is to make immutability heavily constrained mutability … efficient enough for use in systems code.

Also: the experience of C++ should, I think, give some evidence that constraining mutability (e.g. “C++ const”, weak-tea that it is) is valuable for preventing/reducing many kinds of errors. There’s a reason that in well-run C++ shops, there are strict rules about marking things as const, and not casting it away except under extreme duress.

1 Like

Good arguments. Maybe one should talk about constraints in general, rather? But even so, I don’t know if OCaml + ecosystem is more constrained than Go + ecosystem. If you consider things like taint analysis, which is useful in web dev (if you use Go for web services). Hm… Found one such project for OCaml, and a couple for Go. Pja.