HNHacker News
TopNewBestAskShowJobs

robto

992 karma · joined April 30, 2015

robto@idle.horse
submissionscomments
robto··on Ad blocking is under attack (2017)
Firefox has container tabs if you don't want to leak your Google account to everything else. And it blocks ads perfectly.
robto··on What's the right age to get a smartphone?
It's not hard to learn the basics of another operating system, and it's something they're going to have to do no matter what. They'll be learning new software their whole lives. And how would using software that respects their privacy and agency hurt them? I don't particularly want to them to be software devs, I want to empower them to use tools to accomplish their goals, and Linux is great for that.
robto··on What's the right age to get a smartphone?
One thing I'm considering is getting my kid a laptop when they start asking for a smartphone. They'll be able to engage socially for the most part, but it won't have the "with you every moment of every day" problem. And instead of a device that's mainly geared towards consumption, they'll at least have tool that's designed to to empower its user.

And it will run Linux! No kid of mine will grow up thinking proprietary software is normal! The source is yours to command!

robto··on Free Markets Don’t Buy Peace
This article doesn't address the most salient argument in the free trade -> peace syllogism, which is that free trade between two countries reduces the chance of war between them only to the extent in which cutting that trade off (which is what would happen in a war) would cause domestic pain. So it's an incentive, not an absolute.

Take the China example - China as of this September holds $3.055 trillion in foreign currency reserves. This makes the US and China mutually interdependent - if China stopped selling products to the US then it would cause a massive recession in China. If the US couldn't find buyers to finance its spending, it would default on its debt. If the US defaults, the entire international economy would likely go up in flames.

So it's like mutually assured destruction, but instead of stockpiling nukes (though we do that, too), we're actually producing useful goods and services. And it doesn't make war impossible, but it does mean that war won't happen on a whim - it will be an utter last resort, with millions of wage earners and business owners wanting to try to make any other solution work, lest they lose their livelihood.

It's hard to take the article seriously without this sort of analysis.

robto··on Ask HN: What is the coding exercise you use to explore a new language?
If I'm looking for problems I always like to try Advent of Code problems, it's a good chance to learn basic io, sample the standard library, and learn how to idiomatically handle common problems.

But before that I prefer to get a book and work my way through all the examples, otherwise I'm just making up what "idiomatic" means.

robto··on Analyzing Every Clojure Project on GitHub
There's a handy chart in "The Joy of Clojure" that I refer to whenever I'm trying to tackle concurrency problems:

    |              | ref | agent | atom | var |
    | coordinated  | x   |       |      |     |
    | asynchronous |     | x     |      |     |
    | retriable    | x   |       | x    |     |
    | thread-local |     |       |      | x   |
Turns out I have never needed coordinated, synchronous stuff. I have dabbled with agents, but just for an Advent of Code problem.

I do like that 63% (!!) of clojure repos have no mutable references at all - that tracks very strongly with my experience. And that the average number of mutable references is less than 2! Immutability can carry you a long ways, and I love that I can trust that contract. On the other hand, it's nice that I can opt in to mutation really easily if I need it.

robto··on Ask HN: More “experimental” UIs for editing/writing code?
Hazel[0] is really fascinating!

"Hazel is a live functional programming environment that is able to typecheck, manipulate, and even run incomplete programs, i.e. programs with holes. There are no meaningless editor states."

It's a programming language and IDE that's fully integrated with the semantics of the language. I saw the demo at Strange Loop in 2019[1], and it was really cool to see the interactive, dialogue-esque development workflow that I love from super dynamic lisps - but working with a strong, statically, dependently typed language. It reminded me of Idris, but even more integrated.

[0]https://hazel.org/ [1]https://www.thestrangeloop.com/2018/hazel-a-live-functional-...

robto··on Work with Git Forges from Magit
Magit changed git from just a DVCS to a integral part of my dev process. Especially in large projects where I spend much more time reading code and trying to understand how it came to be the way that it is. I mainly write Clojure, but for a while I was writing Scala (many years ago, when its emacs support was inferior to Intellij, I don't know what the state is these days). When I was using Scala it wasn't my emacs-style keybindings that I missed the most (though I did miss them), it was the mind-meld instant navigation of the project history that slowed me down. I ended up suffering the emacs support while planning my changes just so that I could use Magit to read history. Then I'd switch back to Intellij for actual authoring.

It's incredibly flexible, but here are some things that I do all the time in Magit that I hesitate to do when I'm just using the cli:

- stage individual lines from a hunk

- rebase fearlessly

- resolve merge conflicts

- view the list of all commits that touched a file

- view a file from the above list at a point in time next to the current version

- name my stashes!

All of these are possible from the cli or other git uis, but they are very discoverable using Magit - I didn't even know you could name stashes until I was prompted for a name while stashing. And Magit will happily log all the actual git commands that it runs, so if you're curious how it works you can easily peak behind the curtain.

robto··on Cameras and Open Source Smartphones: It’s Complicated
Free Software is so cool - I love how the solutions to tough problems can be shared so that everyone benefits from the work. It's a long journey, but I'm glad that there are people doing the hard work. This is the reason that I'm happy to support Purism!
robto··on Firefox now only available via snap on Ubuntu
I've been using NixOS for several years and one of the pain points was frequently updating software - the updates don't come out until the package definitions get updated. Last year I just started using Flatpak for those packages and it works a treat - plus, I can keep the proprietary, non-free software that I need out of my system config, which I like. Snap is a non-starter, and while I hope more software shows up properly, reproducibly packaged for Nix, Flatpak is the next best thing.
robto··on Three Pillars of Reproducible Builds
Huawei just published a paper (Towards Build Verifiability for Java-based Systems[0]) on trying to get the JVM ecosystem reproducible. It looks like it's early days, but I'm paying attention.

[0]https://arxiv.org/abs/2202.05906

robto··on Show HN: Matrix-CRDT – real-time collaborative apps using Matrix as backend
I'd start with reading the Matrix spec, you'll want to know how the syncing protocol works, and this will give you enough familiarity that you can start playing around with curl to actually see it in action. I'd highly recommend understanding how conflict resolution works, the "Analysis of the Matrix Event GraphReplicated Data Type"[0] lays it out pretty well.

Matrix-CRDT posted here should abstract most of the nitty gritty stuff, but there are no shortcuts to designing with CRDTs so familiarizing yourself with those is important.

Other than that, just start playing and asking questions! The #matrix:matrix.org room is full of friendly and helpful people and I'm sure you'd be able to get answers.

[0]https://arxiv.org/pdf/2011.06488.pdf

robto··on Show HN: Matrix-CRDT – real-time collaborative apps using Matrix as backend
See, this is what I keep going on about to my friends - Matrix is actually a graph syncing protocol, not an instant messaging protocol, and is a great way to build federated applications.

I get that Element needs to focus on one use case in order to pay the bills, but there's a lot of room for applications that have barely been explored - calendars, contacts, games, social media, heck - you could build a federated gitlab-like collaboration site with truly federated data. You get multi-device sync, e2e encryption, and identity management out of the box.

Thanks for putting this together, I hope there will be a gold rush as people realize how much low-hanging fruit there is!

robto··on Go Replaces Interface{} with 'Any'
In Java people regularly refer to a particular JDK version as a Java 17 or Java 11, even though they actually refer to versions 1.17 and 1.11, respectively[0]. In Clojure land they just say 1.x, even when large new features are added.

I like this because it emphasizes the community's commitment backwards compatibility, which I greatly value. I've spent a good deal of time writing Javascript, where library developers seem to have very little respect for their users and constantly break backwards compatibility. In ecosystems like that, upgrading fills me with dread. When I see a library on version 4, I have learned to keep looking - if they weren't thoughtful enough about their API design for the first 3 major releases, I shouldn't expect it to be much better going forwards.

For an application, I'm pretty open to version numbers signifying big features - Firefox and Chrome do this, and it's helpful with marketing. But for a programming language? A programming language is a tool, and when upgrading you need to carefully read the changelog anyways. A programming language is no different from a library (in Clojure it literally is a library), and backwards compatibility is /literally/ the main thing I care about. Is my tool going to intrude on /my/ schedule, and force me to make changes /it/ wants instead of being able to spend my time making changes /I/ care about? I want to know that.

[0]This is apparently an awful example as I've just learned that Java is actually doing the major version only thing. It still sort of works because the only reason they can do that is because they Will Not Break Compatiblity.

robto··on Vlojure – A New Way to Write ClojureScript [video]
This seems like a nifty visualization of Clojure code, and it's rather fun to play with. Certainly looks like it was fun to make!

You can play with it here: https://vlojure.io/

robto··on The growing market of not cutting down trees
I once worked as a data analyst in the EM&V industry (Evaluation, Measurement, and Verification). I worked for a small group of consultants and our primary customer would be energy utilities across the United States. You see, an energy company, all things equal, would prefer to sell more energy rather than less. More energy sold == more profit, for the most part - coops and other, smaller scale operations aside.

Now, society has decided that incentivizing growth in energy consumption isn't a winning strategy in the long run. Or, at least, politicians have signed into law various incentive programs to change the business calculus of energy companies, wherein an energy company can get reimbursed for energy efficiency campaigns that it runs and, if total energy consumption is less than a certain rate year over year, the energy company can claim a prize to offset the profit forgone by promoting energy efficiency.

However, it is not so straightforward to account for how much energy _isn't_ being used on account of a specific intervention. Enter here the entire EM&V industry! We would run studies to account for this missing energy, and it was a very thorough business - comparing lists of equipment replaced under industrial efficiency programs, measuring Watt-hours offset, surveying households to figure out how many of them actually installed those complementary LED lightbulbs. Every year we would run through the same process with the same energy companies and then they'd find out how much energy they saved.

At times it felt surreal to be a part of this giant industry competing for a chance to count how much of something wasn't used, but it looks like that industry is only going to grow as carbon caps and offsets become a bigger deal.

I don't think it's a bad thing, just a profoundly weird one. In 50 years I wonder how many people will derive their income from counting things that don't exist :)

robto··on Immudb 1.0 – open-source, immutable database with SQL and verified timetravel
Reminds me a lot of Fluree[0], an immutable, cryptographically verifiable, temporal database, but with RDF as a query language, which I think is very nice. SQL is nice because it's familiar but it's honestly not that hard to improve on.

[0]https://flur.ee/

robto··on Let’s Talk About Hot Tub Streams
Do you think this moderation paradox - of needing curation at scale, but automatic moderation + "user flag" moderation being inadequate - is a universal problem, or do you think it's specific to ad-funded platforms?

I wonder if a patron-driven community that sets its own moderation policy wouldn't have this problem, because when a topic gets too large it will inevitably splinter into smaller communities where the preferred moderation style of each subset can be catered to.

robto··on The search for a perfect access control system
This looks really great! I was just mulling over doing postgres-style row-level auth in datahike and you've already put it together. I'll give it a spin this week, thanks for mentioning it.
robto··on Making a Lego Domino Machine [video]
This strikes me as a perfect visual example of repl-driven development. I like how he starts very simple and slowly makes it more sophisticated, testing every step of the way.

If you've never tried it before, I highly recommend giving it a shot - it's extremely satisfying. I use Clojure, but other lisps also have fantastic repl environments that facilitate this style of development. "Bottom Up vs Top Down Design in Clojure"[0] is the talk that really made it clear to me how to design programs this way.

[0]https://www.youtube.com/watch?v=Tb823aqgX_0&list=PLZdCLR02gr...

robto··on Emacs org-mode examples and cookbook (2017)
In addition to nix and guix, which have been mentioned, you can also use straight.el[0]. It's a functional package manager for emacs, so you'd use it instead of package.el. It checks out the git repo for each package and maps package name->commit hash in a nice little file, which you can then commit to git. Then, on a new machine, it will check out that specific rev for all your packages.

It even has nice use-package integration, so if you're already using that you likely won't have to change all your config.

[0]https://github.com/raxod502/straight.el

robto··on The Future of Group Messaging
Isn't this a slightly less general version of Zulip? I wish more products would adopt that topic model, it works really well for bridging the overlapping conversation puzzle.
robto··on Tree-sitter: an incremental parsing system for programming tools
I'm so excited for this to become built-in in more places! I think once non-lisp users can experience the Power of Structural Editing they'll say, "Hey, I understand now why you all feel so passionate about your parentheses!"

And I can stop feeling like my fingers have all lost a knuckle when I'm writing Typescript :)

robto··on Guile – Scheme Implementation Supporting R5RS, R6RS, and R7RS Standard and SRFI
The Shepard init system[0] for Guix and most of the Guix plumbing are written in Guile Scheme. There's also Guile Emacs.

[0]https://www.gnu.org/software/shepherd/

robto··on Again on 0-based vs. 1-based indexing
I've noticed this as well, and I've concluded that the actual surprising part for new coders is mutability. In basically every domain where non-developers invent algorithms, everything is immutable - spreadsheets, math!. Heck, even reading an article - the words you've already read don't change their meaning just because you've kept reading.

Mutability is really a result of the fact that computers are physical machines. So I think if you're going to teach software development, you should really start at the machine architecture and build up (ala NAND to Tetris) or start with an immutable-by-default language and only dip into mutation as an "advanced" concept, only to be used by experts and definitely not by beginners.

I endorse the second way, as I've seen it work very well, whereas I've seen more than one ship crash on the shore of understanding pointers...

Of course, my N is small.

robto··on Cerulean: Experimental micro-blogging app for Matrix
I'm really excited about using Matrix for more than instant messaging. This November I spent a week reading all the specs (which were really well documented!) and some spec proposals that I think are really important for non-IM clients (room types, event relations (replies), portable identities). I was able to get a simple web client up and running in ~300 lines of clojurescript.

Cerulean is looking great! Does it support e2e threads? I'm about to take a stab at implementing e2e in my application and I'm curious how much overhead it is.

robto··on Show HN: Polylith – the last architecture you will ever need?
Nice! I went through the poly tool readme and I'm really impressed with the improvements. One thing I don't see highlighted that I'm curious about: have you used it to build cljs projects? Since shadow-cljs has deps.edn integration, I think it could theoretically work, though the repl might be a bit twitchy.
robto··on Show HN: Polylith – the last architecture you will ever need?
Can you sum up what's new, or point me to a changelog? I took a serious dive into it in late 2019, but ended up pausing because of tooling deficiencies - mainly dealing with symlinks, iirc.

I was really impressed with how it encouraged decoupling, and it has positively affected how I write code and think about dependencies.

robto··on Java Concurrency – Understanding the Basics of Threads
We were an all-Java shop and we were considering how to make our application a SAAS cloud application. Our senior engineers read this book. They all agreed that it was very educational, but the conclusion was that Java concurrency in practice has too many footguns, and so we ended up adopting Clojure.

I think modern Java has better support for it, but if you've got mutable state spread throughout your application you're going to have a hard time no matter what.

robto··on CRDTs: The Hard Parts [video]
The entire book is about when and how these statements turn out to not be absolutely true. And it's not a short book. I don't have my copy in front of me right now, so I won't get into specifics. But I consider it one of the most important books I've read, if only for making me realize how difficult it is to get distributed systems correct. Or, rather, learning that getting distributed systems correct is impossible and what sort of tradeoffs you can make in order to keep things mostly working.

And it turns out that most services that I find myself working on these days are distributed systems, so having a healthy respect for all the ways things can break is a useful place to be.

← PreviousPage 2 of 6Next →