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 I have no idea what I'm doing
It's already a static site, but being on the HN front page is really hammering my tiny VPS's network & IO; there are a lot of large images and videos in the post. Guess I should set up a CDN.
tomstuart··on Programming with Nothing (2011) [video]
Previously: https://news.ycombinator.com/item?id=3343205

This talk is old now, but I’m happy to answer any questions.

Someone recently did some really nice sketchnotes: https://twitter.com/deejaygraham/status/528220110331596800

tomstuart··on Refactoring Ruby with Monads
I apologise for that codebase! Let’s just say I’ve learned a lot about building Rails apps since 2007. ;)
tomstuart··on Church Numerals
Thanks! There’s a transcript at http://codon.com/programming-with-nothing, and the FizzBuzz implementation was recently added to Ruby itself: https://github.com/ruby/ruby/commit/628dac1
tomstuart··on Ask HN: Why would you disable JavaScript?
From the UK government:

> Surprisingly, the proportion of people that have explicitly disabled JavaScript or use a browser that doesn’t support JavaScript, only makes up a small slice of people that don’t run JavaScript.

https://gds.blog.gov.uk/2013/10/21/how-many-people-are-missi...

tomstuart··on Why I don't mock
I don’t understand what this means.

The difference between a stub and a mock is about the object under test, not the collaborators that are being replaced with doubles. We use a mock when we want to test the object’s interactions with its collaborators; we use a stub when we don’t care about the interactions, only about the values that result from them.

What does that decision have to do with whether the interface is small and well-defined?

tomstuart··on Why I don't mock
> Ask yourself the question "What tends to get mocked?"

Answer: every collaborator of the object under test, so that only the tested object is actually having its implementation exercised. All other objects that it needs to talk to — database connections, network sockets, or whatever — are replaced with mocks, and the test subject’s interactions with those mocks are verified, so that a) we have confidence that the tested object is interacting with its collaborators in the expected way, and b) the test itself doesn’t depend at all on the actual behaviour of those collaborators’ implementations, which behaviour should be explicitly exercised elsewhere.

That’s the opposite of coupling. I don’t understand where your answer comes from or what it means.

tomstuart··on Why I don't mock
> That may not be what they're "for" (wtf does that even mean?)

It means that “[mocks are] a way to allow you to test code that you can't improve right now” and “[mocks are] a stepping-stone for testing and improving a large existing codebase” is a mischaracterisation of the role and benefits of mocks.

If using them like that is useful for you then that’s great, but it’s misleading to say that that’s why “they’re there”.

Steve Freeman & Nat Pryce’s book [0], for example, is an excellent illustration of what mocks are for.

[0] http://www.growing-object-oriented-software.com/

tomstuart··on Why I don't mock
That’s not what they’re for! Mocks allow you to design the interface of a new object by implementing that object’s collaborators before you implement the object itself. This is a very high-fidelity source of information about what the interface should look like; anything else is just (educated?) guessing.
tomstuart··on Why I don't mock
This isn’t a danger, it’s a benefit: your tests of one unit (whatever you consider a “unit” to be) are isolated from the behaviour of the rest of the system. For example, if you break one part of your implementation, you get one failing unit test, not a thousand.

Checking these assumptions is what integration and acceptance tests are for.

tomstuart··on Uncle Bob on DHH: Monogamous TDD
We just disagree, then.

To pick a tiny, arbitrary example from the keynote, he criticises this method[0]…

  def age(now = Date.today)
    now.year - birthday.year
  end
…as opposed to his preferred version…

  def age
    Date.today.year - birthday.year
  end
“Is [the method with the parameter] better? Is it simpler? Is it clearer?” He makes fun of it as though the second version is obviously simpler and clearer, presumably because it uses fewer characters/parameters/concepts, but in reality it’s not obvious. It depends what you want!

The first version makes it “clearer” that the method’s result is date-dependent, which makes it “simpler” to understand how it will behave as part of a larger system (e.g. is it cacheable?); this is a win for composability. If you want to call it from inside another method, you’ll need to get a date from somewhere — maybe you’ll already have the appropriate date to hand, or maybe you’ll choose to pass that responsibility onto your caller in turn, or maybe you’ll decide that this is the right place to reach for Date.today. Either way, you get a chance to think about it, and to be aware of how another part of the software is going to behave without needing to go and look at its source code. (This argument is essentially “referential transparency is good”.)

Now, it’s entirely plausible that you don’t care about that benefit, and you’d rather have a shorter method that works in the easiest possible way without regard for referential transparency, because your system is small, or this method is hardly called anywhere, or everything else in the application is time-dependent anyway so you don’t need to be reminded of it. That’s fine too! But DHH doesn’t go into any detail on the tradeoff; he just makes fun of the version that takes an argument, because it’s testable for the sake of it, and why would anyone bother with that?

He doesn’t seem interested in exploring the situation, or in interrogating what testability implies in this case, only in laying out his prejudices as if they’re indisputable common sense. They’re not.

[0] Since this is just example code, it’d be churlish to point out that it’s not the right way to calculate someone’s age in the first place.

tomstuart··on Uncle Bob on DHH: Monogamous TDD
I don’t want to sound like a stuck record, but did he actually say that? My interpretation of his keynote was that he was “blindly pretending” that there are only negatives to test-first development, unit testing &c, which is just disingenuous as the scientism you’re highlighting.

I dunno, maybe my biases are preventing me from understanding him properly.

tomstuart··on Uncle Bob on DHH: Monogamous TDD
I agree, but you’re projecting; DHH hasn’t said anything that nuanced.

He doesn’t explicitly touch on “other desirable qualities” of designs (other than the meretricious goal of “clarity”), nor how they relate to testability. He just makes fun of testability without exploring what it means, how it can imply those qualities, and how to decide which tradeoffs to make.

That’s a shame, considering how many people pay attention to what he says. He has the opportunity to promote a more thoughtful and consistent approach to building software, but doesn’t seem interested in exploiting it.

tomstuart··on Uncle Bob on DHH: Monogamous TDD
DHH criticises “good tests” and “being testable” as meaningless goals; he characterises TDD practitioners as being fixated on testing qua testing, completely focused on testability and associated metrics (coverage, ratio, speed) in their own right, as if they blindly believe those things to have intrinsic value.

That’s inaccurate and unfair. Testability is useful precisely because it’s an effective, tangible proxy for other properties of software that are harder to anticipate or recognise: things like modularity, composability, reusability and so on.

Tests are useful on many levels, but at their most basic they provide a second client for your implementation, encouraging you to think harder about what each part of your software is doing and how it’s doing it. They give you an opportunity to step outside of your immediate goal and look at your software in a different way, from a different angle, with a different set of priorities. This gives you more visibility on the decisions you’re making, and that’s almost always worthwhile.

If it’s a nightmare to isolate a piece of your implementation in order to test it, what does that tell you? Directly: it’s not very “testable”. Indirectly: your design is perhaps a bit tangled up, and you probably could work harder to separate concerns and isolate dependencies and think carefully about how the pieces interact and what they individually mean, and it might be difficult to compose those pieces in different ways later. Would you have noticed those problems anyway? Probably, but going through the exercise of writing tests is one way of increasing the chances of noticing them sooner, while you still have a chance to do something about them before they become too baked-in.

In my experience TDD can lead to better designs, because it provides a simple, learnable, repeatable discipline that makes it more likely that you’ll notice design problems sooner. (There are other design benefits too, but I’m trying to focus on the least contentious one.)

Some programmers may be proficient enough at spotting these problems early that they don’t get any benefit from “testability”, and some may exert enough control over their software’s user-facing behaviour that they are able to dodge complexity at the requirements level, but for the rest of us it’s a useful litmus test for avoiding messy, knotted code. Being testable doesn’t make an architecture good, but good architectures tend to be easier to test.

I haven’t seen any sensible person say that TDD is a wholesale replacement for thinking about the design of your software, so it’s misleading to argue against that idea as if it’s representative.

(cross-posted from http://lists.lrug.org/pipermail/chat-lrug.org/2014-April/010...)

tomstuart··on What is the enlightenment I'm supposed to attain after studying finite automata?
I wrote a non-academic book on this subject for the HN crowd: http://computationbook.com/
tomstuart··on Teenagers and the Internet
Ugh, “the girl who let herself be gang raped”? I expect much better than this from the Guardian.
tomstuart··on Save 50% on All O'Reilly Ebooks and Videos
Author here. Thanks for the recommendation! There’s already a reading group in London (http://lanyrd.com/series/compbookclub/), but that may not be of any use to you.

If anyone else is interested in the book, there's more information at http://computationbook.com/.

tomstuart··on Wraith – A screenshot comparison tool from the BBC
See also https://github.com/techbelly/web_regression.
tomstuart··on What If You Could See WiFi?
See also Timo Arnall et al’s work on light painting wifi: http://www.nearfield.org/2011/02/wifi-light-painting
tomstuart··on Ruby 2.0.0 Released
I wasn't trying to compare Ruby and Python (I'm not a big Python user); I was just explaining why I said Ruby was "clean". As simonw observed, all of these points arguably apply to Python too.
tomstuart··on Ruby 2.0.0 Released
Charles Nutter does a good job of explaining why you can't just ignore refinements: http://blog.headius.com/2012/11/refining-ruby.html

In summary, they makes the Ruby language harder to implement, and Ruby code harder to understand. You can't pretend they don't exist if their existence compromises the meaning of your code and the performance of your chosen Ruby implementation.

tomstuart··on Ruby 2.0.0 Released
Ruby only has built-in support for currying procs:

  >> add = -> x, y { x + y }
  => #<Proc (lambda)>
  >> add.call(3, 5)
  => 8
  >> add.call(3)
  ArgumentError: wrong number of arguments (1 for 2)
  >> curried_add = add.curry
  => #<Proc (lambda)>
  >> add_three = curried_add.call(3)
  => #<Proc (lambda)>
  >> add_three.call(5)
  => 8
If you want a no-brainer way of currying methods, you're SOL.
tomstuart··on Ruby 2.0.0 Released
Arguably so. :)

In my opinion Ruby pips Python to the post (however slightly) in each respect, but it's clearly a question of taste.

tomstuart··on Ruby 2.0.0 Released
Cleanliness is subjective, but:

* Everything is an object, without exception.

* The object model is pleasingly orthogonal and its behaviour is easy to understand and predict once you know how it works.

* The syntax is high on alphanumerics and low on punctuation.

* Most of the core library method names strike a good balance between brevity and clarity.

* `Enumerable` is simple and powerful.

tomstuart··on Ruby 2.0.0 Released
It's fun, it's clean, it's simple, and it works.
tomstuart··on Our industry sucks for diversity and conferences are only showing up the fact
I honestly don't understand why you've left this comment, because the OP is arguing against positive discrimination, not for it.
tomstuart··on Ruby 2.0.0-preview2 released
Refinements aren’t all good news: http://blog.headius.com/2012/11/refining-ruby.html
tomstuart··on The British Ruby Conference has been cancelled
I helped to organise the last Ruby Manor conference (http://rubymanor.org/3). As an experiment, we built a web app (http://vestibule.rubymanor.org/) which allowed anyone to submit, discuss and vote for proposals. When voting closed, the 8 most popular proposals were automatically selected.

The result? 8 white guys giving talks (http://rubymanor.org/3/videos).

We’re going to try something different next time, but who knows if that’ll work any better.

tomstuart··on The British Ruby Conference has been cancelled
It only just happened. From the language and timing it looks like a snap emotional decision rather than a rational one; I assume the organisers got blindsided by the negative feedback and didn’t want to deal with it any more.

ETA: “@Rebeccask Due to sexist & racist remarks made on twitter last night got way out of hand. Sponsors pull out. No money no conf” (https://twitter.com/Rebeccask/status/270220165344550912)

tomstuart··on The British Ruby Conference has been cancelled
A Twitter search for “britruby” should clear it up.

Short version: they’d invited all white male speakers; people complained about it on Twitter; the organisers got disheartened and called the whole thing off.

ETA: https://twitter.com/joshsusser/status/269844125363339264, https://twitter.com/jamesarosen/status/269859024164495360

← PreviousPage 6 of 11Next →