android
Boilerplate Code
I don’t feel particularly good about the following code:
Button increaseTip = (Button)findViewById(R.id.IncreaseTip);
That’s how you’re supposed to do it, though, I’m pretty sure. That’s how you’re supposed to get access from the objects from the XML-based declarative layout files.
I’m in favor of declarative programming, of making more of what programmers do “configuration” and less of it actual writing of code. I don’t feel comfortable having Rice’s theorem applying to my GUI design files. But if you’re going to do it, integrate it better.
The .xml files in res/layout/ are used to create an automatically-generated class, R.java, where you can get ID numbers for each of your widgets. You must then use those ID numbers to look up the widgets themselves, involving a very ugly cast, and a line of code where I say “Button” twice and “increaseTip” twice. It makes me want to use C-style #define’s to write a macro to say:
GRAB(Button, increaseTip)
But the clincher is, we shouldn’t need a macro here. We’re already automatically generating a Java file: R.java could have been generated in such a way as to contain real code:
public Button getIncreaseTip(Activity fromWhere) {
return (Button)fromWhere.findViewById(R.id.IncreaseTip);
}
This method would have been easy enough to generate, and it would make my programming easier. I would probably just write:
getIncreaseTip(this).setOnClickListener(new OnClickListener() {
...and not bother with a temporary at all. It would save me typing, it would save me repetition, opportunities to get it wrong, etc. Casts should be a warning flag you’re doing something wrong, not an everyday experience.
We’re already auto-generate code; we might as well auto-generate it to be convenient.
Now, if we had a good programming language here, we’d be able to do something like this:
onNamedButtonClick name action = do
(Button button) <- getNamedWidget name
setOnClick button action
setUpActivity = do
...
onNamedButtonClick ”increaseTip” $ do
updateNamedNumberField ”tip” $ show . (+1) . read
Or similar. Haskell bindings for the Android SDK? So tempting... But no.