HN user

gwking

224 karma

github: gwk

Posts0
Comments80
View on HN
No posts found.

I have one weird trick for people who are exploring this vein. I last opened an Xcode project about five years ago so I could be way behind the times.

Having spent many years fighting with Xcode professionally, I was thrilled when swift build came out, and then appalled at how badly Xcode adopted it. Eventually I realized that you can set up your entire app as a swift package, and then the Xcode project with a single main source file that calls some `app_main()` (or whatever you want to call it) function in your package.

I cannot remember exactly but there was something annoying about setting up a new project; I think by default Xcode assumes that you want a swift package to be treated as a dependency that is checked out from git, but there was a way to drag and drop a local dependency in the same project directory and then it worked.

What this buys you is that files are no longer tracked by Xcode, so renames/merges no longer trigger project.pbxproj surgery. Instead you specify the swift package directories and are done.

I used this for some large personal projects and was very happy with it.

At one point I also wrote my own build tool that imitated all of the steps that Xcode took so that I could truly be Xcode-free. That also worked (and was not even that hard) but I went back to Xcode because the debugger UI was better than what I could get out of VS Code at the time, and especially because I was playing around with the Metal debugger.

I've been working on a wrapper harness that runs claude as a separate user named `agent`. I tried this about a year ago and couldn't get it to work because of OAuth and the keychain, but took another pass recently and claude had enough self-knowledge about recent changes to say we could do it with CLAUDE_CODE_OAUTH_TOKEN. It has required building a some tooling around permissions setup with ACLs but it works on macOS today.

In terms of risk, I see it as halfway between stock claude with the sandbox and full-blown container or machine isolation.

I was recently thinking that as Claude's own sandbox gets better I'm doubting the ROI on my belt-and-suspenders project, but your comment reminds me why I'm doing it.

It is not currently published open source but I'm happy to talk about it with strangers.

The suitability of Litestream for production disaster recovery is also an open question in my mind. I used 0.3.x for several years and when I tried to upgrade to the 0.5.x series there were runaway disk usage problems that would have caused downtime had they made it to prod. As far as I can tell these have not been entirely addressed, although recent bug reports suggest that they might be getting closer.

I want to love it, and I don't take open source projects like this for granted. But during my last production upgrade I chose to decommission Litestream in favor of a dumber, less granular solution using sqlite3_rsync and nightly backups because there is no point in using a backup system that is not rock solid.

The simple answer is, I choose to use Python because I am productive with it. I get a lot done compared to the other languages I have tried. Performance is almost never the limiting factor in my work, nor has it been for the vast majority of the work I've ever been witness to. When it is, it comes up in very particular circumstances, and can usually be fixed algorithmically. Indeed, that is the situation where I have used profilers.

The fact that the base language is an order of magnitude (or two!) slower has almost never mattered. If my work gets to the point where it does, and I have an excuse to go mess around with a rust extension or some cool optimized library, things are going very well.

I've been professional developer for over 20 years now, and I've read this forum obsessively for much of that time. I've seen people write things like, "Most engineers would kill for a 5% speedup" and I think, on what planet? Most engineers have much larger problems that cannot be so easily quantified. Come to think of it, I think that there is an allure to performance optimization due to the fact that it can be so easily quantified.

I’ve casually experimented with this in python a number of times for various hot loops, including those where I’m passing the chunk between c routines. On Apple M1 I’ve never seen a case where chunks larger than 16k mattered. That’s the page size, so totally unsurprising.

Nevertheless it’s been a helpful rule of thumb to not overthink optimizations.

I tried this with Claude code on macOS. I created a new agent user and a wrapper do run Claude has that user, along with some scripts to set permissions and ownership so that I could run simple allow/deny commands. The only problem was that the fancy oauth flow broke. I filed an issue with Anthropic and their ticket bot auto closed it “for lack of interest” or whatever.

I fiddled with transferring the saved token from my keychain to the agent user keychain but it was not straightforward.

If someone knows how to get a subscription to Claude to work on another user via command line I’d love to know about it.

My understanding is that many extension modules are already written to take advantage of multithreading by releasing the GIL when calling into C code. This allows true concurrency in the extension, and also invites all the hazards of multithreading. I wonder how many bugs will be uncovered in such extensions by the free threaded builds, but it seems like the “nuts” choice actually happened a long time ago.

I wrote a very rudimentary schema and automatic migration system for SQLite. One problem that I ran into recently was deploying changes that spanned two migrations, because the tool doesn’t know how to step through commits to do successive auto-migrations between schema versions. I guess there are rather obvious ways to handle this if you generate and then commit the full migration sql for each schema change. Nonetheless I’m curious if this is a problem you have had to think about, if you find it interesting or if it sounds like a bad path to go down, and if atlas does anything smart in this department. Thanks in advance!

This may be outdated because git’s defaults have improved a lot over the years. When I first used git on a team was in 2011. As I recall, there were various commands like git log -p that would show nothing for a merge commit. So without extra knowledge of the git flags you would not find what you were looking for if it was in a side path of the merge history. This caused a lot of confusion at times. We switched to a rebase approach because linear history is easier for people to use.

To answer your question directly, if somewhat glibly, I’m glad I rebased every time I go looking for something in the history because I don’t have to think about the history as a graph. It’s easier.

More to your point, there are times when blame on a line does not show the culprit. If you move code, or do anything else to that line, then you have to keep searching. Sometimes it’s easier to look at the entire patch history of a file. If there is a way to repeatedly/recursively blame on a line, that’s cool and I’d love to know about it.

I now manage two junior engineers and I insist that they squash and rebase their work. I’ve seen what happens if they don’t. The merges get tangled and crazy, they include stuff from other branches they didn’t mean to, etc. the squash/rebase flow has been a way to make them responsible for what they put into the history, in a way that is simple enough that they got up to speed and own it.

I appreciate the even tempered question. I’ve been using mypy since its early days, and when pyright was added to vs code I was forced to reckon with their differences. For the most part I found mypy was able to infer more accurately and flexibly. At various times I had to turn pyright off entirely because of false positives. But perhaps someone else would say that I’m leaning on weaknesses of mypy; I think I’m pretty strict but who knows. And like yourself, mine is a rather dated opinion. It used to be that every mypy release was an event, where I’d have a bunch of new errors to fix, but that lessened over the years.

I suspect pyright has caught up a lot but I turned it off again rather recently.

For what it’s worth I did give up on cursor mostly because basedpyright was very counterproductive for me.

I will say that I’ve seen a lot more vehement trash talking about mypy and gushing about pyright than vice versa for quite a few years. It doesn’t quite add up in my mind.

I jumped through a bunch of hoops to get claude code to run as a dedicated user on macOS. This allowed me to set the group ownership and permissions of my work to control exactly what claude can see. With a few one-liner bash scripts to recursively set permissions it worked quite well. Getting the oauth token token into that user's keychain was an utter pain though. Claude Code does a fancy authorization flow that puts the token into the current user's login keychain, and getting it into the other user's login keychain took a lot of futzing. Maybe there is a cleaner way that I missed.

When that token expired I didn't have the patience to go through it again. Using an API key looked like it would be easier.

If this is of interest to anyone else, I filed an issue that has so far gone unacknowledged. Their ticket bot tried to auto-close it after 30 days which I find obnoxious. https://github.com/anthropics/claude-code/issues/9102#issuec...

My first programming "job" was a sort of summer internship when I was 14 for a family owned company called Signature Systems (signature.net). They are still in business. Their product is an operating system called Comet, that if I'm not mistaken was originally a compatibility play bringing software from the previous era of 16 bit microcomputers onto DOS PCs, and then later into Windows. I may be misremembering some of the details but I think at one point a Comet system ran ticket sales at Madison Square Gardens. My summer project was to build a demo using their new support for Windows GUI elements. The last time I spoke with the owners, they told me that they still had customers, including in the textiles industry where loom patterns had been coded in Basic. I often think about it as an example of a legacy system, and smile at the idea of someone thinking they need to rewrite their plaid weave in TypeScript or Rust.

Separately, I have spent the last three years building a web app that replaced a heap of automation scripts for a ~50 person business. These were much more modern than what the OP describes but it had some of the same qualities. The scripts mostly generated google sheets and emails. The replacement is a python web app using SQLite. Moving the company data into a proper database has been a very significant step for them. In some ways, the project feels a lot like custom business software that got built in the 90s.

One tidbit that I don't see mentioned here yet is that ATTACH requires a lock. I just went looking for the documentation about this and couldn't find it, especially for WAL mode (https://www.sqlite.org/lockingv3.html mentions the super-journal, but the WAL docs do not mention ATTACH at all).

I have a python web app that creates a DB connection per request (not ideal I know) and immediately attaches 3 auxiliary DBs. This is a low traffic site but we have a serious reliability problem when load increases: the ATTACH calls occasionally fail with "database is locked". I don't know if this is because the ATTACH fails immediately without respecting the normal 5 second database timeout or what. To be honest I haven't implemented connection pooling yet because I want to understand what exactly causes this problem.

I have never seen the word “partition” used in this way before. Hard to search for examples because unrelated computer graphics articles about surface partitioning dominate. I did find this:

Partitioning is the distribution of a solute, S, between two immiscible solvents (such as aqueous and organic phases). It is an equilibrium condition that is described by the following equation:

S(aq) ⇄ S(org)

Interesting to think that a surface can play a role comparable to a solvent. I wonder what a chemist would have to say about it.

https://www.chemicool.com/definition/partitioning.html

Speaking only for myself, and in all sincerity: every year, there is some feature of the latest CPython version that makes a bigger difference to my work than faster execution would. This year I am looking forward to template strings, zstd, and deferred evaluation of annotations.

I’ll second this, and add that docstrings are becoming ever more useful as modern editors learn how to show them inline when I hover over a symbol. Starlette lacks docstrings entirely and it’s a real miss in my opinion.

I went from VS Code to Cursor, then got frustrated with Cursor breaking keybindings and other things, tried to go back to VS Code but missed the superior tab completion. Then I gave Zed a long hard try, but after over a month of daily usage I went back to Cursor again, just for the tab completion quality.

I don't use any of the chat or agent features, but for me Cursor's tab completion is a step forward in work efficiency that Zeta and Copilot were not. Sometimes it's subtle, and sometimes it is very obvious. Cursor seems to have sources of context that the others don't, like file names from the directory tree, and maybe even the relevant .pyi type annotations and docs for python modules. It also jumps to the next relevant problem site very effectively. It feels like the Cursor devs have done a ton of practical work that will be hard to match with anything other than a full-on competitive effort.

I want to see Zed succeed. I think it's very important that VS Code and its ultra-funded derivatives not dominate the modern editor landscape too thoroughly. Tab completion used to seem like a straightforward thing, but if the state of the art requires a very elaborate, whole-workspace-as-context environment to operate in, then I wonder if it's going to become a go big or go home kind of feature.

I can't help wonder what the actual internal API for this kind of thing is going to look like in the future. It used to be something like, what's the current token behind the cursor, and look in a big prefix tree of indexed words. Then maybe it got more elaborate with things like tree-sitter, like what's the incomplete parse tree up to this point. Then when editors started using AI, I stopped having any idea of what the actual inputs are. I'd love to hear about real implementation experience at any stage of this evolution.

It seems to me that you need to think about your server as the production database, rather than a web server instance that can be trivially spawned by a management layer.

When I deploy a new version of my python/sqlite web app, I do not replace the whole machine. I just upgrade the python package and restart the systemd service.

If I wanted to reduce downtime I could probably figure out a transition using SO_REUSEPORT. During the transition the old and new processes would be using the db concurrently, so the app would have to respect that case. If part of the upgrade requires a db schema change then I’m not sure how you could avoid some downtime. But I don’t know if it is possible with traditional dbs either.

Hyper-Typing 1 year ago

I started using swift with a lot of enthusiasm for the type system, but at times it was a huge time suck. There were lots of obscure interface types that read like BipartisanPoliticallyCorrectSequence<T> that made writing my own generic utilities challenging. Documentation for that stuff was very poor and the source code was often totally inscrutable due to the implementation of core types in c++ and the overall complexity of the compiler.

I recently saw Chris Lattner talk about Mojo and he made passing reference to Swift trying to do too much with the type system. It’s telling that a guy with his experience is trying something more like zig’s comptime approach to types after two decades of generics.

I merely saw the domain name 'yarchive' and had a strange inkling that there might be a connection. A quick search yielded this: https://unlimitedhangout.com/2021/08/investigative-reports/t....

I have no opinion of unlimitedhangout.com or the veracity of that article. But in response to "I just find it strange", I'm beginning to associate this sort of intensely intellectual inquiry into disparate topics with equally intense political positions.

I was first introduced to Urbit as if it was a purely technical, humorous and extremely nerdy lark. It was a joke thing my friend got me to sign up for, to own a slice of an imaginary universe (in a quantity called a "frigate" or whatever it was). When I learned years later about how serious the worldview behind it was, I was quite shocked.

Since then, and especially since the NYT outing of Scott Alexander in 2020, I've become more attuned to the pattern. These hyper-analytical blogs often come with a lot of political implications below the surface.

Again, I'm not taking sides here. If anything, the takeaway for me is that the world is very complicated. We have these rare polymath personalities who go deep into topics, have a strong voice on the internet, and they end up with all sorts of valid criticisms of the status quo. This in turn can align with extreme political views.

His website is tonykingart.com. It is sorely in need of an update. I don't have any photos of the Farallon paintings, but a small one hangs in my childhood bedroom. You could contact him through his site and I'm sure he'd oblige!