Showing posts with label java. Show all posts
Showing posts with label java. Show all posts

Wednesday, September 28, 2011

The Perfect Android

Yesterday Android developer advocate Reto Meier asked about what developers loved/hated about application frameworks. It got me thinking about if I could change anything about Android development, what would it be? I mentioned some of these things in my comment on Reto's post, but I'll go into a little more detail here.

Less XML. There are a lot of places where XML is really unnecessary in Android. Top among those things is having to declare Activities, and to a lesser degree Services and BroadcastReceivers. I don't know about your code, but the vast majority of the Activity declarations that I've ever made simply stated the class and maybe some options about config changes and screen orientation. Does this have to be in the manifest XML? I'd prefer to not have to declare Activities in XML and still be able to navigate to them without my app crashing. I'd also like to be able to handle most of their options in Java. This could be as annotations, or maybe some kind of getConfiguration() method that you override, or maybe just as APIs to invoke during onCreate. I think I could live with any of those things. Now if you need to do something more complicated like put an IntentFilter, then that can be in XML. In fact I'm OK with XML always being allowed, just optional for the simpler cases that make up the majority of the Activities that developers write. You could apply similar logic to Services. If you have a Service that you only communicate with by binding to it and it runs in the same process as your main application, then it seems like you should not need any XML for it.

Functional programming. If you've read my blog for very long then this is probably no surprise. This probably requires closures to come to Java, but it seems like we are pretty close to that happening. I think that once that syntax is settled on, then Android should not only get this language feature, but the app framework should be dramatically upgraded to take advantage of it. Technically some of this can be smoothed over by the compiler allowing closures to substitute for single-method interfaces. I'd rather be more explicit about it. And by the way, I don't see why Android should have to wait for Java 8 to be finished by Oracle. Android needs to maintain language and bytecode compatibility, but that doesn't mean it has to use somebody else's javac...

No more Parcelables. Yeah I know that Parcelables are a faster serialization/deserializtion solution. Cool. In most cases this requires a developer to write a lot of mindless code. On one hand tooling can help with this, but why not just have the compiler handle it? Then we could get rid of Parcelable. If a class implements good 'ol Serializable, then the compiler could easily generate the Parcelable code that tooling could generate, but that is currently generated by annoyed developers. Of course it's cool to let developers override this if they want to do something clever. If a class has fields that are Serializable, then the compiler could generate a warning or even an error.

MVC. Now this one is a lot more controversial for me. I'm not a big believer in MVC, so I've always liked that Android wasn't either. However I think that a lot of developers would have an easier time if Android followed a more pure MVC pattern. I think that's one of the ways that Cocoa Touch is easier for new developers to pick up. I've had more than one new developer ask me if an Activity was Android's version of a controller. It is not. But maybe it should be? There's room for things beyond MVC as well. With ICS, Fragments should become the norm for app developers. Developers will have to decide for themselves about the best way to coordinate and communicate fragment-to-fragment, fragment-to-activity, etc. Direct method invocation? Shared memory? Message/handlers? Event listeners? Too many choices and too many choices makes life especially difficult for newbie programmers. Provide a "standard" mechanism, while not ruling out the other choices so more experienced developers can still do things the way that they think is best. The same issue exists for activity-to-activity communication.

Better memory management. I'd love to have gobs of RAM and an amazing GC. In the absence of those just do me some favors like make sure all my soft/weak references are GC'd before an OOM. Always fire Application.onLowMemory before an OOM, and give me 20ms to react and prevent the OOM. Kill all non-visible/foreground processes and re-allocate their memory before an OOM. An OOM is a crash and is the worst possible thing for users. I know lots of snooty engineers will look down their nose and say "your app needs to use less memory", but that kind of attitude makes Android seem like a ghetto to end users.

No more sync. This is one of those features in Android that sounds great on paper but is more trouble than it is worth at this point. By adding your app to sync, you let the system schedule a time for your app to synchronize with your server. Sounds great. However your app won't be the only one getting busy at that time, that's part of the point of sync. Worst of all if the user decides to launch some other app when the sync is in progress then that app has a good chance of being hosed. Tons of CPU & I/O will be hogged by the sync and that app will be sluggish to say the least and may even crash. All of this because of sync. What's more is that there is no real need for sync anymore. With C2DM, a server can send an event to the phone to let your app know that it needs to sync state with the server. Your server can decide how often this needs to happen and can make sure there are no unnecessary syncs.

Friday, July 22, 2011

Android JSON Bug

Today I was working on some code that needed to invoke a JavaScript function on a web page that was being displayed in a WebView within an Android application. As part of that function invocation a JSON object is passed in. It's actually a pretty complex JSON object. Of course it must be passed in simply as a string and then parsed by the JavaScript to an object. Android includes the JSON "reference implementation", so naturally I wanted to use this instead of relying on some 3rd party JSON library that would fatten up my APK. The standard way to do this with the reference implementation is to create an instance of org.json.JSONObject and use its toString method. You can create an empty instance and programmatically build up a JSON data structure, or you can give it a Java Map to build from. I chose to go the latter route.
When my web page choked, I wasn't too surprised. I'm never surprised when code I write has bugs initially. I added a log statement to show the data being passed in and was surprised to see that it looked like this:
{"a": "{b={c=d}}", "e":"f"}
This was not correct. This should have looked like this:
{"a": "{"b":"{"c":"d"}"}", "e":"f"}
To create the JSONObject that I was passing in, I passed it in a HashMap whose keys were all strings but whose values were either strings or another HashMap. So to create the above structure there would be code like this:
HashMap<String,Object> top = new HashMap<String,Object>();
HashMap<String,Object> a = new HashMap<String,Object>();
HashMap<String,Object> b = new HashMap<String,Object>();
b.put("c", "d");
a.put("b", b);
a.put("e", "f");
top.put("a",a);
It seemed that the JSONObject code was flattening out my objects and producing incorrect JSON (WTF equal signs!) as a result. I put together a quick workaround to recursively replace any HashMap values with JSONObjects like this:
JSONObject jsonIfy(HashMap<String,Object> map){
	HashMap<String,Object> fixed = new HashMap<String,Object>();
	for (String key : map.keySet()){
		Object value = map.get(key);
		if (value instanceof Map){
			value = jsonIfy((HashMap<String,Object>) value);
		}
		fixed.put(key,value);
	}
	return new JSONObject(fixed);
}
This worked perfectly.

Wednesday, January 20, 2010

JVMOne

This morning, my co-worker Jason Swartz had the great idea of a conference focussing on JVM languages. This seemed like a particularly good idea, given the uncertainty surrounding JavaOne. Personally, I think the JavaOne powers-that-be have done a good job showcasing other languages, especially the last two years. Anyways, I joked that we could probably host it at our north campus, since it has proper facilities and regularly hosts medium sized conferences,  and that we just needed the support of folks from the Groovy, JRuby, Scala, and Clojure communities. A lot of folks seemed to like the idea, and had some great feedback/questions. So let me phrase some of these questions in the context of "a JavaOne-ish replacement, focussing on alternative languages on the JVM, but ultimately driven by the community". Ok here are some of the questions.

1.) What about Java?
2.) What about languages other than Groovy, JRuby, Scala, and Clojure?
3.) What about first class technologies with their roots in Java, like Hadoop, Cassandra, etc.?

Certainly I have opinions on some of these, but obviously any kind of effort like this requires huge participation from the developer community. So what do you think? What other questions need to be asked? If there is enough interest, I will definitely try to organize it. So please leave comments below!

Monday, January 18, 2010

Strikethrough Android

There are a lot of people working on mobile applications these days. Some of them are experienced mobile developers. Maybe they were doing J2ME or Brew apps in the past, and now they are probably happy to be doing iPhone or Android development. However, I would wager that a majority of current iPhone and Android developers were not doing mobile a few years ago. Maybe they were doing desktop development, or maybe they were doing web development. For these folks, it can be very surprising how tricky it is to do some (seemingly) simple things. Case in point, strikethrough text.

If you ever need to do this in Android, here is how you do it, or at least a relatively simple way I found to do it. If you just search the Android documentation, you will find this reference page. As you can see for static text, it really is quite simple. It is very similar to doing it in HTML.
<resource>
    <string id="@+id/strike_one"><strike>Strike one!</strike></string>
</resources>
Nice! Android rocks! But what if your text is dynamic? Well if you keep reading the documentation referenced above, you get into the world of Spannable. This sounds good at first, because it sounds like it's again inspired from HTML. If you look at the sample, it is not so simple. Still, it's not too hard, maybe just a little awkward. But wait, there's more. The class most commonly used for text, TextView, is not a Spannable. Instead, you must use an EditText, which is a subclass of TextView. This is a class that you would not normally use for normal text on the screen, instead you would use it for a text input field.
Turns out there is an easy way to strikethrough a TextView after all. Well easy, if you don't mind use some bit twiddling:
TextView someLabel = (TextView) findViewById(R.id.some_label);
someLabel.setText(someDynamicString);
someLabel.setPaintFlags(someLabel.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
What is going on here? For painting text, there are several bit flags for doing things like bold, italics, and yes strikethrough. So to enable the strikethrough, you need to flip the bit that corresponds to this flag. The easiest way to do this is to use a bitwise-or on the current flags and a constant that corresponds to a set of flags with only the strikethrough flag enabled. For any other bit flags that are already set, this will have no effect. Actually if the strikethrough flag happened to be already set, this will have no effect. However, if it is not set, then it will flip it, so that it will be set and thus add a nice strikethrough effect.

Saturday, November 21, 2009

Passing on the Duby




Last week I had a fun conversation with Charles Nutter. It was about "java.next" and in particular, Charlie's requirements for a true replacement for Java. He stated his requirements slightly before that conversation, so let me recap:

1.) Pluggable compiler
2.) No runtime library
3.) Statically typed, but with inference
4.) Clean syntax
5.) Closures

I love this list. It is a short list, but just imagine if Java 7 was even close to this. Anyways, while I like the list as a whole, I strongly objected to #2 -- No runtime library. Now, I can certainly understand Charlie's objection to a runtime library. It is a lot of baggage to drag around. All of the JVM langs have this issue. JRuby for example, has an 8 MB jar. Groovy has a 4 MB jar. Clojure has two jars totaling 4.5 MB. Scala is also around 4 MB. These become a real issue if you want to use any of these languages for something like Android development. I've written about this issue as well.

However, there is a major problem with this requirement. The building blocks of any programming language includes primitives and built-in types. Those built-in types are part of the runtime library of the language. So if your JVM based language cannot have a runtime library, then you will have to make do with primitives and Java's built-in types. Why is this so bad? Java's types (mostly) make sense in the context of Java, its design principles and syntax. I don't think they would make sense in the java.next hypothetical language described above. The easiest example of this are collection classes. Don't you want a list that can make use of closures (#5 requirement above) for things like map, reduce, filter, etc. ? Similarly, if you static typing, you probably have generics, and wouldn't you like some of your collections to be covariant? You can go even further and start talking immutability and persistent data structures, and all of the benefits these things bring to concurrent programming. This is just collections (though obviously collections are quite fundamental to any language,) but similar arguments apply to things like IO, threading, XML processing, even graphics (I'd like my buttons to work with closures for event handling thank you very much.)

One argument against this is that you can just include the runtime library of your choice. Pick your own list, hash map, thread pool, and file handler implementations. This is what I'd like to call the C++ solution -- only worse. At least in C++ you can generally count on the STL being available. The thing that is so bad about this is that it really limits the higher-order libraries that can be built. Java, Ruby, and Python all have a plethora of higher order libraries that have been built and widely used. These libraries make extensive use of the built-in types of those languages. Imagine building ORMs like Hibernate or ActiveRecord if you did not have built-in types (especially collection classes) that were consistent with the language. You could not do it. If all you could rely on was the Java built-in types, then at best your libraries would have a very Java-ish feel to them, and doesn't that defeat the purpose?

Charlie gave an alternative to this -- leverage the compiler plugins. Now it is certainly true that with a pluggable compiler, you could do this like add a map method to the java.util.List interface, and all of the JDK classes that implement this interface. It can be done. However, if you are going to build higher order libraries on top of this language, then you need to be able to count on these enhancements being present. In other words, the compiler plugin needs to be a required part of the compiler. Fine. Now what is it that we were trying to avoid? Extra runtime baggage, right? Well if you have a compiler that is going to enhance a large number of the classes in the JDK, hello baggage. Maybe it won't be as much baggage as 4 MB runtime library, but it might not be a lot less either. Also, it raises the potential problem of interoperability with existing Java libraries. If I import a Hibernate jar that gives me a java.util.List, that list is not going to be enhanced by my compiler -- because it wasn't compiled with my javac.next, it was compiled with javac.old. What's going to happen here?

Now there is an obvious happy way to deal with the runtime library question: rt.jar. If java.next was Java, and the super revamped collections, IO, threading, etc. classes were part of the JDK, then there is no need for a runtime library since now it has been included with the JDK. However, given the incredibly uncertain state of Java 7, not to mention the long term prospects of Java, does this seem remotely possible to anyone? I don't think so. I think the heir apparent to Java cannot be Java, and I think because of that, it's gotta have a runtime library of its own.

Thursday, October 22, 2009

Concurrency Patterns: Java, Scala, and Clojure

Today I was at The Strange Loop conference. The first talk I attended was by Dean Wampler on functional programming in Ruby. Dean brought up the Actor concurrency model and how it could be done in Ruby. Of course I am quite familiar with this model in Scala, though it is copied from Erlang (which copied it from some other source I'm sure.) The next talk I went to was on software transactional memory and how it is implemented in Clojure. I had read about Clojure's STM in Stuart Halloway's book, but I must admit that it didn't completely sink in at the time. I only understood the basic idea (it's like a database transaction, but with retries instead of rollbacks!) and the syntax. As I've become more comfortable with Clojure in general, the idea has made more and more sense to me.

Now of course, no one size fits all. There are advantages and drawbacks to any concurrency model. A picture of these pros and cons kind of formed in my head today during the STM talk. I turned them into pictures. Here is the first one:

This is meant to be a measure of how easy it is to write correct concurrent code in Java, Scala, and Clojure. It is also meant to measure how easy it is to undersand somebody else's code. I think these two things are highly correlated. I chose to use these various languages, though obviously this is somewhat unfair. It wold be more accurate to say "locking/semaphores" instead of Java, the Actor model of Scala, and software transactional memory instead of Clojure -- but you get the point. So what does this graph mean?
Well obviously, I think Java is the most difficult language to write correct code. What may be surprising to some people is that I think Clojure is only a little simpler. To write correct code in Clojure, you have to figure out what things need to be protected by a dosync macro, and make sure those things are declared as refs. I think that would be an easy thing to screw up. It's still easier than Java, where you have to basically figure out the same things, but you must also worry about multiple lock objects, lock sequencing, etc. In Clojure you have to figure out what has to be protected, but you don't have to figure out how to protect it -- the language features take care of that.
So Clojure and Java are similar in difficulty, but what about Scala and the Actor model? I think this is much easier to understand. There are no locks/transactions. The only hard part is making sure that you don't send the same mutable object to different actors. This is somewhat similar to figuring what to protect in Clojure, but it's simpler. You usually use immutable case classes for the messages sent between actors, but these are used all over the place in Scala. It's not some special language feature that is only used for concurrency. Ok, enough about easy to write/understand code, there are other important factors, such as efficiency:

Perhaps this should really be described as memory efficiency. In this case Java and the locking model is the most efficient. There is only copy of anything in such a system, as that master copy is always appropriately protected by locks. Scala, on the other hand, is far less efficient. If you send around messages between actors, they need to be immutable, which means a lot of copies of data. Clojure does some clever things around copies of data, making it more efficient than Scala. Some of this is lost by the overhead of STM, but it still has a definite advantage over Scala. Like in many systems, there is a tradeoff between memory and speed:

Scala is the clear king of speed. Actors are more lightweight than threads, and a shared nothing approach means no locking, so concurrency can be maximized. The Java vs. Clojure speed is not as clear. Under high write contention, Clojure is definitely slower than Java. The more concurrency there is, the more retries that are going on. However, there is no locking and this really makes a big deal if there are a lot more reads than writes, which is a common characteristic of concurrent systems. So I could definitely imagine scenarios where the higher concurrency of Clojure makes it faster than Java. Finally, let's look at reusability.

By reusability, I mean is how reusable (composable) is a piece of concurrent code that you write with each of these languages/paradigms? In the case of Java, it is almost never reusable unless it is completely encapsulated. In other words, if your component/system has any state that it will share with another component, then it will not be reusable. You will have to manually reorder locks, extend synchronization blocks, etc. Clojure is the clear winner in this arena. The absence of locks and automatic optimistic locking really shine here. Scala is a mixed bag. On one hand, the Actor model is very reusable. Any new component can just send the Actor a message. Of course you don't know if it will respond to the message or not, and that is a problem. The bigger problem is the lack of atomicity. If one Actor needs to send messages to two other Actors, there are no easy ways to guarantee correctness.
Back in June, I heard Martin Odersky says that he wants to add STM to Scala. I really think that this will be interesting. While I don't think STM is always the right solution, I think the bigger obstacle for adoption (on the Java platform) is the Clojure language itself. It's a big leap to ask people to give up on objects, and that is exactly what Clojure requires you to do. I think a Scala STM could be very attractive...

Sunday, October 18, 2009

The IntelliJ IDEA Bomb

In case you missed the announcement from JetBrains yesterday, the popular IntelliJ IDEA has gone free and open source. Sort of. There is now a community edition, that is FOSS, and an enterprise edition that you must pay for. Why is this a big deal? Read on.

IntelliJ really revolutionized Java development. It wasn't the first IDE to allow for code completion, or even the first Java IDE to do this. However, it was definitely a pioneer in code refactoring. And this was huge. It took many of the code improvement ideas catalogued by Martin Fowler, and turned them into simple commands that any programmer could use. This also allowed for things like code navigation, where you could go from the usage of a class or a method to the implementation (or at least the declaration, if the usage only referred to the interface.) This was only the beginning. IntelliJ was a pioneer of bringing in the Java ecosystem. I remember how much easier IntelliJ made it to use Struts, for example.

This reminds me of my own personal use of IntelliJ over the years. When I first started working in enterprise Java development, I was working for a startup that built EJB applications targeted for WebLogic and WebSphere. For WebSphere, we used Visual Age for Java. For WebLogic, we just used Kawa (a bare bones editor.) I hated Visual Age with a passion. It scarred me badly. For years afterwards, I stuck to simple text editors.

Several year later (2003), I joined a fresh startup, KeepMedia (later renamed to MyWire). Prior to KeepMedia, I had a short stint with a .NET startup, Iteration Software (later renamed to Istante, and sold to Oracle.) There I used Visual Studio quite a bit, and appreciated the productivity gains it provided. So at KeepMedia, I took a look at various Java IDEs: JBuilder, JDeveloper, and IntelliJ. I was one of three programmers at KeepMedia, and one of my colleagues was really in love with Struts. He worked on the front of KeepMedia, but I worked mostly on our back end system that integrated magazine content from publishers. I didn't have to use Struts for that obviously, but I did occasionally help with the front end (we had three programmers after all.) I hated Struts, but IntelliJ made it more tolerable. The only negative about it was that it was flaky on Linux, but pretty much everything was flaky on Linux back then.

After I worked at KeepMedia, I worked at a consulting company, LavaStorm Engineering (2004). I had been using IntelliJ for a long time, and was convinced that everything else was crap. One of my colleagues introduced me to Eclipse. I was horrified. Most of Eclipse's codebase came from an all-Java rewrite of Visual Age (the version I had used was written in Smalltalk.) So even though it shared no code with the beast that I had hated, it shared a lot of the look-and-feel. For example, take a look at the outline view in Eclipse (any version, even the most recent.) This was completely taken from Visual Age. Even the icons are exactly the same. There was no way I was going to give up my IntelliJ for that thing...

A couple of years later, I was at another startup, Sharefare (which later changed its name to Ludi Labs.) Being a startup, there was no standardization arounds tools. However, everyone used Eclipse. I had warmed up to Eclipse (though I still preferred IntelliJ), and I had started writing Eclipse related articles for IBM. So I went with Eclipse there, as there were advantages to everyone using the same IDE (being able to share .project/.classpath, plugins, etc.)

After Ludi Labs went down in early 2007, I joined eBay. To say we're a major Eclipse shop, would be putting it mildly...
We're not the only major Java shop that has invested heavily in Eclipse plugins. If you're doing GWT, App Engine, or Android development, then you're probably using Eclipse too. I know I am. I didn't really start using IntelliJ again, until the past year. The reason was simple: Scala. It is the best IDE for doing Scala development currently. Actually IntelliJ's Scala offering vs. the competition, is similar to anything else. It's not that it necessarily has a lot more features, but it has similar and most importantly, it is of higher quality. Here's a great visualization of this key difference:

This is why the open sourcing of IntelliJ is important. It's not that we didn't already have great open source IDEs for Java. No, it's more about what does this mean for IntelliJ. Will the attention to detail go down hill? Will the stable plugin ecosystem be disrupted?

Of course, for most current and would-be users of IntelliJ, the availability of a free IntelliJ is really not big news. The free version is really quite limited. You're not going to build web apps, or apps that connect to databases, use web services, etc. Not with the community version, unless in-the-wild plugins became available that enable this. IntelliJ has awesome support for all of these things, but those parts of IntelliJ remain behind a price wall.

There is one notable exception here: Scala. Right now, IntelliJ has the best Scala support. It has more features and less bugs than NetBeans, and it is much more stable than Eclipse. Scala support is one of the features supported in the community edition. That means a lot of newbie Scala developers can just use IntelliJ. This is great news. I would not give NetBeans or Eclipse to Scala newbies, for the simple reason that both of them report syntax errors inconsistently. In other words, both are guilty of either not identifying an error, or identifying a false error (or both.) That's anathema for somebody learning a language. I'm able to put up with it, simply because I know just enough Scala to say "you're wrong IDE" at times. I've rarely seen this happen with IntelliJ.

Saturday, August 15, 2009

A Tipping Point for Scala

This past week's BASE meeting was all about IDE support for Scala. You can read my notes, posted to the Scala tools mailing list. I was very surprised by this meeting. Not by the findings, if you will, as I have used all three IDEs at various times in the last few months. What I was surprised by was the feedback from the group, and the logical conclusion of this discussion: Scala is near a tipping point, but IDE support is holding it back.

First off, there was a large turnout for the BASE meeting. I would say it was the second largest BASE meeting, only bested by the June meeting where Martin Odersky spoke. It is funny, because I think our esteemed organizer, Dick Wall, had been intending this topic to be like "well if we have nothing else to talk about it, we'll talk about IDEs." If there had been an alternative topic brought up, I don't think people would have objected. After all, developers and their attitude towards IDEs are contradictory. Most developers I know would tell you that IDE support for a language is very important, but they would also act indifferent about IDEs when it came to them personally. It's like "all of those other developers really need IDEs, but I would be ok without them." We all know our APIs so well, that we don't need code completion, right? And we don't write bugs, so a debugger is of limited use, right? However, I am sure that if the meeting had not been about IDEs, then there would have been less people in attendance.

So why so much interest? Like it or not, but Scala's primary audience right now are Java developers. Yes, I know Scala appeals to some dynamic language folks, and to some functional programming folks, and that its .NET implementation is being updated, but you could sum up all of the Scala developers from those disciplines and it would be dwarfed by the Java contingency. Scala has a lot of appeal on its own merits, but it is always going to be framed against Java. Scala's most (only?) likely path to mass appeal is as "the long term replacement for java."

So when you talk about developers choosing to use Scala, you are really talking about Java developers choosing to use Scala instead of Java. This is not the only use case, but not only is it the most common use case, it is arguably the only use case that matters. Without this use case, Scala will at most be a marginal language, a la Haskell, or OCaml, or Groovy for that matter.

Back to my point... Java developers need great IDEs. This is not because they "need" help from their IDE because of some lack of skill. No, it's because they have had great IDEs for a long time now, and thus it has become a requirement. I remember when I joined Ludi Labs (it was still called Sharefare at the time) several years ago, we had a Java programming quiz. Candidates were given a clean install of Eclipse to use for writing their programs. We could have given them Vi or Emacs and a command line, but that would have been asinine and foolish. IDEs are an integral part of Java development.

I knew all of the above before the BASE meeting, but what I did not know was how many development organizations were at a critical juncture when it comes to Scala. For many folks, Scala, the language, has won the arguments. Whatever perceived extra complexity that it has, has been judged as worth it. Whatever challenges there may be in hiring people to develop in Scala can be mitigated. Legacy code is not even a factor, as integration with existing Java code is trivial. Maybe it's bleak future of Java, or maybe it's the high profile use of Scala at Twitter. Who knows, but Scala is poised to take a big piece of the Java pie.

Thus the missing piece is IDE support. Development orgs can't switch to Scala without IDE support, and the support is not there yet. That's the bad news. The good news is that Scala is ready to explode once the IDE support is there. There are a lot of folks out there ready to adopt Scala simply as a "better Java." They just need an IDE that is on par with Java IDEs. That is the standard.

All of that being said, there is a lot of concern around the IDEs. Many people expressed to me that they are worried that IDE progress is being coupled to the release of Scala 2.8. That seems reasonable at first, but what happens if 2.8 is not released until 2010 sometime? Will Scala lose its momentum and window of opportunity?

Monday, August 03, 2009

The Strange Loop

In October, I am speaking at the inaugural Strange Loop conference in St. Louis. This is not your run of the mill conference. It is organized by Alex Miller, who you might have seen speak the last couple of years at JavaOne. The speaker list is sweet: Alex Payne and Bob Lee are doing the keynotes, with sessions by Charles Nutter, Dean Wampler, Stefan Schmidt, Guillaume Laforge, Jeff Brown, and Alex Buckley. I am doing a talk on iPhone/Android development. It will probably be pretty boring compared to the other sessions. I may try to spice it up with some shameless plugging of Scala+Android balanced by some Fake Steve Jobs quotes about Android.

Wednesday, July 15, 2009

Functional Paradigms on Android using Scala

I am slowly plugging away on my little side project. One of the fun things about "pimping" an API, is you can tweak the design of the API. For example, I was modifying TextView, a class used for creating text input boxes of various sorts in Android. One common use case in Android is to create an auto-complete text box. To do this, you need to subclass TextView. Then you can override various lifecycle methods like onEditorAction, onKeyUp, etc. However, I thought that it might be nice to do something like this:

val textView = new TextView
textView.keyUp = (code:Int, event:KeyEvent) => {
// do stuff to your TextView
}

As Debasish pointed out to me, this is a lot like you would do in JavaScript. Is it better? It's a little easier in certain cases. If you just need to change the behavior of a single TextView in a very specific way, then this would seem like the way to go. Subclassing TextView just to override a single method and then using that subclass exactly once definitely seems like overkill. Now if you really wanted to create a new kind of TextView that you could use in multiple places, then subclassing makes sense.

One thing worth mentioning is how this kind of thing is handled in Cocoa on the iPhone. The Cocoa way would be to create an untyped delegate. In the delegate you could override the lifecycle methods that you were interested in. It's untyped, so you have to know the right names. You still wind up defining a new class, even though you usually only want to customize the behavior of one particular instance. Also, it's a little clunky as the TextView instance would have to be passed in to each of the delegate methods, so that your delegate could actually do something to the TextView. I find this a little better than having to subclass as you do in Android, but once again I think using Scala can yield some nice results.

There was another interesting case that popped up while sugaring TextView. I wanted to sugar the setCompoundDrawablesWithIntrinsicBounds methods. This method is overloaded, taking either four integers or four Drawables. Here is what I first thought of doing:

def compoundDrawablesWithIntrinsicBounds_=(bounds:Tuple4[Int,Int,Int,Int]) {...}
def compoundDrawablesWithIntrinsicBounds_=(bounds:Tuple4[Drawable,Drawable,Drawable,Drawable]) {...}
// this allows
myTextView.compoundDrawablesWithIntrinsicBounds = (1,2,3,4)
// or
myTextView.compoundDrawablesWithIntrinsicBounds = (d1,d2,d3,d4)

Of course this won't work. The type parameters of Tuple4 are going to be erased by the compiler, and the two methods are indistinguishable. However, The Amazing Mr. Spiewak gave me a solution:

def compoundDrawablesWithIntrinsicBounds_=[T <% Either[Int, Drawable]](bounds:Tuple4[T,T,T,T]){
bounds._1 match {
case Left => baseTextView.setCompoundDrawablesWithIntrinsicBounds(bounds._1.left.get, bounds._2.left.get,
bounds._3.left.get, bounds._4.left.get)
case Right => baseTextView.setCompoundDrawablesWithIntrinsicBounds(bounds._1.right.get, bounds._2.right.get,
bounds._3.right.get, bounds._4.right.get)
}
}

In addition to this, you need implicits to convert an Int to a Left and a Drawable to a Right. The API looks a lot different, but it allows exactly the same usage that I wanted. Another case of how you need some non-trivial Scala (though I wouldn't be surprised if there is a more elegant way than the above) to create an API that is super simple to use.

Thursday, June 18, 2009

Scala and Android

Recently I was working on an article for developerWorks about using Scala on Android. Stay tuned to developerWorks to see that article. Since then I have started a little side project to create a set of Scala libraries for working on Android. Now you may ask, why bother with this? Is this just a classic case of mental masturbation? Well, no, at least I hope not.

I think Scala is well suited as a programming language for mobile devices. I am not an expert on all mobile platforms, my experience is mainly around iPhone and Android development. For the iPhone you are developing in Objective-C, and for Android in Java. Now in general, I think the Android development environment is superior in almost every way to the iPhone. IDE is mostly a matter of taste, but Eclipse+ADT certainly has a lot more features than XCode. Debugging is definitely better on the Android. It is much easier to debug on a device, and the emulator gives you more ways to vary the environment (cpu/memory/network resources) for more realistic emulation. The only thing advantage I would give to iPhone is that XCode and the iPhone emulator both startup much faster than Eclipse and the Android emulator.

Programming in Java gives you a lot more options than Objective-C. There are just a lot more open source Java libraries out there to help you avoid reinventing wheels. In addition, I think the platform specific APIs added by Google are much better than the ones on the iPhone. A simple example is XML processing. Java and Objective-C both already have XML parsing APIs. However, Android adds extra APIs as they recognize this as a common task for mobile applications that leverage web services. They added convenience APIs for SAX based parsing. They also leveraged a StAX-style parser by leveraging an Apache project. There is nothing like this in iPhone, despite the fact that the iPhone has been around longer and should be more mature. It may be an oversimplification, but I think this comes back to the corporate cultures that produced these platforms. Apple has always been a company that uses software to sell hardware, and this continues with the iPhone. Google is much more of a software company, with strong ties to open source software. It should be no surprise that Android is a much more development friendly platform. And don't even get me started when it comes to garbage collection (Android has it, iPhone does not, despite the fact that Objective-C 2.0 has it.)

So Android is great, why do we need Scala? First there is verbosity. Actually both Objective-C and Java are quite verbose -- Objective-C is even more verbose than Java. Scala is a much more concise language than either. Objective-C can actually be more dynamically typed than Java/Scala, but this rarely makes the code any more concise or readable, and often makes it harder to debug. Next, neither Objective-C or Java have much support for functional programming. This is a bigger deal than you might think at first. UI frameworks are full of events that you must write code to handle. Writing a function to handle those events is so much easier than writing a class. On the iPhone you can often set any type of object as an event handler, and you just have to know the magic methods to implement. On Android, you usually have an interface to implement, and that interface has a single method. This is actually better than what you do on the iPhone, but the interface and its implementation class are both classic cases of boilerplate.

Thus it is my goal to make it possible to write Android applications in a much more concise way by using Scala. In general, you can replace Java code with Scala that is much easier to read and understand. I think this will be especially true on Android, and the contrast will be even more true.

The last reason that I think Scala is a great language for mobile development is threading. Both iPhone and Android support multi-threading, as any UI framework must. Any good UI will perform any non-trivial operations on a background thread, to keep the main UI thread responsive to the user. However, threads are tricky, especially this kind of multi-threading. Updating your UI from a background thread is a recipe for disaster. Android enforces this by using a Handler on the main thread that your background threads send messages to. If you are familiar with Scala then message passing as a way to implement multi-threading should ring a bell. This is exactly how actors work in Scala. I haven't tried using Actors on Android yet, but it sure seems like a good fit.

So there is some of the motivation. I think Scala on Android could be really compelling. My side project is pretty small so far: a handful of wrapper classes and implicit conversions to bring some syntactic sugar and functional programming into the mix on some common Android classes. The project also has a special build of the Scala library that I found necessary to get the library to work on Android and its compiler. I am hoping to add more sugar and to add the actors ideas listed above. I am also hoping to come up with a nice way to integrate something like Proguard to optimize the bytecodes that get compiled for Android.

Friday, June 05, 2009

JavaOne Talk: Performance Comparisons of Dynamic Languages on the Java Virtual Machine

Below are the sldies. Major thanks to Charlie Nutter for great feedback and advice on the Ruby code and tuning JRuby performance. Thanks to Chouser and Timothy Pratley for help with the Clojure code. And major thanks to Brian Frank for help with the Fan code.

JavaOne Talk: RIAs Done Right

Wednesday, May 20, 2009

JavaOne Talk: Scala Reversible Numbers

See this post about why this code is being shown. See this post for the Java version to compare against.

class ScalaReversible(max:Int){
import java.lang.Character._
lazy val numReversible = (11 to max).filter(reversible(_)).size
private
def reverse(n:Int)=n + parseInt(n.toString.reverse)
def allOdd(n:Int) = n.toString.map(digit(_,10)).forall(_ % 2 == 1)
def reversible(n:Int) = allOdd(reverse(n))
}

JavaOne Talk: Python Reversible Numbers

See this post about why this code is being shown. See this post for the Java version to compare against.

class PyReversible(object):
__slots__ = ['max','numReversible']

def __init__(self, max):
self.max = max
self.numReversible = self.countReversible()

def countReversible(self):
return len([i for i in xrange(11,self.max+1) if self.reversible(i)])

def allOdd(self,n):
for ch in str(n):
if int(ch) % 2 != 1:
return False
return True

def reverse(self,n):
return n + int(str(n)[::-1])

def reversible(self,n):
return self.allOdd(self.reverse(n))

JavaOne Talk: Ruby Reversible Numbers

See this post about why this code is being shown. See this post for the Java version to compare against.

class RubyReversible
def initialize(max)
@max = max
@numReversible = nil
end

def allOdd(n)
digits = n.to_s.split(//)
digits.length == digits.map{|c| c.to_i}.select{|i|
i % 2 == 1}.length
end

def reverse(n)
n + n.to_s.reverse.to_i
end

def reversible(n)
allOdd(reverse(n))
end

def countReversible()
@numReversible ||= (11..@max).select{|i|
reversible(i)}.length
@numReversible
end
end

JavaOne Talk: Groovy Reversible Numbers

See this post about why this code is being shown. See this post for the Java version to compare against.

public class GroovyReversible {
final Integer max
final Integer numReversible = 0
public GroovyReversible(max){
this.max = max
this.numReversible = this.countReversible()
}

def countReversible(){
numReversible ?: (11..max).findAll{reversible(it)}.size()
}

def reversible(n){
allOdd(reverse(n))
}

def allOdd(n){
n.toString().toList().collect {it.toInteger()}.every{it % 2 == 1}
}

def reverse(n){
n + n.toString().toList().reverse().join().toInteger()
}
}

JavaOne Talk: Reversible Numbers

See this post about why this code is being shown. This is a different algorithm, it is a brute force solution to Project Euler problem #145. Here is the Java "reference" implementation.

public class Reversible {
final int max;
final int numReversible;

public Reversible(int max){
this.max = max;
this.numReversible = this.countReversible();
}

private int countReversible(){
if (numReversible > 0){
return numReversible;
}
int cnt = 0;
for (int i=11;i<=max;i++){
if (reversible(i)) {
cnt++;
}
}
return cnt;
}

private boolean reversible(int n){
return allOdd(reverse(n));
}

private boolean allOdd(int n){
while (n > 0){
int remainder = n % 2;
if (remainder == 0) return false;
n = n / 10;
}
return true;
}

private int reverse(Integer n){
char[] digits = n.toString().toCharArray();
char[] rev = new char[digits.length];
for (int i=digits.length-1;i>=0;i--){
rev[i] = digits[digits.length -i-1];
}
return n + Integer.parseInt(String.valueOf(rev));
}
}

JavaOne Talk: Scala Word Sort

See this post about why this code is being shown. See this post for the Java version to compare against.

class ScalaWordSort(fileName:String){
lazy val sortedWords = {
Source.fromFile(dataFile).getLines.foreach(_.split(" ").foreach(words ::= _))
words.sort(_.toLowerCase < _.toLowerCase)
}
private
val dataFile = new File(fileName)
var words:List[String] = Nil
}

JavaOne Talk: Python Word Sort

See this post about why this code is being shown. See this post for the Java version to compare against.

class PyWordSort(object):
def __init__(self, fileName):
print "init " + fileName
self.dataFile = open(fileName)
self.words = []
def sortedWords(self):
if len(self.words) == 0:
for line in self.dataFile:
for word in line.split():
self.words.append(word)
self.words.sort(lambda w,w1: cmp(w.lower(), w1.lower()))
return self.words