Very exciting - I'm a long-time vim user but most of my coworkers use VSCode, and I've been wanting to try out in-editor completion tools like this.
After using it for a couple hours (on Elixir code) with Qwen2.5-Coder-3B and no attempts to customize it, this checks a lot of boxes for me:
- I pretty much want fancy autocomplete: filling in obvious things and saving my fingers the work, and these suggestions are pretty good
- the default keybindings work for me, I like that I can keep current line or multi-line suggestions
- no concerns around sending code off to a third-party
- works offline when I'm traveling
- it's fast!
So I don't need to remember how to run the server, I'll probably set up a script to check if it's running and if not start it up in the background and run vim, and alias vim to use that. I looked in the help documents but didn't see a way to disable the "stats" text after the suggestions, though I'm not sure it will bother me that much.
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.
Note about GitHub Windows Actions runners: I think I understand what is wrong with them, though it's somewhat conjecture since I don't actually know how it works internally.
It looks like the free CI runners have C: drive pointing to a disk that is restored from a snapshot, but often times it hasn't finished restoring the entire snapshot by the time your workflow runs, so IO can be very slow, even if you don't need to read from the still-frozen parts of the disk. Some software ran inside workflows will do heavy R/W on C: drive, but it's better to move anything that will be written to disk, e.g. caches, to D: if possible. This often leads to much better performance with I/O and more predictable runtimes, particularly when there isn't a lot of actual compute to do.
I don’t bookmark. I have a "Home" page with "One-liners & Links of the Day." The links are listed in reverse chronological order by day. Only this month is kept on the home page. There are links to previous months’ home pages at the bottom. Since it's a web page, I am not constrained to how some “Bookmark” manager wants me to view links. I can add whatever I want. Annotations, color, and non-links like code snippets are in there. If there is Too Much Information (TMI) I collapse it in a detail / summary HTML tag.
If I actually go back frequently to a link or to a piece of code, I put that link or code snippet in a more permanent "Document" web page which groups the items by topic. For example:
Typography
— ‘ ’ “ ” • … × °
At the moment, I am keeping the web pages local. There is a duplicate on an actual web server so it can be accessed from other devices.
"Basically it states that the degree of similarity between two objects can be approximated by the degree to which you can better compress them by concatenating them into one object rather than compressing them individually."
In the meanwhile, I found that enabling page transitions is a progressive enhancement tweak that can go a long way in making HTML replacement unnecessary in a lot of cases.
1) Add this to your css:
@view-transition { navigation: auto; }
2) Profit.
Well, not so fast haha. There are a few details that you should know [1].
* Firefox has not implemented this yet but it seems likey they are working on it.
* All your static assets need to be properly cached to make the best use of the browser cache.
Also, prefetching some links on hover, like those on a navbar, is helpful.
Add a css class "prefetch" to the links you want to prefetch, then use something like this:
Hacking's an interesting case because all practice is also product. That means that if you practice enough, you eventually "finish" your practice material (which is great in one respect, but it means you have to find a new one to practice on, which often has its own probles). It also means that it's impossible to practice without a project to practice on - I know some blogs suggest "code kata", but most of the interesting problems in software development occur when you get past 3000 lines or so, and you can't really see that when you're writing Quicksort for the umpteenth time.
Anyway, here's what I think the difference between an expert hacker and an experienced non-expert is. When faced with a bug, a non-expert will fix the bug. An expert or prospective expert will ask himself "What caused this bug, and how can I prevent it from ever happening again?"
The answer will usually be some form of unit/regression testing, so the prospective expert will write some tests to catch the bug and then fix it. Then they'll ask themselves "What prevented me from writing tests in the first place?" and the answer will usually be some combination of tedium and lack of defined interfaces. So they'll fix the first problem by learning how to abstract test state into reusable fixtures, and they'll fix the second by refactoring the production code so it has clearly defined public interfaces with defined inputs and outputs.
Then, after doing this a few times, the prospective expert will ask themselves "Where are my bugs coming from? What are most of my tests checking?" And if their code is anything like mine, the answer will be "the use and abuse of mutable state". So they'll go through their code looking for places where they can use purely functional techniques to eliminate mutable state. Or they'll change their APIs so that they eliminate any call-order dependencies they've programmed in. Or they'll encapsulate their mutable state in certain well-defined objects with known lifetimes.
Then the prospective expert will look at this activity and think "how could this be made less tedious?" And the answer will often be to add some extra abstractions which have now been made obvious because of the data flow's been exposed.
Then they add some more features, keep track of the root causes of their bugs, and fix the next most common error. (Which in my experience is usually type errors, but unfortunately working in a statically-typed language seems to eliminate many of the opportunities for abstraction that are exposed in the last step, unless it's Haskell, which isn't yet practical for webapps.)
Disclaimer: I'm not an expert. Yet. I am, however, noticeably better than I was 8 months ago when I left my last job. One of the reasons I left was because there was a ceiling to how many of the above techniques I could apply - I could unit test my own code, but I couldn't change the API to make it more stateless, or eliminate nulls as a legal parameter to methods, or separate components so they were each stubbable on the local computer.
I have known a couple programmers that were real experts though - one wrote the filesystem and transaction server for Stratus and has been an early engineer and tech lead (and sometimes VP of engineering) of 3 IPOs. She was full of all these techniques, some obvious and some pretty subtle, for reducing bug rates. For example, she'd define a private copy constructor on any class that wasn't intended to be passed by value, so the compiler would flag shallow copies as an error. Then she defined this in a mixin base class and inherited from it, so she didn't need to implement the pattern in every single one of her classes. Or she'd use references vs. pointers as a way of flagging object ownership: they're exactly the same thing, but the compiler won't let you delete a reference, so she'd pass by reference if ownership wasn't being transferred and pointer if it was. Every language has these sort of subtle tricks: in JavaScript, it's things like not extending built-in prototypes and using closures effectively. The difference between deliberate practice and mundane programming is that you're actively looking for patterns like this when you deliberately practice.
I think one core thing that you have to do with ASTs in Rust is to absolutely not store strings of the like in your AST. Instead you want to use something like static string libraries (so you get cheap clones and interning) and for things like positions in text you want to use just indices. Absolutely avoid storing references if you can avoid it!
The more your stuff is held in things that are cheap/free to clone, the less you have to fight the borrow checker… since you can get away with clones!
And for actual interpretation there’s these libraries that can help a lot for memory management with arenas and the like. It’s super specialized stuff but helps to give you perf + usability. Projects like Ruffle use this heavily and it’s nice when you figure out the patterns
Having said that OCaml and Haskell are both languages that will do all of this “for free” with their built in reference counting and GC… I just like the idea of going very fast in Rust
I use these for footnotes, eg in [1] which had a lot of footnotes. Ghost and other blogs don't support footnoting well afaict. Sometimes I miss restructured text, which did this quite well, markdown alas does not.
TBH there's more that goes into it than I really want to type out here. LLMs are a good resource for this kind of thing, they generally give correct advice. A quick overview:
Security looks like:
- Ensure SSH (the method by which you'll access the server) is secured. Here is a good article of steps to take to secure SSH on a new server (but you don't have to make your username 16 random characters like the article says): https://hiandrewquinn.github.io/til-site/posts/common-sense-...
- Have a firewall running, which will prevent incoming network connections until you explicitly open ports on the firewall. This helps prevent lack of knowledge and/or misconfiguration of other programs on the server from burning you. The easiest firewall is ufw ("uncomplicated firewall"). Here is a DigitalOcean article that goes into more depth than you probably need at first, or ask Claude/ChatGPT some questions about ufw: https://www.digitalocean.com/community/tutorials/how-to-set-...
- Keep the OS and programs (esp. Nginx/Apache and Node) up to date.
Availability looks like:
- Have a backup of important data (the database). You can set up a 'cron job' that will run a shell script on a schedule that dumps the database to a file (ex. mysqldump) and then copies that file into your backup destination, which could be some cloud storage or another VPS. If you can, backing up to 2 separate destinations is better than one, keeping a history of backups is good, and doing "health checks" of the backup system and the backups is good (meaning periodically check that the backup system is working as intended and that you could restore from a backup if needed)
- Ability to respond to outages, or failure of the host (the server/VPS). This means either having another machine that can be failed over to (probably overkill if you don't have paying customers and an SLA), or you are able to spin up a new server and deploy the app quickly if the server gets borked somehow and goes down. To do that you have some options: have a clear list of instructions that you can manually perform relatively quickly (slowest and most painful), or have automated the deployment process. This is what something like Ansible is for, or you can just use shell scripts. Using Docker can speed up and simplify deployment, since you're building an image that can then be deployed on a new server pretty simply. You will of course also need the backup of the data that you've hopefully been taking.
There are "better" techniques to do all of those that require more know-how, which can prevent and handle more failure scenarios faster or more gracefully, and would be used in a professional context.
Yes, I believe a Droplet or VPS (virtual private server) from some other provider would be sufficient. Digital Ocean isn't the cheapest, but it's pretty frictionless, slick, and has a lot of good tutorial articles about setting up servers.
You'd have a Linux machine (the VPS) that would have at least 3 programs running (or it is running Docker, with these programs running inside containers):
- Node.js
- the database (likely MySQL or PostgreSQL)
- Nginx or Apache
You'd set up a DNS record pointing your domain at the VPS's IP address. When someone visits your website, their HTTP requests will be routed to port 80 or 443 on the VPS. Nginx will be listening on those ports, and forward (aka proxy) the requests to Node, which will respond back to Nginx, which will then send the response back to the user.
There are of course security and availability concerns that are now your responsibility to handle and configure correctly in order to reach the same level of security and availability provided by a good PaaS. That's what you're paying the PaaS for. However, it is not too difficult to reach a level of security and availability that is more than sufficient for a small, free web app such as this one.
To quickly determine passive vs. active voice, you can add the phrase, “by zombies” to the end of the sentence.
If it’s clear the zombies are doing the action (subject), then the content is passive voice. Otherwise, if the zombies are an adverbial phrase, the sentence is in active voice.
Passive voice: “Content is synced by zombies”
Active voice: “NotesHub syncs the content by zombies”
I use a little script [1] and a passive approach to quickly find a PDF I am looking for among a few thousands of academic PDF. The workflow (illustrated in the GIF [2]):
- as I read new PDFs in the browser, the PDFs are passively downloaded typically in a Downloads/ folder.
- This results in thousands in papers lying in Downloads/ or elsewhere.
- The command p from the script [1] let me instantaneously fuzzy-search over the first page of each pdf (The first page of each pdf is extracted using pdftotext, but cached so it's fast). The first page of academic PDFs usually contains title, abstract, author names, institutions, keywords of the paper; so typing any combination of those will quickly find the pdf.
What is particularly convenient is that no time is spent trying to organize the papers into folders, or importing them into software such as zotero. The papers are passively downloaded, and if I remember ever downloading a paper, it's one fuzzy-search away. Of course it does not solve the problem of generating clean bibtex files.
For some history/context on what this is based on:
• During 1977–78, Knuth wrote the first version of TeX (now called TeX78) in SAIL and gave a talk[1] about it. Everyone was excited, and lots of people at other universities/labs starting writing their own ports of TeX.
• During 1980–82, Knuth set out to rewrite a “portable” TeX using Pascal, the most widely available language at that time (actually he wrote his own macros/wrapper on top of Pascal; the resulting language is called WEB). This (TeX82 aka TeX) is the program still in use today if you invoke "tex". (Continues to be updated once every few years, but basically stable.)
• During 1998–2000, there was a Java rewrite of TeX called the New Typesetting System (NTS)[2], which had an alpha release and then was basically abandoned: it had all the problems of TeX and was several times slower, so it was regarded by many as a failure. Meanwhile extensions of TeX like pdfTeX came into existence, which are the programs most people use today.
• The code still exists though, and I imagine people must have tried it on and off. But since I can't find any earlier record, I'll provisionally take credit for the idea of resurrecting/resurfacing it, when I tried it in 2017: [3]
• Recently (in the last few months), Dave Jarvis (user `thangalin` here) has forked/modernized this Java implementation and is trying it out. (I noticed when he left his comment on my TeX.SE question; I guess his post https://tex.stackexchange.com/a/672614 on another question is what led to it being posted here.) I'm excited about this; looking forward to see how it gets used.
(Apologies if this long comment potentially takes attention away from the current state and future possibilities, but felt like the history is useful context…)
————
I'll also add some history about the license, as I see another thread about it. When Knuth wrote TeX, it was to solve a specific problem he had encountered in publishing: the second edition of TAOCP Vol 2 was turning out worse in appearance than the first, because the publisher was moving from hot-metal typesetting (with Monotype machines) to phototypesetting, and could not achieve exactly the same appearance. While being bothered by this, Knuth discovered that digital typesetting machines were starting to come into existence: now it was just 0s and 1s, and as a programmer he felt he could handle it. That was his motivation for creating TeX and METAFONT: the appearance of each page would remain reproducible forever into the future.
Except: when he publicized TeX and various clones sprung up, the situation was heading towards merely re-introducing the problem: if different computer systems had different programs all called “tex” that made even subtly different choices about line-breaking or whatever, then someone could write a paper/book on one computer, fine-tune the typesetting, then send the .tex file to their colleague / editor / publisher who used another computer, and no longer be confident that they would get the same result. This was one of the reasons he used the rewrite to create a portable TeX, going to great pains to use only a common subset of Pascal (Pascal had widely diverging compiler and language features), wrote a very demanding conformance test suite called the TRIP test[4] and insisted that any program would need to pass this test to be called "tex" — that way, everyone using "tex" could be sure they were writing something that would always produce the same result everywhere. If you wanted to make different choices in the program you could, as long as you changed the name.
When he announced in 1990[5] that TeX would be stable (no more features), this is what he wrote:
> My work on developing TeX, METAFONT, and Computer Modern has come to an end. I will make no further changes except to correct extremely serious bugs. I have put these systems into the public domain so that people everywhere can use the ideas freely if they wish. I have also spent thousands of hours trying to ensure that the systems produce essentially identical results on all computers. […]
> […] anybody can make use of my programs in whatever way they wish, as long as they do not use the names TeX, METAFONT, or Computer Modern. In particular, any person or group who wants to produce a program superior to mine is free to do so. However, nobody is allowed to call a system TeX or METAFONT unless that system conforms 100% to my own programs […]
> I welcome continued research that will lead to alternative systems that can typeset documents better than TeX is able to do. But the authors of such systems must think of another name. That is all I ask, after devoting a substantial portion of my life to the creation of these systems and making them available to everybody in the world. I sincerely hope that the members of TUG will help me to enforce these wishes…
etc. And NTS derives a similar licence, and this project (being forked from NTS) simply carries over the license.
Of course such a license is unusual today, and thousands of pages' worth of ink have been spilled over whether or not this counts as “free software” (predating GPL / MIT license etc), and (finally) grudgingly accepted to be. You can read about the history of the LaTeX project's similar license (LPPL) and all the debates on Debian/FSF mailing lists etc if you're morbidly interested[6]; the discussion usually proceeds on similar lines and I hope it doesn't get repeated here. :-)
I've often described my motivation for building software to others using imagery: I like to go find a secluded beach, build a large, magnificent sand castle, and then walk away. Will anyone notice? Probably not. Will the waves eventually destroy it? Yep. Did I still get immense satisfaction? Absolutely.
> What if personal projects are not meant to be finished?
The key is deciding on 2 things before you start anything:
1. What is the goal?
2. How will I know it’s done?
With this approach you can start side projects purely to have fun for an afternoon or to learn a thing or to see how a technology or approach feels. Then you can drop it and move on. Goal achieved, thing learned, no need to keep going.
The worst projects in my experience come from unclear goals and fuzzy definitions of done. Those projects tend to drag on forever, burden your life, and fill up your days with busywork.
Note that it’s always okay to add additional goals to the same project once you’re done.
We systematically get posts and blogs and real-world experience showing that software development is actually about maintenance.
Yesterday we had an article about so many half-arsed software in maintenance mode that the world would be ending soon, crumbling under the weight of not-maintained enough software.
So far I've seen LLMs (I pay for GTP 4o btw) very good at producing boilerplate code. Does it help? Heck, yup.
Does it produce even more code needing ever more maintenance? You bet so.
At this rate it looks like we're going to need way more software developers, not less.
The key to the article, and to all of Western music, is about a set of weird mathematical coincidences involving the twelfth root of two. In particular, that twelfth-root-of-two to the fourth power is almost exactly 4/3, and twelfth-root-of-two to the fifth power is is almost exactly 3/2. And, of course, twelfth-root-of-two to the 12th power is exactly 1.
For some reason, not entirely well understood, when you play frequencies that are nice multiples together, they make pleasant patterns ("consonance"). They interfere and reinforce at regular intervals, and it sounds nice. When you don't get nice ratios, they make irregular interference patterns, and that sounds unpleasant ("dissonance").
So... take a scale (one frequency to twice-that-frequency), divide it into 12 equal parts (geometrically), and you get of those nice patterns. Each successive note is the frequency of the previous note times the-twelfth-root-of-two. That's the "twelve tone equal temperament". It makes it easy to write pretty music just by following some mathematical rules.
There's a Wikipedia article on the-twelfth-root-of-two:
EXCEPT... that those coincidences aren't perfect. They're very close, but tiny differences matter. Some intervals that should work, don't. Different scales take on different feelings, even though in theory they're just the same thing nudged up a few hertz.
Anyway... that set of coincidences is the basis of all of the music you're familiar with. Other musical cultures also take advantage of it. But there's no fundamental reason why those particular coincidences should be the only interesting music, and so people look around (often, to yet more world musical cultures) for alternatives.
We performed a controlled empirical comparison of pie vs linear menus in 1988, which we presented at CHI'88 and published in the proceedings. It showed that pie menus were 15% faster than linear menus, and that they had a significantly lower error rate.
An Empirical Comparison of Pie vs. Linear Menus. Presented at ACM CHI’88 Conference, Washington DC, 1988.
What does this mean? Should we program pie menus into our bitmapped window systems tomorrow and expect a 15–20% increase in productivity since users can select items slightly faster with pie menus. Pie menus seem promising, but more experiments are needed before issuing a strong recommendation.
First, this experiment only addresses fixed length menus, in particular, menus consisting of 8 items — no more, no less. Secondly, there remains the problem of increased screen real estate usage, In one trial a subject complained because the pie menu obscured his view of the target prompt message. Finally, the questionnaire showed that the subjects were almost evenly divided between pie and linear menus in subjective satisfaction. Many found it difficult to “home in on” a particular item because of the unusual activation region characteristics of the pie menu.
One assumption of this study concerns the use of a mouse/cursor control device and the use of pop-up style menus (as opposed to menus invoked from a fixed screen location or permanent menus). Certainly, pie menus can and in fact have been incorporated to use keyed input [7] and fixed “pull-down” style presentation (the pie menu becomes a semicircle menu). These variations are areas for further research.
I made a web app with a similar goal, but with one additional feature: the text field is also the search field, as you type a new note, the existing notes get filtered based on the text of the new note: https://thinktype.app
This is an awesome overview and if you want more, most of those are documented in an approachable way on YouTube.
Just wanted to provide some perspective here on how many things those projects need to take care of in order to get some training setup going.
I'm the developer behind TMInterface [1] mentioned in this post, which is a TAS tool for the older TrackMania game (Nations Forever). For Linesight (last project in this post), I recently ended up working with its developers to provide them the APIs they need to access from the game. There's a lot of things RL projects usually want to do: speed up the game (one of the most important), deterministically control the vehicle, get simulation information, navigate menus, skip cut scenes, make save states, capture screenshots etc. Having each of those things implemented natively greatly impacts the stability and performance of training/inference in a RL agent, e.g. for the latest version the project uses a direct capture of the surface that's rendered to the game window, instead of using an external Python library (DxCam). This is faster, doesn't require any additional setup and also allows for training even if the game window is completely occluded by other windows.
There are also many other smaller annoying things: many games throttle FPS if the window is unfocused which is also the case here, and the tool patches out this behaviour for the project, and there's a lot more things like this. The newest release of Linesight V3 [2] can reliably approach world records and it's being trained & experimented with by quite a few people. The developers made it easy to setup and documented a lot of the process [3].
I have been using this in a CI pipeline to maintain a business-critical PDF generation (healthcare) app (started circa 2010 I think), here is the RSpec helpers I'm using:
Yes, it's me. I did my networking work at Ford Aerospace in the early 1980s. But I left in 1986. It still bothers me that the Nagle algorithm (which I called tinygram prevention) and delayed ACKs interact so badly.
That fixed 200ms ACK delay timer was a horrible mistake. Why 200ms? Human reaction time. That idea was borrowed from X.25 interface devices, where it was called an "accumulation timer". The Berkeley guys were trying to reduce Telnet overhead, because they had thousands of students using time-sharing systems from remote dumb terminals run through Telnet gateways. So they put in a quick fix specific to that problem. That's the only short fixed timer in TCP; everything else is geared to some computed measure such as round trip time.
Today, I'd just turn off ACK delay. ACKs are tiny and don't use much bandwidth, nobody uses Telnet any more, and most traffic is much heavier in one direction than the other. The case in which ACK delay helps is rare today. An RPC system making many short query/response calls might benefit from it; that's about it. A smarter algorithm in TCP might turn on ACK delay if it notices it's sending a lot of ACKs which could have been piggybacked on the next packet, but having it on all the time is no longer a good thing.
If you turn off the Nagle algorithm and then rapidly send single bytes to a socket, each byte will go out as a separate packet. This can increase traffic by an order of magnitude or two, with throughput declining accordingly. If you turn off delayed ACKs, traffic in the less-busy direction may go up slightly. That's why it's better to turn off delayed ACKs, if that's available.
One of the few legit cases for turning off the Nagle algorithm is for a FPS game running over the net. There, one-way latency matters; getting your shots and moves to the server before the other players affects gameplay. For almost everything else, it's round-trip time that matters, not one-way.
I can't theorize on the 'Why' part of your question, but there are ways around using Android Studio IDE to make Android builds without gradle build system.
If you want to learn exactly how the APK/AAB is built and compiled, here are some resources I used to learn:
After using it for a couple hours (on Elixir code) with Qwen2.5-Coder-3B and no attempts to customize it, this checks a lot of boxes for me:
So I don't need to remember how to run the server, I'll probably set up a script to check if it's running and if not start it up in the background and run vim, and alias vim to use that. I looked in the help documents but didn't see a way to disable the "stats" text after the suggestions, though I'm not sure it will bother me that much.