Perhaps ugliness is inevitable. Though if you can write beautiful portions of code you should be able to get a mostly-beautiful big program by putting a lot of beautiful portions of code together, and then the only source of potential ugliness would be in how those pieces interact. (Which tends to be fairly beautiful in the purely functional world and in well-designed OOP architectures but good luck elsewhere, and good luck getting multi-language code to interact for every set of languages (such as Python to C without using Cython).)
But assuming that ugliness is still inevitable, I'd still rather work in a language/environment/culture where ugliness can be kept at bay as long as possible. If ugliness is simply a property of long programs, then obviously languages that let you write shorter programs should scale beauty better.
Adding to the small examples, I dipped my toe into Android development tonight while at the same time getting Clojure to run on it. Clojure let me do:
(defmulti handle-key (fn [key] [key]))
(let [f #(eval (symbol (str "KeyEvent/KEYCODE_" %)))]
(doseq [[k letter] (map list (range 10) (seq "PQWERTYUIO"))]
(defmethod handle-key [(f k)] [key] (st k))
(defmethod handle-key [(f letter)] [key] (st k))))
(defmethod handle-key :default [key] false) ; don't handle event
(Which may not even be the most idiomatic Clojure-way since I'm still reasonably new to that as well.)And the first-thought for how I would do that in Java:
private boolean handle_key(int key) {
switch(key) {
case KeyEvent.KEYCODE_0:
case KeyEvent.KEYCODE_P: return st(key); break;
case KeyEvent.KEYCODE_1:
case KeyEvent.KEYCODE_Q: return st(key); break;
case KeyEvent.KEYCODE_2:
case KeyEvent.KEYCODE_W: return st(key); break;
case KeyEvent.KEYCODE_3:
case KeyEvent.KEYCODE_E: return st(key); break;
case KeyEvent.KEYCODE_4:
case KeyEvent.KEYCODE_R: return st(key); break;
case KeyEvent.KEYCODE_5:
case KeyEvent.KEYCODE_T: return st(key); break;
case KeyEvent.KEYCODE_6:
case KeyEvent.KEYCODE_Y: return st(key); break;
case KeyEvent.KEYCODE_7:
case KeyEvent.KEYCODE_U: return st(key); break;
case KeyEvent.KEYCODE_8:
case KeyEvent.KEYCODE_I: return st(key); break;
case KeyEvent.KEYCODE_9:
case KeyEvent.KEYCODE_O: return st(key); break;
default: return false; break;
}
}
It's not immediately clear to me how I could make that Java code shorter, and it's not exactly very pretty. (Long switch statements rarely are in my opinion.) (After some thought, I suppose you could use Java's reflection capabilities.)