Late To The GameHaving 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 LearningFor 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.
- 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.
- 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++.
- 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.
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.
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.
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.
- 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.
- 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.