HNHacker News
TopNewBestAskShowJobs

tomn

368 karma · joined November 12, 2009

hn@tomn.co.uk

https://www.tomn.co.uk/

https://github.com/tomjnixon

submissionscomments
tomn··on Ask HN: Why did Python win?
> There's a bunch of global functions that should have been methods on objects, like `len()`. OO in general seems slapped on later, as evidenced by the weird double underscores, and the explicit this object as first arguments for methods.

From some angles these are strange, but from where I sit they seem elegant and pragmatic.

The global functions and double underscore methods are part of the same thing: the language defining and enforcing a protocol that many types of objects should support. Other languages do this by having common names (.length() or whatever), but this has problems that the python way avoids:

- it's hard to add new ones because they share the same namespace as user code - they may have different meanings in different contexts (e.g. a line has a length, but isn't iterable) - the language can't enforce the protocol (e.g. len accepts only one argument, checks the result is an integer, and raises the correct exceptions)

For operator overloading, using regular methods with special names is nice because it avoids having special syntax for it, and makes it easier to interactively inspect and experiment with (as you can just call the methods).

The explicit self thing is similar, in that it avoids a load of special syntax: no this keyword, no syntax for static methods, no syntax for superclass calls (until super was added). It even means that there's only really one 'kind' of call.

I can see some confusion about where self actually comes from, but then most languages i've experienced where this is implicit also have corner-cases and awkwardness around it.

IMO these kind of simplifications seem a bit frivolous when looked at in isolation, but end up simplifying your mental model of the language, which helps beginners get more out of it quicker.

> It's nice that function definitions are closures but you can't make them anonymously as function arguments.

I thought this for a while, and it would still be nice in a few situations, but really it's not a burden to name your callbacks, and discouraging overly-clever code isn't a bad thing if you're trying to build an ecosystem that's accessible to as many people as possible. I used to use map/reduce/filter a lot, but most of the time list comprehensions and regular loops end up easier to read.

tomn··on Python Type Hints – *args and **kwargs (2021)
OT, but this is my number one peeve with code documentation: going to the effort to write a doc comment, taking up at least 6 lines, probably using some special syntax, cluttering up the code, but then adding no information that can't be derived from the signature.

If you're not going to document something (which I totally respect), at least don't make the code worse while doing it.

tomn··on Advanced Python Mastery
If you do that, it will try to read from a closed file.
tomn··on Advanced Python Mastery
> which I personally think has a cost

Yeah, so many people don't get this, but too many small functions can be hard to understand -- that's why I qualified that option.

In this case i agree that inlining it is fine, i was talking about the general pattern.

tomn··on Advanced Python Mastery
I don't think you can really improve on this.

You could use a list comprehension, but that can be unclear and hard to extend, depending on the situation. It can be a nice option if most of the parts in the generator can be broken out into functions with their own name, though.

You could turn it into a generator, which can cause some fun bugs (e.g. everything works fine when you first iterate over it, but not afterwards), so IMO that's best used when it needs to be a generator, for semantics or performance.

You could turn it into a generator, then add a wrapper that turns it into a list (keeping the inner function private), or use a decorator that does the same, but it's less clear than this pattern.

So, i'd just learn to live with it.

tomn··on The Nano ESP32
Yeah, i agree that the ESP32 docs are good, and what you're going to be using most of the time while using these things.

That wasn't what i was talking about though -- if you have a look at the datasheet for this board ( https://docs.arduino.cc/static/4260b2f8de0b7abc50d3773839dee... ), there's plenty of board-specific info in there that's useful, and also plenty of stuff that's technically duplicated from the ESP32 documentation, but harder to find if you're a noob.

I can't get mad about the unnecessary layers, sorry. Using the ublox module is quite reasonable: it's smaller than any of the available modules from espressif (necessary for this form-factor), probably because they have licensed a fancy antenna design (the same one that rpi uses, i think). Using a module in general is a good idea, as it means you don't have to take on the cost and risk of doing the RF design yourself. If you buy a board using a 3rd-party module, there are probably going to be three vendors involved.

Another thing i didn't mention -- as far as i know this is the first ESP32 board you can actually buy in the same form factor as the arduino nano, which is handy if you want to switch an existing project over to ESP32.

In general I fail to understand why people are so salty about this. I see engineers using this kind of thing all the time, and they aren't stupid. It's perfectly fine to spend a bit more money to get something even marginally better.

Yes, the relative price difference is huge, but $20 makes no difference in a lot of situations.

tomn··on The Nano ESP32
Yes, but "does it work" is a low standard.

- You don't get any documentation, whereas with something more official you will have a complete schematic (so you know which support components will be used), pinout, information about power supplies etc.

- You can't rely on being able to buy the same thing again. Even if you find something with the same pinout, small changes to the power supply or usb-serial converter can ruin your day.

- Shipping will probably take a while (or you're buying from a local re-seller, increasing the cost). Your company probably doesn't have a process for buying from aliexpress, but orders from digikey all the time.

- I've not had a problem with development boards, but plenty of cheap electronics in the same category are really badly designed; a random memorable example: https://www.aliexpress.com/item/1005001621800502.html . They have had their issues, but arduino stuff does tend to be well designed, and vendor development boards are usually reliable too.

- Stuff like the feather ecosystem can be genuinely helpful when prototyping if the cost isn't an issue.

I chance the cheap stuff for personal projects, but if work is paying I'd go for something more expensive every time (and probably wouldn't have a choice).

tomn··on It Took Me a Decade to Find the Perfect Personal Website Stack – Ghost+Fathom
I don't think they are complaining about the hosting, but the publication process being brittle.

For example, I use pelican (pretty much 'what if jekyll but in python and more flexible'), and found that every time i wanted to update my site there was a problem with some unmaintained plugin not working with the latest python standard library, or similar.

It's also easy to set up what feels like good process for publishing, only to find that it wasn't as well documented or obvious as you thought the next time around. This is natural for anything semi-complicated that you only do once every 6 months, when you're really trying to get something else done (writing the damn content).

If you already know how to use it, nix is a good solution to this, as you can pin all dependencies (including languages and external tools), and they will still be there and working in a few years.

tomn··on If PEP 703 is accepted, Meta can commit three engineer-years to no-GIL CPython
finally. you don't even have to read anything to work this out -- if things like dictionary access were no longer atomic that would imply that threaded code without locks could crash the interpreter, which isn't going to happen.
tomn··on NRF52840 Connect Kit – Rapid prototyping kit for your next connected projects
this is the big one for battery-powered applications

NRF52840 is specified to use 1.5uA when deep sleeping with RTC wake-up, while esp32-c3 is 5uA, which sounds ok, but is not the whole story.

If you try to build something low-power with ESP32 you'll find that it takes a lot of time and energy to go from deep sleep to being able to transmit, while the NRF SDK is designed with that in mind.

The NRF current consumption also includes the built-in voltage regulators -- this works from 1.7v to 5.5v, with a regulated output for peripherals, so all it needs is a battery and some passives.

On the other hand the ESP32 is much more awkward -- it needs 3-3.6v, so you're going to need an external regulator, and a LDO with the required 500mA output current is going to have a significant quiescent current, and even then the voltages are awkward for lithium batteries once you consider the drop-out voltage.

The tl;dr is that it's easy to get multiple years out of a coin cell with an NRF-based sensor, and that's just not happening with any ESP32.

tomn··on My First Impressions of Nix
Yeah, I get your point, but was responding to this:

> Basically, NixOS = zero QA effort from application developer -> nothing works.

"zero QA effort from application developer" does not imply that "nothing works" if the distro and community put in the effort instead.

tomn··on My First Impressions of Nix
Almost -- it's not quite as bad as you'd expect, because nixpkgs has packages for quite a lot of closed-source software, with whatever hacks are required to make it work.
tomn··on Our Plan for Python 3.13
I believe that GIL-removal projects aim to preserve this behaviour:

https://peps.python.org/pep-0703/#container-thread-safety

That's why gilectomy carries an unreasonable single-threaded performance cost: many operations now need to take a lock where before they relied on the GIL.

tomn··on Effective June 7, 2026, Autodesk will no longer sell nor support EAGLE
Ah OK, I misunderstood.
tomn··on ESP32-C3 Wireless Adventure: A Comprehensive Guide to IoT [pdf]
What kind of power supply concerns? I've used quite a few of them and never had a problem.

For USB-powered development boards IMO the best option is the raspberry pi power supplies -- they are cheap, high quality, and can supply plenty of current. It's sometimes necessary to bridge over the input diode if you want to draw any significant current from the 5v pin.

If making your own boards the maximum 3.3v current is higher than you might expect (0.5A), but it's perfectly doable.

tomn··on Effective June 7, 2026, Autodesk will no longer sell nor support EAGLE
Seems like you need to change the URL to point at a schematic file:

https://kicanvas.org/?github=https://github.com/Twisted-Fiel...

tomn··on The guide to software development with Guix
> if i wanted to learn pure FP i would probably pick many things over Nix

of course, but that wasn't the question:

> What do you gain from learning Nix, asside from Nix?

tomn··on The guide to software development with Guix
again, you said

> by learning Guile you learn a lisp which some people find quite enlightening

so learning a lisp is enlightening, but learning a FP language is not

tomn··on The guide to software development with Guix
please compare:

https://archlinux.org/packages/extra/x86_64/lua/#pkgreqs

https://archlinux.org/packages/core/x86_64/guile/#pkgreqs

(lua at least is under-counted as there is luajit, lua51, and various packages which embed their own version, e.g. pandoc)

tomn··on The guide to software development with Guix
> What do you gain from learning Nix, asside from Nix?

Nix is a small and approachable lazy pure-functional language. You can learn a fair bit of functional programming by reading nixpkgs, which is frequently recommended even if you never use it in the real world.

> by learning Guile you learn a lisp which some people find quite enlightening.

By learning nix you learn a FP language which some people find quite enlightening.

Personally I can't find any software which I would want to contribute to or extend which uses guile (except GDB which can also be extended with python), so the "you ain't gonna need it" argument holds for guix too.

It's just such an odd argument for a relatively minor difference between the two ecosystems.

tomn··on SciPy: Interested in adopting PRIMA, but little appetite for more Fortran code
> While a FORTRAN 77 compiler is not necessary for building NumPy, it is needed to run the numpy.f2py tests. These tests are skipped if the compiler is not auto-detected.
tomn··on Fulfilling a reader's request for my “dot files”
One also shouldn't form an impression of arch (or any other distro) from the experience of one user. I've had this arch install for over 10 years and don't remember having any issues like that; while hearing plenty of people having issues doing major version updates on more "stable" distros.

Arch specifically attracts people who want to learn how things are put together and mess with their system, which are also the kind of people most likely to break things.

tomn··on Build 5G networks using open-source software, general-purpose hardware (2021)
This is a bit outdated -- 802.11r fast transitions (FT) allow devices to roam between access points nearly instantly, and 802.11k and v allow access points and clients to exchange scan results, so that access points can move clients to the most appropriate access point.

This does require more than just having multiple access points with the same SSID, and used to be limited to expensive commercial AP brands, but it's quite accessible to consumers these days.

tomn··on Python-based compiler achieves orders-of-magnitude speedups
Maybe i should have explained this..

To share objects between threads, some synchronisation is needed, for example to update reference counts. There are a few ways to do this:

- make the user add locks; the problem with this if it goes wrong it can crash the interpreter and make it impossible to debug the problem from within python, which is not user-friendly, and lots of existing code will break. Competent users are already doing this though, so it's nearly free. - add fine-grained locking/synchronisation for object internals within the interpreter. This slows everything down, even if you're not using threads. - Lock the whole interpreter state whenever a thread is running. This makes threads less useful (no speed-up from threading pure-python code that isn't doing IO; you have to use multiprocessing for that), but it's cheap as you only need to lock/unlock when you're doing something slow anyway (IO, thread switching, native code).

I think this explains why GIL removal has not been successful yet despite much work: the alternatives slow down single-threaded code, which is not worth it when nearly all sensible uses of threading don't benefit either.

tomn··on Python-based compiler achieves orders-of-magnitude speedups
The GIL improves single-threaded performance compared to other options.
tomn··on Building the worlds jankiest serial to USB cable from scavenged parts
This could end up being worse from a signal-integrity point-of-view, as now both of those traces have a stub (of different lengths!), which will comb-filter the signal.

If you wanted to be fancy, it would have been better to lift those two pins, or to cut the traces.

All this is completely unnecessary given the speeds involved (12Mbit/s) and possible skew or stub lengths, which they acknowledge.

tomn··on Nobody needs a faster dishwasher – solve real user needs
From my limited understanding:

- the mechanism is large compared to the capacity

- they are noisy

- they require lots of power

- they need to be pre-heated (so only make sense if you're running more than one load)

- they require more chemicals for the same load sizes

People have done it, but it's not that practical for most people, especially if you're only washing up for one or two people.

tomn··on “Clean” code, horrible performance
> you won't be going anywhere in computer graphics by trying to "write pure functions" or "avoiding side effects"

Not sure about this; in my experience (in a different domain, audio processing) you totally can get away with both of these a lot of the time.

Function inclining works well, so you can write small pure functions in a lot of cases (especially if you accept a function that reads from one buffer and writes to another as pure).

As for avoiding side effects, this is normally more about keeping your state updates small and localised (allowing more parts to be pure), which is often not a problem performance-wise.

IME it's much easier to improve the performance of a piece of code which is easy to reason about and change with some level of confidence that your optimisation will not break things.

I know there's some unavoidable global state in computer graphics, but presumably there is lots of code that doesn't directly touch that.

tomn··on Why CMake sucks (2021)
Yeah, they are quite good at compatibility. In practice there may often be an upper version limit if you happen to use any features which eventually get deprecated or removed.
tomn··on Why CMake sucks (2021)
While what you said is true, for outsiders it misses the 'why' (which I'm sure you are aware of!).

The idea with autotools is that the generated configure script (and other assorted files) is supposed to be forwards and backwards compatible with different systems. It's not perfect, but the behaviour is mostly locked down at the time it is built, based on the particular set of macros it is generated with.

There are definitely aspects of this which don't work (it's nearly impossible to test, getting specific versions of autotools is presumably a PITA, and the make-in-bash-in-m4 language is deeply cursed), but the overall design does make some things better.

For example, if your project needs a specific version of cmake, your users will have to figure out how to install it, but if your project requires a specific version of autotools, only your developers need to install it.

(FWIW autotools is on my 'never again' list of technologies; it's incredibly cursed)

← PreviousPage 3 of 7Next →