Feb 14

I Miss Emacs

I miss Emacs1. Emacs was awe­some and fun and every­thing that I ever need­ed in an editor–at least that is what I thought.

For those who don’t know, Emacs is an edi­tor that is writ­ten in a form of Lisp called eLisp (it’s close enough to just con­sid­er it Lisp) which has been enhanced to include text manip­u­la­tion prim­i­tives. There is a Lisp engine that is writ­ten in C, but except for the text prim­i­tives every­thing else is writ­ten in Lisp. And I mean every­thing. This makes it extreme­ly easy to con­fig­ure and mod­i­fy to make it real­ly yours.

I spent years using Emacs and devel­oped a large body of cus­tomiza­tion and pack­ages to sup­port my work. I once worked for a guy who lit­er­al­ly did not need code to be for­mat­ted to read it so he would cram as much as he could onto the screen with­out any con­sid­er­a­tion for mod­ern ideas of read­abil­i­ty. I on the oth­er hand could not read this jum­ble of char­ac­ters. It was so bad that the code for­mat­ters that exist­ed could not han­dle his code, so I wrote a com­plex Emacs macro that would parse the file (this was C code) and refor­mat it to some­thing that the for­mat­ters could han­dle. To make him hap­py I also wrote the con­verse which would mash the code back into its com­pressed form (hey he was the boss).

There is no way I could do this with most of today’s edi­tors. On the oth­er hand, Emacs has not been able to keep up with the progress of most IDEs. Large scale refac­tor­ing is not real­ly pos­si­ble with Emacs. There are pack­ages to do some sim­ple refac­tor­ing but they are lim­it­ed. So gave up some years ago and moved to and IDE (at the time it was Eclipse but I’ve moved on to IntelliJ IDEA and friends). With all of the code com­pre­hen­sion tools built in to it I just can­not be as pro­duc­tive while using Emacs (or any straight edi­tor) any more.

But I still miss being able to look at a prob­lem and say “I can write a macro for that.” There is some­thing mag­i­cal about know­ing that you can bend the tool to your will rather that hav­ing to bend to its design. And you haven’t lived until you work with an edi­tor that some­one said “you know, this is Turing com­plete so I think I’ll add a new mode that sup­ports Vi inside of Emacs2.” One edi­tor inside of anoth­er just using the macro language–that is pow­er.

I still fire it up some­time when I need to work on a few files from the com­mand line and Vi/​Vim is not enough and I feel a bit of nos­tal­gia when my fin­gers auto­mat­i­cal­ly fall into famil­iar pat­ters: Ctrl‑S (incre­men­tal search), C‑X,C‑S (file save), Ctrl‑K (kill), Ctrl‑Y (yank), and all of the oth­er eso­teric key­strokes. Even after all of these years they are ingrained in my mus­cle memory–unfortunately, the mod­i­fi­er keys have moved around which slows me down. Why do we need a gigan­tic Caps lock but­ton in one of the prime loca­tions on the key­board? Seriously, do peo­ple real­ly need the Caps lock key?

I love IntelliJ and will have a hard time chang­ing if some­thing bet­ter man­ages to be cre­at­ed but it’s just not as fun as Emacs. Need to do a sequence of steps mul­ti­ple times? Just record it as a tem­po­rary macro and exe­cute it as often as nec­es­sary. Need to keep it? Just save it. Need to make it more robust, con­vert it to a code macro and edit it. And do this mul­ti­ple times a day because it is so easy.

I will always have a spe­cial place in my heart for Emacs.

Jan 28

Java Needs Properties

OK, this is get­ting ridicu­lous. It’s been, what, 25 years since Java start­ed and we still haven’t fixed one of the sin­gle biggest pain-​points for the language—properties. I mean, just look at this mess:

The amount of boil­er­plate is huge and that’s with­out con­sid­er­ing oth­er boil­er­plate meth­ods like equals():

Ugh, I hate typ­ing all of that. If the object is a bean/​POJO then we can use gen­er­a­tors to help write some of the code at the expense of some weird code: strange inher­i­tance, abstract objects, anno­ta­tions, etc.

Now with prop­er­ties and some com­pil­er mag­ic we could have the same behav­ior that looks more like this:

And this would inter­nal­ly gen­er­ate the sec­ond exam­ple above. If you don’t like adding new key­words we could do it almost as ele­gant­ly with anno­ta­tions:

This could eas­i­ly be extend­ed to sup­port read-​only prop­er­ties as well as over­rid­ing the getter/​setter. Overriding the set­ter is need­ed to val­i­date the val­ue.

This would inter­nal­ly gen­er­ate the equiv­a­lent of this:

Note the assert in the con­struc­tor in the gen­er­at­ed ver­sion. This was added by the @NotNull anno­ta­tion. If the code gen­er­a­tor can guar­an­tee that name is set before the end of the con­struc­tor the it can elide the assert().

Anyway, there is a lot more that can be done. A prop­er­ty could be marked as part of the objec­t’s order­ing and then it would be added to a gen­er­at­ed compareTo() method. The basic idea is to remove the boil­er­plate and to force con­sis­ten­cy in code between pro­gram­mers.

Jul 23

Java Complexity

Java as a lan­guage is get­ting more com­plex with each ver­sion. From ver­sion 1.0 to 1.4 most of the com­plex­i­ty was added through libraries. Thousands or lines of code were added in hun­dreds of new class­es. But this com­plex­i­ty was contained–if you did­n’t need a fea­ture you could ignore it com­plete­ly. At worst, you might miss out on some new, neat fea­ture. But start­ing with 1.5 the lan­guage itself changed (OK 1.4 added asser­tions but that’s a very small fea­ture that can be read­i­ly ignored).

Version 1.5 added enums and Generics. Enums are a medium-​sized change, main­ly a way of list­ing enu­mer­a­tion val­ues, but there are sub­tleties that make them com­plex (like con­ver­sion to/​from inte­gers, access­ing all the defined val­ues, etc.) Generics are a big change. The fact that all the col­lec­tion class­es were retro­fit­ted to be gener­i­cized1 means that most new code will have to deal with them whether they want to or not. Trying to ignore them just results in streams of warn­ings.

Now with 1.7 or maybe 1.8 we are talk­ing about adding clo­sures and pos­si­bly con­tin­u­a­tions and prop­er­ties. If you think that code with gener­ics is hard to read then just wait for clo­sures. The sub­tleties of where a braces goes to decide if a clo­sure is being defined is guar­an­teed to cre­ate uncer­tain­ty and con­fu­sion.

My ques­tion is “are we adding too much com­plex­i­ty?” The thou­sands of lines writ­ten for the libraries before 1.5 are extreme­ly use­ful and in fact are still used after 1.5 so gener­ics, enums, and clo­sures are not nec­es­sary for use­ful code. So why do we see the need to add this com­plex­i­ty?

When I start­ed using Java I thought it was a nice sim­ple lan­guage for writ­ing web tools but that it was­n’t a “real” lan­guage for use in “real” work. But then I start­ed using it for a real project and I real­ized that it might be a sim­ple lan­guage, but it could do what I need­ed. Granted pre‑1.2 things were a lit­tle coarse but by the time 1.2 came out things real­ly start­ed to smooth out. Then as I used it more I kept think­ing “this is a bor­ing lan­guage; it has no fun fea­tures.” Years lat­er, as I have got­ten old­er, I have begun to recon­sid­er my eval­u­a­tion. Yes, Java is a rather sim­ple lan­guage, but that may be a good thing.

I like func­tion­al lan­guage as I think that func­tion com­po­si­tion is a very pow­er­ful fea­ture that results is small­er code bases. But when I look at what’s com­ing in future releas­es I start to wor­ry. Here where I work we have devel­op­ers of dif­fer­ing lev­els and I have seen them have prob­lems with even the sim­ple things in 1.4. Complex fea­ture like Generics are going to make it hard to keep every­one up to the nec­es­sary lev­el of com­pe­tence.

Even though I was one of those clam­or­ing for Generics I am now not so sure that they should have been added to the lan­guage. I con­sid­er myself a senior devel­op­er and while I am now com­fort­able, but not an expert, with using gener­ics it is such a big change that I would say that Java 1.5 is actu­al­ly a new lan­guage. As a senior devel­op­er I have no prob­lem learn­ing new lan­guages and in fact I learn new ones for fun. But think of the junior and even mid-​level devel­op­ers. May of them are still try­ing to get a han­dle on the base lan­guage.

  1. I know this isn’t a real word yet, but it is becom­ing preva­lent in the busi­ness and it seems to be the right word for this sit­u­a­tion. 
Jul 17

Java Generics III

Last time I talked about using gener­ics to make get­ting val­ues out of col­lec­tions nicer (and a pro­pos­al that would obvi­ate their use) so this time I want to talk about the oth­er half–passing items into a col­lec­tion. This encom­pass­es all meth­ods that take a para­me­ter of the col­lec­tion’s gener­ic typ­ing includ­ing those that add items to the col­lec­tion.

If you look at the byte-​codes gen­er­at­ed for call­ing any of these meth­ods you will see that there is no run­time check­ing of the objects being passed. This is because the meth­ods of the base object are defined as tak­ing Object types. The only check­ing hap­pens at com­pile time. So as long as the sta­t­ic type is cor­rect every­thing is fine but it is easy to over­ride the sta­t­ic type (acci­den­tal­ly or on pur­pose) so what hap­pens? Well, if you attempt to retrieve a val­ue from the col­lec­tion and the type is not assign­ment com­pat­i­ble with the tar­get then you will get a ClassCastException.

Let’s think about that for a moment. The excep­tion is not thrown when the invalid val­ue is added to the col­lec­tion (when track­ing down the error would have the con­text of the sit­u­a­tion) but when it is removed (or exam­ined). This defeats the basic rule of “fail as ear­ly as pos­si­ble”. It also means that a state­ment with no cast oper­a­tor can fail with a class cast excep­tion. This seems counter to the spir­it of the lan­guage and in fact leads to con­fu­sion. You look at the line that the stack trace points to and say to your­self “there is noth­ing there that can throw a class cast excep­tion.” After a this hits you a time or two you will remem­ber but why should you have to make that effort?

I will grant that the gener­ic def­i­n­i­tion does make it hard­er to acci­den­tal­ly put in the wrong thing, but it does­n’t elim­i­nate it entire­ly. If we are going to have a checkcast byte-​code on retriev­ing the val­ue then why don’t we have it on putting the val­ue in as well?

Jul 13

Java Generics II

In Part I I showed how gener­ics have no effect on the byte-​codes gen­er­at­ed by the com­pil­er and that as far as the get­ters of the col­lec­tion class­es the only tan­gi­ble ben­e­fit is that you no longer have to add casts to the get expres­sion. So some­thing like this:

becomes this:

Now don’t get me wrong, I think that this is a good thing. As far as I’m con­cerned, casts are just wast­ed typ­ing that is only for the com­pil­er. So get­ting rid of casts is great. But the prob­lem is that to get this fea­ture you have use an even ugli­er syn­tax (gener­ics) in oth­er places. So the method this line is in might look like this:

Now I will grant you that the casts were in the body which obfus­cates the code you’re try­ing to read but now are in the func­tion def­i­n­i­tion and that if you are using the val­ues more than once you’ve trad­ed _​N_​casts for 1 def­i­n­i­tion. But the flip side of this is that you have now moved an imple­men­ta­tion detail into the pub­lic inter­face. In the old style this method would have said “I take a Map and do some­thing with it” but the new one says “I take a Map of String to String and do some­thing with it.” More on this in a lat­er post.

So I have an idea for a pro­posed lan­guage change that I wish I could have made (and got­ten imple­ment­ed 😉 years ago. It is a sim­ple change but I think it would have made a major pos­i­tive change to the lan­guage.

Why not remove the need for casts for down cast­ing?

If you take the basic assign­ment

The types X and Y are relat­ed in one of four ways (assum­ing nei­ther is a prim­i­tive):

  1. X and Y are the same type.
  2. X is not direct­ly relat­ed to Y.
  3. X is a super­class or inter­face of Y (upcast­ing).
  4. X is a sub­class of Y (down­cast­ing).

In case #1 no cast is nec­es­sary. In case #2 the state­ment is invalid and adding a cast will not change that. In case #3 no cast is nec­es­sary. In case #4 a cast is need­ed to com­pile and a checkcast byte-​code is gen­er­at­ed to val­i­date the assign­ment at run­time. If you look at the casts it turns out that down cast­ing is the only one that we can change and it accounts for most of the casts in a pre-​generics pro­gram.

The inter­est­ing thing about the down­cast case is that the com­pil­er checks to see if a cast could work (are the types relat­ed) but it still emits the checkcast byte-​code. So my ques­tion is if the com­pil­er already checks the assign­ment is valid and gen­er­ates a checkcast byte-​code any­way why can’t we just tell the com­pil­er “if you see a valid down­cast, just emit a checkcast byte-​code with­out requir­ing the cast”?.

To make this con­crete I want to change this

into this:

If the com­pil­er allowed this the sys­tem would be no less safe as the checkcast byte-​code would still be emit­ted to check at run­time but the code is clean­er. As far as I can tell the only rea­son the cast is required (here I’m putting on my Mind Reading Through Time Helmet) is that some­one said some­thing like “If we tell the pro­gram­mer that they are down­cast­ing and that this is a dicey oper­a­tion they will check their code to ver­i­fy that this down­cast is valid at this point and then add a cast to tell the com­pil­er that they val­i­dat­ed the code.” This sounds good but let’s be hon­est, do you real­ly check your code to ver­i­fy the cast in all cas­es or do you most­ly just add the cast because the com­pil­er wants it?

I thought so. But even if you check your code now there is no way to pre­vent a change lat­er doing the wrong thing or if you take a para­me­ter there is no way to pre­vent some­one else from mess­ing you up. This is why the com­pil­er emits the checkcast byte-​code even though you added a cast. It is too easy make mis­takes.

So giv­en that most of the time the cast is just added to shut up the com­pil­er and that the sys­tem still adds a byte-​code to pre­vent mis­takes why not just get rid of the cast require­ment? Just think how sim­ple the col­lec­tion class­es would be to use. They already do not need a cast to put object in and with this change they would not need a cast to get the val­ue out and the gen­er­at­ed code would be iden­ti­cal to the code cur­rent­ly gen­er­at­ed (see Part I).

Casts are intru­sive, ugly, unnec­es­sary for under­stand­ing the code, require dupli­cate typ­ing

and do not make the code any safer. If this change had been made to the lan­guage in any ver­sion before 1.5 I believe that there would have been a lot less demand for Generics.