HNHacker News
TopNewBestAskShowJobs

vbsteven

1,971 karma · joined January 24, 2012

Freelance software development and cloud infrastructure.

I'm always interested in talking to people about autism/adhd/burnout issues in tech.

Email me at (hn username without vb prefix) @ quantus.io

submissionscomments
vbsteven··on Ask HN: Do you self-host your database?
Yes, I selfhost Postgres/Redis/Mongo for small projects (db + app server on the same machine or a small number of VMs). Usually in docker, sometimes systemd units. It's amazing what you can do on a single $5-50/month machine if HA isn't super important.

On larger projects (typically once k8s gets involved) I'm running on a cloud provider anyway and I might as well use a hosted version like RDS for the main database.

It comes down to the importance/budget of the project. I'm not a Postgres expert by any means but I'm confident enough that for simple use cases I can manage selfhosted. And if I need more, hosted versions are available at a cost.

However, any hosted DB product I use has to be open source and in theory easily replaceable with a selfhosted version. After the Parse.com fiasco I'm averse to closed/proprietary components in my infrastructure.

vbsteven··on Using Paper for Everyday Tasks
While I love my Remarkable 2 for taking notes, journaling, drawing and sharing/exporting the results, it lacks search/discoverability/navigation.

In a physical notebook it’s trivial to flip back a few pages to recall a note from last week. On remarkable that takes a lot more time, and the time cost is paid twice, once for finding the old note, and a second time to get back to the page I was writing. (Imagine working in a single browser window fullscreen without tabs).

I’m still looking for an optimal flow. And I’m gravitating towards something that can ingest remarkable pages, perform OCR and categorise/index the results.

vbsteven··on GitHub – nushell/nushell: A new type of shell
Popularity in this context is my personal experience seeing these tools pop up over and over again in the media that I consume.
vbsteven··on GitHub – nushell/nushell: A new type of shell
I'm the parent that you replied to. In my eyes there is nothing wrong with .deb and .rpm files. In fact, many of these tools are available for download in these formats and some others (docker, snap, etc). And it is good that they do but it comes with extra work to setup the pipelines/builds.

The concept of a language-specific package manager distributing not only libraries but also executables isn't new. Go get, ruby bundler, python pip, cargo and npm all have this feature.

I was originally answering a question about why we suddenly see all these "written in Rust" tools pop up. I think that is partly because Cargo provides this easier way to distribute native code to users on various platforms, without jumping through additional hoops like building a .deb, and setting up an apt repository.

Sometimes you just want to get some code out there into the world, and if the language ecosystem you are in provides easy publishing tools, why not use them for the first releases? And if later your tool evolves and becomes popular, the additional packaging for wider distribution can be added.

vbsteven··on GitHub – nushell/nushell: A new type of shell
You can with `-c`:

    $ nu -c "sys | get host.name"
    > Ubuntu
vbsteven··on GitHub – nushell/nushell: A new type of shell
I think Cargo doubling as both build tool and package manager is a big factor here. The combination of Cargo + crates.io makes it very easy to write some Rust code and make it available to anyone with Cargo on their system. Either by `cargo install nu` to build it from sources on crates.io or `cargo install` inside the git repo to build my own customized version. No more waiting for distro packagers to keep up.

Putting this together makes for a nice environment to distribute native system tools. And in the last few years we've seen a wave of these tools becoming popular (ripgrep, bat, fzf, broot, exa and some others).

vbsteven··on Neal Stephenson – Announcing Termination Shock
I liked Fall actually, but I can imagine pure sci-fi readers being put off by the second part. It’s a 2-for-1 situation which brings together sci-fi and fantasy elements in interesting ways. But you’ll have to enjoy reading both genres or else it will be a slog.

As with all fiction books, my usual advice is to read it for pleasure, and put it aside if you don’t like it or it doesn’t live up to expectations. You don’t have to finish a book just because you started it.

vbsteven··on Why Can’t I Sleep?
I read about this technique once in the context of the military. Soldiers were trained to use this technique to fall asleep fast under stressful circumstances.
vbsteven··on Bandcamp's app is no longer listed on Google Play
You just described the buyer side of the marketplace while parent was right about the seller side. Many sellers on Bandcamp are smaller bands/musicians/labels selling their music and merch directly to customers.
vbsteven··on The brain isn’t supposed to change this much
There is I believe also a theory that suggests that the brain actively rewrites and combines/compresses memories to make them more useful. That also fits in well with this defragmentation concept.
vbsteven··on The pedantic checklist for changing your data model in a web application
If the project permits it, Kotlin fills that gap in Java well. Named parameters + defaults + nullability is a nice combination to have when it comes to evolving functions or types with backwards compatibility in mind.
vbsteven··on Summary of June 8 outage
We don't know much about the specific client configuration change that triggered this condition yet. It doesn't necessarily have to be a big company wide infrastructure change.

To me it sounds plausible that an SRE team in an alternate location made a change scoped to their permission level, following company-directed playbooks, which eventually triggered the faulty condition at Fastly.

vbsteven··on Summary of June 8 outage
Lots of tech companies have engineering offices with SRE responsabilities in Europe timezones. Could be anyone really.
vbsteven··on Ppl: The command line address book
I'm working on my passion project that incorporates some features like this with some differences:

* not only contacts but also tasks, projects, notes and calendars

* not local, instead it uses a self hosted rest-like api wrapping a database centralizing all state

* embedded MQTT broker that publishes CRUD events so you can hook into any events to script automations

* cli client that works similar to this so commands can be chained in shell pipelines

* there's also a tui client (mutt-inspired) and I might do web/mobile later

It's far from finished, but if you're interested send me an email (link in profile) and I'll keep you up to date.

vbsteven··on The Repeated Deaths of OOP (2015)
Single run VS state+loop is not the best description of the distinction between MVC and ECS. I look at it like this:

In MVC a typical interaction goes like this:

    -> INPUT: user interacts with view
    -> view triggers controller action
    -> controller updates the model
    -> controller passes model to view
    -> OUTPUT: view changes
    -> (rinse and repeat)
The important part here is that there is a single input that flows through the steps and generates output. This maps well to web frameworks where the input is an HTTP Request and the output is the Response. It also maps well to GUI frameworks where the input is a user interaction event and the output is changes to UI on screen. The perpetual "state and loop" for triggering the next input from the previous output is implementation detail and doesn't really matter for the pattern.

ECS is different because it doesn't have discrete interactions converting input->output. Instead they are built up out of a number of systems all interacting with eachother. User inputs enter a system and that triggers a complex flow of other system interactions, eventually generating 0..N outputs.

Disclaimer: I have lots of experience using MVC in various domains, not that much with ECS.

vbsteven··on Teach Yourself Programming in Ten Years (1998)
This is a great strategy to have but I would reformulate it as “make sure you know enough languages to solve system, scripting, frontend and backend problems efficiently”.

You don’t necessarily need a separate language for each domain.

vbsteven··on Ftxui: C++ Functional Terminal User Interface
I see. We’re talking about different levels of abstraction.

There are two approaches there. One is to project abstract UI onto platform controls (React Native), the other is to use “drawing” (Flutter). Both have their pros and cons.

The main drawback of abstracting over controls is that each platform works very differently and the abstraction quickly starts leaking. Also some of the targets don’t have any controls like the terminal. All you can do in a terminal is draw text in rows and columns.

That is why most (not all) cross platform frameworks abstract on the drawing level. Gtk, Qt, Flutter, Druid, Dear ImGui and many more.

vbsteven··on The modern web on a slow connection (2017)
It’s not just an idea. It’s tech that has been around for decades now. Rails, Django, Spring, Laravel, Sinatra, Flask and hundreds of others.

They work fine for a large chunk of modern websites. And server side templating is not the only concept from that era that is much simpler than what is popular now. Those frameworks were primarily synchronous instead of asynchronous. And they worked in pretty much every browser. Without breaking the back button. With shareable links. And no scrolljacking.

For me personally the sweet spot for many applications/websites is still just that: A synchronous MVC framework with serverside rendering. With a sprinkle of vanilla JS or Vue on select pages for dynamic stuff.

vbsteven··on Ftxui: C++ Functional Terminal User Interface
No you are right, but that’s irrelevant to my point. The point being that Flutter is an example of a “react-like” framework to write UI that renders to multiple backends.
vbsteven··on Ftxui: C++ Functional Terminal User Interface
Htop is an example of a good TUI but it doesn’t really look like a traditional “drawn” GUI.

I think that is the distinction that parent is making.

In a TUI environment (ignoring mouse support) traditional GUI elements and layouts often don’t make sense. Like one of the examples with all the radio buttons in small boxes.

The good TUI apps like htop, newsboat, mutt, vim/emacs, tmux all have mostly line-and-column oriented simple layout primitives.

vbsteven··on Ftxui: C++ Functional Terminal User Interface
That is basically what Flutter is. Renders to desktop, mobile and web, only tui is missing there.
vbsteven··on Unix Shell Programming: The Next 50 Years [pdf]
What if there was a standard way to describe inputs, outputs and side effects of programs?

Think of it like writing/downloading type definitions for existing untyped code. With program descriptions like this shells could become smarter, generate warnings, abort before execution if types don’t match up, etc.

vbsteven··on RectCut for dead simple UI layouts
The article and parent talk mostly about layout in terms of rectangles and subdividing those into smaller rectangles. The basics like Box and Flex layout are pretty simple.

Once you start adding constraints like min/max size and relative sizes it becomes more complex but still manageable. You’re still only reasoning about rectangles and their constraints.

Adding rendered text in the mix increases complexity immensely. Determining the size of rendered text is a very complex problem space in itself involving fonts, dpi, text flow, code points, LTR/RTL, ligatures and more. It’s not just rectangles anymore.

vbsteven··on Unix Shell Programming: The Next 50 Years [pdf]
The article recognizes that interop and backwards compatibility with existing systems is important for adoption and it does not try to impose a new clean room replacement. This is IMHO a good strategy that has proven itself in other contexts.

For example Kotlin/Clojure/Scala all started out focusing on interop with the base Java/JVM technology. They provide a new layer of modern language features that is still compatible with all the existing code without forcing a rewrite. Over time these new languages get adopted, some older libraries get a modern equivalent and that helps these languages to branch out into other areas: e.g. Kotlin Native, multiplatform and ClojureScript.

A similar thing can be seen with Typescript. It started as a type layer on top of JavaScript, making it easy to interop with old JS code and over time lots of pure Typescript library equivalents have popped up. Now that the Typescript ecosystem is flourishing we see technology like Deno that slowly moves Typescript away from its JS base.

For a post-POSIX shell to be adopted widely I think it will need to use a similar strategy.

Edit: re-reading my own comment, I might have just advocated for an Embrace, Extend, Extinguish strategy.

vbsteven··on Tour of our 250k line Clojure codebase
You can maybe get there in kotlin with a generic type with multiple constraints in a where clause. Let’s say you have Sorted and NonEmpty as interfaces (could be empty marker interfaces so they behave like tags). Then you can write a method

  fun <T> doSomething(values: T) where T: Sorted, T: NonEmpty {}
And that function will take any type that has both Sorted and NonEmpty interfaces.
vbsteven··on Tour of our 250k line Clojure codebase
That depends on the language and deserialisation library used. And that is also the reason why I have multiple classes.

My CreateTaskRequest class which is used for deserialisation only does not have defaults (unless intentional) so it throws when required values are not present in the source json. It also takes care of dateformat/uuid parsing. The output is always fully valid typed or it throws. It’s a 1-to-1 mapping on what is described in the API docs.

The service layer that takes CreateTaskRequest and converts to Task for persistence is where the business logic validation happens (valid foreign keys, date ranges, etc, unique checks). Cleanly separated from deserialization.

For reference: I use Kotlin with Jackson which has great support for this.

vbsteven··on Tour of our 250k line Clojure codebase
A language like Kotlin can do some of these things using delegates, interfaces and extension methods.

For example a MutableList<T> can be dropped down to a List<T> which is not mutable. And a generic conversion from Collection<T> to NonEmptyCollection<T> should be trivial to write as an extension method.

vbsteven··on Tour of our 250k line Clojure codebase
Ok yes, C++ might not be the greatest language for this.

My experience here is mostly from Kotlin which is a great language for this. Nullability, extension methods, (reified) generics, data classes, delegates, etc can all help reduce boilerplate.

vbsteven··on Tour of our 250k line Clojure codebase
I don’t agree there. Most of these extra classes are just type declarations with no methods at all.

While the total LoC written might be higher, the amount of written logic in which you can introduce bugs is less.

vbsteven··on Tour of our 250k line Clojure codebase
> There are trade offs for both

Exactly.

Personally I like that bit of extra code because it gives every class one reason to exist. There are no conflicts so the type system can be used fully without ambiguity.

I’ve always disliked the way early rails promoted fat models that combined serialisation, deserialisation, validation, persistence, querying and business logic in the same class.

← PreviousPage 2 of 18Next →