Very interesting video about the non-text-based programming environment subtext. You can go watch the video, I’ll still be here.
I had to have a quick go at a better version of the Java program that he is improving.
He uses:
enum Attack { Magic, Melee } int damage (Attack attack, bool surprise, int defense) { int power; switch (attack) { case Magic: power = 5; break; case Melee: power = 4; break; } int effectiveness = power * (surprise ? 3 : 2); switch (attack) { case Magic: if (effectiveness >= defense) return effectiveness - defense; return 0; case Melee: return (effectiveness / defense) * 2; } }
Which isn’t actually legal java but it’s close enough.
But how about:
enum Attack { MAGIC, MELEE } int damage (Attack attack, boolean surprise, int defense) { int m = (surprise ? 3 : 2); if (attack == Attack.MAGIC) { return Math.max(5 * m - defense, 0); } else { return ((4 * m) / defense) * 2; } }
Which reduces 21 lines to 9. It also gets rid of the main complaint – the “traffic jam” in the middle (but see Update, below).
Or even:
enum Attack { MAGIC, MELEE } int damage (Attack attack, boolean surprise, int defense) { int m = (surprise ? 3 : 2); return (attack == Attack.MAGIC ? Math.max(5 * m - defense, 0) : ((4 * m) / defense) * 2); }
Which is pretty cryptic but only 5 lines.
I think it was a very interesting video and I’m being a bit unfair harping on about this which is kind of irrelevant. But perhaps there’s a lesson in there about picking examples. Conclude what thou wilt.
Would love to have a go with the subtext application.
Update I sent my annoying little examples to Jonathan Edwards who is the creator of subtext. He made some good points in reply (and helped me remove a redundant assertion in my code):
Thanks for your comments. Your revision avoids duplicating the switch by duplicating the multiplication operation. Imagine that single multiplication being instead 10 lines of code. One could of course then push it into a separate method which is called twice, at the cost of separating that code from its uses, and passing as arguments all the dependencies of that code. These are all reasonable trade offs. I am trying to reduce the need to make such trade offs, and keep the code simpler and more compact.
For the books, here’s how I’d bypass the “traffic jam” (D code):
–FeepingCreature, D fanboy
A better version would be done by refactoring into MagicAttack and MeleeAttack classes both implementing the missing methods in the AbstractAttack or something along those lines. Better code is code that is easier to maintain bug free, not just fewer lines.
I like the basic idea of subtext though – it is truly ridiculous to think that the best way to produce maintainable code at a rapid rate is to sit and type it out (even in something like intellij idea where the generation of a line of code is reduced to minimal keystrokes seperated by control-space, control-shift-returns etc)
Additional classes might make sense when this is seen as part of a larger program, for sure. I was treating it as a toy example as in the video.
I actually tried to compress the code because the video explicitly talks about how the java code is “bigger” than the equivalent subtext while showing both screens at once.