HN user

jamii

3,461 karma

http://scattered-thoughts.net/

jamie@scattered-thoughts.net

Posts75
Comments954
View on HN
www.scattered-thoughts.net 20d ago

Artificial Adventures

jamii
25pts2
www.scattered-thoughts.net 28d ago

I'm Not a Cat

jamii
5pts1
www.scattered-thoughts.net 3mo ago

Borrow-checking without type-checking

jamii
91pts32
www.scattered-thoughts.net 3mo ago

Borrow-Checking Surprises

jamii
1pts0
www.youtube.com 7mo ago

Do We Understand SQL?

jamii
2pts0
www.scattered-thoughts.net 1y ago

Store Tags After Payloads

jamii
3pts0
www.scattered-thoughts.net 1y ago

HYTRADBOI 2025 post-mortem

jamii
4pts2
www.hytradboi.com 1y ago

"Enough with All the Raft" by Alex Miller

jamii
5pts0
www.hytradboi.com 1y ago

A quick ramp-up on ramping up quickly in SpiderMonkey

jamii
3pts0
www.hytradboi.com 1y ago

Programming Without Pointers

jamii
8pts0
bsky.app 1y ago

Show HN: Hytradboi DB/PL conference starts tomorrow

jamii
2pts1
www.scattered-thoughts.net 1y ago

Other Kinds of Talks

jamii
2pts0
www.scattered-thoughts.net 1y ago

Other Kinds of Talks

jamii
3pts0
www.scattered-thoughts.net 1y ago

A survey of OLAP and HTAP query engines

jamii
2pts0
www.scattered-thoughts.net 1y ago

Relational Algebra Isn't Math

jamii
2pts0
www.scattered-thoughts.net 1y ago

Query optimization doesn't work because SQL is declarative

jamii
2pts1
www.scattered-thoughts.net 1y ago

Reading every paper in 27 years of the psychology in programming conference

jamii
4pts0
www.scattered-thoughts.net 1y ago

The missing tier for query compilers

jamii
88pts9
www.hytradboi.com 1y ago

Hytradboi 2025 Program

jamii
120pts10
www.scattered-thoughts.net 1y ago

The missing tier for query compilers

jamii
3pts0
www.scattered-thoughts.net 1y ago

What is the point of an online conference?

jamii
140pts106
www.hytradboi.com 4y ago

'Have you tried rubbing a database on it?' call for speakers

jamii
3pts0
www.hytradboi.com 4y ago

Have you tried rubbing a database on it?

jamii
2pts0
scattered-thoughts.net 5y ago

A new newsletter on database engines, streaming systems, query planning

jamii
47pts8
scattered-thoughts.net 5y ago

Why isn't differential dataflow more popular?

jamii
228pts120
scattered-thoughts.net 5y ago

Looking for More Debugger

jamii
2pts1
meltware.com 5y ago

Debugging async generator errors in Rust

jamii
21pts1
scattered-thoughts.net 5y ago

Small Tech

jamii
3pts0
scattered-thoughts.net 7y ago

Frugality is non-linear

jamii
2pts0
scattered-thoughts.net 7y ago

Zero-copy deserialization in Julia

jamii
155pts32

It seems like either one evaluates the contents of the `box`, and would only make a difference if you tried to use `x` afterwards?

More or less. x^ moves the whole box whereas x* copies the contents of the box.

Awkwardly, it also hasn't been assigned so I'm not sure the box is accessible anymore?

Yes, if you move something and don't assign it then it gets dropped, same as rust.

The goal is that most of your code can have the assurances of static typing, but you can still opt in to dynamically-typed glue code to handle repls, live code reloading, runtime code generation, malleable software etc.

WASM 3.0 Completed 10 months ago

I've tried using binaryen, and I've also tried emitting raw wasm by hand, and the latter was far easier. It only took ~200 lines of wasm-specific code.

One of the dynamics is that people get older so they move into different buckets.

We can make the model way simpler to make it clearer. Say in 2020 we hired 1000 20-24yo, 1000 25-29yo etc and then we didn't hire anyone since then. That was five years ago, so now we have 0 20-24yo, 1000 25-29yo, 1000 30-34yo etc and 1000 retirees who don't show up in the graph.

Each individual year we hired the exact same number of people in each age bracket, and yet we still end up with fewer young people total whenever hiring goes down, because all the people that got hired during the big hiring spike are now older.

I made a stupid simple model where hiring in all age brackets rose slowly until 2021 and then fell slowly. That produces very similar looking graphs, because the many engineers that were hired at the peak move up the demographic curve over time. Normalizing the graph to 2022 levels, as the paper seems to do, hides the fact that the actual hiring ratios didn't change at all.

https://docs.google.com/spreadsheets/d/1z0l0rNebCTVWLk77_7HA...

The ... is the useful part. We actually want that string, so we can't avoid allocating it.

But the &str at the end is an additional heap allocation and causes an additional pointer hop when using the string. The only reason the function returns a pointer to a string in the first place is so that the nil check at the beginning can return nil. The calling code always checks if the result is nil and then immediately dereferences the string pointer. A better interface would be to panic if the argument is nil, or if that's too scary then:

    func (thing *Thing) String() (string, bool) {
        if thing == nil {
            return "", false
        }
        str := ...
        return str, true
    }

I don't think Austral uses second-class references. Even the page you linked says:

But is it worth it? Again, the tradeoff is expressivity vs. simplicity... Austral’s linear types and borrowing is already so simple. Austral’s equivalent of a borrow checker is ~700 lines of OCaml. The only downside of Austral is right now you have to write the lifetimes of the references you pass to functions, but I will probably implement lifetime (region) elision.

it solves the actual problem perfectly

The whole post was about how that doesn't solve the problem perfectly - there is no way to interactively edit the output.

by embracing LISP principles directly

This could just as easily have been javascript+json or erlang+bert. There's no lisp magic. The core idea in the post was just finding a way for code to edit it's own constants so that I don't need a separate datastore.

Eventually I couldn't get this working the way I wanted with clojure and I had to write a simple language from scratch to embed provenance in values - https://news.ycombinator.com/item?id=43303314.

This is an old prototype. I ended up making a language for it from scratch so that I could attach provenance metadata to values, making them directly editable even when far removed from their original source.

https://www.scattered-thoughts.net/log/0027#preimp

https://x.com/sc13ts/status/1564759255198351360/video/1

I never wrote up most of that work. I still like the ideas though.

Also if I had ever finished editing this I wouldn't have buried the lede quite so much.

Here's the program (https://www.hytradboi.com/2025/#program):

0900-1000: Compilers

  "Database query compilation: our journey" by Thomas Neumann & Viktor Leis

  "A YJIT interview" by Maxime Chevalier-Boisvert

  "A quick ramp-up on ramping up quickly" by Iain Ireland

  "Can we democratize JIT compilers?" by Haoran Xu

  "Safe and productive performance with user-schedulable languages" by Jonathan Ragan-Kelley
1000-1100: Understanding programs
  "How debuggers work" by Sy Brand

  "Debugging compiler-optimized code: how it works and doesn't" by Stephen Kell

  "Side-Eye: ask your programs anything" by Andrei Matei

  "Let's run a million benchmarks" by Yao Yue

  "Rocket science of simulation testing!" by Alex / matklad
1100-1200: Wild ideas
  "Back to modularity" by Daniel Jackson

  "DB usability: as if" by Jonathan Edwards

  "Twizzler and far out memory sharing: precise abstractions" by Daniel Bittman

  "Programming without pointers" by Andrew Kelley

  "Throwing it all away - how extreme rewriting changed the way I build databases" by Tyler Neely
1200-1230: Programmers are people
  "A case for feminism in programming language design" by Felienne Hermans

  "Malloy, mic drop, peace!" by Michael Toy
1230-1300: Lightning talk buffet
  "Learning about the odd bits of SQL by reading the PostgreSQL docs" by Chris Zetter

  "Hacking Observable notebooks from within" by Tom Larkworthy

  "Zero copy data structures" by Evan Chan

  "Reliable serverless needs distributed transactions" by Stu Hood

  "Pangeo is a database" by Alexander Merose

  "Rubbing a database on a language server" by Philip Zeyliger

  "Language agnostic simulation testing on a budget" by Stevan A

  "Shapeshifter: using LLMs inside a database for schema flexibility" by David Nachman

  "Why S3's conditional writes made people excited" by Miikka Koskinen

  "pghttp: backend-free, lowest latency web apps" by Damir Simunic
1300-1400: Query languages
  "Pipe syntax in SQL; it's time" by Jeff Shute

  "PRQL: a modern, pipelined SQL replacement" by Tobias Brandt

  "AquaLang - a streaming dataflow programming language" by Klas Segeljakt

  "A polymorphic data model for SQL using algebraic types" by Steve McCanne
1400-1430: Databases
  "Use of time in distributed databases - don't fall behind the times" by Murat Demirbas

  "Enough with all the Raft" by Alex Miller

  "Database ideas in Convex" by Thomas Ballinger

  "Serverless primitives for the shared log architecture" by Stephen Balogh

  "Good thing we're not writing a database" by Peter van Hardenberg
1430-1500: Wasm
  "Thinking in Wit" by Dan Gohman

  "Bringing the WebAssembly standard up to speed with SpecTec" by Dongjun Youn

it looks extremely suspicious

It matches my anecdotal experiences with graal. It's a huge complex machine with a lot of surface area for weird performance bugs.

TruffleRuby beats cruby on the same benchmark by 4.38x

That benchmark only looks at peak performance, which TR unarguably dominates at, and ignores other important considerations like warmup time. Here's another railsbench (https://i.imgur.com/IzMRKdQ.png) from the same paper (https://dl.acm.org/doi/pdf/10.1145/3617651.3622982). TR achieves the best peak performance, but only after 3 minutes of warmup and it starts out 17x slower than cruby. If every time you deploy new code your latency spikes by 17x for 3 minutes, that's gonna be painful.

I don't know of anyone that is using TR in production. Shopify were doing some work on it for a while, but they've since developed and shipped yjit so I don't know if they still have any investment in TR.

The tradeoff in SingleStore is interesting. By default and unlike eg postgres, parameterized queries are planned ignoring the values of the parameters. This allows caching the compiled query but prevents adapting the query plan - for the example in the post SingleStore would pick one plan for both queries.

But you can opt out of this behaviour by wrapping each parameter in NOPARAM (https://docs.singlestore.com/cloud/reference/sql-reference/c...).

If I have multiple errors then that in-out parameter has to be a union(enum). And then I'm back to creating dozens of slightly different unions for functions which return slightly different sets of errors. Which is the same problem I have in rust. All of the nice inference that zig does doesn't apply to my in-out parameter either. And the compiler won't check that every path that returns error.Foo always initializes error_info.Foo.

What they're trying to convey is that errors are structurally typed. If you declare:

    const MyError = error{Foo}
in one library and:
    const TheirError = error{Foo}
in another library, these types are considered equal. Unlike structs/unions/enums which are nominal in zig, like most languages.

The reason for this, and the reason that errors are not regular records, is to allow type inference to union and subtract error types like in https://news.ycombinator.com/item?id=42943942. (They behave like ocamls polymorphic variants - https://ocaml.org/manual/5.3/polyvariant.html) This largely avoids the problems described in https://sled.rs/errors.html#why-does-this-matter.

On the other hand zig errors can't have any associated value (https://github.com/ziglang/zig/issues/2647). I often find this requires me to store those values in some other big sum type somewhere which leads to all the same problems/boilerplate that the special error type should have saved me from.

...the compiler won't help you check that your function only throws the errors that you think it does, or that your try block is handling all the errors that can be thrown inside it.

It will do both of those:

    const std = @import("std");

    fn throws(i: usize) !void {
        return switch (i) {
            0 => error.zero,
            1 => error.one,
            else => error.many,
        };
    }

    fn catches(i: usize) !void {
        throws(i) catch |err| {
            return switch (err) {
                error.one => error.uno,
                else => |other| other,
            };
        };
    }

    pub fn main() void {
        catches(std.os.argv.len) catch |err| {
            switch (err) {
                // Type error if you comment out any of these:
                // note: unhandled error value: 'error.zero'
                error.zero => std.debug.print("0\n", .{}),
                error.uno => std.debug.print("1\n", .{}),
                error.many => std.debug.print("2\n", .{}),
                // Type error if you uncomment this:
                // 'error.one' not a member of destination error set
                //error.one => std.debug.print("1\n", .{}),
            }
        };
    }
It wouldn't hurt to just read the docs before making confident claims.

It's definitely possible to get rid of them but:

https://blog.youtube/news-and-events/updates-to-youtubes-ter...

ads can now appear on videos from channels not in the YouTube Partner Program (YPP), and we will begin gradually placing ads on brand safe videos

You have to be eligible for ads and sign up for an ad account in order to turn ads off on your own videos.

Youtube also often shows ads if they misdetect part of the video as copyrighted material, which seems to happen more and more often.

I would, of course, prefer that these people created such content regularly, without needing to be prompted by the occasion of a conference, but very few do.

That's more or less the first two points I mentioned - coordination and distillation. Getting a big group of interested attendees together is an effective way to get busy experts to distill some of their knowledge.

I agree with some of this.

My experience of tech podcasts though has been that it's often the same old people being interviewed, and that a 60 minute interview is often less interesting than a 10 minute talk where the speaker spent a bunch of time thinking about how to explain a subject. The latter is definitely more work, but I've had no problem finding speakers.

Outside of tech, I've seen a few podcasts avoid this pattern. The host of https://podcast.clearerthinking.org/ is really good at picking interesting speakers, preparing questions, ans gently but persistently pushing back when they try to gloss over a weak point in their argument. I'd love to listen to a tech version of that podcast.

Not being on youtube might be a mistake. I definitely don't want to use youtube for the conference itself because I don't want attendees to have to sit through ads. But maybe I should mirror to youtube afterwards. I'll think about it.

The chat at the last hytradboi was pretty dense. That may have been down to having quite a high ratio of experts in the audience though. I'm not sure if that will continue to be the case.

I have mixed experiences with discords. The persistence is much better for community building, but in big discords it's rare to have an actual conversation because everyone is only half paying attention. The ones that do feel interesting are again the ones with a high ratio of experts who are actively engaged in the subject. Or small invite-only discords that also hold regular mini-confs, which is maybe a kind of sweet spot.

I'm definitely not tied to running a conference. Last time was kind of a whim, but people enjoyed it and wanted to do it again. So this post is less an argument in favor of conferences and more me trying to figure out what I accidentally did right so I can do more of it.