HNHacker News
TopNewBestAskShowJobs

rav

1,266 karma · joined February 20, 2013

[ my public key: https://keybase.io/ravv; my proof: https://keybase.io/ravv/sigs/iqfti_2jqJcDaAHMPVlrVndLEH7npqbzA7qHMvhSCmY ]
submissionscomments
rav··on Ghost Font: A font that humans can read but AI cannot
> For example, it would be interesting to incorporate Ghost Font into CAPTCHA systems, as most systems are easily solved by AI today.

It seems to me like it should be easy enough to take Ghost Font, apply normal video compression techniques, and analyze the compressed signal to recover the visual outline of the letters, which you would then analyze with OCR (or an AI I guess ...). In other words, a novel CAPTCHA technique but not necessarily "fundamentally more difficult" than existing CAPTCHA techniques, once the cat-and-mouse game gets going.

rav··on A stray "j" ruined my evening
Today I learned that jq -Rrj is a shorter command line for doing the same as tr -d '\n'.
rav··on Boffin claims Microsoft’s “quantum leap” is invalid due to “basic Python errors”
Not the first time that a Nature publication's "too good to be true" results turn out to be based on simple programming errors... Nature 532, 210 (2016) was retracted after it was shown that a hand-coded gradient function, used in gradient descent, had a simple sign error (details in arXiv 2003.05808).
rav··on The truth about being a manager
There's a note at the end:

> As always, this blog post is written by me, without any AI, so all errors are my own.

However, the illustrations in the post are clearly made by generative AI, are they not?

rav··on The Traditional Vi (2007)
> Of course, if you're implementing POSIX vi, there are quite a few features that have aged poorly, like roff/troff macros and line-editing

What do you mean by "roff/troff macros"?

EDIT: Ah, you're probably talking about the "section-wise" movements, defined in POSIX with language like "A line whose first character is a <period> and whose second and third characters match a two-character pair in the 'sections' edit option (see ex)" - that's the first time I've stumbled upon the 'sections' and 'paragraphs' options in the Vim manual ... Very quaint!

rav··on Is my blue your blue? (2024)
Looking in dev console reveals that the issue is an error response from https://cdn.skypack.dev/canvas-confetti - at the moment that URL returns:

        A server error has occurred

        FUNCTION_INVOCATION_FAILED

        sfo1::qcpj5-1777386477345-b792e22509f4
rav··on A Git helper tool that breaks large merges into parallelizable tasks
Given a commit that both refactors (A) and adds a feature (B), you can go into the codebase and remove the new feature by hand (B^-1), commit the feature removal, and immediately revert the feature removal. This leads to three commits: (A B), B^-1, and B. Squash the first two commits to obtain a commit that only refactors, and another commit that only adds the new feature. I've written more about this technique ("the Hammer") here: https://github.com/Mortal/gittalk
rav··on High-Level Rust: Getting 80% of the Benefits with 20% of the Pain
In TypeScript it's called "bivariance", which sounds very programming language theory like, but is not a term typically used in academic contexts, since it is unsound almost by default. It's described here: https://www.typescriptlang.org/docs/handbook/type-compatibil...
rav··on Show HN: Llmswap – Python package to reduce LLM API costs by 50-90% with caching
How is it "50-90%" savings? If a given application doesn't repeat its queries, surely there's nothing to save by caching the responses?
rav··on Don't unwrap options: There are better ways (2024)
You can rewrite it using let-or-else to get rid of the unwrap, which some would find to be more idiomatic.

    let value = Some(param.as_ref()) else {
      // Handle, and continue, return an error etc
    }
    // Use `value` as normal.
rav··on Ask HN: Do you still use search engines?
At the moment it seems like you can avoid AI search results by either including swear words, or by using 'minus' to exclude terms (e.g. append -elephant to your search query).
rav··on When you deleted /lib on Linux while still connected via SSH (2022)
I often run rm -rf as part of operations (for reasons), and my habit is to first run "sudo du -csh" on the paths to be deleted, check that the total size makes sense, and then up-arrow and replace "du -csh" with "rm -rf".
rav··on AI Blindspots – Blindspots in LLMs I've noticed while AI coding
My suggestion: Change the color of visited links! Adding a "visited" color for links will make it easier for visitors to see which posts they have already read.
rav··on Show HN: "Git who" – A new CLI tool for industrial-scale Git blaming
On a small team I usually already know who wrote the code I'm reading, but it's nice to see if a block of code is all from the same point in time, or if some of the lines are the result of later bugfixing. It's also useful to find the associated pull request for a block of code, to see what issues were considered in code review, to know whether something that seems odd was discussed or glossed over when the code was merged in the first place.
rav··on Hk, a new Git hook manager
Ooh, core.hooksPath is quite nifty. I usually use something like

         ln -sf ../../scripts/git-pre-commit-hook .git/hooks/pre-commit
which simply adds a pre-commit symlink to a script in the repo's scripts/ dir. But hooksPath seems better.
rav··on It's OK to hardcode feature flags
I don't understand what a dedicated "completely open source offering" provides or what your "five nines feature flag system" provides. If you're running on a simple system architecture, then you can sync some text files around, and if you have a more scalable distributed architecture, then you're probably already handling some kind of slowly-changing, centrally-managed system state at runtime (e.g. authentication/authorization, or in-app news updates, ...) where you can easily add another slowly-changing, centrally-managed bit of data to be synchronised. How do you measure the nines on a feature flag system, if you're not just listing the nines on your system as a whole?
rav··on Using uv as your shebang line
It seems to me that macOS has env -S as well, but the shebang parsing is different. The result is that shebang lines using env -S are portable if they don't contain any quotes or other characters. The reason is that, running env -S 'echo a b c' has the same behavior as running env -S 'echo' 'a' 'b' 'c' - so simple command lines like the one with uv are still portable, regardless of whether the OS splits on space (macOS) or not (Linux).
rav··on Using uv as your shebang line
Oh wow, today I learned about env -S - when I saw the shebang line in the article, I immediately thought "that doesn't work on Linux, shebang lines can only pass a single argument". Basically, running foo.py starting with

    #!/usr/bin/env -S uv run --script
causes the OS run really run env with only two arguments, namely the shebang line as one argument and the script's filename as the second argument, i.e.:

    /usr/bin/env '-S uv run --script' foo.py
However, the -S flag of env causes env to split everything back into separate arguments! Very cool, very useful.
rav··on Every HTML Element
No love for the <plaintext> tag? "The <plaintext> HTML element renders everything following the start tag as raw text, ignoring any following HTML. There is no closing tag, since everything after it is considered raw text." - it's my favorite obscure deprecated HTML tag.
rav··on Llama.vim – Local LLM-assisted text completion
FIM is "fill in middle", i.e. completion in a text editor using context on both sides of the cursor.
rav··on Oh Shit, Git?
Actually, "git reset --soft" moves the current branch to another commit, without moving the index (aka staging area) along with it, whereas "git reset" (aka "git reset --mixed") moves the current branch AND the index to another commit. I really couldn't wrap my head around it before I had gone through "Reset demystified" [1] a couple times - it's not a quick read but I can strongly recommend it.

[1] https://git-scm.com/book/en/v2/Git-Tools-Reset-Demystified

rav··on Oh Shit, Git?
For move-branch: Use `git branch -f master HEAD~` if you're currently on another branch, or `git reset --soft HEAD~` if you're currently on master.
rav··on Is WebAssembly Memory64 worth using?
You could use handwritten asmjs in that case. I did it at work to improve performance on some pixel-wise software rendering we were doing. (We have since then switched to WebGL, but asmjs was a nice stepping stone.) If I recall correctly, it basically boils down to using small fixed size arrays and appending "|0" after each uint32 operation and "+" in front of each float32 operation - so it's something you can do by hand. Of course, one of my colleagues then made a tweak which gave a surprisingly huge slowdown - you should probably declare loudly (with comments etc.) that a certain code block is intended to be asmjs if you do this in a large codebase.
rav··on Bad Apple but it's 6,500 regexes that I search for in Vim
To run a macro on the start of each line matching your search, you can use:

    :g//norm @q
Here, g// repeats the most recent search, and norm @q runs the q macro on each matched line. This is not quite the same as starting the macro with a search, since the cursor is at the start of the line and not at the start of the match, but it's often good enough.

You can also restrict it to just the matches inside a range of lines: First select the lines in visual mode, then type :g//norm @q, which will cause Vim to insert a range before g, as in: :'<,'>g//norm @q, which means "between line '< and '>, find lines containing a match of the most recent search, and run @q on each such line".

rav··on Bad Apple but it's 6,500 regexes that I search for in Vim
Heads up - you should use "qD instead of "qdd to avoid an extra newline at the end of the register contents. (In fact the current Vim 9.1.954 behavior seems a bit odd in that it moves the cursor down, but not to the start of the line, as if j is pressed... Seems like a bug to me.)
rav··on Bad Apple but it's 6,500 regexes that I search for in Vim
There's also the no-macro solution where you just use ":%norm [series of keystrokes]" to run the given keystrokes on each line, but that comes with the added difficulty of not giving any visual feedback of what the keystrokes will do before you submit the entire line.

One thing to keep in mind is that ":%norm" will place the cursor at the start of each line, before any indentation, whereas the trick of ending the macro with "+" will place the cursor at the start of each line after the indentation. But this can be worked around with ":%norm ^@q", using ^ to skip indentation before running macro q on each line.

rav··on Bad Apple but it's 6,500 regexes that I search for in Vim
Actually, from an algorithmic standpoint it's the opposite: the minimum cover problem (where overlap is allowed) is NP-hard whereas the minimum partition problem (where overlap is NOT allowed) has polynomial-time algorithms. "An Algorithm for Covering Polygons with Rectangles" by Franzblau and Kleitman 1984: https://core.ac.uk/download/pdf/82333912.pdf

However, that's of course just an academic tangent - the theoretical results don't necessarily imply that one problem is easier than the other when you're just getting something to work for an afternoon project.

rav··on Bad Apple but it's 6,500 regexes that I search for in Vim
Regarding the Vim macro that ends by going to the next line to be "replayable": You can also use the following command to run the macro once per line:

        :%norm @q
rav··on Noise
The default chords from left to right sound pretty standard in my ears: vii⁰, I, ii, iii, IV, V, vi - but maybe it's locrian if you take the leftmost chord to be the tonic, and a plain major if you take the second from the left to be the tonic?
rav··on Joseph Jastrow and his duck – or is it a rabbit? (2004–2020)
Solving the duck-rabbit puzzle in Animal Well gave me such chills. In the beginning of the game the player comes across a room with a duck that quacks at you when you walk by. In a distant corner of the world there's a picture of a duck-rabbit with a passcode. When you enter the passcode in front of the duck, it transforms into a rabbit and warps away through a portal that appears for a brief moment while a spooky sound effect plays.
Page 1 of 10Next →