nicopappl
Joined 6 years ago
Joined 6 years ago
Being better at debugging doesn't necessarily makes you better at writing less complex, more approachable code. Though debugging should teach you which patterns cause bugs or impede debugging.
And what do you do once you are so skilled your software doesn't have bugs? :P
Regarding self improvement, Aaron Swartz put it better here: https://web.archive.org/web/20240928215405/http://www.aarons... (tldr: do things you don't like)
Comparing that to the US, where if you get caught dealing marijuana, you get a 5 years minimum sentence. That seems disproportionate to me. Maybe police in the US is more compassionate than some militants make it seem, and that's why they don't like catching people for that kind of crime?
Looking at Wikipedia[1] it appears the number of policemen per people is two times higher in the US than Switzerland, and about the same as France. If it is true that "the police are plentiful and they come down fast" in Switzerland (which I would not agree with), it is twice as true in the US.
[1]: https://en.wikipedia.org/wiki/List_of_countries_and_dependen...
I would recommend it not just for the philosophical aspect (it has a very interesting way of placating transhumanism) but also for the entertainment aspect (aforementioned shrimps, did I mention the Iranian space program?)
Stross is a very approachable author, Accelerando is not his most accessible book, but if you can go through half of Diaspora, you can easily go through the entirety of Accelerando.
I suspect the author might be reading this post back and cringe a bit. That last code listing with handle_session_completed triggers my inner clippy. Why clone session.customer_id to then pass it as a reference? Why are those CheckoutSession fields Options?
The other advice I would give is to identify what the author calls "Service" as what is called "view type" or "newtypes" in rust. A newtype wraps another type, to give it a different set of methods. For example, a counter could wrap an i32 and only allow incrementing and reading the value. Or put together a set of references to fields/slices of a struct.
It can be useful, but the way it's used by the author here is not very rusty, and the final suggestion of using a function is a descent alternative. Although I think defining handle_session_completed as a method on CheckoutSession or UserRepo might be better.
> “Chain voting” ensures that people vote the right way. Voter 1 goes into the polling station,
> appears to vote by depositing an empty envelope into the ballot box, but comes out with a
> blank ballot. Voter 2 is then sent in with that ballot—now marked by a [party] operative—and
> told to put it in the ballot box and exit with another blank ballot in hand. Carried on down
> the line, the [...] party boss in the town can ensure that all have voted the proper way
> while the election workers find that they are short only one unaccounted-for vote
The old codebase was an hairy ball of scala using a very outdated version of a (now) infamous actor framework. Before they figured out that untyped messages kinda left out one of the major selling point of Scala.
The code was readable, but the authors had this strange idea that every little piece of logic should be part of its own "Actor". An actor is pretty much equivalent to a class, and each one of them had their own little file. With this many classes, with very specialized purposes, you ended up with 90 character identifier names.
To understand what would be a single function in a normal code base, you would have to dive through half a dozen files through several repositories to piece together the logic. Generally, at the end, you find that most of the code is about passing around a value, and there is this one file where there is actual logic applied to the value.
It wasn't that awful. The thing was that it was impossible to change anything: no documentation, no test, no bug tracking, not even any PR process, laconic commit messages, no Wiki pages. And the actor framework made it very difficult to add tests. But later developers did manage it pretty well, they drew fences around the old services, with an HTTP API to communicate with it. And all later additions were part of different services that were very cleanly and consistently designed.
When your text editor is not enough for a task, and it hopefully is extensible, consider writing little plugins to reduce repetitive tasks.
Here is an example. I was working with a legacy code base using an infamous Scala actor framework. Basically, all function calls were replaced by message passing. All messages were sent as 'Any' objects, then downcast to the expected type, so an IDE wasn't of much use. I wrote a little bash script to populate a jump buffer in vim with the result of a grep, and suddenly, I had jump functionality! Originally, I had to jump to type definition, hope that the associated "received message" type was in the same file, then look for downcasting into that received type. I don't remember precisely the details, but what I do remember is that the little script helped go from a few seconds to just pressing two keys to navigate the code. It's especially useful for legacy code, where the main activity associated with it is reading and understanding.
Our capacity to focus as humans is limited in time and energy. Writing tools to do in half a second what otherwise would take a few seconds can help, not only to make you faster (for that, refer to xkcd 1205) but also to effectively increase your capacity to focus.
Though being able to develop your own tooling is less important today. Languages and frameworks nowadays prioritize tooling as an important feature. And I'm grateful for that, programming used to be much more annoying.
* https://blog.plover.com/Unix/whitespace.html (mentioned at the beginning of the linked post)
* https://drewdevault.com/2023/07/31/The-rc-shell-and-whitespa... (mentioned at the end of the linked post)