mrkeen
Joined 9 years ago
Joined 9 years ago
https://www.hrw.org/report/2023/12/21/metas-broken-promises/...
https://www.theguardian.com/global-development/2025/dec/11/m...
Trying to one-shot 'print "hello world";' into
.LC0:
.string "hello"
"square":
push rbp
mov rbp, rsp
...
is probably a non-starter, so compiler writers tend to attack the problem by breaking it down into lots of passes.Parsing into an AST is obviously the first, then you might opt into other passes, like type-checking, handling closures, simplifying into some kind of IR, and finally generating code. Each of those stages can be effectively unit-tested (except maybe the last). If you make a mistake in parsing (e.g. mistaking a statement for an expression), you don't want to have to catch that error by inspecting machine code. It's nice if each pass can be easily tested. And one simple way to test these things is to write an interpreter for each pass (mostly because you get to enjoy the facilities of whatever host language you're writing in). Then you can start saying things like "for all inputs, interpreting the AST gives the same result as interpreting the type-checked-AST, gives the same results as interpreting the closured-AST, gives the same results as interpreting the list of IR instructions."
You mention "It ought to be easy because it is possible to only target the common subset of features these architectures support." <- That's your IR right there!
Once you have an IR that looks close enough to the target machine language, it shouldn't be too hard to translate the final step. Or just use LLVM.
I noticed in your code that you're using C, and really there's no need. Languages don't need to be stacked in a hierarchy (e.g. Clojure on top of the JVM which is C++ which compiles to asm). The compiler can be any language, because it only needs to be able to take in source code and spit out bytes.
The "Goose teleports" code needs to go in Ben/Teleport.src, or Alice/Goose.src. Otherwise the compiler doesn't know which implementation to use if there are multiple.
Scala (and I think Ocaml) have mechanisms for selecting which one to use. In Haskell you'd use a newtype wrapper.
When did it become a future event again?
If you have a protocol for interacting with your own database, you either need to rule out interacting with other systems (i.e. you have Revolut credits and you can only use them in the Revolut store,) or create a second protocol for inter-system transfers, in which case you have two protocols, and that second protocol won't play nicely with the first - e.g. partner bank informs you about a several new money transfers and a chargeback, meanwhile you're taking locks and directly setting balances. If the inter-system protocol is good enough, it will do everything the owned-locked-crud-database protocol would, and the crud is just going to get in the way.
You also have the problem of owning 'one thing'. If you lose 'one thing', you've wiped out all your records. Not to mention regular downtime from patching/releases etc. If for some reason you have the chance to use a database which presents itself as one-thing (but is distributed behind the scenes and has redundant replaceable parts) then whoever implemented that database is at the minimum using some kind of WAL (the 'ledger' of the database world), because those folks know they can't just have multiple masters CRUDding each other willy-nilly.
> How would a ledger work without having some kind of lock, how would you prevent a negative balance?
I wouldn't try to initially (but do see below). If the system can keep your balance from going below 0, then by CAP it's not available. If your supermarket loses connectivity or you're buying a cocktail while flying in a plane, your payment would just fail.
> When someone checks their balance, would you to retrieve every transaction from the ledger and calculate the current balance?
Pretty much everything in the concurrent space boils down to avoiding shared-mutable state. If you have it, your code is probably broken. Locking, ownership, defensive copies, immutability, etc. are all efforts to stay sane. If you go down the immutability path, more options open up. I use Kafka as the example. You append one new fact every time a money transfer happens. From a performance POV, Kafka scales horizontally, and appends only need negligible locking. I mention Kafka specifically because it also acts as the distribution. Different independent systems can follow it in near real-time, and they can choose to store and present the current balances, as a running calculation. And it works as long as you don't go back and edit history (corrections are appended instead.) As long as the kafka records are intact, you can always rebuild any other derived data from it.
If you did really need to forbid less than zero, you can model that in your events. Instead of emitting a MoneyMoved event, you could emit a MoveMoneyIfAvailable event. The reader of the system would see that event strictly in order (this is the key bit - you're basically using Kafka to gain linearisability in ACID-speak) and either emit a MoneyMoved event or a MoneyMoveRejected event in response. But again, this last trick doesn't mean you can order cocktails on a plane (if you tried to emit a MoveMoneyIfAvailable from up there, it wouldn't reach the server, and you also couldn't get the yes/no back anyway).
This is why I wrote:
Technical discussions are incredibly likely to devolve into people discussions.
No people discussion has ever worked it's way back into being about fixing the broken software.
I'm perfectly happy, if things get out of hand, for someone to take me aside and say "you were a bit of a cunt back there mrkeen." We're all human. As long as we actually get fix the code or resolve the intellectual side of the argument too.I wouldn't dream of calling someone a smug disagreeable know-it-all.
I'm here for any discussion of the tradeoffs of balance v ledger, though.
Revolut, for example, has confirmed all its operations, that include, sign-ups, sign-ins, payments and transfers, top-ups, ATM withdrawals, stock trades, cryptocurrency, are all down.
https://www.neowin.net/news/google-cloud-outage-takes-down-h...Who owns the database in your locked example?
You might be assuming that there is only one database, and that all consumers are reliably connected it. So who owns the database: Visa or MasterCard? Because ACID doesn't span across database instances (let alone database vendors or companies).
If you write down that "Bob withdrew $20", that cannot be wrong, (at best it can lack info that you later wish you had).
If you write down "Bob's balance is now $10", you already know the problems with that from your question.
I have all the patience and time in the world to discuss my ideas.
I had the problems, the solutions, slide decks and a Miro board ready to go.
He wanted to shut down discussion at every turn with nonsense like "so you think no banks work at all?". Sure, I can grin and eat shit, or I can say "banks predate your CRUD operations by just a little bit".
If he had working knowledge on how to represent mutable money amounts in a distributed environment, he didn't let on. I was all ears.
So I pushed back on him, and I'll push back on you:
> even if you were technically correct why would a company hire someone...
Because I'm technically correct.
You're certainly not alone in your appraisal of the situation. The market over here works exactly this way. Correct, reliable systems come a distant second to agreeing with the team.
Technical discussions are incredibly likely to devolve into people discussions.
No people discussion has ever worked it's way back into being about fixing the broken software.
Got into a heated argument where the interviewer insisted it was perfectly acceptable to store money as a mutable row in a database.
I pushed back with the standard "You append transactions (including corrections) to a ledger" but he wasn't convinced.
I whipped out the standard two-ATMs -separated-by-a-distance overdraft example, and how you can create or destroy money that way.
He said it made no sense as an example because it was buggy and you would never release buggy code.
I asked if he'd done bug fixes before (yes) but obviously he was going to keep digging in further.
The irony of it was that he was part of the blockchain team.
So, approximately six 0s of uptime for my use case?