MarkBernstein.org

Save $50 at the Tinderbox Labor Day Sale.

A tasty new weblog about notes, from Joel Orr. NotePower.

ArtsHub asks, “Does Anyone Read Hyperfiction?”

According to Bernstein, ‘The great advance of the last few years in hyperfiction, interestingly, has been the reintroduction of techniques we discovered in electronic writing into the vernacular of the novel. Janet Egan's A Visit From The Goon Squad is a wonderful hyperfiction, flattened. Erin Morgenstern's wonderful book, The Night Circus, remediates the work of Punchdrunk, a hyperdrama company, in a wonderful spiral of the imagination.’

I’ve been working on an interesting refactoring of Tinderbox Six this week, prompted by a simple study of which Tinderbox classes depend on which other classes.

An Interesting Refactoring (Wonkish)
Tinderbox 6 #includes (approximate, >10 uses)

Tons of classes depends on Node, the base class for notes, adornments, and other Tinderbox items. Many classes depend on Hypertext, the base class for Tinderbox documents. Node had also grown absurdly large, with something like 270 public methods. This is bad form. I’ve been working to break up Node for years, and most of the real work today is done by specialized classes like Content; most of the 270 methods are simply forwarding messages.

Still: 270 methods!

On the other hand, Tinderbox is about making, analyzing, and sharing notes. It’s not entirely surprising that lots of Tinderbox classes need to know about notes. And each dependent class seems to need a different subset of those methods, so there aren’t lots of great opportunities to solve the problem with Extract Interface.

This has been a headache for a long time. Changing Node or Hypertext means recompiling the world, pretty much; in the Metrowerks compiler, which we used for Tinderbox 1-4, this could take half an hour. Even in Xcode, recompilation can be a deterrent.

Refactoring toward Decorator seems a natural fit. We could have a concrete class, BasicNode with the bare essentials, and decorate it with drawing behaviors, text behaviors, I/O behaviors. But refactoring toward Decorator is notoriously hard, and a 270-method decorator is absurd.

I believe I’ve found a decent refactoring path. I think it’s fairly well known, but I haven’t seen it named before, and I don’t believe it’s in Fowler or Feathers or Kerievsky. So I’m going to call it Extract Satellite until someone writes to tell me what everyone else calls it. (Email me.)

What we do is define a new class — let’s say NodeText, that simply wraps a reference to a Node and has no other data.

class NodeText{
public: 
   NodeText(Node* inNode):node(inNode){}
   ~NodeText(){}
private:
   Node* node;
};

Next, we move some public methods for text handling from Node to NodeText. We can move related private methods as well. Classes that use those methods now depend both on Node and on NodeText; they make a new NodeText on the stack whenever they need it.

NodeText worker(node);
worker.SetText("…");

The new NodeText class now has all the interesting and messy text handling methods. We remove them from Node, and use a NodeText wherever we need them.

Then we extract another Satellite class from Node — perhaps one that deals with moving notes around. Pretty soon, Node can have a bunch of specialized satellites.

We haven’t broken the dependency on Node — and we’re not going to. Worse, we’ve added a new dependency, and we have to make new working objects. But when we want to change text handling, those changes now occur in NodeText, and instead of recompiling the world we only need to recompile the classes that handle text.

Eventually, we can hollow out Node until all, or almost all, its methods are merely plumbing. Everything still depends on it, but that’s OK because it’s not going to change. All the behavior is in the satellite classes, and now Node becomes simply a Facade that adapts its internal classes, like Content, to its Satellites, like NodeText. Most clients that use Node only need one Satellite, and hardly anything needs more than two.

Node becomes so simple that it seldom if ever changes. We can even add additional satellite classes without touching Node.

Extract Satellite is related to the old C++ pImpl idiom, but here we’re using the existing class to serve as the pImpl for a family of satellites, where traditionally pImpl starts with a class and extracts the implementation. Another way of looking at Extract Satellite is that it’s a Strategy turned inside out: where in Strategy the object has the data and the strategy implements the computation, here the Satellite object carries all the methods and has a pointer it can use to get the data.

OK: this is a lot more technical than is my habit, and we’ll return to our usual style next week. But it happens that I’ve read a pretty good chunk of the pertinent monograph literature on this subject, and I haven’t seen this discussed much. I thought I’d get this down for discussion, and to let curious readers know what I’ve been wrestling with this week.

Update: The refactoring is in Feathers after all, where it’s called Extract Class. Confusingly, Extract Class is used of two different approaches, and this one is tucked in as a coda after a refactoring to Decorator.

Aug 13 24 2013

Fun Home

by Alison Bechdel

Bechdel’s acclaimed comic of gay identity, the death of her father, and her parents’ troubled marriage is nearly as good as its sequel, Are You My Mother? Again, what’s most interesting here is not the weight of a comic that deals seriously with serious matters, but the way Bechdel weaves together a story and a novel of ideas in the small compass that comics allow.

And you’ve got to love any sophisticated college student who discovers, browsing in a bookstore, that she’s a lesbian.

Aug 13 21 2013

North

North is a delightful neighborhood restaurant in an out-of-way corner of Providence, run by three Johnson & Wales grads with flair, imagination, and some serious cooking. It’s also a bargain. The tiny place — six tables and a bar — retains the decor it inherited from a previous incarnation of a Japanese restaurant. The tiny menu has imagination and breathes fresh life into the whole idea of Asian fusion.

And there’s a lot going on here. Especially the “nearly boneless friend chicken”, which is delicious. And it’s hiding its light under the proverbial barrel: if I’ve figured it out, this is really complex but really well done. I think they take one leg and, at the wings and thighs, bone them out, and make a forcemeat. The rest of the chicken — not counting one claw-on leg — is boned out and stuffed with the forcemeat, tightly wrapped, and lightly battered. This, I suppose, is a ballotine or maybe a galantine. Anyway, it’s then fried, sliced, and served with the leg, sauces, herb salad, and lots of warm sliced brioche to sop up the juices. There’s a lot going on, in other words, for a “big plate of nearly boneless fried chicken.”

Other interesting dishes: fried oysters wrapped in burmese pancakes, cold buckwheat noodles, spicy braised eggplant, and a revision of dan dan mien that involved spaetzle, seafood, and no peanuts.

Oh — and they have a slushy maker filled with a cocktail of the night.

No reservations, but worth a bit of a wait.These guys are going to be swamped overnight and they’ll have to open a bigger and swankier place. Go now, and it’ll be like recalling Achatz at Trio before he opened Alinea.

Shocking and heartbreaking news this morning of the death of Gene Golovchinsky, hypertext pioneer and one of the engineers most responsible for the success of the modern eBook. Golovchinsky pioneered work on note-making on tablets in an era when tablets were widely dismissed, where eBooks seemed a distant dream.

Aug 13 17 2013

OPS

In an interesting article, seemingly based on a speech to SABR, Colin Wyers revisits how analysts and historians can contribute to baseball and, by extension, to any large and difficult enterprise.

In passing, he observes that it is well known that OPS is superior to Total Average. What’s the definitive treatment of this question? Email me.

For background: OPS is on-base percentage plus slugging percentage. Slugging percentage, in turn, is (singles + 2*doubles + 3* triples + 4*homers)/atBats. Total Average is total bases/plate appearances. I’ve always looked askance at OPS as a frankenstein statistic — who adds two incommensurate ratios? Of course it’s fun and useful, but still...

by Steve Freeman and Nat Pryce

The core of this interesting exploration of test-driven development is an attempt to describe in some detail the process of developing a non-trivial network application. A frequent obstacle in treatments of unit tests and of refactoring is simply demonstrating their utility to skeptics: if the examples are small enough to grasp easily, they are small enough to dismiss as toys. It’s easy to convince yourself that these techniques spend time to polish impractical little gems, especially if you’re a pointy-haired manager with urgent deadlines and little concern for the fate of the code after a successful launch wins you a promotion.

I always despised the whole idea of lab partners. To save a a little space and equipment, the school would yoke you to some bystander who might be useful but often was not. Pair programming always struck me as a ghastly idea, though is can be interesting in very small doses when you’re getting up to speed in a new area. To a considerable extent, this feels like pair programming in print.

Still, there’s good material here. Freeman and Pryce don’t dodge difficult issues, such as concurrency, and they embrace an interesting test style that freely mixes acceptance and unit tests.

Aug 13 11 2013

Blunts

Test-Driven Design is facilitated by several kinds of objects which substitute for real objects and which exercise the system or probe the behavior of other objects. This matters because real systems use objects that you don’t want the test to exercise. If every test creates elaborate windows and reads large files, your tests will be slow. If the system involves alarms or databases or sprinkler systems, your tests are going to be uncomfortable.

Two categories of test objects are widely known.

  • Stubs behave like the real object, but substitute simple or canned behavior for the real thing. For a test, you might stub out a database with an object that accepts your query and feeds back a single precomputed response. For an alarm system, you might have a SprinklerController that (a) turns on sprinklers all over the building to extinguish the fire, (b) rings loud alarms, and (c) returns the string “OK” if the sprinklers are operating, or “FAIL” if they aren’t. The TestController could simply return “OK” without making you wet.
  • Mocks are mock objects that automatically emulate the interface of a real object and that return exactly what you specify.

I’d like to propose a third useful category, the Blunt Object. A Blunt is a subclass of a real object; it does everything the real object does except it removes behavior you don’t want in a test.

For example, a BluntSprinklerController is a subclass of a real SprinklerController and inherits almost all of the parent class behavior. But we do override two methods, RingAlarm() and ActivateSprinkler() — in each case doing nothing instead of actually making noise and extinguishing fires.

Blunts are as easy to write as stubs. Indeed, they’re often easier, since often you only need to override one or two methods. Blunts let you run tests with real collaborators, potentially reducing integration problems. Of course, Blunts have drawbacks:

  • Blunts are only useful if the underlying object is not too difficult to construct.
  • A blunt object derived from a very dangerous object, like the SprinklerController, requires careful analysis to ensure that it really is blunt and safe to use.

Blunts are a very simple idea, of course, and everyone who writes tests is likely to have used them. But I’ve not seen them discussed explicitly and I do like the name.

by Jo Walton

After a slightly disappointing Readercon, it was time to reread this wonderful and thoughtful fantasy. After my first reading, I called this:

A brilliant fantasy novel set in late 20th-century Wales, where young Morwenna Phelps has recently lost her identical twin sister, her name, her ability to walk without a limp. and perhaps her family. In the wreckage of what might be seen as an automobile accident (but might also be seen as a titanic magical duel), she is sent off with a father she scarcely knows to an English boarding school where she is the Barbarian Outsider. As she always has, Mor takes refuge in books. She tells us all about them. The cruelties of school girls and school dinners doesn’t matter nearly as much as her discovery of James Tiptree, Jr.’s secret.

Mor’s bookishness is wonderful, and the fantasy is worked out with such grace and skill that it really requires no suspension of disbelief. Here, the essential nature of magic is that it’s always deniable. Mor lost her sister, and almost died herself, in a titanic magic duel in which they stood together to defend the world from their mother’s insanity. But, if you prefer to believe another story, the were hit by a car — perhaps Mom’s car though even that’s not entirely clear.

The underlying premise, interestingly, is the same as the premise of another under-appreciated fantasy, Babylon 5: what happens to the hero after the story is over? In Babylon 5, the scouring of the Shire leads to an even greater conflict. Here, it leads to boarding school, a boyfriend, and a terrible decision.

Update: review by Larry Davidson. Recent review by Ursula Le Guin., who is one of Mor’s favorite writers.