Moritz Hamann's Avatar

Moritz Hamann

@moritzhamann.com

Engineering Manager at Bloomberg LP. Opinions are my own. Mastodon: @MoritzHamann@mastodon.social https://moritzhamann.com

181
Followers
73
Following
174
Posts
02.11.2024
Joined
Posts Following

Latest posts by Moritz Hamann @moritzhamann.com

βœ… Le Chat

06.03.2026 23:14 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
Preview
Routing Enhancements for Go 1.22 - The Go Programming Language Go 1.22's additions to patterns for HTTP routes.

go.dev/blog/routing...

20.02.2026 18:00 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

I do like the tooling, the backwards compatibility and ecosystem of go, but some of those decisions in the stdlib are really ... interesting. `http.handle("/", handler)` will match every single ULR, `http.handle("/{$}", handler)` only "/"...

20.02.2026 17:59 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Preview
Optimizing an MP3 Codec with OCaml/OxCaml After reading Anil’s post about his zero-allocation HTTP parser httpz, I decided to apply some OxCaml optimisation techniques to my pure OCaml MP3 encoder/decoder. The OCaml-based MP3 encoder/decoder has been the most ambitious project I’ve tried in Opus 4.5. It was a struggle to get it over the line, and I even needed to read large chunks of the ISO standard and get to grips with some of the maths and help the AI troubleshoot. # Profiling an OCaml MP3 Decoder with Landmarks Before dividing into OxCaml, I wanted to get a feel for the current performance and also to make obvious non-OxCaml performance improvements; otherwise, I would be comparing an optimised OxCaml version with an underperforming OCaml version. It was 40 times slower than `ffmpeg`: 29.5 seconds to decode a 3-minute file versus 0.74 seconds. I used the landmarks profiling library to identify and fix the bottlenecks, bringing decode time down to 3.5 seconds (a 8x speedup). ## Setting Up Landmarks Landmarks is an OCaml profiling library that instruments functions and reports cycle counts. It was easy to add to the project (*) with a simple edit of the `dune` file: (libraries ... landmarks) (preprocess (pps landmarks-ppx --auto)) The `--auto` flag automatically instruments every top-level function β€” no manual annotation needed. Running the decoder with `OCAML_LANDMARKS=on` prints a call tree with cycle counts and percentages. > (*) It needed OCaml 5.3.0 for `landmarks-ppx` compatibility; it wouldn’t install on OCaml 5.4.0 due to a ppxlib version constraint. ## Issues 78% of the time was spent in the Huffman decoding, specifically `decode_pair`. The implementation read one bit at a time, then scanned the table for a matching Huffman code. I initially tried a Hashtbl, which was much better than the scan before deciding to use array lookup instead. The bitstream operations still accounted for much of the time, but these could be optimised with appropriate `Bytes.get_...` calls, as the most frequent path is reading 32 bits in big endian layout. The profile now showed `find_sfb_long` consuming 3.4 billion cycles inside requantization. This function does a linear search through scalefactor band boundaries for every one of the 576 frequency lines, every granule, every frame. Switching to precomputed 576-entry arrays mapping each frequency line directly to its scalefactor band index. There were some additional tweaks, such as adding more precomputed lookup tables stored in `floatarray`, using `[@inline]` and `unsafe_get`, `land` instead of `mod`. After this, no single function dominated the profile, and I could move on to OxCaml. # OxCaml OxCaml has `float#`, an unboxed float type that lives in registers, and `let mutable` for stack-allocated mutable variables. Together, they let you write inner loops where the accumulator never touches the heap: module F = Stdlib_upstream_compatible.Float_u let[@inline] imdct_long input = for i = 0 to 35 do let mutable sum : float# = F.of_float 0.0 in for k = 0 to 17 do let cos_val = F.of_float (Float.Array.unsafe_get cos_table (i * 18 + k)) in let inp_val = F.of_float (Array.unsafe_get input k) in sum <- F.add sum (F.mul inp_val cos_val) done; Array.unsafe_set output i (F.to_float sum) done These kinds of optimisations got me from 2.35s down to 2.01s. What I felt was missing was an accessor function which returned an unboxed float from a floatarray, so I wouldn’t need to unbox with `F.of_float`. However, I couldn’t find it. The httpz parser really benefited from OxCaml’s unboxed types because its hot path operates on small unboxed records that stay entirely in registers: #{ off: int16#; len: int16# } # Results The optimisations brought a 29.5s MP3 decoder down to 2.01s. Mostly through standard OCaml optimisations, but OxCaml’s `float#` saved another ~14%. Decoder | Time | vs ffmpeg ---|---|--- ffmpeg | 0.74s | 1x LAME | 0.81s | 1.1x ocaml-mp3 (original) | 29.5s | 40x ocaml-mp3 (Hashtbl) | 6.4s | 8.6x ocaml-mp3 (flat + fast bitstream) | 3.5s | 4.7x ocaml-mp3 (best) | 2.4s | 3.2x ocaml-mp3 (OxCaml) | 2.0s | 2.7x

OxCaml isn't just useful due to its language extensions; it's making us think through how to engineer OCaml code to be lower allocation by default even before switching. See Mark's progress on an MP3 decoder to speed it up 10x https://www.tunbury.org/2026/02/11/ocaml-mp3/

12.02.2026 14:09 πŸ‘ 10 πŸ” 5 πŸ’¬ 0 πŸ“Œ 0

However, the most annoying part is by far is that it sometimes just refuses to produce an output due to safety reasons. This even happened when asked about details of news articles.

08.02.2026 15:37 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Finally got the time to play around with Apple's local LLMs (Foundation Models). So far it's a mixed bag: It's able to answer questions about articles but needs precise prompting and the context window is only ~4.1k tokens, so not much will fit.

08.02.2026 15:37 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

awesome, thanks!

06.02.2026 16:48 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Any chance you can share this markdown file somehow?

06.02.2026 14:58 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Yeah I was noticing something similar. I've put both gemini and chatgpt to write a small Neovim Lua file for a "Zen mode". The resulting code was nearly identical, with the same global table to track windows. I haven't checked, but I'm certain there is somewhere an existing plugin which it copied

04.02.2026 18:22 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

I was trying to give OCaml a shot for a few months, and I was definitely getting more comfortable at the end. But I never felt that the cost/benefit was great when using it as a hobby language. I would love to see if that changes if I would use it full time (it def did for C++ which I use at work).

03.02.2026 21:23 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

To some degree, yeah. But e.g. Rust (ignoring the complexity of async): while there are multiple async runtimes, nearly everyone settled on tokio. F# has a huge standard library, so you can build your abstractions on top of it. Python has different type checkers, but following the same PEP.

03.02.2026 21:23 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Yeah pretty much, i don't think the ecosystem needs more to be productive. Some of the missing libraries i hear people complain about can probably be "vibed" these days imo :D the tooling is good, especially if dune gets package management as well

03.02.2026 21:09 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Sorry for the long rant πŸ˜…

03.02.2026 17:54 πŸ‘ 0 πŸ” 0 πŸ’¬ 2 πŸ“Œ 0

I'm saying this as someone who is trying to get into ocmal once a year or so: i like the promise of it all. Static typing, quick compilation to native code, fast code if needed, quite good lsp. But it's so difficult to pick it all up and every year someone's reinvented something that fragments more

03.02.2026 17:54 πŸ‘ 2 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

OCaml 5 was supposed to resolve the split between async and lwt, but ultimately just create even more runtime systems (eio, riot, probably missing some). All by itself is manageable but i believe that's what people mean with the ecosystem being lacking.

03.02.2026 17:54 πŸ‘ 2 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

I think people just compare it with languages that have a lower barrier to entry. You got multiple standard libraries, a package manager and a build system, two supportes dialects in the compiler, now a new language with oxcaml, a (history) of poor documentation coupled with complex abstractions

03.02.2026 17:54 πŸ‘ 2 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

> tired of maintaining large Python scripts

In your experience, how good are current LLMs generating python vs ocaml (or even something new like oxcaml)?

02.02.2026 17:58 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Preview
Crash before main() on macOS 15.4 Β· Issue #21126 Β· dlang/dmd In the latest upcoming macOS update, any D application currently crashes during runtime initialization. I'm struggling to get a proper stack trace, but it looks like a null pointer dereference in p...

Yeah new to the language. But i think I hit github.com/dlang/dmd/is.... There is also a forum post forum.dlang.org/post/jrbsajc...

02.02.2026 12:07 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

installed D on MacOS and got an immediate segmentation fault when running dmd 🫠

01.02.2026 19:22 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

just tried gemini to vibe some zig, but the recent redesigns around io interfaces and the frequent changes in the stdlib due to being < 1.0, made this a rather frustrating experience. On the other hand it's a good way to actually learn zig by fixing all the compilation errors ...

01.02.2026 13:29 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

So how are they different from modular implicits

28.01.2026 18:03 πŸ‘ 1 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0
Preview
GitHub - antirez/whisperbot: Telegram bot that transcribes audio messages via whisper.cpp Telegram bot that transcribes audio messages via whisper.cpp - antirez/whisperbot

I have had enough of Telegram services run by unknown individuals to do the audio transcription task in my Telegram channels. Wrote one using my botlib, ffmpeg and whispher.cpp. May be useful for you as well, perhaps? github.com/antirez/whis... Transcription quality is WAY better.

27.01.2026 19:13 πŸ‘ 21 πŸ” 4 πŸ’¬ 0 πŸ“Œ 1

I love how LLMs make it so easy to customise my neovim now. Tiny little scripts that either replace existing plugins or add very specialised workflow enhancements. Just wrote a 100 line function that adds a zen mode with backdrop. Still had to tweak the result, but 95% was basically there

23.01.2026 12:02 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

No idea what's going on, but I love it πŸ˜„

23.01.2026 09:31 πŸ‘ 2 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

Roc if I'm not mistaken

22.01.2026 17:29 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0
They need to negotiate with each other. They have to probe each other. They have to dynamically figure out a common language so they can exchange information and fulfill the goals that the human programmer gave to them. So that’s why this goal-directed stuff is going to be so important when we have this internetβ€”is because you can’t write a procedure because we won’t know the procedures for talking to these remote programs. These programs themselves have to figure out procedures for talking to each other and fulfill higher-level goals. So if we have this worldwide network, I think that this is the only model that’s going to scale. What won’t work, what would be a total disaster, isβ€”I’m going to make up a term here, API [Application Programming Interface]β€”this notion that you have a human programmer that writes against a fixed interface that’s exposed by some remote program. First of all, this requires the programs to already know about each other, right? And when you’re writing this program in this one’s language, now they’re tied together so the first program can’t go out and hunt and find other programs that implement the same service. They’re tied together. If this one’s language changes, it breaks this one. It’s really brutal, it doesn’t scale. And, worst of all, you haveβ€”it’s basically the machine code problem. You have a human doing low-level details that should be taken care of by the machine. So I’m pretty confident this is never going to happen. We’re not going to have API’s in the future. What we are going to have are programs that know how to figure out how to talk to each other, and that’s going to require programming in goals.

They need to negotiate with each other. They have to probe each other. They have to dynamically figure out a common language so they can exchange information and fulfill the goals that the human programmer gave to them. So that’s why this goal-directed stuff is going to be so important when we have this internetβ€”is because you can’t write a procedure because we won’t know the procedures for talking to these remote programs. These programs themselves have to figure out procedures for talking to each other and fulfill higher-level goals. So if we have this worldwide network, I think that this is the only model that’s going to scale. What won’t work, what would be a total disaster, isβ€”I’m going to make up a term here, API [Application Programming Interface]β€”this notion that you have a human programmer that writes against a fixed interface that’s exposed by some remote program. First of all, this requires the programs to already know about each other, right? And when you’re writing this program in this one’s language, now they’re tied together so the first program can’t go out and hunt and find other programs that implement the same service. They’re tied together. If this one’s language changes, it breaks this one. It’s really brutal, it doesn’t scale. And, worst of all, you haveβ€”it’s basically the machine code problem. You have a human doing low-level details that should be taken care of by the machine. So I’m pretty confident this is never going to happen. We’re not going to have API’s in the future. What we are going to have are programs that know how to figure out how to talk to each other, and that’s going to require programming in goals.

I have included the most relevant section in the alt text of this image of him giving the talk:

21.01.2026 22:42 πŸ‘ 6 πŸ” 2 πŸ’¬ 0 πŸ“Œ 2

I remember you were a fan of the gemini models before. Curious if tried them recently with the 3 pro release?

21.01.2026 19:04 πŸ‘ 0 πŸ” 0 πŸ’¬ 0 πŸ“Œ 0

So only uncertain in ReScript then? That would make more sense

16.01.2026 13:40 πŸ‘ 1 πŸ” 0 πŸ’¬ 2 πŸ“Œ 0

> uncertainty about the future of ppx

I'm not it the loop, what's the uncertainty?

16.01.2026 12:42 πŸ‘ 0 πŸ” 0 πŸ’¬ 1 πŸ“Œ 0

Everybody thinks 'https://' stands for 'hypertext transfer protocol secure' but it actually stands for 'head to this place, sucka' followed by a colon and two laser sounds

13.01.2026 20:17 πŸ‘ 10180 πŸ” 3805 πŸ’¬ 68 πŸ“Œ 66