Wednesday, July 10, 2013

My First Dart Component

Late To The Game

Having programmed C++ for many years I have finally come to the conclusion this web thing has a future. Being late to the game I was looking for the best path for a traditional OOP programmer to be productive in developing web applications. With this backdrop and after a fair amount of playing around and investigating various technologies, I decided to give Dart a go for front end development. My ultimate goal is to be in a position to create rich internet applications (RIAs) that can scale. So far I am quite happy with my decision to learn Dart.

Project-Based Approach To Learning

For me there is so much to learn on the web front that it is not easy to decide where to begin. Since there is no real beginning or end, you kind of have to start somewhere in the middle and work your way outward. One of the first applications I would like to create is a single page web application for manipulating data related to a user's personal portfolio. I will want the user to be able to enter all sorts of information related to their assets, liabilities, incomes, expenses, etc... But given my need to learn how to do something small/manageable first, I settled for creating a simple component that will allow me to divide HTML content into multiple panes with the familiar splitter. The following were motivators for this particular project selection:
  • Being new to the web I am weak at creating presentable content. I know in the future I'll want to divide my single page application up and I don't feel confident that I will ever be at a point where I could get by with just CSS. Having an ability to break up a page with components in a user controlled, flexible way is appealing. Thus splitters.
  • Having done a search for Dart specific Web UI splitter windows, I was unable find any. I did find cool projects with splitters in them (DWT for example and Dock Spawn). DWT is not Web UI but is a fairly comprehensive framework. Dock Spawn also is not Web UI, but is a very cool framework for setting up IDE like functionality in which you can drag panels from one side to the other like Visual Studio, Dart Editor and many others. While quite slick it is much more than I need. So, not finding any Web UI splitter could have been just be a weakness in my search or maybe an indication that the use of splitter windows are out of fashion or not a good design choice. My hope is that instead it is just an indication that the Dart Web UI technology is so new they have yet to be created. 
  • It is small/manageable enough to be a useful tool in learning how to create Dart Components.
  • There exist many splitter solutions in the javascript world. I did not and still do not know javascript, but having javascript solutions available would provide useful information on how to get started. An example implementation that I studied was http://methvin.com/splitter/. Check out the code - the splitter support itself is less than 200 lines. I have tremendous respect for the knowledge and skill required to create that component. But, to be honest, getting a feel for what it was doing was difficult for me. Part of the difficulty was my ignorance of javascript, the DOM and Web programming in general. But, now that I think I have a much better understanding of these, I still feel I need much more structure in my code to be comfortable with it. This is what Dart can provide as part of the language rather than as selection of conventions.
  • Finally, things are developing rapidly. The missing components of today will hopefully be there tomorrow and a splitter/splitter window should be encapsulated enough to move to some more professional Google or third party supplied solution with only a few changes on the declarative side (i.e. in html composition) in the future.
One benefit I hoped to get out of this exercise beyond just a splitter component was to learn about Web UI components in the Dart world and share here my thoughts on the Dart Language and my Web UI experience here.

Dart Features

My background is primarily C++, but I love languages so I have dabbled in Perl, Python, Ruby,  Go and most recently D. I am not a javascript guy and as of now I don't intend to devote much time on that language. My hope is that with Dart I will be able to bypass javascript altogether - although since javascript is the current lingua franca of the web that may not be realistic. Unfortunately, given my lack of javascript knowledge I can not compare/contrast with that in detail. So far, the features in Dart that I love:
  • Familiar: If you have done Java, C# or C++ you should feel right at home.
  • Optional Typing: Just use it. It catches so many errors for me that I fear what I would be creating without it. I do appreciate being able to be not too specific using var as with auto in C++ or leaving types off when it is not adding much value. But every time it catches an error I smile.
  • Cascades: The '..' operator is very cool. If you buy into the "declarative renaissance" that Seth Ladd (Dart evangelist)  talks about, which I do, then you will really appreciate this feature. Object initialization can be so much more convenient with this. 
  • String Interpolation: This has been around in languages for ages. I became very fond of it years ago while using Perl. One type of programming that I really enjoy is code generation and string interpolation is my requirement for that. That feature alone was my motivation for porting my code generation infrastructure from Python/Cheetah to Ruby/Tenjin.
  • Fast Compilation/Interpretation: Quick turnaround is there for sure. All the cool languages these days allow you to get from modified source to the first line of main quickly - within seconds, even for newer compiled languages. Similar to Python and Ruby it is great to change and run immediately. Static languages, like Go and D have really made great strides in this area as well, so the distinction is less a comparative advantage unless you have other driving forces, like performance, pushing you toward C++.
  • Web Development: This is the main reason I am using Dart - you can run it in the browser. Well, actually you can run javascript that is transpiled from your Dart, but honestly I have not yet felt the difference. Granted it is just a simple splitter component so far - but the approach works as advertised and I'm happy with it. 
Here are some features that I miss:
  • Enums: There are patterns for this in Dart and there was talk of true support coming in the future. 
  • Real templates and meta-programming: They have some support for templates, but it is nothing as rich as that in C++ or even better D.
  • Support for const correctness: D shines in this area by providing real guarantees of immutability. Maybe this is too much to hope for in a language that is aiming at the RAD web world, especially when typing is optional.
  • No eval: I can understand why it is not allowed and can live without it - but sometimes the lack of eval hurts. 

Performance

And of course there is also performance, which is extremely important to the creators of Dart. You can't complain about Dart performance. Currently there may be a small penalty or there may even be a small gain when running javascript transpiled from Dart over hand written javascript. It is really hard to say, though, because to do any fair comparison you would want the best reasonable javascript solution to your problem compared against the best reasonable Dart solution to your problem. But this is not reasonable. So, for someone choosing between Dart and Javascript the question with respect to performance should be: Do you really think your prowess in Javascript is at the level that code written in Dart could not generate javascript as efficient yours? For the vast majority of javascript developers that answer should be *no* because they simply do not have the experience to know all the low level intricacies impacting performance nor the consistency of a transpiler to always make the proper choice. But if you were a javascript performance guru, you may feel you can beat any Dart transpiler solution out there. And maybe you are correct. But here is a thought: they can improve the efficiency of javascript itself, and when they do both javascript and Dart transpiled to javascript solutions win. But when the Dart team finds a new way to exploit something particular to Dart leading to a new efficiency in the transpiled javascript, only the Dart users benefit. So, if you do have an edge, for how long?

Arguably for the vast majority of projects, even for server side work, Dart will likely fit the bill nicely. But at some point there are likely limits to the performance you can get from a VM. I am a fan of D and my current solution for back end is targeting the vibe stack (http://vibed.org/http://vibed.org/) not just as a hedge on the performance front but for the features of the stack itself. It is funny how many of us, even when we know performance is not a big deal, still gravitate toward performance claims as deciding factors.

Web UI GUI Development

Most of my exposure to GUI development has come through Windows via J# and later WinForms using C++ with CLR. It was your typical drag and drop designer approach to laying out the Forms and components of the GUI, then clicking those components in the IDE which transports you to the event handlers and you're off coding. Web UI is not nearly that friendly - at least not yet. On the plus side it is looking like the advertised ability to compose with components and build large scale RIAs is there. I think one of the true benefits of Dart and the Web UI approach will be in consistency and reduction in number of incongruous competing approaches to tackling the same tasks. Competition is great and having multiple choices is not the problem. The problem is when you can't put the competing approaches into a single solution. 

Again, not a lot of experience with javascript, but one of the reasons I shied away is not knowing where to start. So many competing approaches and different ways of doing things and not much of it seeming to play well with others. I investigated Ext JS from Sencha and was close to committing to it because of the beautiful RIAs that could be created with it. What held me back partially was fear of what committing to that framework meant with respect to the others. Plus, have a look inside ExtJS - it is really beautiful code. It is so consistent in the pattern usage I wonder how much of it is hand written versus code generated. This of course is a plus and I think if I were told I had to use Javascript I would start by buying a copy of ExtJS and studying what they do and then mimicking it. My impression is the people who wrote that clearly did a great job of (1) identifying a reasonable set of approaches and patterns required by large scale javascript and (2) following those patterns consistently throughout. 

For RIA, the downside to selecting Dart and Web UI over something like ExtJS is that while the pieces are there to create an ExtJS like framework, that framework does not exist. In fact, most of the Web UI widgets you would want are not yet to be found: no panels, layout managers, splitter windows, tool tips, etc... Assuming they existed but were created by different groups I feel confident they would fit together. There are great projects indicating a start like the port of Bootstrap called Widget (http://pub.dartlang.org/packages/widget). Both useful and easy to use, it hits the mark for its intended purpose - but it is not comprehensive. There are also interesting Dart solutions that pre-date Web UI, like Rikulo (http://rikulo.org/). But then it is not clear how well components from Rikulo will sit beside Web UI components. If there were an area where Google should ramp up investment to increase likelihood of adoption of Dart it would be in creation of the first complete ExtJS-like framework showcasing the Web UI approach and the advantages of declarative programming.

Tooling

This is a big deal - probably bigger than I appreciate because I don't think I take full advantage of it. Over the years I have invested a lot of time in my Emacs set up and switching to something like Dart Editor for actually working in the code is not compelling. So my m.o. is to write the Dart code in Emacs and then pop over to the Dart Editor if I need to run. Obviously not an ideal set-up and some pain is felt primarily for web-related code. I ported a suite of code generation tools from Ruby to Dart and since it was not web code I did not feel any pain from bypassing the Dart Editor. For that to work, I have an Emacs key binding that runs the Dart file associated with the current Emacs buffer through a run_dart.dart script. This script adds some niceties like running the code with --checked flag so I get much of the benefit of the Optional Typing and like passing a --package-root flag pointing to a single package referencing all the other packages I use so keeping a pubspec.yaml file in the folder is not required.  Whenever I need to debug I pop back to the Dart Editor which works well enough for that purpose. Also, periodically bringing up the Dart Editor just to look at all the warning annotations is quite useful. I should do it more often.

Ready For Prime-Time?

This is a big question for anyone considering a new technology and I haven't the breadth of experience in web development to know if it is really ready for prime time. But what I can say is the approach is enjoyable to work in and delivers on the promise of adding familiar OOP structure to the deliverables. I'll stick with it and hope that the emergence of professional component libraries providing the breadth of functionality of ExtJS will develop quickly.

Glitches/Stumbling Blocks

  • Running on my Mac the Dart Editor is fine at startup and for several hours. However, after a day or so it is not so nice and at times seems to take over my machine. My fix is to just restart it.
  • While creating the SplitPanel component I would test by running in Dartium. For some reason I would periodically get the "Aw Snap". I have yet to see the same error when running from Javascript which runs it in Chrome. My hope is this is just a bug in Dartium and not my code. I was able to recreate the issue consistently, but to do so required rapid and vigorous mouse movement while moving a splitter around. I used the binary search approach to get it to the point where commenting out the handler on the onMouseMove would make it go away - so there is something either in my code or in the framework on Dartium that can not handle the events when they come in very rapidly. Even when my code was narrowed to a simple math calculation I was able to recreate it, leading me to believe it is not my code.
  • I am a fan of documentation. Unfortunately I was not able to get the Dart Editor to generate my documentation. According to Stack Overflow (http://stackoverflow.com/questions/16610339/what-is-non-standard-about-this-package-directory-structure) this may be because I have an non-standard directory structure, but I'm not convinced. Anyway, to get documentation I would have to run from command line like:

    dartdoc --mode=static  --show-private --enable-diagnostic-colors --package-root=`pwd`/packages bin/ebisu.ebisu.dart
    The key is the requirement of specifying --package-root.
  • I ran into minor issues when trying to import libraries in Dart. Because you can have multiple libraries in the same pub package you need to decide how one library in the package will reference another in the package. You can use relative imports or package imports in this situation. But I found that by using a combination of both was a problem. In the end the same code file was somehow imported twice leading to errors. In the end I standardized my code to always using import ":..." and it is working for me.
  • The largest difficulty with this first project was not related to Dart but rather in trying to get control of the sizing of elements in HTML. The combination of the generic concept of width/height in combination with borders, padding and margins that come with HTML elements can get very confusing. Unfortunately I spent many hours in games of Whack a Mole in which I would try to assign what was a sensible formula to a width or height only to find something somewhere else did not like the formula. Any change to a contained elements borders, padding or margin messed up layout somewhere else. This pain gave me an appreciation for the approach taken by the Rikulo team that they have described in The Rikulo Way.