HNHacker News
TopNewBestAskShowJobs

polyrand

4,355 karma · joined March 16, 2020

Medical doctor and machine learning/software engineer.

ricardoanderegg.com

Twitter: [at] ricardoanderegg Contact: hn [at] polyrand [dot] net

submissionscomments
polyrand··on We're Building Postgres in Rust. Using the LLVM of Databases
I'm already quite excited about Turso being SQLite-compatible, but adding many features on top.

And when a feature is not directly compatible with SQLite (ie: you can't directly read the file with `sqlite3`, it's straightforward to convert). This is great because you know you'll always be able to continue working with that database. Even if Turso stopped working, it's still a valid SQLite database.

A combination I would be excited about is:

- Full support for Postgres protocol/wire format (ie: Postgres, but in-process, backed by a single file). - Optional: Client/server architecture for further scaling and remote management using existing Postgres tooling - All backed by a SQLite-compatible file

They are already adding MVCC to SQLite anyway. So their effort seems doable, and I hope they succeed.

polyrand··on ChatGPT Work
On one hand, this had to happen at some point. I feel the split between ChatGPT vs. Codex wasn't helping OpenAI.

Anthropic did it right from the beginning by unifying everything in the same application. From my perspective, Codex is much better than any other app, but for non-technical users they were still stuck in ChatGPT only, and "nobody" knew about Codex. Anthropic also did it better by putting everything under the "Claude" brand: Claude Code, Claude Cowork, etc. Compared to ChatGPT vs Codex. OpenAI seems to be trying to revert that unwanted split.

With that said, I share the sentiment that it's 100% unclear what's the difference between Codex and Work. Chats now are a second-class citizen of the app. Although the "Attach to task" feature of chats looks useful. Putting "Chats" below the "Tasks" section would have been much better.

This may end up badly. Most people use ChatGPT just for regular chats, and they are not used to "agentic" interactions. It may take people time to adapt, and you can definitely lose users during that transition.

This also seems to have indirect implications regarding pricing. Codex (and Work) consume credits. Chats were also limited before, but you could mostly use ChatGPT without thinking about it. Now people will inevitably use Codex/Work more, simply because that's what the UI shows them, thus consuming credits. This will force you to keep an eye on credits a lot more.

Others have mentioned that the old ChatGPT can't be installed any more. Only if you had it installed before, it now became ChatGPT Classic. However, you can still add the chatgpt.com page as a Web App. You'll need an internet connection to use it, but the old ChatGPT app wasn't working properly without internet anyway... so the overall experience may not be that different. I'd even say that, to me, the web UI has always felt more polished than the native app.

polyrand··on The history of butterfly swimming
I believe that's like saying we should only have a single "throw" event in athletics. Or why having hurdles events when you already have regular running ones.

I like that we can have more variety, more people competing, and overall different modalities to test human performance.

polyrand··on The history of butterfly swimming
Finswimming is actually a separate sport, just not an olympic sport. Although it has some exciting characteristics like very fast 50 meter races, which I enjoy as a "regular" (non-fins) swimmer.
polyrand··on MacBook Neo
I find this a very exciting release. I was actually hoping we would somehow get macOS on mobile 'A' chips some day. And I think this is better than putting 'M' chips on an iPad.

My iPad with an 'M1' chip actually consumes more battery than much older iPads when both are locked and with the screen off. I ended up figuring it was probably because, in the 'M' chip, the lowest possible energy usage is way higher than the 'A' chip. So even small background wake-ups used more energy.

I'm still hoping one day we have an iPad with macOS.

polyrand··on Start all of your commands with a comma (2009)
I do this, and it's a huge quality of life improvement. No so much because of shadowing existing binaries, but for better command auto-complete. For example: I have a bunch of tmux utilities and all start with `,t` which is not a polluted command-name prefix compared to just `t`.

But I'm now facing the problem that LLM agents don't like this, and when I instruct them to run certain tools, they remove the leading comma. It's normally fixed with one extra sentence in the prompt, but still inconvenient.

polyrand··on My AI Adoption Journey
> a period of inefficiency

I think this is something people ignore, and is significant. The only way to get good at coding with LLMs is actually trying to do it. Even if it's inefficient or slower at first. It's just another skill to develop [0].

And it's not really about using all the plugins and features available. In fact, many plugins and features are counter-productive. Just learn how to prompt and steer the LLM better.

[0]: https://ricardoanderegg.com/posts/getting-better-coding-llms...

polyrand··on Apple, What Have You Done?
I share the same feeling. I waited as much as possible to upgrade to iOS 26 / macOS Tahoe.

Two days ago, I finally upgraded. Liquid Glass is one of the worst things I've ever seen in terms of design. It reminds me of when I personalized old cheap android phones or Linux distros just "to look cool". Cool-looking: yes. Unusable: also yes. Tasteful design: almost absent.

Just the increase of the border-radius in all elements makes it hideous. Apps with a search bar on a scrollable list look like a CSS bug when the search bar is on top of the elements. Neither the search bar nor the element underneath are visible. Although this applies to most transparency effects on Liquid Glass. Neither the elements above nor below the "glass" are visible. And the extra value added is zero.

The thing is, I can still adapt to it, or tweak transparency and contrast. But I've seen elderly relatives struggle just because WhatsApp decided to add the "Meta AI" floating button. I can't imagine what this "inaccessible" UI changes can do.

polyrand··on Many Small Queries Are Efficient in SQLite
Don't forget that if you're using SQLite on something like EBS, multiple queries may not be efficient.

I'm saying this as a huge SQLite fan, but also beware of what kind of storage you're using in your instance.

polyrand··on GLM-4.7-Flash
I've been using z.ai models through their coding plan (incredible price/performance ratio), and since GLM-4.7 I'm even more confident with the results it gives me. I use it both with regular claude-code and opencode (more opencode lately, since claude-code is obviously designed to work much better with Anthropic models).

Also notice that this is the "-Flash" version. They were previously at 4.5-Flash (they skipped 4.6-Flash). This is supposed to be equivalent to Haiku. Even on their coding plan docs, they mention this model is supposed to be used for `ANTHROPIC_DEFAULT_HAIKU_MODEL`.

polyrand··on Fabrice Bellard Releases MicroQuickJS
Not sure about the impact of these, I guess it depends on the context where this engine is used. But there seems to be already exploits for the engine:

https://x.com/itszn13/status/2003707921679679563

https://x.com/itszn13/status/2003808443761938602

polyrand··on GLM-4.7: Advancing the Coding Capability
That's interesting, thanks for sharing!

It's a pattern I saw more often with claude code, at least in terms of how frequently it says it (much improved now). But it's true that just this pattern alone is not enough to infer the training methods.

polyrand··on GLM-4.7: Advancing the Coding Capability
A few comments mentioning distillation. If you use claude-code with the z.ai coding plan, I think it quickly becomes obvious they did train on other models. Even the "you're absolutely right" was there. But that's ok. The price/performance ratio is unmatched.
polyrand··on Structured outputs create false confidence
I enjoyed the post. I was about to link the "Let Me Speak Freely" paper and "Say What You Mean" response from dottxt, but that's already been posted in the comments.

I'm a huge fan of structured outputs, but also recently started splitting both steps, and I think it has a bunch of upsides normally not discussed:

1. Separate concerns, schema validation errors don't invalidate the whole LLM response. If the only error is in generating schema-compliant tokens (something I've seen frequently), retries are much cheaper.

2. Having the original response as free text AND the structured output has value.

3. In line with point 1, it allows using a more expensive (reasoning) model for free-text generation, then a smaller model like gemini-2.5-flash to convert the outputs to structured text.

polyrand··on A “frozen” dictionary for Python
A frozen dictionary would be very welcome. You can already do something similar using MappingProxyType [0]

  from types import MappingProxyType
  
  d = {}
  
  d["a"] = 1
  d["b"] = 2
  
  print(d)
  
  frozen = MappingProxyType(d)
  
  print(frozen["a"])
  
  # Error:
  frozen["b"] = "new"

[0]: https://docs.python.org/3/library/types.html#types.MappingPr...
polyrand··on Implications of AI to schools
There is too much focus on students cheating with AI and not enough on the other side of the equation: teachers.

I've seen assignments that were clearly graded by ChatGPT. The signs are obvious: suggestions that are unrelated to the topic or corrections for points the student actually included. But of course, you can't 100% prove it. It's creating a strange feedback loop: students use an LLM to write the essay, and teachers use an LLM to grade it. It ends up being just one LLM talking to another, with no human intelligence in the middle.

However, we can't just blame the teachers. This requires a systemic rethink, not just personal responsibility. Evaluating students based on this new technology requires time, probably much more time than teachers currently have. If we want teachers to move away from shortcuts and adapt to a new paradigm of grading, that effort needs to be compensated. Otherwise, teachers will inevitably use the same tools as the students to cope with the workload.

Education seemed slow to adapt to the internet and mobile phones, usually treating them as threats rather than tools. Given the current incentive structure and the lack of understanding of how LLMs work, I'm not optimistic this will be solved anytime soon.

I guess the advantage will be for those that know how to use LLMs to learn on their own instead of just as a shortcut. And teachers who can deliver real value beyond what an LLM can provide will (or should) be highly valued.

polyrand··on Claude Code 2.0
Me too! I also have a bunch of hooks in claude code for this. But codex doesn't have a hooks feature as polished as claude code (same for their command permissions, it's worse than Claude Code as of today). That's why I explored this "workaround" with bash itself.
polyrand··on Claude Code 2.0
It depends. If you allow running any of bash/ruby/python3/perl, etc. and also allow Claude to create and edit files without permission, then it won't protect against the pattern you describe.
polyrand··on Claude Code 2.0
Instead of containers, which may not always be available, I'm experimenting with having control over the shell to whitelist the commands that the LLM can run [0]. Similar to an allow list, but configured outside the terminal agent. Also trying to make it easy to use the same technique in macOS and Linux

[0]: https://ricardoanderegg.com/posts/control-shell-permissions-...

polyrand··on Rails on SQLite: new ways to cause outages
A bit off topic but:

  The reason for the "lite" in the name is that it doesn’t run a separate process, it doesn’t listen on a port or a socket, and you can’t connect to it.
The name doesn't really contain "lite". It's SQL-ite. So the suffix is "ite":

  The suffix "ite" is derived from the Greek word lithos (from its adjectival form -ites), meaning rock or stone [0]

[0]: https://english.stackexchange.com/a/34010
polyrand··on Lit: a library for building fast, lightweight web components
Hi! Not really a question, but just an appreciation message. I haven't used the full "Lit" package a lot, but "lit-html" is incredibly useful.

I use it in almost all my personal websites. And when I don't use it, I end up reinventing half of it and realize I should have used it from the start. This command is in most of my projects:

  curl -L https://cdn.jsdelivr.net/npm/lit-html@3/lit-html.js -o ${project}/lit-html.js
I've never felt I'm using a framework or anything that deviates from Vanilla JS and valid HTML, which is why using it hardly causes any more cognitive load than using regular string templates and JavaScript functions. Which is something that I can't say about other frontend tools.

Another thing I like from Lit is that with the CDN bundle, it's straightforward to experiment and use all the features without needing a build step.

polyrand··on What should a native DOM templating API look like?
After trying a bunch of ways of creating client-side apps, I've now also settled on using lit-html (not even the full Lit framework). Just the `html` and `render` functions. It's simple, convenient, and fast.

Since it "caches" the rendered parts, I haven't had performance issues just re-rendering everything on state changes (with some basic scheduling). I find it easier to reason about than React since I can use Vanilla JS everywhere, and components are just functions using the `html` tagged template, which can be composed.

polyrand··on A love letter to the CSV format
As someone who likes modern formats like parquet, when in doubt, I end up using CSV or JSONL (newline-delimited JSON). Mainly because they are plain-text (fast to find things with just `grep`) and can be streamed.

Most features listed in the document are also shared by JSONL, which is my favourite format. It compresses really well with gzip or zstd. Compression removes some plain-text advantages, but ripgrep can search compressed files too. Otherwise, you can:

  zcat data.jsonl.gz | grep ...


Another advantage of JSONL is that it's easier to chunk into smaller files.
polyrand··on Lynx: Open Source Native Cross Platform framework used in TikTok
Thanks. What do you mean with "native" (vs. C++)?

What I assumed from the podcast is that there's a lot of internal reusable tools in C++, and the web-based stuff is mostly about the UI layer.

Is there a lot of WASM to use both at the same time?

polyrand··on Lynx: Open Source Native Cross Platform framework used in TikTok
I remember listening to a Syntax FM[0] with Zack Jackson from ByteDance, which mentioned this framework briefly. Some quotes and notes from that part of the podcast:

- All ByteDance products, even native apps, are web-based

- They have an in-house framework called "Lynx" which is essentially their version of React Native[1]

- "All apps are Lynx apps. Everything is a Lynx app. It's all backed off the same stack."

- This approach allows them to maintain a unified architecture while having specialized teams focus on different aspects (algorithms, compiler, kernel, etc.)

[0]: https://syntax.fm/show/860/module-federation-microfrontends-...

[1]: The one being released, in the podcast they confirmed they would be open-sourcing it this year

polyrand··on Using executable scripts instead of shell aliases
Hi! Author here.

Yes, this is another one which greatly benefit from, and I forgot to add, I'll update the post.

I'd say more generally: being able to use those executable scripts inside other scripts, subshells, and other environments that don't use the `.bashrc` aliases by default.

polyrand··on How much memory do you need in 2024 to run 1M concurrent tasks?
Out of curiosity, I checked if using uvloop[0] in Python changed the numbers.

This is the code:

  # /// script
  # requires-python = ">=3.12"
  # dependencies = ["uvloop"]
  # ///
  
  import asyncio
  import sys
  
  import uvloop
  
  
  async def main(num_tasks):
      tasks = []
  
      for task_id in range(num_tasks):
          tasks.append(asyncio.sleep(10))
  
      await asyncio.gather(*tasks)
  
  
  if __name__ == "__main__":
      num_tasks = int(sys.argv[1])
      # uvloop.run(main(num_tasks))
      asyncio.run(main(num_tasks))
I ran it with 100k tasks:

  /usr/bin/time -l -p -h uv run async-memory.py 100000
On my M1 MacBook Pro, using asyncio reports (~170MB):

  170835968  maximum resident set size
Using uvloop (~204MB):

  204259328  maximum resident set size

I kept the `import uvloop` statement when just using asyncio so that both cases start in the same conditions.

[0]: https://github.com/MagicStack/uvloop/

polyrand··on FastHTML – Modern web applications in pure Python
For what it's worth. One thing I really like about `htpy` is that the element attributes go before the child elements. I find this easier to write and read. Other things I like:

Having child elements as a list (i.e: the __getitem__ override) makes it convenient to build elements based on simple conditions + list comprehensions. This can be done with other frameworks, but it seems more natural to me when using `htpy`.

I also like that you can just `print()` elements and get the final HTML without having to pass it through a different function. This is not something specific about FastHTML, but rather something I've found I also had to do when using `lxml` or similar tools (I wrote about my experiments here[0])

[0]: https://ricardoanderegg.com/posts/python-build-html-componen...

polyrand··on FastHTML – Modern web applications in pure Python
Very cool! After trying different approaches to render HTML from Python objects (including lxml, xml, etc.) I ended up liking htpy[0] the most, and the apps I built look similar to the examples in the FastHTML docs. I'll definitely try it.

One pattern I use is putting all the functions that generate HTML inside their own class. That way, I can more easily create and reuse components like:

  class Views:
      ...

  def comp1(self):
      return Div(self.header(), P("too"))
Then `self.header()` can be reused in other parts, or to return partial HTML. It also makes it easy to pass the "request" object to the class, and do conditional rendering based on it (cookies, auth, language, etc).

[0]: https://htpy.dev/

polyrand··on Ludic: New framework for Python with seamless Htmx support
This is wonderful, I love it. I recently wrote a blog post about generating HTML in Python using LXML (https://ricardoanderegg.com/posts/python-build-html-componen...) and I didn't know about your library. I'll update it to add a mention to it.

Apart from the simplicity, I like the fact you can "install" it by copy-pasting the code at the top of your script, or running:

  curl -L https://raw.githubusercontent.com/j4mie/hotmetal/main/hotmetal/__init__.py >> myscript.py
which is nice when you want a self-contained file.

I think I'll be using this in the future.

Page 1 of 6Next →