News for hackers. Stuff that matters.

mrkeen

I've always been skeptical about "unified memory" vs VRAM. But my memory isn't great, so I tried to measure it right now, and see if a tiny model was as slow as I remember.

llama-ui on unsloth/Llama-3.2 3B Instruct:

  > hello

  Runtime info
  Current time is 2026-11-02T13:00:18+01:00
  Runtime info
  Current time is 2026-11-02T13:00:19+01:00
  Runtime info
  Current time is 2026-11-02T13:00:21+01:00
  Runtime info
  Current time is 2026-11-02T13:00:23+01:00

  There is not enough information about the functions to properly answer the prompt.
Not really my jam.

I did do the yak-shaving for the longest time. llama in a second-hand RTX3070 8GB was a useful tool. When gpt-oss came out, I upgraded to a second-hand 16GB card. It was slower (didn't seem to one-shot as much) but it gave smarter overall answers. At some point I bought a 24GB card which was basically dead on arrival. I kept my 16GB card in a server and maintained my VPN infra so I could access it from wherever.

I was still using this setup even when my workplace was pushing windsurf/copilot harder and harder. For me they were just broken. I'd ask for trivial tasks like "copy this unit test into a second unit test which tests something slightly different" and it would just get confused and delete shit, or leave random UUID strings throughout the codebase.

Eventually I tried out cline/openrouter/deepseekv4flash, and that was actually useful enough for me to tell it to do something to my code base, and as long as I supervised carefully enough it was useful, and priced OK.

At some point in the process I tried Claude Code because of all the hype, but I couldn't get any useful value out of it. I tried working with it all morning on something and hit my token limit without achieving anything worthwhile, so I cancelled Claude and went back to Deepseekv4flash.

These days every job application requires proficiency with claude code (or similar), so I was forced to get it again. And this time it just worked better. I haven't hit any limits, and it works like a better version of my cline/deepseek setup.

So where does that leave me?

Deepseek-v4-pro is 1.6T params, the cut-down version is 284B params, and I wouldn't trust them to do something on their own.

I'm very skeptical of a model being both small enough to run fast on my hardware and somewhere in the v4-flash <-> claude quality range.

If I did put down $2k, I wouldn't want it in such an old chip (M1) or a second-hand device that could die tomorrow with no chance of refund, especially to just 'see if it's good enough' (compared to the effectively-free v4-flash token spend).

Did we ever get back to 16GB feasibility?

AFAIK the timeline was:

  - AI was shit, models could fit in your GPU
  - AI was shit, models could no longer fit in your GPU
  - AI got good
Any chance a good model will ever be seen in a consumer GPU again?
Re:Jepsen: ParticleDB 1.1.4 on Sunday November 01, 2026 @01:23AM (#50323158)
The explanation is more damning than the devex.

The condition is unsatisfiable, and the engine went ahead and gave a 0-warning result?

Re:Jepsen: ParticleDB 1.1.4 on Sunday November 01, 2026 @01:15AM (#50323134)
"SQL engines implement well known SQL semantics"

That's why I preplied:

> if enough people did it that way it would be the new normal, and apologists would fall out of the woodwork

If 4=5 made it into the spec, would it be no longer up for criticism?

Re:Jepsen: ParticleDB 1.1.4 on Sunday November 01, 2026 @01:10AM (#50323108)
I'm claiming that

1) It would be no more fucked up than anything else that has been grandfathered into our tools.

2) If it already had mass adoption in the market, people would jump onto this thread to explain to me that I just don't understand the brilliant semantics behind language of why 4 = 5.

Re:Jepsen: ParticleDB 1.1.4 on Saturday October 31, 2026 @05:42PM (#50320531)
Hi apologist. How was the woodwork? Your exact comment was why I wrote mine.

  You could write predicates over non-existent columns:

  root=> SELECT * FROM t
         WHERE definitely_not_a_column = 4;
Cool, definitely_not_a_column doesn't exist, so therefore that whole WHERE clause doesn't exist either, so the real query is SELECT FROM t.

  SELECT * FROM t WHERE 4 = 5;
   a | b
  ---+----
   5 | 6
  (1 row)
We're comparing 4 and 5. Precedent?

  System.out.println(((Integer)4).compareTo((Integer)5));
  > -1
What happens when you treat -1 as a bool? The following languages agree that -1 is true: C, C++, JS, Python, PHP, Ruby, Perl, Lua, R.

So it's SELECT FROM t WHERE true;

Now, let's get busy blaming Jepsen for using the tool wrong.

Re:Jepsen: ParticleDB 1.1.4 on Saturday October 31, 2026 @03:59PM (#50319536)
I won't push back on it being garbage, but I would suggest that if enough people did it that way it would be the new normal, and apologists would fall out of the woodwork, e.g. [1]

I complain that mainstream SQL engines have no problem returning less than the total number of rows if you first query WHERE column = NULL and then query WHERE column <> NULL. Your example queries remind me of that.

[1] https://medium.com/dailyjs/the-why-behind-the-wat-an-explana...

Re:Vegemite is not a human right on Monday October 26, 2026 @10:41AM (#50244562)

  The judge upheld prison authorities’ argument that McKechnie had failed to provide any proper foundations for his opinion that Vegemite does not interfere with drug sniffer dogs.
What is the null-hypothesis, who is making a claim, who has the burden of proof?
Re:Lula Vows to Regulate Social Media Giants on Monday October 26, 2026 @08:03AM (#50242284)
Too late for that. Hoping that social media continues to be a bastion of free speech is like hoping that casinos continue to be responsible with their customers' finances.

https://www.hrw.org/report/2023/12/21/metas-broken-promises/...

https://www.theguardian.com/global-development/2025/dec/11/m...

Re:Small Programs and Languages on Sunday October 25, 2026 @11:41AM (#50232755)
I think the viewpoint that your're missing is: how do I make sure the machine code means the same thing as the source code?

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.

Re:We Have Traits at Home on Friday October 23, 2026 @04:15PM (#50214706)
Complexity budget and all that. But I'd sooner throw out inheritance than traits.
Re:We Have Traits at Home on Friday October 23, 2026 @04:13PM (#50214666)
Traits/typeclasses tend to disallow your three-part scenario. It's called the orphan instance problem.

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.

Re:The 1.5°C goal of the Paris Agreement is no longer viable on Wednesday October 21, 2026 @08:23AM (#50179716)
I remember way back when exceeding 1.5 was in the past, not the future.

When did it become a future event again?

Re:Revolut down as users report app not working on Wednesday October 21, 2026 @08:16AM (#50179638)
> Revolut would own the database in my example.

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).

Re:Revolut down as users report app not working on Tuesday October 20, 2026 @09:47AM (#50166381)
I would love if it all engineers were professional enough to avoid the personal criticisms and stick to the comp sci, which is far more interesting.

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.

Re:Revolut down as users report app not working on Tuesday October 20, 2026 @09:23AM (#50166029)

  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...
Re:Revolut down as users report app not working on Tuesday October 20, 2026 @09:19AM (#50165960)
He suggester that they had both. My question was what to do when they disagree, and he wasn't able to either conceive of the 'two sources of truth problem' or wasn't able to suggest a solution. He pushed back saying: if they disagree then you've got buggy code, and that your job is to not write buggy code. "That's why we test". "For race conditions?" etc. etc.

Who owns the database in your locked example?

Re:Revolut down as users report app not working on Tuesday October 20, 2026 @09:06AM (#50165807)
I don't think you can avoid negative balance, without giving up on availability (i.e. moving from AP to CP). And then an outage like TFA takes down your whole system.

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.

Re:Revolut down as users report app not working on Tuesday October 20, 2026 @08:18AM (#50165220)
The interviewer's job (I was briefed beforehand) was to make sure I know my concurrency, because they use a lot of it there.

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.

Re:Revolut down as users report app not working on Tuesday October 20, 2026 @07:41AM (#50164788)
Interviewed for them this year.

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.

Re:Revolut down as users report app not working on Tuesday October 20, 2026 @07:31AM (#50164684)
I've been hearing about bitcoin for 15+ years and I don't think I've ever walked into a shop where they accepted it.

So, approximately six 0s of uptime for my use case?

Re:Parser Combinators on Sunday October 18, 2026 @09:37AM (#50141000)
What kind of mapping/unwrapping are you being subjected to with PCs?
Re:Parser Combinators on Sunday October 18, 2026 @09:33AM (#50140976)
Tokenising is actually a strength of PC, it fits the parser structure exactly!

  pToken :: Parser<Bytestring, Token>

  pExpr :: Parser<List<Token>, Expr>
Re:Parser Combinators on Sunday October 18, 2026 @09:23AM (#50140892)
If you use an Either instead of a List, then you can write an or combinator, which accepts two parsers and tries the second if the first fails. It branches on the Left/Right of the Either.

If it's a List, wouldn't you be forced to write the Cartesian product of two parsers instead?

Re:Parser Combinators on Sunday October 18, 2026 @09:17AM (#50140843)
Each parser blindly follows its own rules.

If pDigit saw "123 ", according to TFA's design, it would return (1, "23 ").

If PInt saw the "123 ", it would return (123, " ").

You could approximate pInt in terms of pDigit via:

  PInt = many1 pDigit
(Ignoring negatives, int maxvalue, and many1 implies 1-or-more, not 0-or-more.)

I say "according to TFA's design" because I've been arguing elsewhere that parsers must return Either<Error,(T, Remainder)> not (T, Remainder)

Re:Parser Combinators on Sunday October 18, 2026 @09:05AM (#50140761)
No. The parser code (in a library that everyone depends on) will branch on success/fail internally. It has nothing to branch on if it only sees T, because T may not have a success/fail nature.

You could take a step back and make sure T has a fail case, e.g. T-extends-Either<A, B>, but what is to be gained?

* Firstly, what the hell is A?

* The user would need to type Parsers of T=Cat and T=Dog instead as Parsers of T=Either<Error,Dog> and T=Either<Error,Cat>. If everyone has to do it, pull the common abstraction back into the library itself! Also the caller would receive a successful parse of T=Either and would then need to check to see if it was success(success) or success(fail).

* You also mix abstractions in the same way as newlines in string literals. You could no longer represent a successful parse of a failed Either, since the failed Either would look like a parse error.

Re:Parser Combinators on Sunday October 18, 2026 @07:50AM (#50140242)
No, that was my ironically landed upon definition of partial.

The article used it as in a sub-parser, which is the other thing I objected to. If you add two Integers, you get back an Integer, not a Sum. Same principle here, two parsers make a parser. You don't need to write new code to combine a partial parser with a parser, or vice versa.

Re:Parser Combinators on Sunday October 18, 2026 @06:53AM (#50139895)
Not a good starting type:

  type Parser<T> = (input: string) => [T, string]
This implies that it accepts a string and will return a T. Parsers might return a T.

The article also starts with the concept of a 'partial parser', from which other (non-partial?) parsers can be constructed?

  Or, and this is where the real power of partial parsers comes in: we wrap the chain up as a new parser of its own.
Nope, there's no distinction. If you combine partial parsers, you end up with a partial parser. If you combine full parsers (whatever that means) you end up with full parsers.

(Ironically there is a fitting definition of 'partial' here: the function isn't well defined on all inputs. For some inputs, T is returned, on other inputs, maybe an error is thrown, who knows..)

Re:Microsoft Teams is a red flag on Sunday October 18, 2026 @02:10AM (#50138345)
The last time I was part of a Teams environment (late 2025 or early 2026), search literally did not work.

I could see the keywords right there in the chat, enter them into the search bar, and get back 'no results found'.

(This was across at least a period of months too, not just an intermittent bug)

Re:Types of types: Haskell's Kind system on Sunday October 18, 2026 @01:50AM (#50138260)
"Generic" and "for a particular type" cancel out.

You don't need List<A> to write an IntList, nor do you need + to work on different integers in order to have a particular integer.

Older »