HackerTrans
TopNewTrendsCommentsPastAskShowJobs

mononcqc

no profile record

Submissions

When Groups Get Stuck on the Wrong Problem

jrwinget.com
2 points·by mononcqc·9 miesięcy temu·0 comments

comments

mononcqc
·2 lata temu·discuss
Two years after writing A Pipeline Made of Airbags, I ended up prototyping a minimal way to do hot code loading from kubernetes instances by using generic images and using a sidecar to load pre-built software releases from a manifest in a way that worked both for cold restarts and for hot code loading: https://ferd.ca/my-favorite-erlang-container.html

It's more or less as close to a middle-ground as I could imagine at the time.
mononcqc
·3 lata temu·discuss
I'm not quite sure how Erlang's world is totalizing. It has ways to ship things in a very integrated manner, but I have shipped and operated Erlang software that was containerized the same as everything else, in the same K8s cluster as the rest, with the same controls as everything else, with similar feature flags and telemetry as the rest, using the same Kafka streams with the same gRPC (or Thrift or Avro) messages as the rest, invisibly different from other applications in the cluster to the operator in how they were run aside from generating stack traces that look different when part of it crashes.

That it _also_ ships with other ways of doing things in no way constrains or limits your decisions, and most modern Erlang (or Elixir) applications I have maintained ran the same way.

You still get message passing (to internal processes), supervision (with shared-nothing and/or immutability mechanisms that are essential to useful supervision and fault isolation), the ability to restart within the host, but also from systemd or whatever else.

None of these mechanisms are mutually exclusive so long as you build your application from the modern world rather than grabbing a book from 10-15 years ago explaining how to do things 10-15 years ago.

And you don't _need_ any of what Erlang provides, the same way you don't _need_ containers (or k8s), the same way you don't _need_ OpenTelemetry, the same way you don't _need_ an absolutely powerful type system (as Go will demonstrate). But they are nice, and they are useful, and they can be a bad fit to some problems as well.

Live deploys are one example of this. Most people never actually used the feature. Those who need it found ways (and I wrote one that fits in somewhat nicely with modern kubernetes deployments in https://ferd.ca/my-favorite-erlang-container.html) but in no way has anyone been forced to do it. In fact, the most common pattern is people wanting to eventually use that mechanism and finding out they had not structured their app properly to do it and needing to give it a facelift. Because it was never necessary nor totalizing.

Erlang isn't the only solution anymore, that's true, and it's one of the things that makes its adoption less of an obvious thing in many corners of the industry. But none of the new solutions in the 2023 reality are also mutually exclusive to Erlang. They're all available to Erlang as well, and to Elixir.

And while the type system is underpowered (and there are ongoing area of research there -- I think at least 3-4 competing type systems are being developed and experimented with right now), that the syntax remains what it is, I still strongly believe that what people copied from Erlang were the easy bits that provide the less benefit.

There is still nothing to this day, whether in Rust or Go or Java or Python or whatever, that lets you decompose and structure a system for its components to have the type of isolation they have, a clarity of dependency in blast radius and faults, nor the ability to introspect things at runtime interactively in production that Erlang (and by extension, languages like Elixir or Gleam) provide.

I've used them, I worked in them, and it doesn't compare on that front. Regardless of if Erlang is worth deploying your software in production for, the approach it has becomes as illuminating as the stacks that try and push concepts such as lack of side-effects and purity and what they let you transform in how you think about problems and their solutions.

That part hasn't been copied, and it's still relevant to this day in structuring robust systems.
mononcqc
·4 lata temu·discuss
I tried it with Erlang. Their "Sample Code 2" does not generate working code (lowercase variable assignments), and their "Sample Code 3" does not even generate valid syntax, flat out leaving bits of typescript untranslated.
mononcqc
·4 lata temu·discuss
See https://news.ycombinator.com/item?id=31425298 for a response, since this is a duplicate. TL:DR; I had never seen it and had no idea it was possible because I don't recall seeing any documentation or post ever mentioning it! Ignorance on my part.
mononcqc
·4 lata temu·discuss
You're right. After all these years (and even writing a book that had Elixir snippets in it) I had never seen a single example showing it was possible and did not know it could do it.

Well there you go, I guess the pattern is equivalent but incidental.
mononcqc
·4 lata temu·discuss
The Erlang 'maybe' expression expands on what 'with' allows in Elixir, mostly because the 'with' construct allows a list of conditional patterns and then a general 'do' block, whereas the Erlang 'maybe' allows mixed types of expressions that can either be conditional patterns or any normal expression weaved in together at the top level.

It is therefore a bit more general than Elixir's 'with', and it would be interesting to see if the improvement could feed back into Elixir as well!

The initial inspiration for the 'maybe' expression was the monadic approach (Ok(T) | Error(T)) return types seen in Haskell and Rust, and the first EEP was closer to these by trying to mandate the usage of 'ok | {ok, T}' matches with implicit unwrapping.

For pragmatic reasons, we then changed the design to be closer to a general pattern matching, which forced the usage of 'else' clauses for safety reasons (which the EEP describes), and led us closer to Elixir's design, which I felt was inherently more risky in the first drafts (and therefore I now feel the Erlang design is riskier as well, albeit while being more idiomatic).

So while I did get inspiration from Elixir, and particularly its usage of the 'else' clause for safety reasons, it would possibly be reductionist to say that "the good ideas were stolen from Elixir." The good ideas were stolen from Elixir, but also from Rust, Haskell, OCaml, and various custom libraries, which have done a lot of interesting work in value-based error handling that shouldn't be papered over.

I still think these type-based approaches represent a significantly positive inspiration that we could ideally move closer to, if it were possible to magically transform existing code to match the stricter, cleaner, more composable patterns that they offer.

In the end I'm hoping the 'maybe' expression still provides significantly nicer experiences in setting up business logic conditions in everyday code for Erlang user, and it is of course impossible to deny that I got some of the form and design caveats from the work done in the Elixir language already :)

Also as a last caveat: I am not a member of the Erlang/OTP team. The design however was completed and refined with their participation (and they drove the final implementation whereas I did the proof of concept with Peer Stritzinger and wrote the initial EEP), but the stance expressed in my post here is mine and not the one of folks at Ericsson.
mononcqc
·4 lata temu·discuss
So this disagreement is an interesting example of error being a construction in itself: I will posit that you are wrong or not interpreting my point of view properly, and you will say that I am wrong or possibly not explaining things properly.

There is an objectively quantifiable disagreement. But its nature (and even whether it is desirable or not) are possibly camped in subjective terms. Of course you could argue that I am objectively wrong — though trying to prove that with my own writings is risky since we’ve established I’m not a trustworthy source — but that in itself does not resolve the overall disagreement from existing.

This sort of situation can also happen in software where an ambiguous specification yields two distinct compliant implementations that nevertheless do not work together.
mononcqc
·4 lata temu·discuss
Well if all you have is bugs but you never look into how they get there and how they happen, you’re not going to improve your process or tools much.

Also blame and accountability and responsibility are all subtly different.
mononcqc
·4 lata temu·discuss
Fixing the bug does not necessarily fix anything else it caused though, and none of the questions in my post are answered by “fix it”.

Here’s another one: should the incident actually have an impact on anyone of the companies employees yearly reviews? Either positive or negative? Why?
mononcqc
·4 lata temu·discuss
To illustrate the point, let's imagine that 5 years ago, a driver in the linux kernel was written in such a way that interplay with a new disk drive could corrupt data when power failed. The disk on its own (and with other OSes) is fine, and the linux kernel in all other cases are fine.

An open-source database is being used and operated as a service by a vendor, which a SaaS company relies on to provide a feature that your organization uses to manage data on behalf of users.

We now have a chain that includes: users <- customer organisation <- SaaS vendor <- DB as a service vendor <- OSS DB maintainers <- Linux maintainers <- Driver writers <- Hardware vendors.

There is suddenly a power outage at the DB as a service vendor (because of an unmaintained powerline falling over) and their UPCs appear not to be functional for yet unknown reason (cost cutting or supply chain issues during covid time may receive some blame). Your users lose their data regardless.

What is the bug? Who is at fault? Is it the engineer? The team who wrote the code? The QA folks? The organization that hired them? Who should fix the issue? Who should be on charge with repairing data corruption? Whose backups should be trusted most? The least? Have you been lenient in your usage of a SaaS vendor? Has the SaaS vendor been lenient in the services they use? Which actors can be considered liable from a legal standpoint? Which actors can be considered liable from an ethical or moral standpoint? Are your customers the one who made a bad decision contracting you? Can there be more than one party responsible? Do any of these answers changed based on whether the power loss is caused by an act of god or bad maintenance? Based on which jurisdiction you're in? How do you define honest mistakes? Negligence? A bug is a bug because the software did not meet the expectations that were set. Were the expectations reasonable? Who should have managed them?

Events happen. The meaning we attach to them is of course based on expectations and standards and the environment and context, but the way we build our explanation, the ways we attach blame and accountability varies. You can sometimes decide to assign accountability to individuals, sometimes to systems, sometimes both. Sometimes only some or sometimes neither.

So sure, you can point at the actual technical lines of code and say "these aren't doing what they should", but if you do this in a vacuum without also wondering who decided what these lines should be doing and what pressures were at play when they were written, are you necessarily learning a lot about how events unfold and how they might unfold in the future?

A systemic perspective will yield different reactions than one based on personal engineer responsibility, which will be different from one that looks at it from an insurer's point of view, which will be different from one which looks at it from an education point of view, etc. So the lens you take to look at the events surrounding the error and the interpretation you make of it are absolutely crucial to the corrections and learnings that follow.
mononcqc
·5 lat temu·discuss
I'm aware of this. I'm living in a place where power is over 99% renewable and makes use of no gas for utilities, work from home and drive fewer than 5,000km/y as a household, and eat a low-meat diet.

The biggest gains to be had are obviously systemic, and what I do as a consumer is far more limited in its scope and impact. I still limit my flights, no longer attend in-person conferences, try to travel more local, because what else am I going to do? I'm aware this is like putting out a cigarette when the whole town's already on fire, but I can't deal with the dissonance otherwise. It's still an individual luxury that can have an oversized impact compared to everything else I do.

Advocating for it is not going to be sufficient at all, but it's still the most impact I can have when all the big stakeholders who have to fix their powergrid are not even in countries I live in.
mononcqc
·5 lat temu·discuss
Because that 60% from coal is more or less shared across everyone, but flights are, on the global scale, a luxury item. In many cases, taking a transatlantic flight emits more CO2 equivalent than your average person commuting for a year.

So even though aviation is a small part of it all, it is one of the individual actions able to have outsized impact, usually for leisure or at least often for non-essential reasons.
mononcqc
·5 lat temu·discuss
Generally this is going to be true of newer experiences that offer a shift in perspectives.
mononcqc
·6 lat temu·discuss
as one of the rebar3 co-authors, you'd have gotten rebar3 regardless of hex: we couldn't use the packages in there, and there were no packages that existed. We even entirely broke rules about how package versioning works compared to what Hex expects.

However, we didn't spit on having a package manager (that wasn't a bad lazy index hosted on a github repo), and it became a very interesting bridge across communities that we don't regret working with. Our hope now is to try and make it possible to use more Elixir libraries from the Erlang side, but the two languages' build models make that difficult at times.