HNHacker News
TopNewBestAskShowJobs

ruuda

2,195 karma · joined August 15, 2018

https://ruuda.nl
submissionscomments
ruuda··on Docusaurus – Build optimized websites quickly, focus on your content
If you don't like to run javascript outside of a browser, MkDocs is a great Python-based alternative: https://www.mkdocs.org/
ruuda··on Vega – A declarative language for interactive visualization designs
Or if you write it by hand at all, use RCL, then you can also abstract away the repetitive parts: https://github.com/ruuda/rcl/blob/master/examples/vega.rcl
ruuda··on Ask HN: What are you working on (August 2024)?
The RCL configuration language, https://rcl-lang.org / https://github.com/ruuda/rcl. Lately I'm working on support for floats to complete the json superset promise. Also I added a shorthand for "query --format=raw" to make it more useful as a jq replacement.
ruuda··on On Writing Well
https://developers.google.com/tech-writing covers the same topics in more detail.
ruuda··on The waiting time paradox: why is my bus always late? (2018)
Another one is that your friends on average have more friends than you. (Because you are more likely to be friends with people who have many friends than with people who have few friends.)
ruuda··on Transformers in music recommendation
I tried to make embeddings from my personal listening history a few years ago (https://github.com/ruuda/deepnote) with the idea that listens of music that matches well would be played in the same session, basically word2vec applied to listening history. It didn't work very well, it mostly found that tracks on albums are similar because I tend to listen to full albums. Maybe I didn't stir the parameters enough, or maybe it needs far more data. (All of Listenbrainz?) I also still want to experiment with generating embeddings for tracks just from the time of the day, week, and year. (I tend to listen to different things on a Friday night vs. Sunday morning, and I listen to very different music in summer vs. winter.) But that's for locally recommending relevant tracks that you already have in your library (for https://github.com/ruuda/musium), not for discovering new music. I already implemented a sorting mode to "rediscover" albums (albums that have a lot of listens in the past but few recently), and it works reasonably well. I expect that adding time of day/week/year will improve this a lot, but I haven't implemented it yet. I wonder how much of an improvement a transformer like in the article adds on top of that.
ruuda··on Primitive Recursive Functions for a Working Programmer
That’s interesting!
ruuda··on Primitive Recursive Functions for a Working Programmer
Thanks for pointing that out, I didn’t know types in Cue could be self-referential.
ruuda··on Primitive Recursive Functions for a Working Programmer
Two examples that satisfy these criteria are Dhall [1] and Cue [2], but in one sense they are not interesting examples: Dhall is a total language on purpose, it does go the “not Turing-complete” route, and Cue has no functions so there is nothing to recurse.

I would say that RCL [3] satisfies the criteria. It’s deterministic and pure, has metered execution, and it sandboxes filesystem access. It can read files when allowed by the sandbox policy, but in my view that makes those files part of the source code, it behaves the same as imports.

For RCL I did not want to go the “not Turing-complete” route for exactly the reason the author mentions: knowing that a program enventually terminates is not a useful property in practice. And conversely, it is possible to write very complex programs in total languages like Agda, non-Turing-completeness is no guarantee for simple programs/configurations. All loops in RCL are bounded, but it has functions, so it has recursion. It does not have tail calls, so at first I added a recursion depth limit (to prevent overflowing the native stack), but then the fuzzer discovered a function that runs in constant stack space, yet it hangs. I still don't fully understand how it works:

    let f = g => g(g(h => k => g(g(h))));
    f(f)
Anyway, it is not a problem in practice that this kind of pathological function can be expressed, I just put a limit on the number of execution steps (a “gas limit”, or what the author calls “metered execution”). For keeping code simple, I think the fact that the built-in looping constructs are bounded, and recursion is awkward, are a good nudge, but in the end the most valuable tool is code review and applying good judgment.

    [1]: https://dhall-lang.org/
    [2]: https://cuelang.org/
    [3]: https://rcl-lang.org/
ruuda··on A skeptic's first contact with Kubernetes
At the moment nothing like that exists. Eventually it should be possible to generate RCL types like https://github.com/dhall-lang/dhall-kubernetes does for Dhall.
ruuda··on A skeptic's first contact with Kubernetes
RCL has control flow and types: https://rcl-lang.org/. No record types yet though, so they are not yet very useful to validate e.g. a Kubernetes manifest against a schema.
ruuda··on Reverse-engineering my speakers' API to get reasonable volume control
Yep. I was always using only the low end of the volume slider and having the same problem as OP that the steps were too coarse. So for Musium, I added a logarithmic volume control with a step size of 1 dB. That difference is on the border of being perceivable in the range I usually listen at, which is fine enough in practice.

https://docs.ruuda.nl/musium/loudness/

ruuda··on A type system for RCL, part 2: The type system
> Will that always hold?

It’s hard to be sure about whether anything will always be true, but I intend to not expose environment variables, CLI arguments, or other impurities to RCL.

> What about environment variables? If the language ever needs to handle parameters, this assumption breaks and thus compile time and runtime will be separated.

This is more of an argument about the definition of “input”. In RCL you can import other RCL/json files (as structured data) or any UTF-8 file (as a string). If the evaluation of the program depended on environment variables (or if you could pass input values on the CLI), that would be very annoying for reproducibility. You’d have to specify out of band how to invoke `rcl`, and how to pass the right values. Instead, we can simply write those values to a file and import them. For my definition of “program”, by doing that, they have become part of the program, so we again have a program with no _external_ parameters.

Regardless of whether you call them inputs, the person who sets these values also immediately evaluates the program, so if the combination of parameters causes an error somewhere, the programmer can fix the input or the program. That’s different from a daemon, or program deployed to users, where the programmer does not yet know at development time which values can occur at runtime.

I can think of one case where this does not hold. What if you want to develop a _library_ of RCL code, with functions where you don’t know how they will be called? I don’t think that RCL programs should grow so complex that this is needed, but maybe I am too naive or nearsighted about that, and it will happen anyway. (Sharing schemas may be useful, but they only define types, not functions.) Even in that case, a configuration language is forgiving, because when the program is evaluated there is a programmer running it, even if it is not the person who wrote the function where the error originates.

(What if you build some system that autonomously generates json files and calls an RCL program that imports them, without a human watching? Sure you can do that, but then if it fails at runtime, I think that’s a case of the Baton Roue meme.)

I guess the summary of this is: for some languages, yes the type system should be very strict, and you want to know that when you write a function, it can’t fail at runtime. But for a configuration language, that is not a problem that the type system needs to solve. I wrote more about this in part 1: https://ruudvanasseldonk.com/2024/a-type-system-for-rcl-part....

ruuda··on The sad state of property-based testing libraries
Shrinking is built in to libFuzzer! (`-minimize_crash` in libFuzzer, `cargo fuzz tmin` with cargo-fuzz)
ruuda··on The sad state of property-based testing libraries
The major omission in this article is fuzzing. Not only is it practical and in wide (and growing use), it’s also far more advanced than QuickCheck’s approach of generating random inputs, because fuzzing can be _coverage-driven_. Property-based testing came out of academia and fuzzing came out of security research, initially they were not connected. But with the advent of in-process fuzzing (through libFuzzer), which encourages writing small fuzz tests rather than testing entire programs; and structure-aware fuzzing, which enables testing more than just functions that take a bytestring as input, in my view the two techniques have converged. It’s just that the two separate communities haven’t fully realized this yet.

One pitfall with non-coverage-driven randomized testing like QuickCheck, is that how good your tests are depends a lot on the generator. It may be very rarely generating interesting inputs because you biased the generator in the wrong way, and depending on how you do the generation, you need to be careful to ensure the generator halts. With coverage-driven fuzzing all of these problems go away; you don’t have to be smart to choose distributions so that interesting cases are more common, coverage instrumentation will automatically discover new paths in your program and drill down on them.

But isn’t fuzzing about feeding a large program or function random bytestrings as inputs, whereas property-based testing is about testing properties about data structures? It is true that fuzzers operate on bytestrings, but there is no rule that says we can’t use that bytestring to generate a data structure (in a sense, replacing the role of the random seed). And indeed this is what the Arbitrary crate [1] in Rust does, it gives tools and even derive macros to automatically generate values of your data types in the same way that QuickCheck can. The fuzzing community calls this Structure-Aware Fuzzing and there is a chapter about it in the Rust fuzzing book [2]. There are also tools like libprotobuf-mutator [3] that substitute fuzzers’ naive mutation strategies, but even with naive strategies fuzzers can usually get to 100% coverage with appropriate measures (e.g. recomputing checksums after mutation, if the data structure contains checksums).

I am using this extensively in my own projects. For example, RCL (a configuration language that is a superset of json) contains multiple fuzzers that test various properties [4], such as idempotency of the formatter. In the beginning it used the raw source files as inputs but I also added a more advanced generator that wastes less cycles on inputs that get rejected by the parser. The fuzzer has caught serveral bugs, and most of them would have had no hope of being found with naive randomized testing, because they required a cascade of unlikely events.

Structure-aware fuzzing is not limited to generating data structures either, you can use it to generate reified commands to test a stateful API, as you describe in the _Stateful property-based testing_ section. The Rust fuzzing book has an example of this [5], and I use this approach to fuzz a tree implementation in Noblit [6].

[1]: https://docs.rs/arbitrary/latest/arbitrary/ [2]: https://rust-fuzz.github.io/book/cargo-fuzz/structure-aware-... [3]: https://github.com/google/libprotobuf-mutator [4]: https://docs.ruuda.nl/rcl/testing/#fuzz-tests [5]: https://rust-fuzz.github.io/book/cargo-fuzz/structure-aware-... [6]: https://github.com/ruuda/noblit/blob/a0fd1342c4aa6e05f2b1c4e...

ruuda··on Show HN: Qq: like jq, but can transcode between many formats
Or you could write the query in a language that is easy to write by hand, like https://rcl-lang.org/, so you don't need ChatGPT to translate for you.
ruuda··on Ask HN: What are some iconic comments on HN?
This one was iconic among the people involved, we printed it and stuck it on the wall in the office: https://news.ycombinator.com/item?id=13783584
ruuda··on Microsoft to delay release of Recall AI feature on security concerns
Apologies, wrong tab, I meant to post here: https://news.ycombinator.com/item?id=40677941
ruuda··on Land value tax in online games and virtual worlds (2022)
> The lack of a formal market for land has not made land any cheaper, it has simply shifted the price from being denominated in money-dollars, to time-dollars and pain-in-the-butt-dollars.

Vitalik writes about this too: https://vitalik.eth.limo/general/2021/08/22/prices.html

ruuda··on Microsoft to delay release of Recall AI feature on security concerns
> The lack of a formal market for land has not made land any cheaper, it has simply shifted the price from being denominated in money-dollars, to time-dollars and pain-in-the-butt-dollars.

Vitalik writes about this too: https://vitalik.eth.limo/general/2021/08/22/prices.html

ruuda··on Google shuts down GPay app and P2P payments in the US
https://goomics.net/239/
ruuda··on Tegelwippen
In Utrecht, the municipality will lend you a bakfiets with all the equipment you need (soil, shovel, tile cutter) to replace a few tiles in front of your house with plants. You don't need a permit to do it. https://www.utrecht.nl/wonen-en-leven/parken-en-groen/zelfbe...
ruuda··on How to Use JSON Path
RCL (https://rcl-lang.org):

    [
        for book in input.store.book:
        if book.price < 10:
        book.title
    ]
ruuda··on Ask HN: Who is hiring? (May 2024)
Chorus One | https://chorus.one/careers | Platforms Engineer | REMOTE (Switzerland ± 6 hours)

Chorus One operates validators on many proof-of-stake blockchains (the ones where security is based on a Byzantine fault-tolerant consensus algorithm rather than wasting energy). We are hiring for several roles, but the one I will highlight is what we call the Platforms Engineer. Some companies call this Site Reliability Engineering or Devops.

The main thing we do is take upstream software, build it, run it on our infrastructure, and then monitor it and optimize that setup. Some things that make this interesting are:

* Building automation that enables us to do this for many networks (50+ currently). * Doing this with high uptime, building automation for failover, etc. * Working with software that is on the one hand cutting-edge and doing interesting things (consensus algorithms, distributed systems, cryptography), but on the other hand that means it’s immature and often not easy to operate and monitor. Often we have to build custom tools, and dive into the source code of the project. We contribute patches upstream when it makes sense. * Some of these projects are exercising the limits of what a machine can do, we have to do some low-level investigation that requires understanding of what the Linux kernel and network hardware are doing to properly identify what’s going on.

We do have a small cloud footprint but run primarily on bare metal. We are looking for people who can not just configure services offered by the public clouds, but who deeply understand what lies below; people who could build their own cloud. (That sounds a bit pretentious and it’s not exactly what we do, but it does involve many of the same aspects.) If this sounds interesting to you, check out https://careers.chorus.one/o/platforms-engineer-remote.

ruuda··on HCL: Toolkit for Structured Configuration Languages
Yes, at some point. It's the IDE I use myself so I definitely want one, but it's also one of the hardest ones to write a plugin for, so I haven't gotten to it yet.
ruuda··on HCL: Toolkit for Structured Configuration Languages
Frustration with HCL is why I wrote RCL (it now has a website, https://rcl-lang.org). It can generate HCL's json form for use with Terraform, and it has functions and sensible list comprehensions.
ruuda··on Show HN: Building a GPS receiver
> Have you ever noticed that your Maps app still works during a flight?

I noticed the opposite, it always fails to locate any satellites, even when GPS is still turned on in aeroplane mode. I'm not sure why.

ruuda··on Jpegli: A new JPEG coding library
What is your use case for degrading image quality that much? At quality level 80 the artifacts are already significant.
ruuda··on Ethereum has blobs. Where do we go from here?
I used to think it had something to do with dank memes, but I recently learned it's named after Ethereum researcher Dankrad Feist who came up with the idea.
ruuda··on Price fixing by algorithm is still price fixing
Increasing supply decreases prices globally, but increases them locally: https://www.astralcodexten.com/p/change-my-mind-density-incr...
← PreviousPage 5 of 13Next →