Archive | Uncategorized RSS feed for this section

Speed Racer is one of the best films of the last 10 years

22 Feb

Certainly one of the very best blockbusters. And I’m not the only one who thinks so, apparently. My only major criticism is that it’s maybe 20 minutes too long, but I can’t say specifically what I would cut.

Animvs: Lisp for people who don’t like Lisp

7 Feb

I made this video several months ago but just uploaded it today. It describes, Animvs, my programming language project I’ve kept on the back burner for the last five years. The selling points are, briefly:

  • based on the semantics of Clojure, but allows mutability and immutability to live side-by-side
  • also allows dynamic and static code to live side-by-side
  • features clean syntax with the virtues of traditional S-expressions but without the ugly flood of parens
  • designed with editing environment conveniences in mind, including some usually only found in traditional static languages, e.g. name refactoring like found in Java IDE’s

The video doesn’t get into the mutable/immutable or dynamic/static business, but it does give you a good taste of the syntax (which is far more important than many would give credit).

“exclusive province” vs. “exclusive provenance”

20 Jan

When wondering which is proper, I found this obnoxious answer:

“Exclusive province” not “provenance.” People shouldn’t use words without knowing what they mean.

I’ll take the answer as given, but how the hell does this person think people learn most of their vocabulary, idiomatic expressions and all?

Besides, while “exclusive province” seemed more right to me, “exclusive provenance” isn’t that much less logical and has the virtue of being less metaphorical: most uses of “exclusive province” analogize land area to an abstract domain of ideas. “Provenance” on the other hand applies without metaphor as equally to ideas and culture as to tangible things.

Where’s the fire?

19 Jan

Too often, opponents of SOPA, PIPA, and their like concede that ‘piracy is a real problem’. While it’s intuitively obvious how illicit copying could be a problem, it’s equally and empirically obvious that illicit copying has had no serious effect on the production and availability of content. The new distribution models of the internet are almost certainly responsible for a far greater boost in production than the illicit copying is responsible for depressing production. Maybe the copying has cost content industries non-trivial money, but until the public actually sees a real reduction in output, why are the rest of us supposed to care? The current levels of illicit copying seem perfectly benign or even beneficial, so why subject the internet to chemotherapy?

Typing: which is the one true faith?

26 Dec

Dynamic typing can be attributed three main virtues over static typing:

  • flexibility: A single function can vary the type of its returned value, and collections can hold heterogeneous values. Consequently, dynamic typing often lets us get away without having to think too far ahead.
  • concision: Functions, variables, and collections needn’t declare their types, and interfaces can be kept informal. (Inferred typing arguably closes this concision gap significantly.)
  • simplicity: Heterogeneous collections mean we don’t need to introduce generics.

Conversely, static typing can be attributed two main virtues over dynamic typing:

  • efficiency: When the compiler knows the variable types for certain, it can make numerous optimizations that otherwise aren’t possible.
  • correctness: The compiler can perform type checks, effectively eliminating a whole class of bugs. (However, any remaining errant null references and incorrect ‘down casts’ arguably constitute type errors, so not all static languages eliminate type errors entirely.)

The interesting question to me is, ‘when and why do programmers actually make type errors?’ In my limited experience, I’ve worked on long term projects in dynamic languages and hardly ever made any type errors. In a 10k-line Javascript project, for example, I bet I probably made fewer type errors than I can count on one hand.1 This realization puzzled me for a while because it got me wondering why the hell so many people obsessed over type errors? After all, a type error is only one kind of bug among many and, in my experience, a not terribly common kind. All the programmer has to do is consult the documentation of the functions and objects they use to avoid making type errors. Right?

Well a little more experience explained this mystery: type errors become easy to make when dealing with ‘alternate-form types’. Such types enter the picture in a few ways:

  • numeric types: int, short, double, float, decimal, complex, etc. These are all numbers and so easy to confuse.
  • strings of different encodings: Again, these are all representations of essentially the same thing and so easy to confuse.
  • strings representing non-textual data: Do we need a number or a string of numeric digits? A boolean or a string reading ‘true’ or ‘false’? A code object or a string of code? A Foo object or its string representation?
  • numbers used for enumerations: Do we need a 0 or false? Does this function expect us to indicate the color blue with ‘blue’, 3, or COLOR.BLUE?
  • wrappers and collections: Do we pass in a Foo object or a FooWrapper object? An int or an Integer? A Bar object or a collection of Bar objects? The row object returned by the ORM or the business object representing the same data?

Without alternate-form types, type errors would almost never occur, for why would anyone ever accidentally mistake an Elephant for a Motorcycle? Mistaking a Scooter for a Motorcycle, on the other hand, is not so hard to imagine.

The important takeaway of my experience is this: the fact that alternate-form types arise less commonly in higher-level domains (such as Javascript for a webpage) partly explains why dynamic typing is generally more favored in front-end coding than in back-end and ‘engine’ coding. What seemed like a non-issue to me in one domain became a constant concern when working in another.

Typing peace in our time?

Now, if front-end and back-end code always lived in neat separate boxes, having to choose between static and dynamic code wouldn’t be a hard choice: we could use dynamic languages for front-ends and static code for back-ends. Most projects, though, straddle a line in both worlds, for a front-end, of course, must ultimately call into a back-end. Often this is done over the network such that the dynamic/static divide doesn’t really matter, but in other cases, we want to invoke a back-end as a library or framework, requiring some bridge. For example, Python can use modules written in C, but only with some significant adaptation.

Could we solve this problem? Could a single language accommodate both static and dynamic code that interoperate without hassle? I believe such a language is possible, and all it would require is for the programmer to declare each function/method as either static or dynamic:

  • In a dynamic function, type declarations would be optional, such that you might leave some or all types undeclared.
  • In a static function, all types must be declared (except those which can be inferred).
  • A dynamic function can invoke static functions with no hassle, though the runtime of course would have to perform a type check on the inputs. In some cases, type errors could be caught by the compiler in the context of a dynamic function, e.g. the return type of an invoked static function is known, so we might detect the improper use of the return value as argument to another invocation of a static function. On the whole, though, no guarantee is made about the type correctness of code in a dynamic function.
  • A static function can invoke dynamic functions but must declare the expected return type (where it cannot be inferred by context) so that the type can be checked at runtime. Of course, while the runtime check preserves the type correctness of the rest of the code, invoking a dynamic function effectively introduces potential for a type error within the context of the static function, in a sense nullifying the type assurance we’re aiming for with static typing (though of course null references and down-casts, if present in the language, already undermine the type safety of our static code.)
  • Homogenous collections and generic types would retain their typing in dynamic code, e.g. an ArrayList<Foo> would throw an error if you attempt to append a non-Foo object.

The other necessary measure for mixing static and dynamic code is introducing a distinction between static and dynamic classes, for it wouldn’t do for static code to access properties that might get deleted or change their type. Dynamic code would interoperate with static types freely, but static code would have to assert types to use dynamic types.

So the general pattern would be that using static functions and types in a dynamic context would be pain free, but using dynamic functions and types in a static context would require a bit of bother. This is likely not really a painful cost at all, as invoking static code from dynamic code is the much more useful case, for generally front-ends call into back-ends rather than the other way around. Programmers would start out writing a project in dynamic code but then gradually evolve their codebase, in whole or in part, into static code.

It can’t be that easy

Surely if the solution were so simple, someone would have done this by now, right? Well, not necessarily. One explanation is that static vs. dynamic is one of those religious debates in programming, and language designers are certainly opinionated, for why else would they create a language? Static typing purists create static languages because they believe efficiency and type safety shouldn’t be compromised, and dynamic typing purists create dynamic languages because they believe static type systems are overly troublesome and complicated. On the static side, especially, most energy seems to go into fixing type system problems by doing static typing ‘the right way’ (see Scala and Haskell).

But the main reason no one has integrated dynamic and static typing into one language is that, until fairly recently, no one could see the point. Until the rise of Javascript, Python, et. al., dynamic languages were used almost exclusively for small codebases of high-level code, meaning the alternate-format types problem never became pronounced. Now, however, we’re pushing dynamic languages into domains of larger codebases and infrastructure code, which suggests the need for a dynamic/static hybrid.

I’m certainly not he only person to get this idea. A future version of ECMAScript, for example, may feature optional static typing (though this is very much up in the air). Also, the academic project StaDyn approaches this problem from the opposite direction as my solution, treating static code as the default with optional dynamicism. I haven’t looked closely enough at this to form an opinion, but it looks interesting.

  1. This excludes errors from mistyped property names, which is an error I made multiple times each day. I don’t consider these to be type errors, though, but rather ‘name errors’, and as I’ll discuss an another post, static typing isn’t needed to eliminate name errors. []

What does it take to motivate online students?

6 Oct

Kevin Drum and Matt Yglesias note that students have a hard time getting motivated in online courses. Online education is something I’ve been thinking about a great deal, but for now I’ll just give you two simple answers to this problem:

  1. The units of education need to be considerably shorter, say two or three weeks in length instead of two or three months. People who accomplish big things do so because they can mentally break the task into manageable units. For example, imagine how easier it would be to lose weight if it only took a couple weeks to lose 5-10 pounds and those pound were guaranteed to stay off for good.
  2. Have students talk to tutors/mentors/counselors on a regular basis, over the internet or perhaps even in person. When taking piano lessons, I always practiced more diligently in the two or three days after my lesson, often slacking off the rest of the time. What this suggests to me is that, in fact, the greatest value in music lessons is probably not in the parting of any real information so much as just in coaching students through practice. If you find the optimum frequency a particular student can go without coaching, I predict you’ll largely solve their motivation problem.

11 ways to ruin team play, a.k.a. Why Battlefield 3 will (probably) still be fundamentally broken

3 Sep

1. Where the hell is my teammate?

There isn’t much to say about this one. If you have no idea what your teammates are doing half-the-time, you can’t even begin to coordinate.

2. Hey, there’s my teammate! No wait, he just exploded.

Like characters in a horror movie, players in most team action games reflexively go their own way. Even in ostensibly team-based games, such as Battlefield, players have learned that it’s simply not worth the bother in most cases trying to follow teammates or trying to get teammates to follow them.

Perhaps the biggest reason no one ever sticks together is because quick deaths make it wasted effort. Nine times out of ten, if I spawn and dutifully hop in the helicopter you’re piloting, you’re just going to get me killed faster. On foot, two players moving together will spend most of their time trudging across the map only to end up with one player killed immediately in an ambush; so effectively, when the combat finally comes, teammates die too quickly most of the time to really fight together.

Mainly because of this endless quick-death/respawn cycle, most team combat games devolve into teammates barely playing together in any real sense at all. My teammates and I aren’t working together: we just happen to be trying to kill the same enemies.

3. Action, action, action! Who needs time to think or coordinate?

However long it takes one person to think, a group of even just two or three people seems to take ten times as long to do the same thinking. This is true even under ideal circumstances, let alone in a fast-paced action game with iffy text and voice communication.

Now this doesn’t mean we can’t have fast-action team play, but it does mean games should consciously allow for breaks in the action. Instead of ‘action, action, action!’, game design should always privilege ‘pacing, pacing, pacing!’

4. If one ball is fun, then ten balls must be ten times as fun.

Looking at sports, focus is almost always very clearly focused on a single ball, and for good reason. Too many points of focus mean the team play quickly devolves to incoherence: everyone just ends up doing their own thing, defeating the whole idea of team play.

5. If having ten players is fun, then having one hundred players must be ten times as fun.

Similarly, past a certain number of players, team play becomes incoherent. Too many players means too many teammates to coordinate with and too many opponents to worry about. Again, looking at sports, we see that eleven or twelve players per team seems to be the upper limit. In fact, on the soccer field, half the players spend most of the time standing outside the zone of action waiting for the ball to get closer. So the sweet-spot seems to be about 3-6 players per side actively engaging each other around a local objective.

Notice I said “local” objective. Teams beyond the 11-12 player threshold can conceivably work coherently as long as strong mechanisms are in place to divide the team into smaller units, each engaging separate objectives. For example, a Battlefield-style game could work with 32-player teams or beyond if stronger mechanisms were in place to enforce squad-based play and if those squads were ensured to have separate objectives. The danger, though, is that too many squads off doing their own thing eventually becomes as incoherent as a game of too many individual teammates off doing their own thing.*

*This is where the idea of a game played at multiple levels of coordination might make sense, e.g. a Battlefield-style game where squads take orders from a small number of commanders responsible for the overall strategy.

6. You can’t make me play medic! I’ll do what I want!

For role-based gameplay (such as class-based and/or vehicle-based combat), games shouldn’t leave role selection up to the whims of each player.

DICE has not only gotten this consistently wrong, they’ve made getting it wrong into a principle: on the one hand, their mantra ‘rock, paper, scissors’ means that the game balance relies upon teammates competently covering the various roles, but their other mantra ‘player freedom’ means DICE is not willing to take any necessary measures to make ‘rock, paper, scissors’ actually work.

Now, how exactly role-selection should be handled is up for discussion because the simplest solution (first come, first pick) isn’t satisfactory. ‘Who should get to fly the jet?’ is a difficult question, but ‘the guy who happened to spawn next to it at the right time’ is not an acceptable answer. Likewise, ‘Who must play medic?’ is a difficult question, but ‘no one’ is not an acceptable answer.

7. Nobody tells me what to do! I’ll do what I want!

So I’ve already asserted that players must be forced sometimes to play roles they don’t want to, but they also must sometimes be forced to go places they don’t want and attack/defend targets they don’t want. Again, game balance simply requires it to keep each game competitive, so mechanisms must exist that strongly incentivize the player to actually follow orders.

So where would players get their orders? Three possibilities:

  1. issued automatically by AI
  2. issued by a teammate in a command role
  3. issued by vote of the team/squad

Having the AI issue orders is least likely to trigger social unrest. On the other hand, AI decisions could diminish the human element that makes multiplayer (potentially) interesting in the first place.

If elevating certain players to privileged positions is too fraught with drama, voting could work as an effective substitute. For example, in Battlefield, your squad could pick its target by a vote for which flag to capture/defend (with perhaps seniority used to break ties); members of the squad would only be capable of capturing/defending the elected flag, making the vote meaningful rather than something players can ignore.

8. Voice chat: the highest form of communication known to man.

If you’re like me, the speech center in your brain nearly shuts down when occupied with action. Even for people for whom this isn’t the case, voice communication is still not the ideal medium for coordinating team play: even with solid connections, good headsets, and proper audio level balance for all players, it can be difficult to parse everything said or correctly identify who said what (especially in a team of many players).

To make voice chat more effective, larger teams must be broken into squads of four to six players, and those squads must stick together.

To better supplement voice chat, more games should include coordination mechanisms like the placement indicators in Portal 2 co-op. Designers should study the common messages actual players use and integrate them into the game.

Games also must be careful to make sure communication channels of all kinds don’t devolve into spam. In several games, the ‘enemy spotted’ message quickly becomes meaningless because players constantly spam it with a hotkey. In other games, medics tune out calls for healing because the teammates are too often nowhere nearby to be healed and die before the medic can reach them.

9. Hats for sale! Someone stand on my head so I can get this achievement.

Every time new items get released for TF2, half the players sit around in spawn for the next week playing the trading meta-game rather than, you know, actually playing the game.

Players also get distracted by achievements and character advancement. If I’m trying to get my 1000′th headshot to get an achievement or gun upgrade, I’m not really playing for my team to win.

10. Hey, there’s this neat trick I read about online where if you jump on these boxes in this one exact spot and melee at the same time…

Some people like to join multiplayer games to deliberately Not Actually Play the Game. My favorite kind are the 10-year-olds who want to try the neat exploit they heard about from their friend’s cousin who knows a guy who did it once before. ‘Don’t shoot those barrels! If I stack them in the right way, I can reach that ledge and fall through the floor to…’ etc. etc.

Others join games to grief, and others just sit in spawn while they organize their hat collection.

Whatever their reason for not actually playing the game, these players must be gotten rid of quickly and without hassle lest they ruin the team balance. Amazingly, many games still don’t appreciate this. In fact, few games have figured out how to do vote kicks properly: rather than calling votes that expire, a vote to kick a player should persist indefinitely until a majority has voted to kick the same player.

11. We won! I guess we killed more (or died less) than they did.

In a good, satisfying match, players can tell a story of why and how they won or lost. Even if it’s as simple as ‘we got pinned down at this place’, it’s still better than just ‘the winning team killed more (or died less)’.

Teamwork is more than just the collective sum of our actions. If you and I are working together, that means we make some decisions together and/or at the very least observe each other’s major decisions. e.g. ‘we decided to take the underground passage to infiltrate the enemy base, and Ted decided to set up a sentry gun’. That is the beginning of a narrative, a story of what we did together.

In an incoherent team match, teammates don’t make decisions together, don’t observe each other’s major decisions, or perhaps just make and observe so many decisions that they all blur together into a meaningless mush.

In a great game, the winning-or-losing story of each match tends to be novel rather than the same old thing every single time. A team game with matches that lack any narratives to speak of simply can’t be great.

 

Why David Brooks is awful

5 Mar

Were it not for laziness, I’d have long ago articulated exactly what I hate about David Brooks. Fortunately, my laziness has payed off in the form of two recent Salon takedowns of his new book, which together hit the mark close enough that I needn’t bother. The first is PZ Meyers critiquing Brooks’s clutch cargo deployment of science factoids:

The technicalities don’t illuminate the story in any way, and the story undercuts the science. Ultimately, the neuroscience in the book feels a micrometer deep and a boring lifetime long, with the fiction[...]giving the impression that it’s built on a sample size of two, and both [samples] utterly imaginary.

The second is Alyssa Battistoni critiquing Brooks’s core message, that the solution to the problems of the world lie in everyone simply being more like our current stock of super-awesome elites:

Brooks is so enamored of his vision of a new economy, driven by American middle-class values and invariably described as “creative,” “diverse” and “innovative” (because who can argue with those?) that he can’t see that this seemingly bright future is already leaving millions behind. Indeed, his vision of the future world is literally just a variation on Richard Florida’s “creative class” economy in which cities around the world compete for global elites. Brooks gets that certain people — the Mark Zuckerbergs of the world — are the “sorts of people who become stars in an information economy and a hypercompetitive, purified meritocracy.” But although he acknowledges that it will be necessary to address “human capital inequalities” to give everyone a “chance to participate,” he doesn’t seem to understand that the meritocracy he champions is anything but purified. Instead, it’s the Organization Kids, with their elite educations and global connections, who have the advantage in a competition driven by “relationships” and “charisma,” which begins to sound suspiciously like the old boys’ network of yore.

 

 

I hate nature

23 Oct

Odds

4 Jul

Did Kristol ghostwrite Palin’s speech?:

The odds are against her pulling it off. But I wouldn’t bet against it.

That’s some shrewd betting strategy, betting on the outcome you yourself find least likely.