HNHacker News
TopNewBestAskShowJobs

tomstuart

2,961 karma · joined August 27, 2009

Computer scientist, technical leader, Ruby & JS hacker, http://computationbook.com/ author, &c. https://tomstu.art/, hi@tomstu.art
submissionscomments
tomstuart··on Square Root of Any Number Mentally and Instantly [video]
Thank you for explaining this!

To elaborate for anyone who’s curious: the square root function is 𝑓(𝑥) = 𝑥^½, so its derivative is 𝑓′(𝑥) = ½𝑥^-½ (power rule) = 1 / 2𝑥^½ = 1 / 2𝑓(𝑥).

If we know the value of 𝑓 for some nearby input 𝑎, we can approximate its value at 𝑥 by using 𝑓’s derivative (i.e. rate of change) at 𝑎 to guess how much the value of 𝑓(𝑎) has increased or decreased by the time it becomes 𝑓(𝑥). We can calculate that guess by multiplying 𝑓′(𝑎) by the difference between 𝑎 and 𝑥. It’s only a guess because it assumes that 𝑓 has a constant rate of change from 𝑎 to 𝑥, which the square root function doesn’t (it’s a curve, not a straight line), but if 𝑎 and 𝑥 are close together then the error isn’t too large.

e.g. 𝑓(67) ≈ 𝑓(64) + 𝑓′(64) × (67 - 64) = 8 + (1/16) × 3 = 8.1875

tomstuart··on The Education of Melvyn Bragg
Then you might enjoy this: http://pascalwyse.com/blog/2017/12/15/in-our-time-machine
tomstuart··on The stack monoid revisited
An earlier post (https://raphlinus.github.io/gpu/2020/09/05/stack-monoid.html) explains it. The elements of the monoid are stack operations represented by pairs `(n, vs)`, where `n` is a number of values to pop off the stack and `vs` is a list of values to push on afterwards. So e.g. `(3, [])` is “pop 3 values”, `(1, ['foo', 'bar'])` is “pop 1 value then push 'foo' and 'bar'”, etc. Two elements are composed by combining their pop counts and push lists to reflect what happens to the stack if you apply the operations sequentially, e.g. the previous two examples compose to `(4, ['foo', 'bar'])`. The identity is `(0, [])`.
tomstuart··on Trump's blog isn't lighting up internet, showing effectiveness of deplatforming
There was, but it got suspended: https://www.bbc.co.uk/news/technology-57018148
tomstuart··on The Secret Life of Components: Springs [video]
With time: https://youtu.be/6l18q7Gi4GQ?t=553
tomstuart··on Firefox replaces Google Analytics with fake no-op in strict tracking protection
The problem is with the centralisation and aggregation of that knowledge. It’s not (necessarily) bad that the site owner knows you’ve visited their site, it’s bad that Google knows all of the sites you’ve visited.
tomstuart··on The Elements of Computing Systems, Second Edition
That’s a very generous comparison, thank you!
tomstuart··on Mocks Aren't Stubs (2007)
I find the distinction between “fake”, “stub” and “mock” very useful when making decisions about my own code, but I’ve basically given up on using it to communicate because I never find myself dealing with anyone who cares about the different meanings. Most people I know use “mock” to refer to any kind of test double.
tomstuart··on Detective Game Design Problems
This video from Game Maker’s Toolkit is an excellent overview of the topic: https://youtu.be/gwV_mA2cv_0
tomstuart··on What I didn't know about Ruby Classes
It’s a class dedicated to a single object. Every object has its own eigenclass — this sounds expensive but in practice they’re lazily created. Regular classes are used to store the definitions of methods which are available on all instances of that class. In contrast, a single object’s eigenclass is used to store the definitions of methods which are available on that object only.

`def foo.bar … end` defines a `bar` method in the eigenclass of the object `foo`, which can then be called with `foo.bar`. (This is how “class methods” work in Ruby: their definitions are stored in the class object’s eigenclass so that those methods can be called only on that specific class rather than all classes.)

tomstuart··on Some Math Problems Seem Impossible. That Can Be a Good Thing
The parent comment meant three consecutive collinear vertices among other vertices, not a zero-area “flat triangle”.
tomstuart··on Fast Inverse Square Root
This is a great post! The setup could be clearer: I found it a little difficult to follow (during “a real number x … this value which I will denote f … treat the 31-bit value as an unsigned integer u”) what each of the named variables was intended to refer to, and formatting the 31-bit number as 32 bits threw me off too. Nothing insurmountable but I could feel my brain stumbling before I got to the clever part.
tomstuart··on Ruby's Proposed STM
This is the opposite of my point of view. I think it’s a great example because the whole point is that, while most people’s everyday experience of a bank account is as a single mutable value, the reality is far more complicated and subtle. Teaching is all about using simplified examples to convey intuition, and “you might think it’s easy to keep a single number up to date, but moving money between two accounts is fraught with danger” is a perfect demonstration.
tomstuart··on Applying “make invalid states unrepresentable”
My favourite real-world example is something like: you have a React component which accepts the boolean props `showFoo`, `showBar` and `showBaz` to control its mode. The intention is that exactly one of `foo`, `bar` or `baz` will be shown at any given time, but that invariant is maintained only loosely, e.g. by a parent component which holds three flags in its state and mutates them in tandem inside various event handlers.

The obvious problem is that those three props can easily get out of sync if you make a mistake in updating them, and the equally obvious solution is to replace them with a single prop (e.g. `show` or `mode`) which contains a value from some enumeration — maybe just the name of the thing to show, or a numeric ID that is given meaning elsewhere, or (galaxy brain) a component. That way the invariant is maintained strongly and automatically by the representation itself.

This example sounds vacuous — who would ever use three booleans in the first place? — but in practice it’s very easy for UI code to incrementally get into this mess over time without anyone noticing. The situation is also often more subtle, e.g. the invariant is more complex than “exactly one flag is true”, which makes it harder to spot that you can model all the valid states with a finite enumeration.

tomstuart··on Ruby 3.0 Preview 1
You may be interested in precompiled native Nokogiri: https://github.com/sparklemotion/nokogiri/issues/2075
tomstuart··on I Want to Fix Goodreads
I’ve read Only Forward by Michael Marshall Smith. It stuck in my mind the same way that Vurt did. I still think about the man with no head sometimes, and the idea of a road being different when you’re going the other way on it.
tomstuart··on Show HN: Gomp – a tool for comparing Git branches
This looks similar in spirit to `git range-diff` [0], which may interest anyone who wants more visibility of what’s changed between branches (e.g. before and after a rebase).

[0] https://git-scm.com/docs/git-range-diff

tomstuart··on Introducing Swift Service Lifecycle
The context implies it’s macOS on Apple silicon.
tomstuart··on New 13-inch MacBook Pro
The Magic Keyboard uses scissor switches, not butterfly.
tomstuart··on A fast 100% spec compliant, self-hosted JavaScript parser
The purpose of this project is to parse JavaScript (turn a flat string of code into a structured tree), not evaluate it.
tomstuart··on What I wish I knew about React
You can, of course, do the same with React: https://reactjs.org/docs/add-react-to-a-website.html
tomstuart··on A crash course in compilers (2018)
I think PLT is generally broad enough to include anything related to making (vs using) programming languages — the more practical topics like compiler/interpreter construction, VM implementation etc seem to obviously qualify despite not necessarily being very formal.

Concretely, you can definitely design and implement your own dynamically-typed scripting language without knowing anything about type systems or formal semantics.

tomstuart··on LICEcap: Simple Animated Screen Captures
This is such a great tool which deserves a wider audience. I honestly think that more people would hear about it & use it if it had a less unappealing name.
tomstuart··on I Don't Use Classes
You’re always going to be on one side of the expression problem [0]: either your operations live with your datatype (classes), which makes it inconvenient to add a new operation, or they live somewhere else (“functional modules”), which makes it inconvenient to add a new case to the datatype. This choice is probably informed by your expectations of how often you intend to do either of those things, but there’s going to be inconvenience regardless.

The big benefit of objects, and therefore classes (or something like them), is polymorphism via dynamic dispatch; it seems a shame to throw the baby out with the bathwater because you don’t like inheritance or mutable state, both of which are independent of the choice to use classes.

[0] https://en.wikipedia.org/wiki/Expression_problem

tomstuart··on Ask HN: Do you ever truly use your revision history?
Yes, every day. Well-written commit messages are like comments that never go out of sync with the code they’re attached to. Often it’s the stuff from years (vs months) ago that’s the most valuable, because that’s the information that nobody who still works at the company can remember.
tomstuart··on Ask HN: Is it worth it to move to London as a SWE?
No. If you’re good then there’s lots of demand.
tomstuart··on Ask HN: Is it worth it to move to London as a SWE?
There are plenty of good software engineering jobs in London (with higher salaries to offset the higher cost of living), but if I were you I’d wait until the dust has settled from Brexit before you decide whether you really want to move here. Some of my London friends are making the move in the opposite direction.
tomstuart··on Ruby Lazy Enumerators
Lazy enumerators were added in Ruby 2.0 back in 2013: https://www.ruby-lang.org/en/news/2013/02/24/ruby-2-0-0-p0-i...
tomstuart··on Enough with the Dead Butterflies (2017)
Site is down. Internet Archive version: https://web.archive.org/web/20191214080139/https://emilydams...
tomstuart··on A new way to read and print double-sided paper (2016)
From the previous post:

“Can you come up with a good algorithm to read a stack of triple-sided sheets of paper? You may not be familiar with triple-sided sheets of paper, so here’s how they work: they stack nicely, just like regular sheets of paper, but you have to flip one over three times before you get back to the original side. In particular, there are two different operations you can do: call them flip (say, left-right) and anti-flip (right-left). On two-sided paper, flip and anti-flip are the same. On three-sided sheets, two flips are the same as an anti-flip, and two anti-flips are the same as a flip. Of course, three flips, or three anti-flips, are both the same as doing nothing.”

← PreviousPage 4 of 11Next →