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.