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 Reddit CEO lashes out on protests, moderators and third-party apps
The peculiar viewpoint you’re demonstrating in this comment is similar to Reddit’s. It’s not objectively wrong, but the calculus involved definitely looks weird from the outside.

How would you quantify the value of Hacker News to Y Combinator? You’re talking about it like it’s a cost centre, a charitable contribution to society; what proportion of Y Combinator’s revenue can be attributed to the brand and content marketing benefits which flow from the (almost) entirely unpaid contributions of HN users? The Firebase API now costs “quite a bit”; is that amount comparable to the income of a YC partner? How much should a third-party developer be compensated for the work of building a native client which brings HN to a wider audience or increases the engagement of its existing audience? How much should an HN user be compensated for their submissions and comments? Which people deserve to make money here and why? Who is “indirectly funding” whom?

tomstuart··on JavaScript private class fields considered harmful
I don’t think you’re misunderstanding anything, but to clarify, I’m talking about a more general notion of subtyping (e.g. structural, “duck typing” etc), not necessarily inheritance. Instances of A and B can (in Smalltalk parlance) respond to the same set of messages, and therefore be substitutable for each other, without having any inheritance relationship. In that case there’s no coupling of implementation, only the flexibility of being able to swap out an A instance for a B instance without its collaborators being any the wiser.
tomstuart··on JavaScript private class fields considered harmful
> My question is, why is that necessary? Exactly what is the benefit, except for a tiny bit of convenience? Why is that better than functions that work on well-defined types?

The benefit is subtype polymorphism via dynamic dispatch. When values flow through the program they carry the implementations of their operations with them, so a caller can operate on a value without knowing how that operation is implemented; a newly-introduced value can bring a new implementation of an existing operation, and existing callers can use that implementation without knowing that it’s new. There are other ways of achieving this, but OOP is a good one.

tomstuart··on Why don't we define “imaginary” numbers for every “impossibility”? (2012)
If anyone’s interested, I wrote up an example application of dual numbers in Ruby: https://tomstu.art/automatic-differentiation-in-ruby
tomstuart··on European Commission ask Nintendo to repair controllers
You have to fill in an online form. Go to support.nintendo.com, choose your country, and search for the page about joycon drift — e.g. in the UK it’s https://www.nintendo.co.uk/Support/Nintendo-Switch/Troublesh....
tomstuart··on The Missing Semester of Your CS Education
The metaprogramming lecture [0] perpetuates the common misunderstanding of what “mocking” is [1], which is unfortunate.

[0] https://missing.csail.mit.edu/2020/metaprogramming/#a-brief-...

[1] https://martinfowler.com/articles/mocksArentStubs.html

tomstuart··on Writing JavaScript without a build system
The newer (or perhaps still the same!) version of this is to add `babel-standalone` to the page [0] and put the `type="text/babel"` attribute on any `<script>` tags where you want to use JSX.

[0] https://reactjs.org/docs/add-react-to-a-website.html#quickly...

tomstuart··on Ask HN: Great text based games to play?
…by Sam Barlow, now better-known for the live-action video games Her Story, Telling Lies and Immortality.
tomstuart··on Ruby 3.2’s YJIT is Production-Ready
It’s hard to generate efficient code ahead-of-time because the compiler doesn’t know what the types of values will be, so it has to emit very general code that can cope with all possibilities at the expense of performance. A just-in-time compiler has access to this type information because it’s executing at runtime, so it’s able to generate more efficient code which only works in the more specific situation that is actually happening right then.

See Natalie [0] for a work-in-progress Ruby compiler which works ahead of time. It’s a super cool project but it’s just for fun [1] so I don’t believe it’s trying to compete on performance.

[0] https://natalie-lang.org/

[1] https://justforfunnoreally.dev/

tomstuart··on Ask HN: Strategies for working with engineers that are too smart?
True enough. I think when we say “simple” we often really mean “cheap” (to maintain), so maybe it’s better to cut to the chase and just say that instead.
tomstuart··on Ask HN: Strategies for working with engineers that are too smart?
I agree with what you mean, but I’d nitpick and say it’s not the code itself that’s the asset, but rather the behaviour of that code when executed. If you could refactor and get the same behaviour with less code (whatever that means), that’d be a net win, right? So the quantity of code is making a negative contribution.
tomstuart··on Ask HN: Strategies for working with engineers that are too smart?
You’re describing people who believe that code is an asset, when the reality is that it’s a liability: zero lines of code would be ideal if you could get away with it, but you can’t, so you have to compromise and limit that liability as much as possible by minimising the amount of code and relentlessly keeping it simple, easy to read, etc. Perhaps they’d be more sympathetic to your perspective if you framed it that way?
tomstuart··on Raspberry Pi Camera Module 3 released
This isn’t a complete project, but it’s a good start if you wanted to hack on the idea yourself: https://learnopencv.com/center-stage-for-zoom-calls-using-me...
tomstuart··on Ruby 3.2.0 is from another dimension
Thank you, that’s very kind!
tomstuart··on Ruby 3.2.0 is from another dimension
> I don't think the execution model you mention, which results in the absurdity of C style transitive includes polluting the global namespace, will ever be changed though.

There is a proposal at https://bugs.ruby-lang.org/issues/19024 to change this but, as you can see from the comments, it’s a bit tricky to get right while preserving backwards compatibility. (Whether that conversation makes you more or less optimistic about the chances of it ever being changed is up to you.)

tomstuart··on Ruby 3.2.0 is from another dimension

  >> 6.626e-34 < 9.109e-31
  => true
tomstuart··on Ruby 3.2.0 is from another dimension
While the original Wasm PR description is a useful historical snapshot of the cross-build instructions, the copy in the official documentation is being updated over time: https://github.com/ruby/ruby/blob/master/wasm/README.md
tomstuart··on News for Ruby 3.2.0
For better or worse, the convention in Ruby is to name methods in a second-person style [0], as if addressing the object directly: “file, do you `#exist?`”; “string, do you `#start_with?` foo?”. So, for consistency, `Dir.exist?` and `File.exist?` have been preferred for a long time.

[0] https://bugs.ruby-lang.org/issues/9041#note-1

tomstuart··on How to draw ugly lines fast
The endpoints of the lines have subpixel resolution, so although you’re only drawing whole pixels, the choice of which pixels to draw along the line may change based on the subpixel positions of the endpoints.
tomstuart··on Ruby 3.2.0 preview 3 released
Notable addition since preview 2 not mentioned here: `Data.define` can be used to define stricter, immutable Struct-like classes.
tomstuart··on Passkeys.io – A Passkey Authentication Demo
This was, for me, not an effective demo: when I tap “sign in with a passkey” it shows me a QR code to scan with another device. What? (I assume this is because I haven’t created an account yet, but if so, the demo needs to make that about ten times clearer.)
tomstuart··on Git’s database internals I: packed object store
I know what you mean, but — as the article explains [0] — Git’s packfile format uses delta compression, which is essentially “storing diffs”.

[0] https://github.blog/2022-08-29-gits-database-internals-i-pac...

tomstuart··on Writing Snake in 12 Lines of PyTorch
A complex number represents a 2D point in the complex plane, but multiplication by a complex number on the unit circle also happens to correspond to a rotation in the complex plane, e.g. 3 × i = 3i, which is a rotation of 90 degrees anticlockwise, or -5i × -i = -5, which is a rotation of 90 degrees clockwise.

So if you use the complex numbers 1, i and -i to represent the actions “go straight”, “turn left” and “turn right” respectively, you can update a complex number representing the current heading of the snake (1 = east, i = north, -1 = west, -i = south) by multiplying it by the action. To get the snake’s current position, add up all the “current heading” numbers you’ve seen so far.

tomstuart··on Writing Snake in 12 Lines of PyTorch
This is incredibly clever. In case anyone else is confused by the order: the ASCII codes for L, S, R are 76, 83, 82 respectively, so L encodes i and R encodes -i as you’d expect.
tomstuart··on Phrases in computing that might need retiring
I do find “BDD” a frustrating term.

It was coined by Dan North [0] to refer to a coherent set of sensible TDD practices — give tests expressive names, say “behaviour” not “test”, write executable “given/when/then” acceptance criteria — but in the intervening 16 years (!) it’s mutated into… I don’t even know what.

There’s a community of “BDD” practitioners who talk about all sorts of ideas that aren’t necessarily even specific to software engineering. Which is fine and good, but it’s rendered the term essentially meaningless in a software context.

These days I usually say “double-loop TDD” or “outside-in TDD” when I want to emphasise the use of executable acceptance tests; it’s impossible to predict what (if anything) “BDD” will mean to anyone.

[0] https://dannorth.net/introducing-bdd/

tomstuart··on Commit Messages Don’t Matter
I have neither the motivation nor the energy to start an internet argument about it, but I’d like to reassure the casual reader that this post is promoting a minority viewpoint.
tomstuart··on Nearly half of Gen Z is using TikTok and Instagram for search instead of Google
A thread investigating the source of this claim: https://twitter.com/Vortex_Egg/status/1548047874411245570
tomstuart··on To Ruby from Python
You may be making a point about what happens by default (and perhaps Ruby’s similarity to Scheme?), but in Ruby you can also say `data.sort!` if you want the `data` array modified in-place. It’s still returned, though.
tomstuart··on To Ruby from Python
A fair complaint, but FYI it’s outdated as of Ruby 3.0 (released in 2020) which includes the `debug` gem [0]. So in Ruby 3.0 onwards it’s as easy as `require 'debug'; debugger` just like you want. Hopefully your build systems will upgrade to a newer Ruby before too long.

[0] https://stdgems.org/debug/

tomstuart··on To Ruby from Python
Right, I see, because you have to say `method(:foo)` or `-> { foo }` or whatever. To me this is an acceptable syntactic trade-off in exchange for being able to invoke the method with bare `foo` (i.e. variable reads and method calls look the same) but I can see from other comments here that some people dislike that ability anyway. Vive la différence!
← PreviousPage 2 of 11Next →