May 19, 2012

Richard Griffith

Having Fun with Dart, AJAX, and JSON

Update 19 May 2012: Updated source code for the demo to Dart Editor Build 7552 after finding that the previously compiled js file no longer ran under newer releases of Chrome. The following minor changes were required to the source code in the article to perform the update and generate a new js file:

_feedCont = window.document.query('#feedContainer'); 
// becomes
_feedCont = document.query('#feedContainer');
// and
xhr = new XMLHttpRequest.getTEMPNAME(feedURL, (jsonRequest)
//is now
xhr = new XMLHttpRequest.get(feedURL, (jsonRequest)

Introduction


A few weeks ago, I let myself get distracted from a project I was working on thinking about Dart's [1] jQuery like DOM manipulation features [2]. It occurred to me that as a quick experiment, I could take the RSS/Atom feed for this blog and see how well I could manipulate the returned XML document using Dart's very nice DOM API. I assumed I could simply use the following standard XHR request to return the feed:

//AJAX request for an XML Document.
XMLHttpRequest RSSRequestObject;

void getRssFeed() {
  RSSRequestObject = new XMLHttpRequest();
  RSSRequestObject.open("GET", rssFeedURL, true);
  RSSRequestObject.on.readyStateChange.add((e) {
  reqChange();
});
RSSRequestObject.send(null);

void reqChange() {
  if (RSSRequestObject.readyState == 4 && RSSRequestObject.status == 200) {
    Document feedDocument = RSSRequestObject.responseXML; 
  } else { 
    print(RSSRequestObject.statusText); 
  }
}

Well, this didn't actually work. After some experimentation and head scratching, it appeared that the XML parser for AJAX requests had not yet been implemented in Dart when I attempted this [3] (note that this bug appears to relate only to library dart:html). But rather than return to the project I was working on, I was now curious to find an alternative approach, and of course that led me to use JSON (Java Script Object Notation) instead. The final Dart widget (a Didget, if you will), which makes use of AJAX (Asynchronous Javascript and XML), JSON and a bit of CORS (Cross Origin Resource Sharing) is included below and you can find the source code here. If you are interested in a walk through of the code, you can find that included after the demo.

The "Didget"


My quick attempt, then, to parse an XML document and manipulate the data with Dart's DOM API (which some may say is not an appropriate use of the API anyway) turned instead into a tabbed panel widget that pulled in JSON data from both this blog as well as my Github account. I decided to use CORS instead of JSON-P for cross-domain data access although it is apparently possible to communicate between JavaScript and Dart to access JSON-P data using the postMessages() method of the DOM [4][5]. I was therefore limited to sites where CORS was actually implemented, and after some investigation, found that the Github v3 API has a very convenient method for accomplishing this [6], especially if all you desire is to retrieve publicly available information (although, oddly, their v3 API doesn't seem to support search queries the way v2 did). I had hoped that Google+ and Twitter would also allow cross-origin access with XHR2 (ie, using the CORS protocol), but this does not appear to be the case [7].

loading data...

Using JSON with Dart


Once I had decided to abandon XML in place of JSON, the first issue I ran into was a fairly straight forward one - this blog doesn't actually generate a JSON feed, at least not natively. Luckily, I was able to find a 3rd party tool [8] built on a RESTful API that provided the feed in JSON format. An example of retrieving the feed using this API is as follows:

http://www.greatandlittle.com/studios/index.php?rest/blog&f=getPosts&cat_url=Google/Dart

Oddly enough, this didn't actually work either. But at least this time I could tell immediately from the console that the JSON parser was finding problems with the syntax being returned. Using this path with the JSONLint validator [9] confirmed that there were in, fact, syntax errors. The errors were confined to the content field in some of the entries (particularly the very long ones). Feeling the pressure of my long neglected other projects, I decided the best way to move forward was to filter the entries individually since trying to capture all of the entries in one request would likely result in not getting any at all. The getPosts method of the API has three query parameters, count_only, limit and offset, that allows me to step through the feed entries and skip the ones that are returning invalid JSON. So first I needed to get the total number of entries for a given entry category which is easy enough (note that I am using the '+' operator for string concatenation. For performance reasons, Dart doesn't recommend this approach and it is possible in the future the '+' operator may not be supported by the language, at least for concatenating string literals [10][11]):

//Retrieve number of entries in the given category:
void JSONFeedReader() {
  feedURL = "http://www.greatandlittle.com/studios/index.php?rest/" + 
      "blog&f=getPosts&cat_url=Google/Dart&count_only=1";
  num totalEntries;
  XMLHttpRequest xhr = new XMLHttpRequest.getTEMPNAME(feedURL, (jsonRequest) {
    var jsonResponse = JSON.parse(jsonRequest.responseText);
    totalEntries = jsonResponse["data"];
    iterateEntries(totalEntries);
  });
}

Note I am using the getTEMPNAME() method of the XMLHttpRequest Interface in the dart:html library [12]. As the name suggests, this method is still under development and may change in future releases, so it is recommended that you check the DOM API documentation for updates. Currently, this is how it is implemented in Dart Editor [13] build 4577. Ok, so now that we have the total number of entries, we can iterate through each one. At first, I tried something like this (note that I'm using the loop iterator to control the offset in the URL path and $feedLimit is set equal to 1 to return only one post at a time):

//Iterate through each entry and skip those with invalid JSON data:
void iterateEntries(num totalEntries) {
  XMLHttpRequest xhr;
  var jsonResponse;
  HeadingElement titleHeading;

  for (var i=0; i<totalEntries; i++) {
    feedURL = "http://www.greatandlittle.com/studios/index.php?rest/" +
        "blog&f=getPosts&cat_url=Google/Dart&offset=$i&limit=$feedLimit";
    xhr = new XMLHttpRequest.getTEMPNAME(feedURL, (jsonRequest) {
      try {
        jsonResponse = JSON.parse(jsonRequest.responseText);
        titleHeading = new Element.tag("h2");
        titleHeading.text = jsonResponse["data"][0]["title"];
        _output.nodes.add (titleHeading);
        processResponse(jsonResponse);
      } catch (var exception) {
        print("invalid json: $exception<br>");
      }
    });
  }
}

We'll look at the processResponse() function in just a moment, but first notice that this approach has an unacceptable weakness to it. It filters invalid responses fine, but due to the asynchronous nature of the AJAX request, the order in which the valid responses are processed is unpredictable. The for loop continues to execute XMLHttpRequests in parallel with the parsing of the JSON data by the browser. Therefore, there is no set order in how the entries are displayed in the reader and the order may (and often will) change each time the feed is loaded. To correct this, we replace our for loop with an if statement to enable us to process each entry prior to moving on to the next. Note that this results in a recursive loop if the data is found to be invalid (otherwise, iterateEntries() is called from within the processResponse() function):

//Iterate through each entry but process the valid entries before requesting the next entry:
void iterateEntries() {
  XMLHttpRequest xhr;
  var jsonResponse;
  
  if(totalEntries > 0) {
    totalEntries--;
    feedOff++;
    feedURL = "http://www.greatandlittle.com/studios/index.php?rest/" + 
        "blog&f=getPosts&cat_url=Google/Dart&offset=$feedOff&limit=$feedLim";
    xhr = new XMLHttpRequest.getTEMPNAME(feedURL, (jsonRequest) {
      try {
        jsonResponse = JSON.parse(jsonRequest.responseText);
        processResponse(jsonResponse);
      } catch (var exception) {
        print("invalid json: $exception");
        //Recursive call to try again:
        iterateEntries();
      }
    });
  } else {
    //Done with blog entries, on to github.
    githubFeed();
  }
}

When we look later at using XHR2 with our gitHub requests, you'll see that we replace our try-catch error exception handling methodology with an actual error handler attached to the XHR request, but for now this approach seemed to work quite well. Before we discuss the processResponse() function, however, it might help to take a look at the JSON that is returned for one of the valid entries:

{
    "data": [
        {
            "id": "16",
            "title": "Keeping Time with Dart - The Clock, Stopwatch and Date Classes",
            "excerpt": "<p><em>All that really belongs to us is time...
            "content": "<h4>The Clock Class</h4>\n\n\n<p>The <code>...
            "user": "user6488972b",
            "creadt": "2011-12-12 05:52:24",
            "upddt": "2012-01-13 22:09:17",
            "url": "2011/12/11/Keeping-Time-with-Dart-Clock-Stopwatch-and-Date-Classes",
            "selected": false,
            "nb_comments": 0,
            "nb_trackbacks": 0,
            "category": 8
        }
    ],
    "status": "ok"
}

In our processResponse() function, we can then access the individual JSON fields using bracket notation:

//Received a valid entry, use bracket notation to gather and post the information desired:
void processResponse(var jsonResponse) {
  HeadingElement titleHeading = new Element.tag("h2");
  String link = "http://www.greatandlittle.com/studios/index.php?post/" +
      "${jsonResponse["data"][0]["url"]}"; 
  titleHeading.text += "${jsonResponse["data"][0]["title"]}";
  _blogOut.nodes.add(titleHeading);
  _blogOut.innerHTML += "${jsonResponse["data"][0]["excerpt"]}";
  _blogOut.innerHTML += "<a href='$link'>read full entry</a><br>";
  _blogOut.innerHTML += 
      "Entry created ${jsonResponse["data"][0]["creadt"]}<br>";
  _blogOut.innerHTML += 
      "Entry modified ${jsonResponse["data"][0]["upddt"]}<br>";
  //Finished with this entry, try the next one:
  iterateEntries();
}

At this point, I had (sort of) completed what I had set out to do originally and should have really gotten back to my other projects. But the nagging question that had developed during all of this was - this is nice, but what about if I was interested in data from a different domain? How would I go about retrieving and displaying it with Dart?

JSON-P is Great, but CORS is Even Better


The fundamental limitation of XHR, of course, is that its security model limits access to data only on the same domain as that of the requesting agent (known as the same origin policy) [14]. By far the most common method around this limitation (and the most supported) is by using JSON-P (JSON with padding) [15]. JSON-P does not use an AJAX request at all but rather makes use of a callback function which is called when the JSON data arrives from the content provider. This is typically handled with a library like jQuery, but it can also be handled manually as follows:

//Dynamically add a script tag to your DOM that calls a JSONP enabled provider.  For example:
<script type="text/javascript" src="http://search.twitter.com/search.json?q=blue%20angels&callback=myCallbackHandler"></script>

//Now pass the returned data to the function that actually makes use of the data.
function myCallbackHandler(data) {
  jsonpData(data);
} 

A Dart specific example of the above is shown in [4]. But as I mentioned earlier, I was looking more for something I could do completely within Dart. Certainly there had to be another way. And that other way is to use CORS.

CORS (Cross-Origin Resource Sharing) [16] is a protocol that can be used with AJAX directly to allow cross-domain data sharing. Most modern browsers support the protocol, although Mozilla suggests that you check for browser support [17]. Unfortunately, it is not widely supported [7] by API/Client providers. One exception, however, is GitHub, which provides CORS support through version 3 of its API [6]. Once you register your domain, assuming you have an account, access to public data in your account is available through standard AJAX requests using XHR2. For example:

//Define a path to the github repos:
githubUser = "scribeGriff";
githubURL = "https://api.github.com/users/$githubUser/watched";
//Request the data using standard AJAX
void githubFeed() {
  var jsonResponse;
  githubXHR = new XMLHttpRequest();
  //Check if browser supports CORS:
  if (githubXHR.withCredentials != null) {
    githubXHR.open("GET", githubURL, true);
    githubXHR.on.load.add((e) {
      jsonResponse = JSON.parse(githubXHR.responseText);
      processGits(jsonResponse);
    });
    githubXHR.on.error.add((e) {
      _githubOut.innerHTML += "There was an error loading this feed.<br>";
    });
    githubXHR.send(null);
  } else {
    _githubOut.innerHTML += "This browser doesn't appear to support XHR2";
  }
}

Processing the returned JSON formatted data is done in much the same way that we handled the blog feed. JSONLint showed us the structure of the data and the rest was just simple bracket notation manipulation. Note that I have started making use of multi-line string literals, a nice feature of Dart, in the next block of code. But be aware that this technique can insert (ie, capture) spaces in your string if you decide to introduce them for formatting purposes. For this example, the added spaces are added only to programmatically constructed HTML and are therefore ignored by the DOM. This may not be the case for other types of string literals.

//Take the JSON formatted response and process using bracket notation:
void processGits(var jsonResponse) {
  Date creationTime = new Date.now();
  HeadingElement titleHeading = new Element.tag("h2");
  titleHeading.text = 
      "$githubUser is watching ${jsonResponse.length} repositories:";
  _githubOut.nodes.add(titleHeading);
  HeadingElement dateHeading = new Element.tag("p");
  dateHeading.text = "data is current as of $creationTime";
  _githubOut.nodes.add(dateHeading);
  //Loop through all responses, creating a new div for each entry.
  for (var i = 0; i < jsonResponse.length; i++) {
    DivElement _reposDiv = new Element.tag("div");
    _reposDiv.attributes = ({
      "class": "reposClass"
    });
    _githubOut.nodes.add(_reposDiv);
    //Multi-line strings use triple single or double quotes. 
    _reposDiv.innerHTML += 
        '''
        <a href='${jsonResponse[i]["owner"]["url"]}'><img src=
        '${jsonResponse[i]["owner"]["avatar_url"]}'></a>''';
    _reposDiv.innerHTML += 
        '''
        <a href='${jsonResponse[i]["html_url"]}'>
        ${jsonResponse[i]["description"]}</a><br>''';
    _reposDiv.innerHTML += 
        "Coded by ${jsonResponse[i]["owner"]["login"]}<br>";
    _reposDiv.innerHTML += 
        "Last updated at ${jsonResponse[i]["updated_at"]}<br>";
    _reposDiv.innerHTML += 
        "This repo has ${jsonResponse[i]["watchers"]} watchers<br>";
  }
}

The Tabbed Panel in Dart


So I had these two divs that contained some of the dynamic content that I wanted for my Dart widget, but I didn't want to present it as just two consecutive blocks of information. This didget, however, lended itself quite nicely to a tabbed panel approach. If you use a library like jQuery, you have a lot of choices for building a large variety of tabbed panels. But even without a library, creating tabbed panels is not that difficult. Some solutions try to do tabbed panels with just CSS [18], although with mixed results. For this application, I'm using a fairly simple but easily extensible algorithm [19] that makes use of display style in an interesting way. First, to create our tabs in Dart, we create two divs for each tab (one for focus, the other for ready) and set its display property accordingly:

//Create Tab One Focus Div:
_tabOneFocus = new Element.tag("div");
_tabOneFocus.attributes = ({
  "id": "tabOneFocus",
  "class": "tab",
  "style": "display:block;"
});
 _tabOneFocus.innerHTML = "Blog Feed";
_feedCont.nodes.add(_tabOneFocus);
//Create Tab One Ready Div:
_tabOneReady = new Element.tag("div");
_tabOneReady.attributes = ({
  "id": "tabOneReady",
  "class": "tab",
  "style": "display:none;"
});
_tabOneReady.innerHTML = "Blog Feed";
_feedCont.nodes.add(_tabOneReady);
//Create Tab Two Focus Div:
_tabTwoFocus = new Element.tag("div");
_tabTwoFocus.attributes = ({
  "id": "tabTwoFocus",
  "class": "tab",
  "style": "display:none;"
});
_tabTwoFocus.innerHTML = "Repos Watched";
_feedCont.nodes.add(_tabTwoFocus);
//Create Tab Two Ready Div:
_tabTwoReady = new Element.tag("div");
_tabTwoReady.attributes = ({
  "id": "tabTwoReady",
  "class": "tab",
  "style": "display:block;"
});
_tabTwoReady.innerHTML = "Repos Watched";
_feedCont.nodes.add(_tabTwoReady);

Now let's add event listeners to just the tabs whose id indicates that it is a "ready" tab:

//Onclick listener for Tab One Ready Div:
_tabOneReady.on.click.add((e) {
  var displayList = [_tabOneFocus,_tabTwoReady,_blogOut];
  changeDisplay(displayList);
});
//Onclick listener for Tab Two Ready Div:    
_tabTwoReady.on.click.add((e) {
  var displayList = [_tabOneReady,_tabTwoFocus,_githubOut];
  changeDisplay(displayList);
});

Note how the event listener defines a display list variable displayList which passes to function changeDisplay() a list of elements whose display needs to alternate from its present display setting of "none" to "block". Note also that the code below contains a list of all the elements whose display needs to be programmatically controlled and which is then compared with the list passed to the function as a parameter:

void changeDisplay(var displayList) {
  var idList = [_tabOneFocus,_tabTwoFocus,_tabOneReady, 
                _tabTwoReady,_blogOut,_githubOut];
  for(var i = 0; i < idList.length; i++) {
    var block = false;
    for(var j = 0; j < displayList.length; j++) {
       if(idList[i] == displayList[j]) {
          block = true;
          break;
          }
       }
    if (block) {
      idList[i].style.display = "block";
    } else {
      idList[i].style.display = "none";
    }
  }
}

The only thing left to do to complete the tabbed panels is the CSS, much of which is left to the designer to craft as he or she pleases. There are just a few things I would like to point out. First, we define a class that applies to all the tabs, making sure to define a width of the tab:

#feedContainer .tab {
	font-family: Georgia, "Times New Roman", Times, serif;
	font-size: 18px;
	font-variant: small-caps;
	width: 210px;
	white-space: nowrap;
	text-align: center;
	padding: 20px 10px 5px 10px;
	height: 25px;
}

Then, since we only have two tabs, we can simply float tab one to the left and tab two to the right. If you want to use more than two tabs, you can float all tabs to the left and then use margin-left (since we no longer care about the double margin bug of IE6!) to adjust the spacing between each tab.

#feedContainer #tabOneFocus {
  cursor: default;
  float: left;
  background-image: url(images/tabbedPanelTabSelected.png);
  background-repeat: no-repeat;
  background-position: center top;
  margin-left: 40px;  
  color: #000;
}

#feedContainer #tabOneReady {
  float: left;
  background-image: url(images/tabbedPanelTabNotSelected.png);
  background-repeat: no-repeat;
  background-position: center top;
  margin-left: 40px;
  color: #556270;
}
#feedContainer #tabOneReady:hover {
  cursor: pointer;
  color: #000;
  text-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
}

#feedContainer #tabTwoFocus {
  cursor: default;
  float: right;
  background-image: url(images/tabbedPanelTabSelected.png);
  background-repeat: no-repeat;
  background-position: center top;
  margin-right: 40px;
  color: #000;
}
#feedContainer #tabTwoReady {
  float: right;
  background-image: url(images/tabbedPanelTabNotSelected.png);
  background-repeat: no-repeat;
  background-position: center top;
  color: #556270;
}
#feedContainer #tabTwoReady:hover {
  cursor: pointer; 
  color: #000;
  text-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
}

Finally, the divs holding the content need to clear the floats. Note that the initial state of div githubOut's display property is initialized to none:

#feedContainer #blogOut {
  clear: both;
  padding: 10px 30px;
  text-align: left;
}
#feedContainer #githubOut {
  clear: both;
  padding: 10px 20px;
  text-align: left;
  display: none;
}

The files for this didget at on github. Please feel free to take a look.

Conclusion: Dart is Fun!


One problem I'm having with Dart, if you can call this a problem, is that the longer I work with it, the less I'm able to drag myself away and work with any other language, like JavaScript. It's not that JS is bad, it's just that Dart is better. And better in a way that makes it addicting - like you can visualize it being the last language you'll ever need to learn. Now wouldn't that be something? But I've neglected my other projects long enough, and need to get back to them. I'm saying this though, even as I'm plotting what I'm going to be doing next in Dart.


Works Cited

[1] Dart's Homepage
[2] Improving the DOM: Dart's DOM API
[3] Dart bug 1142
[4] Dart Discussion: JSONP with Dart
[5] Dart Discussion: Dart with JS APIs
[6] GitHub API v3: Working with CORS
[7] CORS: an insufficient solution for same origin restrictions
[8] Dotclear Plugin dotAjax
[9] JSONLint - The JSON Validator
[10] Dart Puzzlers Chapter 2: Puzzle 13
[11] Dart bug 1866/1867
[12] Interface XMLHttpRequest in dart:html
[13] Dart Editor
[14] Wikipedia: Same Origin Policy
[15] Cross Domain AJAX with JSONP
[16] Cross domain AJAX with CORS
[17] Mozilla: Cross site XMLHttpRequest with CORS
[18] Functional CSS Tabs Revisited
[19] Creating a Tab Panel

by Richard Griffith at May 19, 2012 07:36 PM

May 18, 2012

Dartwatch

DartJSONP for simple JSONP callbacks

At last the London Dart Hackathon last week, one on the questions that I was asked the most was how to access JSON data using XMLHttpRequest that is served up from a different server to the one serving the Dart app.  XMLHttpRequest is part of the magic behind "AJAX", and allows a browser to request data from a server, but accessing data from a different server presents some challenges.

XMLHttpRequests blocked

The issue is this: In the web browser, you use XMLHttpRequest to access data from a different server, in order to create some kind of "mashup" application.  Browser security restricts this unless the remote server returns special headers indicating that this is allowed.  This is shown in Figure 1, below, with a typical JSON request, such as when trying to access JSON data from Twitter: http://search.twitter.com/search.json?q=dartlang



Figure 1. XMLHttpRequest response data is blocked by browser security

JSONP workaround

This has already been solved in JavaScript by using a callback.  The data returned is wrapped in a JavaScript function call (known as a callback), so that when the data is received, the browser calls the callback function, passing in the returned data.   This is known as JSONP, with the url now having a new callback parameter (specifying the callback function name), for example: http://search.twitter.com/search.json?q=dartlang&callback=onDataReceived

Using JSONP with Dart

Unfortunately, this is trying to call a JavaScript function, and not a Dart function.  At present, the only way to communicate between JavaScript and Dart in the same application is by using window.postMessage in JavaScript and adding a handler with window.on.message.add( ... ) in Dart.  Seth Ladd discusses how to achieve this for JSONP callbacks in his blog post, and the flow is much like that shown in Figure 2.


Figure 2 - Using JSONP with a JavaScript callback and window.postmessage

Introducing the DartJSONP library

This all works fine, but you need to write some boilerplate code, such as manually adding a JavaScript callback function to your html, and writing a postMessage handler to receive the data.  If you want to receive data from multiple, separate sites, you also need to design a way to tell the difference between the different callbacks sent by postMessage.

In order to make this simpler, I have created the DartJSONP library, which automates the task that Seth describes in Option 2 on his blog post.  This allows you to call out to multiple servers and get JSONP data back with minimal code.

The following example shows how you can access some Twitter data using DartJSONP which defines the class JsonpCallback.  You create an instance of the object, passing in the name of the callback (which can be any valid function name).  Then when you call the doCallback(url) function, the DartJSONP library takes care of all the JavaScript and postMessage handling, simply returning the data in the onDataReceived handler.


var callbackFuncName = "twitterFunction";
JsonpCallback twitterCallback = new JsonpCallback(callbackFuncName);
twitterCallback.onDataReceived = (Map data) {
  // do something with the returned data
};

var twitterUrl = "http://search.twitter.com/search.json?q=dartlang&callback=$callbackFuncName";
twitterCallback.doCallback(twitterUrl);


Internally, JSONP will dynamically add the JavaScript callback function, invoke the call to the remote server, post the response back to JavaScript, which posts the data back to Dart.

You can see this running by navigating to this link: http://example.dartwatch.com/jsonp/DartJsonPtest.html which loads data from Google Plus and Twitter (it's the example that is used in the test currently on github).

JSONP is available on Github.

References:
Seth's blog post where the JSONP and postMessage handling is described
MDN documentation on CORS - which is how web servers can avoid the requirement for clients to use JSONP




by Chris B (noreply@blogger.com) at May 18, 2012 05:44 PM

May 16, 2012

Seth Ladd

Misleading strong type systems


This post is a record of a Dart Misc mailing list post titled "Types are useless (?)".

The original author was curious why Darts "allows running code with invalid arguments".  My reply follows:

---


For reference, let's look at Java. Many would think that Java has a "strong
type system" and that its types prevent, as you say, invalid arguments.
However, it's easy to write a Java program that will compile just fine, yet
fail at runtime. In your words, it will allow running code with invalid
arguments. Here's an example:

import java.util.*;

public class hacked {
  public static void test(int i) {
    System.out.println(i);
  }

  public static void main(String[] args) {
    String msg = "hacked";

    Map cache = new HashMap();
    cache.put("hacked", msg);

    // later
    int hacked = (Integer) cache.get("hacked");
    test(hacked);
  }

}

This code will compile, yet fail at runtime. (Yes, I could have used
generics to help a bit, but they aren't mandatory)

I will assert that even with something like Java's type system, which
creates barriers and hoops for developers, one can still write incorrect
code. In fact, any time you have to cast, you are trying to express
something your type system can't express.

So, what if a language has a new perspective on static types? What if a
language used static types as annotations, which helped you without getting
in your way? Your tools still give you warnings and errors, yet your
programs will run without burdensome ceremony.

There is a direct tradeoff between constraining type systems that disallow
any ever possible error (which is also probably impossible), and developer
productivity. Remember that Dart is trying to appeal to a wide array of
developers, from JavaScript developers that deal only in functions and have
never seen a type, to Java/C# developers that love their tools, static
types, and structure. Dart is optimizing for developer productivity
without sacrificing structure or tooling. Its optional types help you when
you need them, but don't create unnecessary barriers.

I personally felt more free once I realized that no mainstream language
actually had a perfect type system. A combination of tool support, static
analysis, checked mode assertions, and unit tests can allow me to feel just
as safe, yet more productive.

Thank you for your questions, it's healthy to be skeptical. :)

---

by Seth Ladd (noreply@blogger.com) at May 16, 2012 09:39 PM

Dartlang

Extract local variable refactoring now in Dart Editor

Posted by Devon Carew



New Dart Editor build is now available. Highlights from build 7696 include:
  • Extract local variable refactoring!
  • Search and search box fixes
  • Ignore . (hidden) directories for search results
  • Update #import, #source and #resource references in Dart source during resource rename in Files view
  • General fixes to the analysis server
  • And in non-editor news: the dart:dom library has been throughly deprecated
Read the full change log or start downloading the Dart Editor from the Editor tutorial.

Thanks for trying Dart!

by Dart News (noreply@blogger.com) at May 16, 2012 08:01 PM

Notes from 5/14 Dart language meeting

Posted by Bob Nystrom


Once a week, Lars, Gilad, and Kasper meet to discuss the design of the language. For your delight and edification, here are my notes from this week's meeting:

var and Dynamic

We see people using Dynamic as a type argument even when they don't have to. Also see people trying to use var as a type argument. Gilad said there are very few cases where you actually do need to use Dynamic.

The source of the confusion is that var is used in a place (local variable declaration) where you can also use a type to declare a variable, so it makes people think var is itself a type.

He proposed always requiring var to declare variables to clarify that:

  var int foo = 123;

but doesn't think it will be liked.

Alternately, we could follow users' intuition and allow var to be used like a type:

  var map = new Map<int, var>();

Gilad is worried allowing var anywhere a type can appear may have some unpleasant corner cases we aren't thinking of. He likes the current behavior because he knows it is non-problematic.

No decision was reached.

I asked if when a user declares a variable with var are is the intent they are stating that they don't care what the variable's type is, or that they do care and want it to be dynamic? Gilad said from the language's point of view, it doesn't matter because there is no difference.

Re-export

Agreed to have an "export" parameter in #import directives. So to re-export, you do:

  #import('somelib.dart', export: true);

If you want to use a library internally but only re-export a subset of its names, you would do:

  #import('somelib.dart');
  #import('somelib.dart', show: ['foo', 'bar'], export: true);

One consideration is how this works with prefixes. If you re-export something you imported with a prefix, does the prefix compound?

The current answer to keep the semantics restricted is "no". Prefixes are for using a name internally, and do not affect how it gets exported.

Cast syntax

Our hangout flaked out and Gilad dropped off for a few minutes. In that interim, we briefly discussed an explicit cast syntax.

Kasper pointed out that if you want to support an optional second type system that doesn't allow implicit downcasts, you'll need some kind of cast syntax. Lars says "as" is probably a good idea.

Statics on interfaces

Lars does not like code appearing in interfaces. Kasper says default classes are confusing for people, and that in large interfaces, people don't see that the constructors are there.

We talked briefly about constructors in interfaces just working like factory constructors so that you wouldn't need "default" to do the delegation.

Lars had to leave at this point. I don't think there was a firm decision, but it seems like we do not intend to support static methods defined directly in interfaces but may support them by delegating to the default class.

Directives

Kasper mentioned that we may want to refresh the directive syntax at some point. Users don't seem to like it. Gilad favors dedicated syntax for imports.

Cheers!

by Dart News (noreply@blogger.com) at May 16, 2012 05:50 PM

Dartwatch

Dart in Action is Manning's deal of the day


Dart in Action is Manning's "Deal of the Day" 


Deal of the Day for May 16th, 2012
Get half off Dart in Action. Enter dotd0516 in the Promotional Code box when you check out at manning.com.

Valid from Midnight Eastern Time, May 16th for 24 hours only.




Dart in Action is currently available as an "early access" publication (MEAP), which gives you the opportunity to provide feedback and influence the book.  4 chapters are currently available, two more are currently with the publishers, and I should be working on chapter 7 (instead of typing this!)


by Chris B (noreply@blogger.com) at May 16, 2012 12:09 PM

May 15, 2012

Dartwatch

Weekly Dart community update – week ending 15 May

Dart weekly news update.  Extended this week, due to the Dartwatch server outage.  News from Dart Hackathons, Libraries and Blogs.

Hackathon News:


Jai Luthra shared his Rock Paper Scissors Game: (G+)
London Dart Hackathon:
Ukraine Hackathon:

Events:

Blog Posts


Adam found (G+)this dart podcast from the Silicon Valley hackathon:

Dart Libraries and Examples


Adam tidied his (G+) websocket chat example:
Justin Fagnani created a static file server (G+)




by Chris B (noreply@blogger.com) at May 15, 2012 08:01 PM

Dartwatch up and running again, and apologies for the RSS spam

Dartwatch up and running again, and apologies for the RSS spam


Following the unfortunate incident with my ISP's RAID array, I've now pretty much transferred the site over to blogger.  I've still got to move the images over, and changing the RSS feed on feedburner has triggered all the posts to be re-issued - sorry for that!

In terms of timing, it couldn't have been worse, having been the weekend of the London Dart Hackathon, so apologies to all those who who tried to access the community packages list.

I'm catching up with everything now - normal service is being resumed.


Storm Internet: Status Update - 12/05/2012 15:14:13
WinSrv104 hosted at IP address 94.76.230.101 has suffered a catastrophic disk failure. This has been caused by a failed RAID array which has corrupted all three hard disks on the server. We are now in the process of setting up a new temporary server in order to get sites and hosted services back online ASAP. Once the server is setup we will begin restoring web sites from backup copies we hold. We estimate this process to complete within the next 18 hours. The reason for the lengthy delay is due to the amount of data that needs to be transferred. 

 (It took them the whole weekend to get back up and running again).


by Chris B (noreply@blogger.com) at May 15, 2012 04:21 PM

Dartlang

5 items the Dart team has on their radar

Posted by Seth Ladd

Hello Dartisans,

Some of you have asked what the bigger picture is with what we’re working on. The Dart team has the following items on their radar. There is no particular order or priority implied, nor is this exhaustive, but these are some of the features we are either working on or intend to work on.

Across all components we are working improving performance and stability.


  • Dart language and libraries
    • Language see http://goo.gl/2Z9ZY (Area-Language, Milestone-M1)
    • dart:html: parity with the deprecated dart:dom, IndexedDB
    • dart:io: HTTPS, improved HTTP support, optimize performance
    • Package manager: discover, install, upgrade, version, and publish.
    • Date refactoring
    • Continued work on Future and Isolates API
  • Dart Editor
    • background analysis (which will provide a significant speedup)
    • debugging support (browser and VM)
    • simple refactoring support (various rename options to start)
    • search improvements (like text search in libraries)
  • Dart VM
    • debugging standalone and server programs (from command line and from Editor).
    • conformance with the language spec (in particular synchronize with dart2js when implementing new features)
    • implementation of mirror based reflection
    • improved handling of GC
    • rollout of optimizations to the new compiler pipeline
  • Dartium and Dart + Dev Tools
    • dev tools debugger to understand Dart scripts
  • Dart compiler to JavaScript
    • dart2js to replace frog
    • conformance with the language spec
    • improve size and performance of generated JS code

As always, thanks for trying Dart! Please join the Dart mailing list for discussions, and check out Stack Overflow for how-to questions. Please use http://dartbug.com to file bugs and issues.

by Dart News (noreply@blogger.com) at May 15, 2012 04:13 PM

May 13, 2012

Dartery

Time Server Demo with WebSockets

Continuing from the last post on static file serving, here's a version of the Time Server demo that uses WebSockets to push time updates from the server to the browser.

Compared to my last experiment with WebSockets just two months ago, Dart has come a long way. I'm not sure it can get much easier that this!

First, here's server.dart:
#import('dart:io');

Map<String, String> contentTypes = const {
"html": "text/html; charset=UTF-8",
"dart": "application/dart",
"js": "application/javascript",
};

List<WebSocketConnection> connections;

void main() {
connections = new List();

WebSocketHandler wsHandler = new WebSocketHandler();
wsHandler.onOpen = (WebSocketConnection conn) {
connections.add(conn);
conn.onClosed = (a, b) => removeConnection(conn);
conn.onError = (_) => removeConnection(conn);
};

HttpServer server = new HttpServer();
server.addRequestHandler((HttpRequest req) => (req.path == "/time"), wsHandler.onRequest);
server.addRequestHandler((_) => true, serveFile);

new Timer.repeating(1000, (Timer t) {
Date time = new Date.now();
connections.forEach((WebSocketConnection conn) {
conn.send(time.toString());
});
});

server.listen("127.0.0.1", 8080);
}

/// Very simple async static file server. Possibly insecure!
void serveFile(HttpRequest req, HttpResponse resp) {
String path = (req.path.endsWith('/')) ? ".${req.path}index.html" : ".${req.path}";
print("serving $path");

File file = new File(path);
file.exists().then((bool exists) {
if (exists) {
file.readAsText().then((String text) {
resp.headers.set(HttpHeaders.CONTENT_TYPE, getContentType(file));
resp.outputStream.writeString(text);
resp.outputStream.close();
});
} else {
resp.statusCode = HttpStatus.NOT_FOUND;
resp.outputStream.close();
}
});
}

String getContentType(File file) => contentTypes[file.name.split('.').last()];

void removeConnection(WebSocketConnection conn) {
int index = connections.indexOf(conn);
if (index > -1) {
connections.removeRange(index, 1);
}
}

I think it's incredibly straight forward. Here's the important bits:

  1. First we set up a very basic WebSocket handler that adds each incoming WebSocketConnection to a list, and removes the connection when it's closed or if there's an error.
  2. Then we create the HTTP server use the WebSocket handler for /time and the static file handler for everything else.
  3. Finally we create a Timer that updates all the connections once a second.

Now for the client side. If you put these files in the same folders as server.dart, and compile client.dart to JavaScript, everything should just work when you run the server.

index.html:
<!DOCTYPE html>

<html>
<head>
<title>Server Timer</title>
<style>
body { background-color: teal; }
h2 { background-color: white; border-radius: 8px;
border:solid 1px #555; text-align: center; padding: 0.5em; }
</style>
</head>
<body>
<h2>Server Time:<span id="time"/></h2>
<script type="application/dart" src="client.dart"></script>
<script src="http://dart.googlecode.com/svn/branches/bleeding_edge/dart/client/dart.js"></script>
</body>
</html>

client.dart:
#import('dart:html');

void main() {
new WebSocket("ws://localhost:8080/time").on.message.add((MessageEvent e) {
document.query("#time").innerHTML = "${e.data}";
});
}

Here we simply have a WebSocket object that connects to the server at the /time URL and replaces the text of our #time span with whatever message it receives.

I don't know about you, but this is so much simpler than the numerous hacks of Flash, Comet, hanging GETs, etc. that have been used over the years that I'm ready to start making collaborative apps with WebSockets and forget about supporting older browsers. Well... in my day job I have to support at least middle aged browsers, so I'm half kidding. But still...

Next time I get to experiment again I think I'll be working on a bi-directional RPC mechanism. Either that or a painting app for something completely different.

Awesome work Dart team, and have fun Dartisans!

by Justin Fagnani (noreply@blogger.com) at May 13, 2012 02:11 AM

A Simple Async HTTP Static File Server in 36 Lines

Sorry for the long radio silence since I last blogged about Dart. I haven't been able to do as much extra-curricular programming as I'd like lately, and for a while Dart wasn't ready to handle many of the experiments I wanted to try.

Luckily, or more accurately, due to the incredible work of the Dart team, the language and libraries have come a long way and I finally got back to trying out WebSocket support. I'm very glad to report that all of the issues I ran into last time have been solved. Great work Dart team!

Along the way towards an end-to-end WebSocket demo, I needed to serve some static files - just the basic HTML, JavaScript and Dart assets - so I coded up a quick static file server using the new-ish dart:io HttpServer.

My first cut used the File.*Sync() methods, because I'm no node.js junkie and that's what I'm used to. I quickly saw that the async APIs are pretty easy to use, and the code isn't too ugly, assuming you're not chaining together too many async calls. So here it is, a static file server in 36, quite readable, lines:

#import('dart:io');

Map<String, String> contentTypes = const {
"html": "text/html; charset=UTF-8",
"dart": "application/dart",
"js": "application/javascript",
};

void main() {
HttpServer server = new HttpServer();
server.addRequestHandler((_) => true, serveFile);
server.listen("127.0.0.1", 8080);
}

/// Very simple async static file server. Possibly insecure!
void serveFile(HttpRequest req, HttpResponse resp) {
String path = (req.path.endsWith('/')) ? ".${req.path}index.html" : ".${req.path}";
print("serving $path");

File file = new File(path);
file.exists().then((bool exists) {
if (exists) {
file.readAsText().then((String text) {
resp.headers.set(HttpHeaders.CONTENT_TYPE, getContentType(file));
resp.outputStream.writeString(text);
resp.outputStream.close();
});
} else {
resp.statusCode = HttpStatus.NOT_FOUND;
resp.outputStream.close();
}
});
}

String getContentType(File file) => contentTypes[file.name.split('.').last()];

Now, I wouldn't actually use this server. It's missing all kinds of error checking and probably exposes every file on your computer. It does show that the APIs are pretty nice and understandable though. I still find Dart much more readable that either Java or JavaScript.

Next time I'll show a full client and server Dart application that uses this server to send the HTML and Dart or JavaScript to the browser and WebSockets for subsequent server pushes.

Cheers!

edit: I switched to a Map literal for the content types. I keep forgetting about Dart's nice literal syntax.

by Justin Fagnani (noreply@blogger.com) at May 13, 2012 12:43 AM

May 12, 2012

Dartlang

New Dart Lang Spec tweaks switch statement, abstract methods, and more

Posted by Seth Ladd


We just published version 0.09 of the Dart Language Spec.

Changes include:

  • Abstract methods may specify default values.
  • Interface methods may specify default values.
  • The ~/ operator can apply to doubles.
  • Refined rules regarding abstract class instantiation, allowing factories to be used.
  • switch statement specification revised.
  • throw may not throw null.
  • Imports introduce a scope separate from the library scope. Multiple libraries may share prefix.
  • Recursive typedefs disallowed.

The switch statement now requires either all the expressions in the cases to evaluate to constant integers or they all evaluate to constant strings. Also, a warning can be generated if you omit the break statement in a case.

As always, the Dart mailing list is standing by to answer your questions, and dartbug.com is a good way to file bugs and feature requests.

by Dart News (noreply@blogger.com) at May 12, 2012 11:03 AM

May 07, 2012

Seth Ladd

When Dart types aren't optional


Dart, the structured web programming language, has a feature typically called "optional types". Dart claims that "type annotations don't affect the runtime semantics of the code". This post helps to explain when a type is and isn't optional, and what "type annotation" means as different than "type".

The Dart discussion mailing list kicked off a good thread about generics, which evolved into when types can be optional. The Dart community chimed in with great answers (thanks to Ladislav, Sam, John, Dirk, Ross, Bob, and Eli!). Bob Nystrom summed it up well, with some examples that I wanted to specifically highlight:

Bob writes:

---


Types aren't always annotations. There are type annotations, but there are also places where types appear in code that are not annotations. For example:

// type annotations: 


int i;
foo(int i) => ...
class Foo {
  int bar;
  int baz() => ...



// types that are not annotations:


foo is String;
new Foo();
new Foo<Bar>();
class Foo extends Bar implements Baz
{ ... } catch (SomeException ex) { ... } 

In every place where a type appears outside of an annotation, the type absolutely does have an important effect at runtime, and cannot be ignored. It's only type annotations that are "optional" in that sense.

---


Remember that Dart programs can run in two different modes: production mode and checked mode. In production mode, which is the default runtime mode, the program ignores type annotations. Production mode loads, compiles, and runs the code as fast as possible.

In the above examples, the types that are not annotations are respected in production mode.

In contrast, checked mode is an optional mode that does respect the type annotations and turns on "dynamic type assertions". In this mode, Dart will automatically insert assertions which check the types of objects with the declared static type annotations. If there isn't a match, an exception is raised to indicate the potential problem at the location of the mismatch. In general, we think developers should develop and test in "checked mode". Learn more about how to enable checked mode in the SDK and enable checked mode in Dartium.

In the above examples, checked mode will respect both the type annotations and the types that are not annotations.

As always, the Dart discussion mailing list is a great way to join the conversation and get your questions answered. You might also be interested in the Dart questions on Stack Overflow.

by Seth Ladd (noreply@blogger.com) at May 07, 2012 08:19 PM

May 04, 2012

John Evans

I'm A Contributor, And So Can You!

A while back I made a small contribution to the Dart code base (Dart is open source, didn’t you know?). It wasn’t anything spectacular, just a enhanced output for HTML unit tests (source, blog) Eventually, my patch was accepted and is now part of the Dart trunk codebase, which is both personally satisfying and just really cool. More to my pleasant surprise, I found that the Google Dart team added my name to the AUTHORS document in the root of the Dart repository – neat!




This started me thinking about other meaningful ways I could contribute to the project. There were lots of improvements to Dart that I’d suggested over time (all of them awesome), so why not work on one of those, right? As it turns out, this isn’t as easy as it seems. The Dart core code moves fast and furious inside Google – and that’s a good thing. It also means that submitting something truly impactful requires one to keep up with the fast pace of change in the ‘bleeding edge’ branch; not such an easy task. And even if one were able to keep up with the change rate, any patch that would significantly alter the core language would come under heavy scrutiny, and rightly so. Such a contribution might not be considered at all.

After some dialog with Seth and other members of the Dart team on this topic, we (well mostly he) came up with a list of suggestions for folks who want to contribute to the Dart open source project. While some of the suggestions on the list aren’t “core” Dart programming tasks, they are important to the project, and would provide a way for Dart enthusiasts to get their own names listed as a contributor in the Dart AUTHORS document.

It is important to note that the items in the list below are merely suggestions.  You can submit anything you like, and it is highly recommended that you familiarize yourself with the  “How To Contribute - Guidelines” as your first step.  It is also important to note that there are no guarantees that your submission will be accepted.  In fact, you’ll probably go through some stringent, but ultimately satisfying, feedback cycles with the Google Dart team.  I found the process to be both challenging and rewarding.

Contribution Suggestions (see ‘Resources’ below for reference material):

  • Documentation (code docs, updated/comprehensive README’s, etc.)
  • Better build instructions (full walk-throughs for each OS)
  • Better “How To Contribute” docs (full walk-through, step-by-step)
  • HTTPS support for Dart VM
  • Libraries to unify HttpClient and XHR
  • Libraries to unity FileSystem API and the File/Directories form dart:io
  • Unified Logging API
  • Move to true Element constructors in dart:html (from Element.tag(‘div’) to Element.div())
  • Add or update samples (check existing samples first)

So what are you waiting for? Become a Dart project contributor today!

Resources:

by John Evans (noreply@blogger.com) at May 04, 2012 04:24 PM

April 30, 2012

Seth Ladd

Dart Crypto early access


The Dart project just saw its first crypto libraries land, specifically for SHA1 and SHA256. Also appearing is HMAC support. Learn how to use these very new libraries in this post.

This new functionality is very new. You'll need to pull the latest from the bleeding_edge branch, as of 2012-04-30. It's so new, it's not even wired into the dart: library scheme, nor is it in the SDK yet. I expect crypto libs to get the full SDK treatment very soon.

Here's an example of how to create a SHA256 hash and convert to a hex string:


#import('../dart/lib/crypto/crypto.dart');


// Want this in the crypto lib? Star this bug: http://code.google.com/p/dart/issues/detail?id=2839
String digestToString(List<int> digest) {
  var buf = new StringBuffer();
  for (var part in digest) {
    buf.add("${(part < 16) ? "0" : ""}${part.toRadixString(16).toLowerCase()}");
  }
  return buf.toString();
}


main() {
  var sha = new SHA256();
  print(digestToString(sha.update('hello'.charCodes()).digest()));
}

The current crypto library includes a Hash interface:


/**
 * Interface for cryptographic hash functions.
 *
 * The [update] method is used to add data to the hash. The [digest] method
 * is used to extract the message digest.
 *
 * Once the [digest] method has been called no more data can be added using the
 * [update] method. If [update] is called after the first call to [digest] a
 * HashException is thrown.
 *
 * If multiple instances of a given Hash is needed the [newInstance]
 * method can provide a new instance.
 */
interface Hash {
  /**
   * Add a list of bytes to the hash computation.
   */
  Hash update(List<int> data);


  /**
   * Finish the hash computation and extract the message digest as
   * a list of bytes.
   */
  List<int> digest();


  /**
   * Returns a new instance of this hash function.
   */
  Hash newInstance();


  /**
   * Block size of the hash in bytes.
   */
  int get blockSize();
}

View the full commit for more code and test cases.

As always, the Dart team is interested in your feedback. Please file bugs and feature requests or join the mailing list to share your experience. Thanks for trying Dart!

by Seth Ladd (noreply@blogger.com) at April 30, 2012 10:53 PM

April 27, 2012

John Evans

GitHub Most Watched

Pleasantly surprised to find that 3 of my projects are in top 10 of the github "most watched" list.


Thanks Dartians! :)

by John Evans (noreply@blogger.com) at April 27, 2012 10:33 PM

Seth Ladd

Dart Server supports Web Sockets


Dart is a structured web programming language that runs on the client and the server. Web sockets are bi-directional data channels for real-time streaming communication between modern web browsers and servers. Thanks to a recent commit, Dart Servers can host Web Socket connections now!

You'll need a copy of the bleeding_edge Dart code as of 2012-04-26 for this to work.

Dart already ships with basic HttpServer functionality. The new Web Socket is built on top of HttpServer, so it slides right into an existing Dart server app. Just like Node.js, Dart server apps favor asynchronous callback APIs, and the Web Socket implementation is no different.

The following code snippet is a simple example of a Web Socket echo server running in Dart.

#import('dart:io');

void main() {
  HttpServer server = new HttpServer();
  WebSocketHandler wsHandler = new WebSocketHandler();
  server.addRequestHandler((req) => req.path == "/ws", wsHandler.onRequest);
  
  wsHandler.onOpen = (WebSocketConnection conn) {
    print('new connection');
    
    conn.onMessage = (message) {
      print("message is $message");
      conn.send("Echo: $message");
    };
    
    conn.onClosed = (int status, String reason) {
      print('closed with $status for $reason');
    };
          
    conn.onError = (e) {
      print('Error was $e');
    };
  };
  
  server.listen('127.0.0.1', 8000);
}

Once you have this running, you can use a simple Web Socket test page to connect and receiving echo messages. For example, if you are running the above code, you can connect to ws://localhost:8000/ws

As always, the Dart team wants to hear your feedback. Please don't hesitate to join the Dart mailing list and file bugs and feature requests at dartbug.com. Thanks!

by Seth Ladd (noreply@blogger.com) at April 27, 2012 06:49 AM

April 26, 2012

Dart Vader (German)

Dart vs Motörhead: Das Ergebnis steht fest

Am Dienstag, den 24.04.2012 war ich Gast der Java User Group Saxony. Ich traf so einige nette Leute und war von der Organisation dieses kleinen Events beeindruckt. Dank der JUG Saxony konnten wir nun endlich das Geheimnis lüften: Wer rockt mehr, Motörhead oder der Newbie Dart? Näheres kann meinen online Folien entnommen werden (pdf).

Die letzte Folie ist die vermutlich wichtigste: die Schlacht zwischen David-Dart und Goliath-Motörhead endet mit einem unentschieden!

Dart macht ein paar Punkte in Bezug auf Offenheit (niemand sagt Lemmy wie der seine Songs zu schreiben hat), Zukunft (Lemmy ist immerhin schon fast 70) und Geschwindigkeit (Motörhead ist schnell, aber diese Bits und Bytes…). Aber Motörhead liegt mit den Punkten Lautstärke, Anzahl der Releases (21!) und einer stabilen API, äh, Bandbesetzung vorne.

Es war ein spaßiger Abend für mich. Und ich hoffe, das Gleiche gilt für meine Gäste.

by grobmeier at April 26, 2012 04:08 PM

Christian Grobmeier

Dart vs Motörhead: The result and the slides

On tuesday (24.04.2012) I was guest of the Java User Group Saxony. I met nice people and was pretty impressed by the well done organization of this little event. Thanks to the JUG Saxony we could finally reveal the secret: who rocks more, Motörhead or the uprising Dart? You can check out the my slides online (pdf) and see yourself.

The last slide is the most important: the battle between David-Dart and Motörhead-Goliath ends with a draw!

Dart makes some points on openness (tell Lemmy how he should write songs!), future (Lemmy is nearly 70) and speed (Motörhead is fast, but bits and bytes… you know). But Motörhead is louder, has much more releases (21!) and a stable API, er, Lineup!

This was a fun evening for me and I hope for my guests too.

by Christian Grobmeier at April 26, 2012 03:59 PM

April 22, 2012

Olov Lassus

Call for testing: Pygments Dart highlighter

As mentioned before, the Dart highlighter lives in the upstream Pygments repository now and is included in releases since 1.5 (released Mar 10, 2012). I will try to keep it correct and updated.

Another milestone is that Github recently started using it! I found a few bugs just by clicking around in people’s repositories. The most obvious was keyword-detection on substrings, i.e. the String substring of StringBuffer got marked as a keyword. Another was failing to recognize escape characters inside string literals. Both are now fixed in my repo, so the example below renders fine.

main() {
  StringBuffer sb; // String isn't a keyword
  var integer; // nor is int
  var str = "Escapes \"just works\" now";
}

I need help with testing the highlighter to find bugs or missing features. I’m maintaining the Dart highlighter in my bitbucket repo. You can help by downloading it, trying it out on your own code and letting me know what works or not:

hg clone https://bitbucket.org/olov/pygments-main
cd pygments-main
./pygmentize -f html -o yourfile.html yourfile.dart

If you don’t have Mercurial (hg) installed then you can also click “get source” on bitbucket to download the source as a zip-file. Running pygmentize will create markup from your source code, which you then need to combine with a style sheet to get some color going. Feel free to copy my color scheme (syntax.css) if you like it. You can also run pygmentize yourfile.dart without -f and -o to get highlighted text directly on your console.

To install the development version of pygments system-wide just run sudo ./setup.py install.

File issues on bitbucket or fire a mail to the Dart misc thread or me directly. Even better, submit a pull request! :)

Show comments (Dart misc)

by Olov Lassus at April 22, 2012 11:30 AM

April 21, 2012

John Evans

My Own Little Dart Hackathon: XML Parser

The Dart hackathon taking place around the world this weekend looks like a blast.  I’m really happy to see so many new faces exploring and working with Dart. 

Sadly, there wasn’t a venue in my area (Dallas) this time, but I decided not to let that stop me from throwing something out there I’ve been meaning to do for quite some time.  I’ve been needing something like this for a while anyway for my Buckshot project, and I hope others will find it useful.

It’s not fully finished yet, but it does parse and stringify your average xml document.

Still on the to-do list:
  • Handle nested strings in attribute values
  • Handle comment nodes.
  • Support in-code queries on XmlNode trees (at least tag name queries).
  • Support for prologue and doctype nodes.
  • Unit tests.
Here's the Repo: https://github.com/prujohn/dart-xml

Happy Darting!

by John Evans (noreply@blogger.com) at April 21, 2012 09:29 PM

April 19, 2012

Dart Vader (German)

Entwickler Magazin: Dart und das liebe Web

Teil 2 meiner kleinen Dart-Serie im Entwickler Magazin ist erschienen. Er heißt “Dart und das liebe Web” und kümmert sich hauptsächlich um DOM-Manipulation mit Dart. Enjoy!

by grobmeier at April 19, 2012 05:56 AM

Darts neue Isolate API

Eines meiner Lieblingsfeatures in Google Dart sind die Isolates (eine Art Multithreading Feature für Dart, falls Sie es noch nicht kennen. Jedoch war die erste Version der API noch sehr komplex. Sie erinnerte sehr stark an das Java Threading und war generell sehr schwer zu erlernen. Die Dart-Entwickler haben jedoch recht bald angekündigt, eine Überarbeitung vorzunehmen, was mittlerweile getan ist.

Mit der alten API musste man noch die Isolate-Klasser erweitern, um ein Isolate zu erstellen. Dabei wurde zwischen “Heavy” und “Light” Isolates unterschieden. Das ist alles Vergangenheit. Die Dart VM entscheidet mittlerweile für den Entwickler, welche Art von Isolate angemessen ist. Außerdem muss nicht mehr von Isolate abgeleitet werden, jetzt arbeitet man mit Funktionen. Das Ergebnis führt zu sehr viel besser lesbaren Code. Ein Beispiel.

Zunächst muss das Isolate-Packet importiert werden. Auch das ist neu, denn vorher haben sich die Isolate Klassen im Core befunden.

#import('dart:isolate');

Dann kann der Spaß beginnen!

Zunächst definiere ich eine Funktion, die als neues Isolate agieren soll.

process() {
  port.receive((var message, SendPort replyTo) {
      print ("Got message: ${message}");
      replyTo.send("close");
      port.close();
  });
}

Es muss sich hierbei um eine Top-Level Funktion handeln und darf keinen Rückgabewert haben. “Void” würde daher nicht funktionieren. In Zeile 2 sieht man, dass ich auf den “port” zugreife. Es handelt sich hier um eine get-Methode, die den Port dieser Funktion zurückliefert. Über Ports kann man mit anderen Isolates kommunizieren.

Dieser Port kann eien Funktion ausführen, wenn eine Nachricht erhalten wurde. Dessen Argumente sind dann die eigentliche Nachricht. Eine Nachricht kann aus null, num, bool, double oder String bestehen. Auch Listen und Maps, die diese Typen beinhalten, sind erlaubt. Sogar Objekte sind möglich, wenn die Isolates im selben Prozess laufen (vorher auch als “light” Isolate) bekannt. Die Dokumentation sagt dazu, diese ist der Fall wenn das Isolate mit “spawnFunction” erzeugt wurde.

Zusätzlich zur Nachricht erhalten wir auch noch einen SendPort, was eine Art Rückkanal zum sendenden Isolate darstellt.

In meiner Funktion drucke ich eine Nachricht, sende einen “close”-String zurück und schließe im Nachhinein den Port. Das Isolate ist dann bereit in den Müll zu wandern und die VM sollte dies auch erledigen. Es ist wichtig, die Ports zu schließen, da sonst der Code für immer läuft und den Speicher unnötig belastet.

Soweit zur Isolate-Funktion. Sehen wir uns an, wie wir die Funktion dann eigentlich erzeugen (spawn).

main() {
   port.receive((var message, SendPort replyTo) {
     print("Got message: ${message}");
     port.close();
   });

   SendPort sender = spawnFunction(process);
   sender.send("start", port.toSendPort());
}

Dieser Code läuft in der Main-Methode. Die Main-Methode ist auch nur ein Isolate, deswegen habe ich hier auf einen Port zugriff. Ich lege wieder eine Funktion als Empfänger fest, die abermals eine Nachricht druckt und den Port im Anschluß schließt. Sobald der Main-Port schließt, ist die Anwendung beendet.

Dann rufe ich die “spawnFunction()” Methode auf die die bereits beschriebene Top-Level-Funktion als Argument erhält. Ich verwende keine Klammern. Der Grund ist, dass ich eine Referenz zur Funktion übergeben möchte, und nicht dessen Ergebnis. Die eigentliche Durchführung soll ja im eigenen Isolate erfolgen, und zwar durch die spawnFunction-Methode.

Die spawnFunction-Methode liefert einen SendPort, den ich in der letzten Zeile benutze, um meine erste Nachricht zu senden. Mein zweites Argument ist der Rückkanal für das zweite Isolate. Jetzt kann ich also Antworten meiner “process”-Funktion erhalten.

Das war’s!

Ich habe festgestellt, das die Funktion nicht gespawned wird, when die port.receive() Methode keinen Handler erhält. Zusätzlich darf man nicht vergessen, dass die Funktion die gespawned werden soll, kein “void” als Rückgabewert erhält. Zu guter Letzt habe ich festgestellt, dass der SendPort – obwohl er in der API als optional markiert war – immer vorhanden oder null sein muss.

Fall Sie gerne mit Futures arbeiten möchten: auch dafür gibt es Unterstützung im SendPort. Es ist außerdem möglich einen Isolate von einer URI zu spawnen. Mehr dazu bieten die Docs.

Die API ist meiner Meinung nach ein Schritt in die richtige Richtung. Alles ist einfacher und benötigt weniger Code. Mal sehen, wie das in ein paar Monaten so aussieht. Es soll wohl auch bald Isolates geben, die auf dem gleichen DOM Stück operieren können, was die Geschwindigkeit von Webapps ziemlich steigern dürfte.

by grobmeier at April 19, 2012 05:52 AM

Christian Grobmeier

Google Dart at the Entwickler Magazin Pt. 2

Part 2 of the small article series on Dart just appeared in the Entwickler Magazin. While Part 1 covered the basics, Part 2 is more into DOM manipulation. Enjoy!

by Christian Grobmeier at April 19, 2012 05:11 AM

April 17, 2012

Christian Grobmeier

Darts new Isolate API

When I found out that Google Dart supports Isolates (which is some kind of multithreading for Dart, if have not heard it yet) I was excited. Still Isolates are among my favorites. But the first version of the API was pretty complex. It reminded heavily on Java Threading and honestly it was pretty difficult to get into it. But the Dart developers said pretty early that they want to do some refactoring. They did.

In the first API version you had to create an Isolate with extending the Isolate class. You had to choose between “heavy” and “light” Isolates yourself. This all is history with the new Isolates API. The Dart VM decides for you if it needs heavy or light Isolates (or if it can work with it). Also you don’t need to extend a class for Isolates anymore, you work with Functions. The result is a much more readable code. Here is an example.

First you need to import the Isolate package. This is new. Before you had the Isolate classes in the core.

#import('dart:isolate');

Then the fun can begin!

First I will define a function (!) which shall act as a new Isolate.

process() {
  port.receive((var message, SendPort replyTo) {
      print ("Got message: ${message}");
      replyTo.send("close");
      port.close();
  });
}

This function is a top level function and does not have a return type. Using “void” as return type will break your code by the way. On the second line you see that I am accessing “port”. Actually this is a get-Method which return the port of this function to me. Via a port one can communicate with other Isolates.

The port can take a function which is executed when a message is received. The arguments are the actual message, which should be a primitive value like null, num, bool, double or String. List and Maps containing these values are also allowed. Objects are allowed too, when the Isolates are running in the same process (formerly known as light Isolate). This is the case, if you spawn the new Isolate with “spawnFunction” – say the docs.

In addition to the message argument you get a SendPort, which is some kind of a backchannel to the sending Isolate.

In my function I print the message, send back a “close”-String and finally close the port. The Isolate is then ready for trash and the VM should clean it up then. Don’t forget to close your ports when you are done or it is very much likely that your code will run forever and probably cause messes around with your memory.

Thats it for the new Isolate function so far. Let’s look into how we actually spawn it.

main() {
   port.receive((var message, SendPort replyTo) {
     print("Got message: ${message}");
     port.close();
   });

   SendPort sender = spawnFunction(process);
   sender.send("start", port.toSendPort());
}

This code runs in my main-Method. This is just another Isolate, therefore I have a port ready to access. I put a function as my receiver, which again prints the message and closes my port. Once the main Isolates port closes, the application is done.

Then I call “spawnFunction()” and my argument is the mentioned top level function. You see, I don’t use parenthesis here. The reason is that I need the reference to my function and not its result. The real execution should be done by the spawnFunction-Method – in its own Isolate.

The spawnFunction-Method returns me a SendPort which I use in the last line to send a first message. My second argument is the back channel for the second Isolate. Now I can get the replies of “process”.

That’s it already.

I have observed that a function is not spawned when the port.receive() Method didn’t get a function. In addition, don’t put a “void” to your top level function definition. Last but not least I saw this API can break when you are not sending a port or null as SendPort argument, even when it is marked as optional in the API Docs.

There is support in the SendPort if you prefer to work with Futures. It is even possible to spawn an Isolate from an Uri. You can read more at the official docs.

For me this API has progressed well – everything is easier and one needs less code. Let’s see how it looks in another couple of month. I have read somewhere about Isolates which can act on the same piece of DOM which can significantly speed up webapps. Wouldn’t it be nice?

by Christian Grobmeier at April 17, 2012 06:24 PM

April 16, 2012

John Evans

Proposed Pattern Matching Syntax For Dart

Matching expressions-to-patterns is already possible in Dart using IF..ELSE IF..ELSE constructs:

var a = true;
var b = false;
var c = false;

if (a == true && b == true && c == true){
// all true
}else if (a == true && b == true && c == false){
// c false
}else if (a == true && b == false && c == true){
// b false
}elseif (
// and so on...
}

There is a certain amount of verbosity that makes this approach cumbersome, if not somewhat difficult to read in complex scenarios.

I’m working on a proposal (along with a patch) for Dart, which will introduce a more concise idiom for pattern matching.  It will look something like this:

var a = true;
var b = false;
var c = false;

match (a, b, c){
: true, true, true => print('all true');
: true, true, false => print ('c is false');
: var z when z is bool && !z, any, any => print('z: $z (a) is false');
: any, any, any => print('anything else');
}

Generally speaking, the match statement encloses one or more candidate expressions, and then evaluates one or more patterns.  When a pattern is matched to the given candidates, the the right hand side statements are executed for that pattern.

The patterns will support two more concepts. 

First, the keyword ‘any’, which will act as a wildcard to return a correct match on any value. 

Second, is the ‘when’ keyword, which allows a conditional guard on patterns.  It also allows implicit assignment of the candidate expression to a local variable, which is then available to any statements on the right-hand side.

The de-sugared version of the match block from above would look like this to Dart:

if (a == true && b == true && c == true){
print('all true');
}else if (a == true && b == true && c == false){
print('c is false');
}else if (a is bool && a == false){
var z = a;
print('z: $z (a) is false');
}else{
print('anything else');
}

The nice thing about this, is that it allows the Dart compiler to perform all optimization steps available for such conditionals, just as it normally would.

We’ll see how this develops as I continue to work out the implementation.  My hope is that in the end, ‘match’ will provide a more concise and powerful way to express complex conditionals in Dart.

If interested, you can follow along and comment on my progress here: My Dart Fork and Pattern Matching Branch on Github

by John Evans (noreply@blogger.com) at April 16, 2012 06:21 PM

April 05, 2012

Chris Strom

No Dart Pygments for Me

‹prev | My Chain | next›

tl;dr asciidoc / a2x do not support pygmentized output in any format other than HTML.

The epub and mobi versions of Dart for Hipsters continue to lack Dart syntax highlighting. I have the correct version of Pygments installed, but git-scribe, despite throwing all kinds of warnings before the pygments update, is still not producing epubs with syntax highlighted.

Of course, this could just be my fork of git-scribe that is causing the troubles. It has been a while, but one of the additions to my fork was a post-generate clean-up with Calibre. Perhaps this is somehow scrubbing the syntax highlighting?

The answer to that question was no. Not wanting to introduce yet another dependency to git-scribe, I made the post-generate clean-up optional by virtue of the presence of a script in the source directory for my book:
    def do_mobi
# ....
info "GENERATING MOBI"
# Generate with kindlegen...

cmd = @wd + '/scripts/post-mobi.sh'
if File.exists?(cmd) && File.executable?(cmd)
return false unless ex(cmd)
end

# ...
end
I had completely forgotten about that, which means... that Dart for Hipsters does not have the most Kindle Fire friendly mobi possible. I rectify that by copying the post-mobi.sh script from Recipes with Backbone into my dart-book repository:
➜  dart-book git:(master) ✗ mkdir -p scripts                                       
➜ dart-book git:(master) ✗ cp -p ../backbone-recipes/scripts/post-mobi.sh scripts/
➜ dart-book git:(master) ✗ cat scripts/post-mobi.sh
#!/bin/sh

echo -n "doing post mobi things..."
ebook-convert book.mobi book_ebok.mobi --chapter-mark=none --page-breaks-before='/'
mv book.mobi book.mobi.pre-calibre
mv book_ebok.mobi book.mobi
echo "done!"
With that I can regenerate the mobi and it will now play nice with the Kindle Fire:
➜  dart-book git:(master) ✗ git-scribe gen mobi
...
GENERATING MOBI
adding: etype (stored 0%)
adding: META-INF/ (stored 0%)
adding: META-INF/container.xml (deflated 33%)
...
**************************************************
* Amazon.com kindlegen(Linux) V1.2 build 33307 *
* A command line e-book compiler *
* Copyright Amazon.com 2011 *
**************************************************
...
Info(prcgen): The document identifier is: "Dart_for_Hipsters"
Info(prcgen): The file format version is V6
Info(prcgen): Saving MOBI file
Info(prcgen): MOBI File successfully generated!
doing post mobi things...
1% Converting input to HTML...
...
MOBI output written to /home/cstrom/repos/dart-book/output/book_ebok.mobi
Output saved to /home/cstrom/repos/dart-book/output/book_ebok.mobi
done!
If you have a Kindle Fire, you can re-download Dart from Hipsters (from the same URL in the original email).

But that still leaves me with my non-syntax-highlighted problem, which clearly is not being caused by Calibre. The do_epub function in git-scribe is mercifully short:
    def do_epub
return true if @done['epub']

info "GENERATING EPUB"

generate_docinfo
# TODO: look for custom stylesheets
cmd = "#{a2x_wss('epub')} -a docinfo -k -v #{BOOK_FILE}"
return false unless ex(cmd)

@done['epub'] = true
end
Hrm... that TODO note looks promising. The a2x_wss function calls the AsciiDoc executable a2x with a hard-coded stylesheet:
    def a2x_wss(type)
a2x(type) + " --stylesheet=stylesheets/scribe.css"
end

def a2x(type)
"a2x -f #{type} -d book "
end
Looking through the HTML in resulting epub, I see no evidence of syntax highlighting. The intermediary Docbook XML does, at least, mention Dart as the syntax type:
<simpara>We start our Dart application by loading a couple of Dart libraries with a <literal>main()</literal> function in <literal>scripts/comis.dart</literal>:</simpara>
<programlisting
language="dart"
linenumbering="unnumbered">
#import('dart:html');
#import('dart:json');

main() {
load_comics();
}

load_comics() {
// Do stuff here
}</programlisting>
Taking a step back, I run the simplest asciidoc / a2x command possible—just asciidoc with no command line switches—against a small, self contained chapter from my book:
➜  tmp git:(master) ✗ asciidoc -v dom.asc
asciidoc: reading: /etc/asciidoc/asciidoc.conf
...
asciidoc: writing: /home/cstrom/repos/dart-book/tmp/dom.html
asciidoc: dom.asc: line 30: filtering: pygmentize -f html -l dart -O encoding=UTF-8
asciidoc: dom.asc: line 42: filtering: pygmentize -f html -l dart -O encoding=UTF-8
asciidoc: dom.asc: line 53: filtering: pygmentize -f html -l dart -O encoding=UTF-8
asciidoc: dom.asc: line 65: filtering: pygmentize -f html -l javascript -O encoding=UTF-8
...
That looks promising. And, in fact, it does produce Dart (and Javascript) syntax highlighted output:


But I'm not using the asciidoc command to produce things from AsciiDoc format. Instead, as mentioned earlier, I am using the a2x wrapper for asciidoc. So I generate HTML from a2x using the simplest command-line options possible:
➜  tmp git:(master) ✗ a2x -f xhtml -v dom.asc
a2x: args: ['-f', 'xhtml', '-v', 'dom.asc']
a2x: executing: /usr/bin/asciidoc --backend docbook --verbose --out-file /home/cstrom/repos/dart-book/tmp/dom.xml /home/cstrom/repos/dart-book/tmp/dom.asc
asciidoc: reading: /etc/asciidoc/asciidoc.conf
asciidoc: reading: /home/cstrom/.asciidoc/asciidoc.conf
...
asciidoc: writing: /home/cstrom/repos/dart-book/tmp/dom.xml
a2x: executing: xmllint --nonet --noout --valid /home/cstrom/repos/dart-book/tmp/dom.xml
a2x: chdir /home/cstrom/repos/dart-book/tmp
a2x: executing: xsltproc --stringparam callout.graphics 0 --stringparam navig.graphics 0 --stringparam admon.textlabel 1 --stringparam admon.graphics 0 --output /home/cstrom/repos/dart-book/tmp/dom.html /etc/asciidoc/docbook-xsl/xhtml.xsl /home/cstrom/repos/dart-book/tmp/dom.xml
a2x: chdir /home/cstrom/repos/dart-book/tmp
a2x: finding resources in: /home/cstrom/repos/dart-book/tmp/dom.html
a2x: finding resources in: /home/cstrom/repos/dart-book/tmp/dom.html
a2x: deleting /home/cstrom/repos/dart-book/tmp/dom.xml
There is no mention of pygmentize and there is no longer syntax highlighting in the output:


My guess is that the --backend docbook option that a2x supplies to asciidoc is the culprit here (since nothing else in the printed command line looks at all different that my first run). And, indeed, running the command-line option without that switch does produce highlighted output.

At this point, I have reached an impasse. I cannot produce pygmentized output from a2xunless it is based on HTML and no other highlighter supports pygments. At the same time, I cannot produce epub unless it is based on DocBook. Indeed, the asciidoc documentation says as much:
You also have the option of using the Pygments syntax highlighter for xhtml11 outputs.
I do not believe that I ever paid much attention that last caveat. I'm paying attention now.



Day #346

by Chris Strom (noreply@blogger.com) at April 05, 2012 03:39 AM

April 04, 2012

On Dart (Dzenan Ridjanovic)

From Spiral12 To Spiral13

In Spiral 12, a model may be saved in a local storage under a model name and later opened by using the model name. A type of a data attribute may be changed from default String to another type. Based on the current item obtained by the Get 1 button (where 1 is determined by the name in the item input field), the next item may be selected by the Get +1 (Next) button.
In Spiral 13, there are only minor changes. In the Menu Bar, the File menu is renamed to Model. A model may be opened, saved and closed. In the Tool Bar, the Get 1 (item) button is renamed, as it used to be, to Get. The sequence of buttons is rearranged, so that buttons with -1 are now after buttons with +1.

by Dzenan Ridjanovic at April 04, 2012 11:47 AM

April 03, 2012

Chris Strom

Dart Syntax Highlighting Not Working in Git-Scribe

‹prev | My Chain | next›

Don't think that I haven't noticed that Dart for Hipsters lacks syntax highlighting for my Dart code. Like last night's bug, this was one of those things for which I just could not spare 30 minutes of investigation. Well now I can.

This is different than my issues with PDF highlighting, which I will try another day. Rather this is for the syntax highlighting in the EPUB and mobi versions.

By default, git-scribe (my ebook toolchain of choice) uses source-hightlight to do this. The problem is that source-highlight has no idea about Dart. Pygments, on the other hand were made Dart aware a while back. Perhaps that has even made it into mainstream pygments.

When I run git-scribe gen epub I am getting many unknown Dart errors from source-highlight:
....
asciidoc: WARNING: testing.asc: line 133: filter non-zero exit code: source-highlight -f xhtml -s dart: returned 1
asciidoc: WARNING: testing.asc: line 133: no output from filter: source-highlight -f xhtml -s dart
source-highlight: missing feature: language inference requires input file
source-highlight: could not find a language definition for dart
asciidoc: WARNING: testing.asc: line 159: filter non-zero exit code: source-highlight -f xhtml -s dart: returned 1
asciidoc: WARNING: testing.asc: line 159: no output from filter: source-highlight -f xhtml -s dart
source-highlight: missing feature: language inference requires input file
source-highlight: could not find a language definition for dart
....
To switch to pygments, I ought to be able to edit ~/.asciidoc/asciidoc.conf to contain:
pygments=
But this has no effect. So, instead, I add that line (or rather uncomment it) in the /etc/asciidoc/asciidoc.conf system configuration file.

Only that still seems Dart-unaware. To install a more recent version of pygments, I first install python-setuptools:
sudo apt-get install python-setuptools python-dev build-essential
This should give me easy_install for the latest and greatest pygments:
➜  ~  sudo easy_install Pygments                                       
Searching for Pygments
Best match: Pygments 1.4
Adding Pygments 1.4 to easy-install.pth file
Installing pygmentize script to /usr/local/bin

Using /usr/lib/python2.7/dist-packages
Processing dependencies for Pygments
Finished processing dependencies for Pygments
Only that still does not have Dart:
➜  ~  /usr/local/bin/pygmentize -L | grep -i perl
* antlr-perl:
ANTLR With Perl Target (filenames *.G, *.g)
* perl, pl:
Perl (filenames *.pl, *.pm)
* perldoc:
Style similar to the style used in the perldoc code blocks.
➜ ~ /usr/local/bin/pygmentize -L | grep -i dart
Bah! It looks as though I will need to install pygments from source code management. That is a task better suited for tomorrow.

Day #343

by Chris Strom (noreply@blogger.com) at April 03, 2012 03:59 AM

April 02, 2012

Dart Vader (German)

Dart vs. Motörhead – Dresden

Rock in Dresden – präsentiert von der Java Usergroup Saxony.

Dart ist eine neue Band, die aber schon gewaltig rocken soll. Kann es die Nachwuchsband mit alteingesessenen Rockstars – wie etwa Motörhead – aufnehmen? Motörhead kommt mit einer eingespielten Truppe daher: die Bibliotheken ändern sich quasi niemals und timingprobleme kennt der Drummer nicht. Dart dagegen ist jung und unerfahren. Konnte es von den “Großen” genug abkupfern um selbst auf Tour gehen zu können? Wirkt der Dart-Sänger ohne die charakteristische Motörhead-Warze im Gesicht wie ein Milchbubi? Oder ist es gerade das charmante Äußere, mit dem Dart die Herzen der Entwickler zum Schmelzen bringt?

Der Vortrag zeigt, was Dart musikalisch so drauf hat. Lockere Kleidung, Ohrstöpsel und eine Dose Bier werden für dieses Konzert empfohlen. Ach ja, der Vortrag ist zwar kostenlos, jedoch: you might loose your soul to Gods Rock’n'Roll!

Sprecher: Christian Grobmeier, The Apache Software Foundation

Ort: Fakultät Informatik der TU Dresden, Raum E023

Datum: 24. April 2012, 19:00-22:00

by grobmeier at April 02, 2012 09:33 AM

Christian Grobmeier

(Google) “Dart versus Motörhead” in Dresden

Recently I already explained: Dart rocks. Meanwhile the Dart band has seen several great releases – it is now time to see if Dart can compete with the big rockstars in the scene – like Motörhead! Motörhead is a great band too with much steam behind. But then there is Dart: heavy drumming and tight timing. Does the lack of a wart make the Dart vocalist a soft boy? Dart uses modern, state-of-the-art instruments while Motörhead plays the same instruments for several years (and damn, they sound great!). Surely there are many questions when one wants to compare Dart with Motörhead.

This evening is free to attend, as usual in the Java User Group Saxony (Dresden, Germany), but I recommend you to wear loose clothing and take some earplugs and beer with you. And of course, you might loose your soul to the gods rock’n'roll.

Visit the page in my event calendar.

by Christian Grobmeier at April 02, 2012 09:25 AM

March 31, 2012

Chris Strom

Dart Templates (Bleeding Edge)

‹prev | My Chain | next›

When I wake up later today, I plan to do nothing but edit Dart for Hipsters. But of course, now is not the time to displease the gods of my chain for they have been so good to me. So before I get a few hours of sleep, I make a small offering in the form of messing about with the template stuff in Dart's bleeding edge.

I already have much of bleeding edge checked out from the other night when I was trying out dartdoc. But I do not have the utils sub-directory. So I again install subversion:
sudo apt-get install subversion
Then in the same directory in which I checked out the other bits of the SDK, I grab utils:
➜  dart  svn checkout http://dart.googlecode.com/svn/branches/bleeding_edge/dart/utils
A utils/apidoc
A utils/apidoc/html_diff.dart
A utils/apidoc/.gitignore
...
Checked out revision 6072.
Then I remove subversion on principle:
sudo apt-get remove subversion
With that, I am ready to templatize something!

In my sweet Hipster MVC-based comic book application, I already have a poor man's template defined:
  _singleComicBookTemplate(comic) {
return """
<li id="${comic['id']}">
${comic['title']}
(${comic['author']})
<a href="#" class="delete">[delete]</a>
</li>
""";
}
This seems like a nice candidate on which to experiment.

So I extract that out into ComicBook.tmpl as:
template ComicBook(comic) {
<li id="${comic['id']}">
${comic['title']}
(${comic['author']})
<a href="#" class="delete">[delete]</a>
</li>
}
Next, I try compiling that into Dart code with the template utility:
➜  dart-comics git:(modal-dialog) ✗ ~/repos/dart/utils/template/template public/scripts/ComicBook.tmpl 
:1:20: fatal: Template paramter missing type and name
template ComicBook(comic) {
^^^^^
Parsed /home/cstrom/repos/dart-comics/public/scripts/ComicBook.tmpl in 63 msec.
Codegen /home/cstrom/repos/dart-comics/public/scripts/ComicBook.tmpl in null msec.
Wrote file /home/cstrom/repos/dart-comics/public/scripts/ComicBook.dart in null msec.
Ugh. Does it really need to know that code is an instance of HipsterModel? Can it even find that class if it needs it? There is an easy way to find out and that is adding the type declaration:
template ComicBook(HispterModel comic) {
<li id="${comic['id']}">
${comic['title']}
(${comic['author']})
<a href="#" class="delete">[delete]</a>
</li>
}
With that, it compiles:
➜  dart-comics git:(modal-dialog) ✗ ~/repos/dart/utils/template/template public/scripts/ComicBook.tmpl
Parsed /home/cstrom/repos/dart-comics/public/scripts/ComicBook.tmpl in 60 msec.
Codegen /home/cstrom/repos/dart-comics/public/scripts/ComicBook.tmpl in 12 msec.
Wrote file /home/cstrom/repos/dart-comics/public/scripts/ComicBook.dart in 12 msec.
To get that back into my comic book view, I need to #source() (pull directly into library namespace) the generated template code:
#source('ComicBook.dart');
Looking through the generated code, it seems like I need to access the result of the template on the root property:
Element get root() => _fragment;
The problem with that is that, at the point that I extracted this from a working application, I was building HTML strings, not Element objects. So, to use this, I need to replace my previous String function:
    var html = '';
list.forEach((comic) {
html += _singleComicBookTemplate(comic);
});
With an outerHTML call on the root Element:
    var html = '';
list.forEach((comic) {
html += (new ComicBook(comic)).root.outerHTML;
});
Loading that up in Dartium, however throws an error:
Internal error: 'http://localhost:3000/scripts/ComicBook.dart': Error: line 20 pos 56: unterminated string literal
var e0 = new Element.html('<li id="${comic['id']}">
^
Looking at the generated output, I see that it does seem incorrect in that a multi-line string is declared with single quotes:
  ComicBook(this.comic) : _scopes = new Map<String, Object>() {
// Insure stylesheet for template exist in the document.
add_ComicBook_templatesStyles();

_fragment = new DocumentFragment();
var e0 = new Element.html('<li id="${comic['id']}">
${inject_0()}
(${inject_1()})
</li>');
_fragment.elements.add(e0);
var e1 = new Element.html('<a href="#" class="delete">[delete]</a>');
e0.elements.add(e1);
}
And, indeed, adding triple quotes fixes that problem:
  ComicBook(this.comic) : _scopes = new Map<String, Object>() {
// Insure stylesheet for template exist in the document.
add_ComicBook_templatesStyles();

_fragment = new DocumentFragment();
var e0 = new Element.html('''<li id="${comic['id']}">
${inject_0()}
(${inject_1()})
</li>''');

_fragment.elements.add(e0);
var e1 = new Element.html('<a href="#" class="delete">[delete]</a>');
e0.elements.add(e1);
}
I am unsure if that single quote would work in bleeding_edge Dart or not. Regardless, triple quotes definitely eliminates the error.

That eliminated the unterminated string problem, but now I get:
Internal error: 'http://localhost:3000/scripts/ComicBook.dart': Error: line 19 pos 21: type 'DocumentFragment' is not loaded
_fragment = new DocumentFragment();
^
My Hipster MVC is so well encapsulated, that I have not needed the HTML library yet, which is why DocumentFragment is not defined. To gain access to it, I #import() the HTML library into the view class:
#import('dart:html');
#source('ComicBook.dart');
With that, I have my compiled template working in my Hipster MVC view:


Problems with bleeding edge aside, I cannot say that I am sold on these templates. This was a somewhat contrived, small example. The pseudo-template with which I started seems more appropriate. No doubt this would have worked better on a larger example, but I really go out of my way to keep my views small.

The use of safeHMTL under the template covers is encouraging. That said, the compilation step is painful. Perhaps templates will get first-class support before long. I would also prefer to define most templates inside my view classes. Assuming both of those concerns are addressed, then I can see using these templates. Until then, I will stick with multi-line strings.


Day #342

by Chris Strom (noreply@blogger.com) at March 31, 2012 06:16 AM

Making HipsterModel Even Easier

‹prev | My Chain | next›

Up tonight, I document and, if necessary, polish off HispterModel, the model class in my Dart Hipster MVC library.

I see that I am optionally allowing the collection to be set on the model (it's useful for delegating the backend URL):
class HipsterModel implements Hashable {
// ...
HipsterModel(this.attributes, [this.collection]) { /* ... */ }
}
This was a bit of premature optimization on my part as I am not using the option collection parameter anywhere. Even when the collection creates a model, it assigns itself after the model is built:
class HipsterCollection implements Collection {
// ...
_buildModel(attrs) {
var new_model = modelMaker(attrs);
new_model.collection = this;
return new_model;
}
}
If this ever becomes useful, I can add it back or define a named constructor (e.g. new ComicBook.withCollection(comic_collection)). For now, I remove it.

This leads me to wonder again about the model subclass. Currently, I have to define a redirection to super() in all subclasses:
class ComicBook extends HipsterModel {
ComicBook(attributes) : super(attributes);
}
I would prefer to only define that as necessary. In other words, I would like to reduce the minimal HipsterModel subclass to:
class ComicBook extends HipsterModel {}
In this case, Dart has an implied redirection constructor that effectively calls the superclass constructor with no arguments. In other words, the above is the same as defining the subclass as:
class ComicBook extends HipsterModel {
ComicBook(): super();
}
As defined now, HispterModel will not support this because I still require attributes. This will work if I make attributes optional:
class HipsterModel implements Hashable {
/// The internal representation of the record.
Map attributes;

HipsterModel([this.attributes]) {
on = new ModelEvents();
if (attributes == null) attributes = {};
}
// ...
}
I still have the option to define a constructor on ComicBook that takes an argument, but now I do not have to do so. Since I do not, my modelMaker() factory function can no longer pass arguments to the constructor:
class Comics extends HipsterCollection {
get url() => '/comics';
modelMaker(_) => new ComicBook();
}
That modelMaker() function still needs to accept an argument in case another subclass wants to use it. Here, I use the convention of an underscore parameter to signify that it is being discarded.

One last hoop that I have to go through is for the collection to assign attributes when they are discarded like that. A simple isEmpty() suffices:
  _buildModel(attrs) {
var new_model = modelMaker(attrs);
// Give the factory a chance to define attributes on the model, if it does
// not, explicitly set them.
if (new_model.attributes.isEmpty()) new_model.attributes = attrs;

new_model.collection = this;
return new_model;
}
With that, my empty model definition now works, as evidenced by my sample comic book application still working:


That might seem like a lot of work to go through just to eliminate one line, but I am eliminating one line that users of my library need to define. Forcing potential users to write extra code is never cool.

So... win!

Lastly, I notice that I have a TODO in HipsterModel#save():
  // TODO: update
Back before I switched the data sync layer to HipsterSync, this must have seemed to me a difficult task. Now, all that I need to do is pass in 'create' or 'update' depending on whether or not the model has been previously saved to the backend:
  Future save() {
Completer completer = new Completer();
String operation = isSaved() ? 'update' : 'create';
Future after_call = HipsterSync.call(operation, this);
// ...
}
With that, I have a well-documented, fully operational Death S... er, model class in Hipster MVC.


Day #341

by Chris Strom (noreply@blogger.com) at March 31, 2012 03:46 AM

March 26, 2012

On Dart (Dzenan Ridjanovic)

From Spiral11 To Spiral12

In Spiral 11, a model may be transformed to JSON and back from JSON to a model. JSON (JavaScript Object Notation) is a lightweight data-interchange format. JSON is easy for humans to understand and for software to parse it. It is based on two data structures: a collection of name/value pairs {} and an ordered list of values [].
In Spiral 12, a model may be saved in a local storage under a model name and later opened by using the model name. A type of a data attribute may be changed from default String to another type. Based on the current item obtained by the Get 1 button (where 1 is determined by the name in the item input field), the next item may be selected by the Get +1 (Next) button.

by Dzenan Ridjanovic at March 26, 2012 04:27 PM

March 23, 2012

David Chandler

App Engine, Dart, and Android at DevNexus

DevNexus keynote

DevNexus keynote

First, a huge thank you to the volunteer organizers and sponsors of DevNexus! The Atlanta JUG‘s annual not-for-profit conference attracted 500 mostly Java developers this year and remains one of the best values of any developer conference in the world.

I gave an update on Google App Engine for Java (see slides) and a pitch for HTML5 + Dart (see slides).

There were a lot of talks on mobile / Web development this year, including:

  • JQuery Mobile framework (Raymond Camden, Adobe)
  • Intro to PhoneGap (Raymond Camden, Adobe)
  • Java-Powered Mobile Cross-Platform Mobile Apps with Phone Gap (Andrew Trice)
  • Web vs. Apps keynote (Ben Galbraith)
  • Easy Mobile Development: Intro to Appcelerator Titanium (Pratik Patel)
  • What’s New in Android (Robert Cooper)
  • Spring for Android (Roy Clarkson, Spring)
  • Mind-Blowing Apps with HTML5 Canvas (David Geary)

All the mobile / Web talks that I attended were standing room only (70-130 people, depending on room capacity). It seems that mobile in the enterprise is red hot and enterprise apps are good candidates for Web apps vs. native. I was particularly impressed with

Thanks again to Gunnar, Vince, Sudhir, and the gang for making DevNexus such a high-quality event.


by David Chandler at March 23, 2012 02:32 PM

March 19, 2012

Adam Coding

Dart Templates

As mentioned by Seth Ladd, Dart now has a template system in the bleeding_edge branch. One way to learn what is offered, is to look at the uitest.dart unit test. Since the template code is in flux I’ve created some scripts to help init and build templates. A sample Dart Template Example is provided to follow along with this post. Please keep in mind this is currently subject to change by the Dart team, provide feedback to help the project along.

exportTemplateUtils.sh script is used for exporting all the dependent code from the dartlang code base. The template build script depends on lib, css, and template folders from the utils directory.

22:54:59-adam@Adams-MacBook-Air:~/dart/DartTemplateExample
$ ./exportTemplateUtils.sh 
A    lib
[...]
Exported revision 5635.
A    css
[...]
Exported revision 5635.
A    template
[...]
Exported revision 5635.

The DivisionSales.tmpl was ripped from the unit test and adjusted for the project. The template keyword is used for defining the template name. Inside the template you can have css, html and scripting. Dart team is currently experimenting with the following.
template DivisionSales(var divisions) {
  css {
    .division-item {
      background-color: #bbb;
      border-top: 2px solid white;
      line-height: 20pt;
      padding-left: 5px;
    }
    .product-item {
      background-color: lightgray;
      margin-left: 10px;
      border-top: 2px solid white;
      line-height: 20pt;
    }
    .product-title {
      position: absolute;
      left: 45px;
    }
    .product-name {
      font-weight: bold;
      position: absolute;
      left: 100px;
    }
    .product-users {
      position: absolute;
      right: 150px;
      font-style: italic;
      color: gray;
      width: 110px;
    }
    .expand-collapse {
      margin-left: 5px;
      margin-right: 5px;
      vertical-align: top;
      cursor: pointer;
    }
    .expand {
      font-size: 9pt;
    }
    .collapse {
      font-size: 8pt;
    }
    .show-sales {
      display: inherit;
    }
    .hide-sales {
      display: none;
    }
    .sales-item {
      font-family: arial;
      background-color: lightgray;
      margin-left: 10px;
      border-top: 1px solid white;
      line-height: 18pt;
      padding-left: 5px;
    }
    .ytd-sales {
      position: absolute;
      left: 100px;
    }
  }
  <div>
    ${#each divisions}
      <div class="division-item">
        <span>${name}</span>
        <span>&nbsp;-&nbsp;</span>
        <span>${id}</span>
      </div>
      <div>
        ${#each divisions.products}
          <div class="product-item">
            <span var=productZippy class="expand-collapse expand">▼</span>
            <span class='product-title'>Product</span>
            <span class="product-name">${name}</span>
            <span class="product-users">${users}&nbsp;</span> 
            <div class="show-sales">
              ${#each products.sales}
                <div class="sales-item">
                  <span>${country}</span>
                  <span class="ytd-sales">${yearly}</span>
                </div>
              ${/each}
            </div>
          </div>
        ${/each}
      </div>
    ${/each}
  </div>
}

template Header(String company, Date date) {
  css {
    .header {
      background-color: slateGray;
      font-family: arial;
      color: lightgray;
      font-weight: bold;
      padding-top: 20px;
    }
  }
  <div class='header' align=center>
    <h2>${company}</h2>
    <div align=right>${date}</div>
  </div>
}

The scripting is very basic at the moment. Looking at the tokenkind.dart one can get an idea of what is supported.
[...]
  // Synthesized tokens:

  static final int END_NO_SCOPE_TAG = 50;       // />
  static final int START_EXPRESSION = 51;       // ${
  static final int START_COMMAND = 52;          // ${#
  static final int END_COMMAND = 53;            // ${/
  static final int EACH_COMMAND = 53;           // ${#each list}
  static final int WITH_COMMAND = 54;           // ${#with object}
  static final int IF_COMMAND = 55;             // ${#if (expression)}
  static final int ELSE_COMMAND = 56;           // ${#else}
[...]

buildTemplates.sh script will loop over all *.tmpl files in the current working directory and generate *.dart files for each one.
22:57:41-adam@Adams-MacBook-Air:~/dart/DartTemplateExample
$ ./buildTemplates.sh 

Building dart templates

Parsed /Users/adam/dart/DartTemplateExample/DivisionSales.tmpl in 3134 msec.
Codegen /Users/adam/dart/DartTemplateExample/DivisionSales.tmpl in 215 msec.
Wrote file /Users/adam/dart/DartTemplateExample/DivisionSales.dart in 215 msec.

Copy & Paste import statements

#source('DivisionSales.dart');


After the dart code is generated the following source statements can be copied into the main/lib.
#import('dart:html');
#source('DivisionSales.dart');

class Sales {
  String country;
  String yearly;
  Sales(this.country, this.yearly);
}

class Products {
  List<Sales> sales;
  String name;
  String users;
  Products(this.name, this.users, this.sales);
}

class Divisions {
  List<Products> products;
  String id;
  String name;
  Divisions(this.id, this.name, this.products);
}

class DartTemplateExample {

  DartTemplateExample() {
  }

  void run() {
    document.body.elements.add(new Header("Dollar Shave Club", new Date.now().toString()).root);
    
    List<Sales> sales = [new Sales("USA", "3500"), new Sales("USA", "4500")];
    List<Products> products = [new Products("Razor", "Sammy", sales)];
    List<Divisions> divisions = [new Divisions("South West", "A-Team", products), new Divisions("North East", "B-Team", products),];
    
    DivisionSales divisionSales = new DivisionSales(divisions);
    document.body.elements.add(divisionSales.root);
  }
}

void main() {
  new DartTemplateExample().run();
}

This example is deployed on github. You can also experiment with the template system to see what code gets generated on a live page. At first glance the template system is simple enough to use, I would assume things would change in the future. For now the Dart team has provided enough for people to start banging away and provide feedback.


by financecoding at March 19, 2012 07:08 AM

March 16, 2012

David Chandler

Is the mobile Web ready for business app developers?

Disclaimer: these thoughts are my own, not necessarily those of my employer.

I recently attended A Night with Sencha and Ted Patrick, and it got me thinking more about the mobile web. Mobile developers are clearly hungry for cross-platform solutions like Sencha and Titanium, and HTML5 promises significant cross-platform compatibility. (Action game developers, you can stop reading now because you already know that the high-performance mobile Web is not there yet. In fact, many folks I talked to last week at GDC are not even using the Android SDK, but rather the Android Native Development Kit to port games from iOS in C.)

Having said that, the mobile web for business app developers is arguably the easiest way to develop mobile apps, period, even without the side benefit of cross-platform compatibility. Why?

  • Web development frameworks is a rich and mature space. There are dozens of well-established popular frameworks on both client and server for MVC, CSS, JSON, etc. We’ve been doing Web development for almost 20 years now.
  • Web design tools abound. Although IDEs for native apps offer design & layout functionality, more designers are familiar with tools like Dreamweaver for HMTL+CSS. Firebug and Chrome DevTools are the ultimate WYSIWYG editors. Who wants to learn another style language when you’ve finally conquered CSS (kicking and screaming)?
  • Mobile browsers, like their desktop cousins, offer great tools for design and debugging (such as Safari Web Inspector and remote debugging with Chrome Beta for Android). Tools like the Window Resizer Chrome extension let you quickly test your app in a variety of different resolutions.
  • Frameworks like Sencha do a lot of the heavy lifting around RPC, local storage, dynamic UI creation & data binding. These things take a lot of work to do correctly in a native app.
  • You don’t have to worry as much about device compatibility. Mobile browsers aren’t perfect and there are still compatibility gaps (see mobilehtml5.org), but most players in the ecosystem are motivated to ensure that the browser runs well on all devices. The ecosystem is probably less concerned with your apartment finder app. Provided you’re using standard browser features, the browser vendor bears much of the testing burden.

So why does anyone write native apps?

  • Monetization, of course. But you can wrap your app in a WebView. As far as I know, WebViews aren’t an issue in any of the app markets with the possible exception of Apple, and according to Ted Patrick, Apple has been good about letting WebView apps in “once they get to know you and find that your app is reliable.” YMMV.
  • Native look and feel. Sencha / jqTouch does a convincing job with this on iOS. I haven’t seen it on Android.
  • Performance. I already mentioned this with respect to fast-moving games, but most business apps don’t use Canvas or a lot of CSS transitions. And with care, even large apps that manage a lot of data (like mobile GMail for the Web) can be snappy.
  • Hardware access. With HTML5, you can get the user’s location and even the accelerometer, but not the camera. At least not yet. But for most business apps, location is all you need.
  • Integration with the OS. If your app needs a ContentProvider or background Service or handles Intents, then you do indeed need a native app. Several well-known apps are succeeding with a hybrid approach, however, by using WebViews for rendering and native Services for data access. This simplifies the UI design as noted earlier while retaining other advantages of the platform.
  • Finally, native apps let you write code in something other than Javascript. Of course, you could try GWT or Dart and compile to JS, too. Ironically, many of the native cross-platform solutions also require you to write your app in Javascript.

Over the next few weeks, I’ll be porting my listwidget app to native Android and mobile Web using a variety of technologies. I’ll keep you posted.


by David Chandler at March 16, 2012 02:28 AM

March 15, 2012

Dart Experience

“Dart in Action” COMING SOON

Link: http://www.manning.com/buckett/ Table of Contents Part 1: Welcome to Dart   1. Hello Google Dart: Free   2. Creating “Hello World” Part 2: Learning Dart concepts   3. Core Dart   4. Using Dart in …

Continue reading »

by Dani Geta at March 15, 2012 12:39 PM

On Dart (Dzenan Ridjanovic)

From Spiral10 To Spiral11

In Spiral 10, a relationship created between two concepts, may be changed to inheritance or is-a relationship, first by selecting the relationship line, second by getting information about the relationship in the tool bar, third by choosing the inheritance category in the pop-up list. Similarly, the obtained relationship may be categorized as reflexive or twin. A reflexive relationship will connect the parent concept to itself. Two relationships between the same two concepts will split apart when becoming twins.
In Spiral 11, a model may be transformed to JSON and back from JSON to a model. JSON (JavaScript Object Notation) is a lightweight data-interchange format. JSON is easy for humans to understand and for software to parse it. It is based on two data structures: a collection of name/value pairs {} and an ordered list of values [].

by Dzenan Ridjanovic at March 15, 2012 10:23 AM

March 14, 2012

Dart Experience

News to the Dart Editor

Those of Mountain View have released three revisions to its editor Dart since 5 March,the news of all of them are: 5 March New Dart Editor build includes new dart:isolate library Highlights from build 4760 include: Dartium launch functionality improvements …

Continue reading »

by Dani Geta at March 14, 2012 07:52 AM

March 10, 2012

On Dart (Dzenan Ridjanovic)

From Spiral09 To Spiral10

In Spiral 09, line min..max cardinalities may be changed by getting the selected line with a click on the Get button in the tool bar, making changes and setting them with a click on the Set button. Line direction names may be added. A line direction with 1..1 cardinalities may become a part of the identifier of the source concept.
In Spiral 10, a relationship created between two concepts, may be changed to inheritance or is-a relationship, first by selecting the relationship line, second by getting information about the relationship in the tool bar, third by choosing the inheritance category in the pop-up list. Similarly, the obtained relationship may be categorized as reflexive or twin. A reflexive relationship will connect the parent concept to itself. Two relationships between the same two concepts will split apart when becoming twins.

by Dzenan Ridjanovic at March 10, 2012 11:31 AM

March 08, 2012

Trials (and Errors) in Dart

Darting here and there

So another Dart Editor update, now at Build 5104, get it here!. I love how quickly the dart integrated builds have been coming lately. This new version does away with the old 'Libraries' view panel on the left side (by default) and instead implements a Files view. Instead of opening a project you now open the folder containing your project. All of your .dart files are loaded into that. I wasn't sure about it at first, as it is a changes in how it would work previously but already I'm seeing the benefits of it. It does help to encourage a Good folder/subfolder layout, which I was already comfortable with anyways.

I've seen a few people report some difficulties loading their existing projects, however I can't really comment on that as I have not encountered those issues myself. This version did correct the mass of errors I was receiving in the previous version regarding variables hiding other variables or methods. However it did introduce a couple of new ones.

First, this version introduced the changes to the dart:io library, changing all eventHandlers over to be in the form of onEvent, and one-shot methods (such as File.exists) now take the callback function as an argument, as opposed to having to specify an 'existsHandler'. As such I had to go through my code and made updates to the Sockets and Files to properly reflect the changes to the library.

Secondly, I ran into an issue where any print statements, within a class, would generate an error or warning that "print" is not a method in , where ClassName is whatever class happened to contain the print statement. This post in the Dart Group provided an easy, temporary fix, that is to simply import 'dart:builtin' where required. A simple fix and helped to clean up the errors there so I could focus on my own errors that I had to worry about.

I notice that while the IDE and SDK were updated to Build 5104, the Dartium Build remains at 5070. At this time I am still unable to get the Dartium builds to run on my machine due to a version problem with the shared libraries. I receive the following error:

error while loading shared libraries: libgconf-2.so.4: wrong ELF class: ELFCLASS64

I believe this error is related to the fact that I'm running a 64-bit OS, but it's trying to load 32-bit build. This may also have something to do with my early ventures in trying to build DartVM, IDE, and Dartium myself and installing the extra libraries, etc, which may have conflicted with what Dartium is trying to load. In fact, now that I think of it, I should run a good apt-get autoclean and autoremove regardless. I don't believe it will fix it, but certainly clean up my system a little at least. Now I've not been too worried about this as my current project doesn't use or require any client-side work, but eventually it might be interesting to have a working copy of Dartium for when I start working on some client side projects. Hopefully the 64-Bit builds of Dartium will be available by then.

by Matthew Butler (noreply@blogger.com) at March 08, 2012 02:38 PM

March 05, 2012

Trials (and Errors) in Dart

Dart Mud... Progress 2

So I decided it's time for another progress report on my Dart based MUD. This project has be a lot of fun, and giving me experience with the dart:io libraries including Files, ServerSockets, and Sockets. Before I get into too much, I will mention that there is a new Integrated Dart Build available. Version 4760 (though SDK appears to be build number 4759). You can find your download here. Since using this build I have been getting errors and warnings when using the dart:io library. However it doesn't prevent my project from running properly. Just distracting thinking I have an error when I don't.

To follow up on my previous post, I have begun using git locally to archive changes and keep a bare-bones changelog system. Already I see this being helpful in keeping track of what I have changed or done, and additionally, in being able to revert changes easily. Once I clean up some of the code and add a plethora of comments, I may pop the project up onto Github as well.

My User Object now allows for the creation of a new character, automatic saving of a user and loading user (and password) from a save file. To save character information I'm currently placing the information I want saved into a map, and using saving it as a JSON object. In the future I can see some issues I may need to work out, but since I haven't decided on how things such as Objects, equipment etc will be implemented yet I don't know yet how much of an issue they will be.

As part of adding to the User object, I decided to create a separate Login object as well which will handle the accepting of username/password and loading the character and creating a new User object from the loaded information. Additionally the Login object also handles creating a new account, posing the various questions (username, password, password confirmation etc), then creating a new User object based off of the data provided. This way a full User object isn't created until credentials have been verified, and also prevents User from showing up in the user list, or receiving broadcast messages etc before they have completed the Login process.

As part of the work to separate the Login class from the User class, I also created a separate 'Connection' class as a wrapper over top of the raw sockets. Primarily this just creates a couple of convenience functions over the Socket for write, writeLine, readLine, set the lineHandler and close the Socket. I made this its own library, so it is imported into the Server which creates the initial socket and then wraps the Connection around it, and then hands it off to the mudlib (which is its own library). The mudlib also imports the Connection class. The mudlib then passes the Connection off to a new Login object which uses that to communicate to the user (again as opposed to the raw socket). The connection object is then passed off to the newly created User object once it is created. User object adds a couple more convenience functions as well but mostly works with the Connection object as well.

I've added a couple more commands as well. Now able to 'say' to the local room, change the default prompt (which does save to the User file), and of course the always abused 'emote' command. Additionally I've got a good start on a simple line editor (and a simple command wrapper for it to see the results). The Editor is a separate object which will take over the Input/Output streams of a socket from the user. It does not remove the user itself, nor does it take the user's connection object. Rather it just updates the Connection object to use the Editor's lineHandler.

The editor has two modes, Command mode and input put. By default you start in command mode, from which you can either insert or append which will put you into the input mode. To exit the input mode, one just needs type a period (.) on a blank line. The editor works similarly to 'ed' but a little prettier. (For instance a prompt of ': ' in command mode and prompt of '~ ' in input mode). Currently implemented commands in the editor: a - append, i - insert, q - quit, h - help, p - print line, d - delete line. In the future some commands such as p and d will accept a range argument as well however this is yet not implemented. There is no 'save', if you quit it will return whatever is in the buffer.

The editor is called by the User object. The User object in turn is called by some other command or object (most likely a command which will do something with the output). To start the edit the User object has startEdit method called on it with a callback function as an argument. Once the editor finishes it calls the method doneEdit in the User object which resets the proper line handlers, and then calls the previous callback function with the String returned from the Editor.

When I first started working with the Editor I thought the obvious solution to use it would be a StringBuffer. However after only a few minutes of implementing it with the StringBuffer I found it lacked much of the basic functionality I needed, such as getting a specific line from the buffer, or removing a line from the buffer. I also can only add to the end of the Buffer and not to any particular point in the buffer. So that didn't last long at all.
When I looked at the StringBufferImpl class in the library, I saw that it was nothing more than a List of Strings. So I decided to do the same. So I created two List of strings. One for the full Buffer, and one for a temporary buffer. The temporary buffer is used in input/edit mode. Upon leaving input mode back to command mode then the temporary buffer is inserted into the full buffer.
To accomplish this, I originally tried using List#setRange. However I quickly discovered that wouldn't work as it would just overwrite the range, as opposed to inserting at that point. Additionally if the temporary buffer would exceed the length of full buffer, then it would throw an exception. Even though the list is an extendable list. So I tried List#insertRange, and that expanded the List as required, but it will only initialize the new range to the same value. You can't insert the range with with list as the new values. So it required first using insertRange to add the space for the temporary list, then setRange to change those values to be the strings in the temporary buffer.

Another area of interest is that I have implemented a RoomManager. Eventually the RoomManager will be expanded to have time outs so once a room has gone 'stale' (no activity in it for x number of minutes) it will reset the room. And, if still not used after y number of minutes, the object will be unreferenced for the GC to clean up as it will. The first part of this however, was trying to to determine how I can efficiently 'dynamically' load the rooms when someone tries to access them, or alternatively reference an already loaded room. Since I can't use eval to load a file at this point, the code has to be loaded on start up.
So I created two maps, each map has a key of a room identifier. One map holds the rooms themselves if they are loaded. The other, roomFuncs holds functions which create the room. Rooms are added by calling the add method on the RoomManager, which takes a callback as an argument. The add method then runs the call back to create the room. It gets the room's unique identifier to use as the key. Then it stores the callback in the roomFuncs map. Then when it comes time to access the room, we call the method putIfAbsent method on the room map, passing our roomId and a reference to roomFuncs[roomId] which returns the callback to create the room if the object is not already loaded. The putIfAbsent is a nice little method, and quite handy for this.

Well that's about all for now anyways. I must say I'm having a blast writing this simple mud, and while I have a long way to go for a full featured mud, it is virtually usable at this point. Dart is a lot of fun!

by Matthew Butler (noreply@blogger.com) at March 05, 2012 03:44 PM

February 27, 2012

Trials (and Errors) in Dart

Dart MUD... Progress 1

So before I get started, I just want to put out there that the latest integration build of DartEditor has been released, and you should pick it up here. This build contains the latest IDE, the SDK and now Dartium as well! For those of you running 64-bit systems, it is a 32-bit build of Chromium so you may encounter some library errors if you have not installed the extra components you need.

So now that that news is out of the way.. a little progress report on my Dart MUD. (I may need to come up with a better development name, as it conflicts with the already existing MUD: Dartmud.com) So far I have a minimal server, from which I've managed to remove most unnecessary code from and make the mudlib independent of the server. I have a generic MudLib object which handles most interactions between server and specific mudlib components. A User object which handles the client connections and various user properties (username, passwords, etc). However I'm not completely happy having the socket implementation directly part of the User object, and may break down into a connection object which the User class will either have it as a property, or may inherit from (just because someone connects, doesn't mean it will result in a User on the system).

After some playing around with a static class which contained the various commands a player can execute, I decided to instead create a small class, and each command is an instance of the class. All of which are managed by a CommandDaemon/Command Manager. I can see this allowing for more flexibility in adding commands globally and perhaps even in just specific rooms or objects. On the note of Rooms and GameObjects, I have classes for these also implemented, as well as a 'container' interface and a factory class for it. Users and Rooms both currently extend the factory class for the container.

At this point, I've added a few 'commands', including the exit and shutdown commands from the EchoServer (though now setup to be used with the Command Manager I have implemented). I've also added a basic 'look', 'broadcast' and 'help' command, and am in the process of fleshing out these respective commands so they properly handle any arguments sent to them (broadcast works to notify all users, regardless of if they are in the same room as the person issuing the commands.

I still have so much to do. Currently when connecting you are prompted for a username/password to log in. However you can enter anything an be granted access with the username you enter. I need to be able to create a new user, to save the user, and to load them when logging in. Also I have a very basic room, but only the one. I still have to create more rooms and implement travel commands to move between rooms. To say nothing of the other normal things you would expect on a mud including equipment, objects, money, combat, etc etc etc.

While I still have a very long way to go to make a basic mud, I'm quite pleased with the progress I have been making towards that end. Something I may want to look towards as well is some type of 'reload' or 'refresh' command, as I have to shutdown the server and restart it after each change I make. I'll also need to work on a memory management daemon of some kind too, so that once the mud gets to a decent size, objects will only be loaded/created when accessed, and after a period of time, removed if not used or near an active player.

One of these days I'm going to make an effort to learn git/git hub too.

by Matthew Butler (noreply@blogger.com) at February 27, 2012 02:14 PM

Dartery

Experimenting with WebSockets

This is just some notes and a preview of what will probably be a more in-depth post on WebSockets in Dart. Between GWT compiles over the past few days I've been trying to get a simple WebSocket client/server app up and running. Going in, I didn't know anything about WebSockets other than that they're bidirectional and as close to raw sockets as you can get in a browser.

Unfortunately, I've never done any raw TCP work, unless it was in school and I forgot already, so once I got to data framing and saw how much work it'd be to implement the RFC I quickly hit my time allowance for this excursion. Yay for higher-level protocols like HTTP and all the implementations I've used over the years. Working higher on the stack has it's advantages, but from a pure cranial exercise point-of-view, it does arguably shield you too much from what's happening underneath.

But... I do have a simple echo WebSocket server up and running, using the http library from the Chat sample (with a few tweaks) to handle the handshake.

There were a few noteworthy lessons along the way:
  1. WebSockets were broken in Dart for a while. The WebSocket constructor just landed in bleeding_edge, but it only works in Frog, not in Dartium. 
  2. I didn't know about the handshake, and the W3C draft spec doesn't really cover it. Chrome also doesn't give much indication of anything going wrong when the server simply doesn't send a handshake response. I'm not sure it could, other than timeout, but that was confusing. Reading the RFC and Wikipedia helped.
  3. ws://echo.websocket.org was helpful to check that the client code worked. 
  4. I needed base64 encode and SHA1 digest functions. I took a base64 encode function from the Total sample and modified it to work with lists of int and to pad the output correctly, and I got SHA1 from dart-crypto-lib.
  5. I initially tried to base64 encode the hex string digest from SHA1 until I figured out I need to encode the raw byte array digest. Oops.
  6. Once I had what I thought was a correct handshake response, debugging why the handshake wasn't working was quite a pain because Chrome wouldn't let me see the response headers if they weren't correct and Firefox doesn't have a WebSocket() constructor. 
  7. To fix Firefox I added a script that assigned WebSocket to MozWebSocket. This let me use Firebug to see the response headers from my server. 
  8. I didn't use the HTTP server from Chat, but I used an HTTPConnection attached to a ServerSocket, so that I could remove the handlers from the HTTPConnection after the handshake completed and have a raw socket again.
  9. HTTPConnection didn't let me set the HTTP status, so I added it to the interface. 
  10. HTTPConnection also wanted to set the connection header to closed, so I had to add a check to not set the header if it was already set to "Upgrade".
  11. I tried to decode messages on the server with the utf8 library, but that failed because I hadn't yet read about framing. Oops again.
As of now, I can echo a received message back to the client, but I'm pretty sure this only works because the message is small and fits in one frame. Parsing and constructing frames is obviously key to building even the simplest WebSocket server. The client API exposed in browsers is comparatively simple to use, it's a shame there isn't a simpler bi-directional HTTP-based protocol, like an EventSource that can also send messages from browser to server.

It shouldn't be too hard from here to implement the framing and wrap everything up into a WebSocket server that takes care of the handshake, parses frames, and exposes a simpler interface with handlers for text and binary messages. It'd be really nice to have this built in to a future http library.

I'll post some code next time around, but hopefully these notes help anyone else playing around with WebSockets in Dart.

Happy Darting!

by Justin Fagnani (noreply@blogger.com) at February 27, 2012 01:46 AM

February 23, 2012

Trials (and Errors) in Dart

Featureless Sockets

Okay, so the title is a bit of a stretch. Dart Sockets are far from featureless. As some of you may or may not know, I've decided to take a segue in my EchoServer towards working on a basic MUD and MUDLib written in Dart. It will be far from full featured, and far from fully functional but it will be the basis and a nice little start.

Within a few minutes of converting the EchoServer to be the basis of the MUD driver, I've already run into an issue of a missing feature with Sockets in Dart. I'm unable to get the host of an incoming connection. That is, I can't find out who is connecting to me. While it's a trivial matter for a MUD, or many other services, one would expect such functionality for various uses including HTTP server logging, etc.

After digging through the bleeding edge to see if it may have been recently included but just not yet updated in the API, I still can't find any reference to such properties. So as such, I've created a bug report over in the Dart issue tracker. If you're interested, or want to star the report you can view it here at: Issue 1819

As I progress with the Dart core and MUDLib I'm sure I'll find some additional bugs to report, or just missing features I can think could be added. Additionally I'll keep progress reports available on here and eventually release the source on GitHub or something similar.

by Matthew Butler (noreply@blogger.com) at February 23, 2012 03:38 PM

February 21, 2012

Test Driven Dart Development


Getting Familiar with IO

I have been checking out what is new with Dart for some time now, and I was quite interested to see that they released a formal library for IO. The server side is where a lot of my interest is for Dart, so I was anxious to try out some of the API.

As I became familiar with IO, I noticed that there was quite a bit of async calls happening. The testing I had coded up to this point was all synchronous calls, so I looked into support for async.

It turns out that there is a method called asyncTest that can be used. I have put together a 5 part presentation that illustrates how you can test async method calls.

The scenario for this post is based on a library I am coding now that is targeted as an add-on library to the existing http library that I retrieved from the bleeding edge repo. From spending time trying to learn Node.js, I decided that my library would be based on a similar library in Node called 'Formidable'. I originally attempted to port their Node.js library, but decided that eventually that it would be a good learning experience to follow their API, but provide my own Dart based implementation.

I am not finished the library (almost), but I wanted to show you how I did some of my testing early on. Here are the 5 parts;

Part 1
Part 2
Part 3
Part 4
Part 5

The GitHub repository for this project is here.

I will be releasing the library very soon, but in the meantime, you can get started testing your async calls.

by Allan (noreply@blogger.com) at February 21, 2012 04:25 AM

February 14, 2012

Olov Lassus

February 09, 2012

Adam Coding

Dart classify markup example

I was looking for a simple way to create some markup dynamically of syntax highlighted dart code, in dart! A big thanks to Bob Nystrom from the Dart team for suggesting the simplest solution. Use classify from dartdoc.

A live example of this can be found here along with the source code.

Example of how to use dartdoc/classify.dart
dartdoc is used for generating static HTML for the api.dartlang.org site. This example shows how importing dartdoc/classify.dart one could generate syntax highlighted dart code at runtime.

Patching
Currently you need to modify the import statement to reference the location of classify.dart.

#import('../../dart_bleeding/dart/utils/dartdoc/classify.dart', prefix:"classify");

Building
Build with minfrog for best results. At the moment dart editor does not seem happy with me on importing dartdoc/classify.dart. So compiling with minfrog worked best.

minfrog --compile-only --out=ClassifyExample.dart.js ClassifyExample.dart

Using classify
This is the easiest part! Create a SourceFile and add pass it along to classifySource which will return a properly formatted string of span elements that has class attributes set. From that point you can add a css style to the span elements.

    String code = "main() { print('hello world'); }";
    classify.SourceFile sf = new classify.SourceFile("sf.dart", code);
    String c = classify.classifySource(sf);

   <span class="i ">main</span><span class="p ">(</span><span class="p ">)</span><span> 
   </span><span class="p ">{</span><span> </span><span class="i ">print</span>
   <span class="p ">(</span><span class="s si">'hello world'</span>
   <span class="p ">)</span><span class="p ">;</span><span> </span><span class="p ">}</span> 

Example css style

/* Syntax highlighting. */
/* Note: these correspond to the constants in classify.dart. */
.e { color: hsl(  0, 100%, 70%); } /* Error */
.c { color: hsl(220,  20%, 65%); } /* Comment */
.i { color: hsl(220,  20%, 20%); } /* Identifier */
.k { color: hsl(220, 100%, 50%); } /* Keyword */
.p { color: hsl(220,  20%, 50%); } /* Punctuation */
.o { color: hsl(220,  40%, 50%); } /* Operator */
.s { color: hsl( 40,  90%, 40%); } /* String */
.n { color: hsl( 30,  70%, 50%); } /* Number */
.t { color: hsl(180,  40%, 40%); } /* Type Name */
.r { color: hsl(200, 100%, 50%); } /* Special Identifier */
.a { color: hsl(220, 100%, 45%); } /* Arrow */

/* Interpolated expressions within strings. */
.si {
  background: hsl(40, 100%, 90%);
}

.s.si { background: hsl(40, 80%, 95%); }
.i.si { color: hsl(40, 30%, 30%); }
.p.si { color: hsl(40, 60%, 40%); }


by financecoding at February 09, 2012 08:27 AM

February 05, 2012

Dartery

Syntax Highlighting Dart on Blogger with Pygments

Olov Lassus has recently added Dart support to Pygments, so I decided to try it out to add some syntax highlighting to my previous post.

As far as I know, Pygments is the only syntax highlighter out there with Dart support that can easily output HTML. There are some Dart modes for popular text editors, and I believe a mode for CodeMirror, but Olov's contribution and Pygments is the only one I found that could output HTML that I could easily embed in Blogger.

I had to install the development version of Pygments to get Dart support, so I installed Homebrew, then Mercurial, then checked out the latest Pygments.

Pygments comes with simple command line utility - pygmentize - that will generate HTML and CSS. To use it, just put your Dart snippets into files and run:
./pygmentize -f html test.dart
That will output the HTML formatted version to your console that you can copy into Blogger's HTML editor.

The next step is to generate some CSS to add to your template. Run pygmentize again with these flags:
./pygmentize -f html -S colorful -a .highlight
and you'll get CSS that you can add to your site template.

I customized my CSS a little bit, but I couldn't quite get the styling I wanted, particularly with interpolated strings. Pygments or the Dart highlighter (I don't know which is responsible) doesn't look like it'll nest <span> tags, so I can't target a name within a string. It also treats all names the same, whether they are function declarations or calls. I personally like to highlight just declarations.

It's a good start though. Much thanks to Olov!

by Justin Fagnani (noreply@blogger.com) at February 05, 2012 06:04 PM

Olov Lassus

Pygments contribution now upstream

My Pygments Dart highlighter that I’ve written about previously is now upstream! This means that there’s now out of the box support for Dart if you get the development version from source control and that the next formal release is likely to have it too. Github enabling it shouldn’t be far away now.

Show comments (Dart misc)

by Olov Lassus at February 05, 2012 11:30 AM

February 02, 2012

Dart Experience

Dart official blog

Something that many Dart fans had complained was the lack of an official blog about Dart. From dartlang have listened to the community and have launched this expected blog. The …

Continue reading »

by Dart Commander at February 02, 2012 05:54 PM

January 31, 2012

Test Driven Dart Development

Getting Started

I decided to check out a new development language recently called Dart. I must say that there is plenty of excitement surrounding this effort by Google, and I am finding myself drawn to the language.

Most of my background is developing in a structured language, Java in my case, and I have gotten used to using enterprise tools and technologies to help me and my team deliver a quality product.

My goal with this blog is to help support the Dart initiative, and to provide a way for developers coming from a Java background (or any background) to more easily adopt Dart as another tool in their web development efforts. There should be plenty here for anyone wanting to learn Dart, regardless of their background.

I will try to choose topics that I feel have helped me the most in adopting the language, and I will attempt to draw similarities and contrasts with Java.

Before I get started, I also want to point out that Google has released this language at a very early stage, so you should lower your expectations early on and take an opportunity to make the language as good as it can be by providing feedback to the Dart team. I have found that the Dart team, and the community that has grown from their efforts, have been terrific in addressing any questions or issues that I have had.

From the title of this blog, you can probably tell that I subscribe to the proven approach described as Test Driven Development. My intention is not to debate the merits of TDD, but I am hopeful that those of you who have never tried this approach will see some benefit in such an approach. Particularly when it comes to web development, which has not typically lent itself well to this type of approach.

I will begin my series by covering the basics of setting up a development environment, in particular for the benefit of those who would like to follow along with some of the code samples. I will base this series on a Windows environment, mainly because I am seeing a great deal of Linux and Apple based Dart material out there already. In addition to this, I will be encouraging you to download the binaries, not because it is not fun compiling for hours, but because it will get you up and running quickly.

Download Resources
The current version I am using for my development environment is build 3331. You can find the same files here. You should see a list of files something like the following.


I have highlighted the specific files that I use in my environment. If you extract both files to a directory of your choosing on your computer, the directory structure will look something like this.


The folder labeled 'dart' (<DART_EDITOR_HOME>) contains an editor for you to develop your applications, based on the popular Eclipse platform. Some of the features I have grown to really like are not implemented yet, but as mentioned, it is still early, and the editor is constantly improving.

The other folder contains the Dart runtime files that includes the Dart executable as well as a compiler written in Dart called frogc. We will use these files occasionally, so it is good to have them in a known location early on.

I would suggest that you follow the convention as set out by the Dart team, to use your home folder as the starting point, and create a directory called dart your home directory. In here, I keep all of my projects that get created in the editor. This way, I can use different builds of Dart, but always be pointing to the same directory for source code. There are other things that I prefer to do in my environment, but I will leave that out for now.

As long as you have a recent version of Java installed and recognized on your OS, you can navigate to  <DART_EDITOR_HOME> , and execute DartEditor.exe. Here is what you should see.



I was fortunate to find an article on Unit Testing with Dart, and I have used this article as a starting point for my unit testing. Use the same libraries I am using by downloading this file, and extracting to your home\dart directory.

Create a Simple Demo using TDD

One of the principles of TDD is to write a test first and watch it fail. I will create a project that represents a sample application, and a second application for testing that sample app.

In the Dart editor, click File > New Application. Fill-in as shown here.


Click Finish, and you will have a skeleton application that technically can be run directly, but that is not what we want here. What I would like is to create a sample library and test that library.

Replace what is in the editor window with one statement as follows.

#library('calculator');

Save the file.

Notice that the Libraries view now has an icon labelled 'calculator', indicating that there is now a library with that name.

Now right-click on the package labelled 'calculator', and choose New File. Fill-in as shown here.


A new class file will be in the editor window, with only a class definition. This class declaration is identical to how a class would be declared in java, except that the source file ends in a .dart extension.

Select the original source file labelled MySampleApplication.dart, and you will notice that the editor has already added a new entry for the source file just created.

Repeat the steps just performed so that there is another source file called addition.dart. Make a small change to the addition and subtraction class definitions such that the class declarations begin with a Capital letter. This will not require, unlike Java, that the source file name be changed.

So, all that we have at this time in out primary source file for our library are these 3 lines.



#library('calculator');

#source('subtraction.dart');

#source('addition.dart');


So far, so good. Now lets write some tests!

Create a new application and fill-in as follows.


Notice we are choosing 'Web' this time, because the testing framework is graphical.

Change the string text 'hello World!' with 'MySampleApplication Test Suite!'. As a sanity check, save all (and wait for compiling to finish) and click Tools > Run in Browser. If your default browser is not currently Chrome, copy the url that is displayed in your default browser, and paste it into Chrome. For this series, I will assume Chrome as your browser.

You should see something like this.

Not very interesting yet, but we are making progress.

Add the following statement as the second line in the TestMySampleApplication.dart file.

#import('../MySampleApplication/MySampleApplication.dart');

This is all that is required to expose the class Addition and Subtraction.

Now add 2 additional lines as shown here.


#import('../testing/unittest/unittest_dartest.dart');
#import('../testing/dartest/dartest.dart');

Also, after the last line in the main method, add this line.

new DARTest().run();

Save all files and wait for the build to finish (done automatically). Go back to the Chrome browser window you had open previously and press F5 or click refresh.

You will now see something like.


As you can see, there is now a console that appears, allowing you to run unit tests. We have no unit tests at the moment, but that can't last long! :)

Write a Test and Watch it Fail!

In my very simple scenario here, we have a use case where a client of our library would like to call a method/function that accepts 2 parameters of type int and returns a value of type int that represents the sum of the 2 parameters passed in. (I will not debate the merits of statically typed and dynamically typed languages. Not now anyway. )

To write a test, we need to define a new method/function, and we will call it simpleTests().

Immediately after the main method definition, define the function called simpleTests(). In that function, define a nested function called setupData(), followed by a nested function called group() that accepts a String and an anonymous function for parameters. In the anonymous function, define a function called test() that accepts a String and another anonymous function for parameters.

It should look like this if you were following along.



That is not very interesting yet, so we will add some additional code that actually exercises something.

The first test we want to write will be to test a function called 'add()'. Here is what we start with.



Naturally, the editor complains because the add() function does not exist, so following TDD, we will satisfy the compiler by adding a static method called add to the Addition class as shown here.


This allows us to compile, in spite of the fact that we did not provide any implementation to the add function.

Add a new call to the function simpleTests(); in the main method, just before the call to new DARTest().run();

If we save all files and look at our application in the chrome browser, we will now see that there is a test. Click the button with the right arrow to run the test listed. You will see something like this.



Great work!! We got it to fail.

Now lets change the implementation so that our test passes.

If we provide the simplest code that will get the code to work, then we may have something like this.

return operand1 + operand2;

Save, wait for compile and refresh our page. Click the right arrow to execute the tests. We will see this.



Now that we have this simple function behaving as we would expect it to in this test, we can re-factor the code knowing that running this test again will ensure that we know if and when we break the code.

I admit that this is a very simple example, but now that we have a grasp of our environment and how to set-up tests, we will continue in the next series with testing a more real application that most can relate to.



by Allan (noreply@blogger.com) at January 31, 2012 06:35 PM

Dart Experience

Translations from Javascript to Dart

One of the steps which should give Google to get massively introduce dart on our websites is to embed the existing code to facilitate the migration of existing projects. Here …

Continue reading »

by JRomay at January 31, 2012 08:28 AM

January 29, 2012

Adam Coding

Dart: A short introduction to dart.

On 1/28/2012 I was fortunate to give an introduction to dart at a GTUGsf Mobile HTML5 Codelab event. Conrad Wade did a spectacular job of arranging the event and promoting the DartSF meetup group. I truly enjoy the GTUGsf events!


by financecoding at January 29, 2012 07:16 PM

January 26, 2012

Adam Coding

Dart: Updated Dartium builds with breakpoint support for Linux and Mac

As Seth Ladd has commented on google plus, Dartium now has breakpoint support. Big win in such an early stage of the project. Providing Release builds for Mac and Linux below. While I was trying breakpoints out, one thing noticed was to getting scripts to show up properly in inspector you need to hit an extra refresh on the page. My public is can be found on pgp.mit.edu.

wget http://dl.dropbox.com/u/33138127/dartium_macosx/Chromium.app.tar.gz
wget http://dl.dropbox.com/u/33138127/dartium_macosx/Chromium.app.tar.gz.sig
wget http://dl.dropbox.com/u/33138127/dartium_macosx/Chromium.app.tar.gz.md5
wget http://dl.dropbox.com/u/33138127/dartium_macosx/README.txt
gpg --verify Chromium.app.tar.gz.sig Chromium.app.tar.gz
md5sum -c Chromium.app.tar.gz.md5

wget http://gsdview.appspot.com/dart-editor-archive-continuous/latest/DartBuild-linux.gtk.x86.zip
wget http://dl.dropbox.com/u/33138127/dartium/dartium-linux-32bit-Release.tar.gz
wget http://dl.dropbox.com/u/33138127/dartium/dartium-linux-32bit-Release.tar.gz.sig
wget http://dl.dropbox.com/u/33138127/dartium/dartium-linux-32bit-Release.tar.gz.md5
wget http://dl.dropbox.com/u/33138127/dartium/README.txt
gpg --verify dartium-linux-32bit-Release.tar.gz.sig dartium-linux-32bit-Release.tar.gz
md5sum -c dartium-linux-32bit-Release.tar.gz.md5


by financecoding at January 26, 2012 07:15 AM

January 13, 2012

Richard Griffith

Keeping Time with Dart - The Clock, Stopwatch and Date Classes

All that really belongs to us is time; even he who has nothing else has that. - Baltasar Gracian

Time is free, but it's priceless. You can't own it, but you can use it. You can't keep it, but you can spend it. Once you've lost it, you can never get it back. - Harvey Mackay

It was the best of times, it was the worst of times... Charles Dickens - A Tale of Two Cities

Time cannot be absolutely defined, and there is an inseparable relation between time and signal velocity. Albert Einstein

Introduction


The ability to determine time of day, the date, or to calculate elapsed time is just one of several fundamental capabilities to be found in just about every modern programming language. We frequently need to answer the question "when did this event happen?" or "how long has it been since this other event happened?". Dart's [1] time keeping methodology is divided among the Clock, Stopwatch and Date classes. In this article, we'll not only take a look at each one, but we'll also touch upon what is currently required to trigger a method execution at fixed intervals of time in Dart. So let's get started with the Clock class.

The Clock Class

The Clock class allows you to implement a counting device whose output increments monotonically at a fixed frequency of 1000 Hz. The class has two methods, frequency() and now(). The value for frequency is hardcoded to return a value of 1000, defining a resolution of 1 msec. The now() method simply returns the current clock tick defined by new Date.now().value from the Date class, which we will discuss in a moment. Here is a simple example of using the Clock class to determine when a certain amount of time has elapsed:

// Create a  1 sec delay using the Clock class:
int f1 = Clock.now();
int f2 = f1+1;
while ((f2-f1) < 1000) {
  f2 = Clock.now();
}
print(f2-f1); // Outputs 1000

But the Clock class is otherwise quite limited. A far more useful class is the interface Stopwatch, which provides all of the capabilities of the Clock class with the additional benefit of being able to stop and start the timer as necessary.

The Stopwatch Interface

Recall that Interfaces can be thought of as an agreement between a class and the outside world. When a class implements an interface, it promises to provide the behavior published by that interface. Hence, interfaces are types that define which methods a class provides. Which methods are provided by the Stopwatch interface may depend on whether you are using the Dart Editor or the Dartboard. As of this writing, Dartboard still had the old StopWatch class, which has some distinct differences to the new interface. Let's take a look at the Dartboard version first. Here's an example:

// Old StopWatch class still in use at try.dartlang.org
// Note the old class uses an upper case 'W' in StopWatch()
StopWatch watch = new StopWatch();
// In the old class, the start() method needs to be called after the instance is created 
watch.start();
while (watch.elapsedInMs() < 2000) { }
watch.stop();

print("The watch frequency is " + watch.frequency() + " hz");
print("The number of clock ticks since start was called is " + watch.elapsed());
print("The elapsed time in msecs is " + watch.elapsedInMs() + " ms");
print("The elapsed time in usecs is " + watch.elapsedInUs() + " us");

// Prints the following:
The watch frequency is 1000 hz
The number of clock ticks since start was called is 2000
The elapsed time in msecs is 2000 ms
The elapsed time in usecs is 2000000 us

If you are using the Dart Editor, you have access to the new version of the Stopwatch class (note that Stopwatch is now written using a lower case w). The new class adds a reset() method and allows the watch to be started as soon as it is instantiated, if desired. You may start, stop and reset the stopwatch instance as necessary depending on your application. The following code snippets show several different ways of instantiating a Stopwatch provided for illustration purposes:

// Declare a global variable watch of type Stopwatch
class keepingTime {
  Stopwatch watch;

  // instantiate and start the watch in the constructor method
  keepingTime() {
    watch = new Stopwatch.start();
    //etc

or keep the watch local to your constructor method:

class keepingTime {
  
  // declare the variable and initiate it within the constructor method
  keepingTime() {
    Stopwatch watch = new Stopwatch.start();
    //etc

or establishing methods to start, stop and reset:

class keepingTime {
  Stopwatch watch;
  keepingTime() {
    watch = new Stopwatch();
  }

  startWatch() {
    watch.start();
  }

  stopWatch() {
    watch.stop();
  }

  resetWatch() {
    watch.reset();
  }
  // etc

The following is a complete example using the Dart Editor where we implement a simple 2 second delay and output information regarding the delay to a browser window. Note that we have embedded our watch expressions directly within the string literals using string interpolation with ${expression}:

#import('dart:html');

class keepingTime {
  Stopwatch watch;
  
  keepingTime() {
      watch = new Stopwatch();
  }

  void delay2s() {
    watch.start();
    while (watch.elapsedInMs() < 2000) { }
    watch.stop();
    String s1 = "The watch frequency is ${watch.frequency()} hz<br>";
    String s2 = "The number of clock ticks since start was called is ${watch.elapsed()}<br>";
    String s3 = "The elapsed time in msecs is ${watch.elapsedInMs()} ms<br>";
    String s4 = "The elapsed time in usecs is ${watch.elapsedInUs()} us<br>";
    watch.reset();
    String s5 = "We have reset the watch:<br>";
    String s6 = "Now the number of ticks is ${watch.elapsed()}<br>";
    String s = s1 + s2 + s3 + s4 + s5 + s6;
    write(s);
  }

  void write(String message) {
    document.query('#status').innerHTML = message;
  }
}

void main() {
  new keepingTime().delay2s();
}

In a browser window, we get the following output:

The watch frequency is 1000 hz
The number of clock ticks since start was called is 2000
The elapsed time in msecs is 2000 ms
The elapsed time in usecs is 2000000 us
We have reset the watch:
Now the number of ticks is 0

Keep in mind that resetting the watch neither starts nor stops it.

The final technique we would like to cover for keeping time with Dart is the Date interface.

The Date Interface

The Date interface is a subtype of Interface Comparable and comes with a robust set of methods and constructors. We can, for example, construct a new Date instance with the current date time value (recall the earlier Clock class discussion). The timeZone of this instance is set to the local time-zone by default.

Date creationTime = new Date.now();
print("Right this millisec, the time is " + creationTime);
print("which translates into a value of " + creationTime.value + " clock ticks.");

// Outputs:
Right this millisec, the time is 2011-12-17 19:45:02.054
which translates into a value of 1324172702054 clock ticks.

As we mentioned before, the Date class in Dart provides a lengthy set of fields, constructors and methods. Here are just a few, simple examples:

print(new Date.withTimeZone(1970, 1, 1, 0, 0, 0, 0, new TimeZone.utc()));
print(new Date.fromEpoch(0, new TimeZone.local()));
print(new Date.now().difference(new Date.fromEpoch(0, new TimeZone.local())));
print(((new Date.now().difference(new Date.fromEpoch(0, new TimeZone.local()))).inDays).toString() + " days since epoch.");

// Outputs:
1970-01-01 00:00:00.000Z
1969-12-31 18:00:00.000
367826:21:27.421
15326 days since epoch.

Notice the last two print statements. We have made use of the Difference method of the Date interface to return a value of type Duration representing the time span from epoch to the current time. The Duration interface has a number of useful fields. In the last print statement, for example, we convert the duration since epoch, returned as hours:minutes:seconds:milliseconds to days. We then employ the toString() method from the Date interface to allow us to combine the calculated number of days (of type Number) to a string. Not using the toString() method results in a static type warning as well as a dynamic type error if in checked mode.

We'd like to do one last example before we conclude. This example may be a bit contrived, but it does bring together a couple of the methods that we have just talked about. Let's say we want to know the "age" of an instance at some given time in the future relative to the time in which it was created. We could monitor elapsed time by using a watch created with the Stopwatch class which starts when we create our instance, similar to an example we explored earlier. An alternative approach might be to use the Date class in the following manner:

// We've just created an instance of something that we'd like to track its age
// so we will also create a new Date at the same moment
Date creationTime = new Date.now();
// Then, at any point in the future, we can determine the age of our instance as follows:
var age = new Date.now().difference(creationTime);
print("My instance is now " + age.inHours + ” hrs old”);

The duration interface also has fields inDays, inMinutes, inSeconds and in Milliseconds. In order to demonstrate our example, though, we will have to simulate the passage of time and for that, we will use a watch:

Date creationTime = new Date.now();
// Old StopWatch class still in use at try.dartlang.org
StopWatch watch = new StopWatch();
watch.start();
while (watch.elapsedInMs() < 5000) { }
watch.stop();
var age = new Date.now().difference(creationTime);
print("The age of your instance is " + age.inMilliseconds/1000 +"s.");
//Outputs:
The age of your instance is 5s.

Note that duration can have a negative value.

Method Execution using a Timer

None of the classes that we have talked about so far provide a way to trigger a method execution. There is an open issue to make the Timer class currently available only in the Dart shell on the server side available to the client side. For now, it appears we must make use of the window.setInterval and its related functions to accomplish this task. I've included an example of using setInterval and clearInterval within a Dart program to provide a simple illustratation of what working with the DOM in Dart looks like:

#import('dart:html');

class progressMonitor {
  var progressIntervalID;
  var progress;
  var progressRate;
  var startTime;

  progressMonitor() {
    progress = 0;
    progressRate = 10;
  }
  
  void startMonitor() {
    document.query('#status').innerHTML = "I'm never going to finish this project.  I'm only now starting!<br>";
    startTime = new Date.now();
    progressIntervalID = window.setInterval(runMonitor, 5000);
  }
  
  void runMonitor() {
    String s, s1, s2;
    if(progress + progressRate >= 100) {
      window.clearInterval(progressIntervalID);
      progress = 0;
      Date finishTime = new Date.now();
      var hours = finishTime.hours;
      var minutes = finishTime.minutes;
      var seconds = finishTime.seconds;
      hours > 12 ? hours -= 12 : hours;
      s1 = "Yay! I'm all done and it's only $minutes minutes after $hours, give or take about $seconds seconds.<br>";
      s2 = "In fact, it only took ${finishTime.difference(startTime).inSeconds} seconds to finish.  Well, that wasn't so bad!<br>";
      s = s1 + s2;
    } else {
      progress += progressRate;
      s = "I'm never going to finish this project.  I'm only $progress% done with it.<br>";
    }
    write(s);
  }

  void write(String message) {
    document.query('#status').innerHTML += message;
  }
}

void main() {
  new progressMonitor().startMonitor();
}

The program prints the following in a browser window:

I'm never going to finish this project. I'm only now starting!
I'm never going to finish this project. I'm only 10% done with it.
I'm never going to finish this project. I'm only 20% done with it.
I'm never going to finish this project. I'm only 30% done with it.
I'm never going to finish this project. I'm only 40% done with it.
I'm never going to finish this project. I'm only 50% done with it.
I'm never going to finish this project. I'm only 60% done with it.
I'm never going to finish this project. I'm only 70% done with it.
I'm never going to finish this project. I'm only 80% done with it.
I'm never going to finish this project. I'm only 90% done with it.
Yay! I'm all done and it's only 48 minutes after 9, give or take about 24 seconds.
In fact, it only took 50 seconds to finish. Well, that wasn't so bad!

Once the Timer class becomes available, we'll redo this example using a timer and its methods.


Acknowledgements

Thanks to Florian Loitsch for suggestions on the use of the Stopwatch class.


Works Cited

[1] Dart's Homepage

by Richard Griffith at January 13, 2012 11:09 PM

January 08, 2012

Richard Griffith

Using the HTML5 <input> range Attribute with setInterval() in Dart

Note: Edited 8 January 2012 to clarify and correct text related to attaching an external style sheet.

Introduction


HTML5 adds a number of useful type attributes for the <input> tag [1], including fields for validating email addresses, entering dates, and providing a color picker. Although browser adoption has so far been somewhat inconsistent as of this writing, one attribute that has been of particular interest is the range attribute, more commonly referred to as the slider. Not currently supported by either Firefox (surprisingly) or IE (less so), the remaining popular browsers (Chrome, Safari and Opera) do offer support for this attribute of the <input> tag.

The HTML for this type of tag looks like the following:

<input id="mySlider" type="range" min="1000" max="10000" step="20" value="5000" />

In this article, however, we will be implementing our example almost entirely in code. Therefore, in Dart [2], we can create the <input> tag above as follows:

InputElement mySlider = new Element.tag("input");
mySlider.attributes = ({
  "id": "mySlider",
  "type": "range",
  "min": "1000",
  "max": "10000",
  "step": "20",
  "value": "5000"
});
container.nodes.add (mySlider);

where container is the name of the enclosing <div> tag, which we will create in just a moment.

For this example, we will use the slider to control setInterval(myFun, delay)'s fixed time delay when calling function myFun(). We will also mention an alternative method for accomplishing approximately the same thing with setTimeout() that may be more robust for certain scenarios. First, however, we need to create a simple web page to display our example.

Working with HTML in Dart


In the Dart Editor [3], we've created a new project that contains a fairly sparse HTML file comprised of only a few basic tags:

<html>
  <head>
    <title>Using the HTML5 input range Attribute with setInterval() in Dart</title>
  </head>
  <body id="home">
    <script type="text/javascript" src="htmlInDart.dart.app.js"></script>
  </body>
</html>

Code currently developed in the Dart Editor for web viewing is compiled to JavaScript, hence the script tag of that type. Before we start adding some page elements to help us organize our example, let's just discuss for a few minutes several different ways that we have to add styles to these elements in Dart.

Adding Styles

There are three different ways to add styling to an HTML page - external style sheet(s), internal style sheet(s) or by applying an inline style to a particular tag [4]. In the Dart Editor, if you create an external style sheet in your project folder by using File -> New File, it will place a #resource directive in the .dart file that contains your application's main() method. For example:

#import('dart:html');
#resource('myStyleSheet.css');

void main() {
  // application code
}

However, at the time of this writing, the resource directive is not currently used, but is under consideration as a way to bundle non-code resources with libraries in the future. To attach an external style sheet to your project, you can, of course, add a link to the css file in the <head> tag of your project's HTML file:

<link type="text/css" rel="stylesheet" href="myStyleSheet.css">

or, if you would prefer, you can add a link to the external style sheet programmatically by defining a LinkElement:

LinkElement myStyleSheet = new Element.tag("link");
myStyleSheet.type = "text/css";
myStyleSheet.rel = "stylesheet";
myStyleSheet.href = "myStyleSheet.css";
window.document.head.nodes.add(myStyleSheet);

You can also have Dart create an internal style sheet. If you look at our simple HTML file above, you'll notice we gave the body tag an ID selector of id="home". To style this selector using an internal style sheet, you can add the following in your application:

StyleElement myStyle = new Element.tag("style");
myStyle.type = "text/css";
myStyle.innerHTML = "#home {background-color: #E1CF75}";
window.document.head.nodes.add(myStyle);

Finally, if you want to apply your styles to tags inline, there are two ways to do this. In this example, we will be creating a div with an ID selector of id="page". We can then style it as follows:

DivElement page = new Element.tag("div");
page.id = "page";
window.document.body.nodes.add(page);
page.style.width = "1000 px";
page.style.margin = "20 auto";
page.style.backgroundColor = "rgba(255,255,255,0.75)";
page.style.borderRadius = "15px";

Note that if you use this approach, the CSSStyleDeclaration method name will not necessarily match its corresponding CSS style name (ie, backgroundColor for background-color). Refer to the CSSStyleDeclaration section of Dart's HTML library for a complete list of style methods [5].

A more concise way of writing an inline style is to use the cssText() method. We can then rewrite the above as follows:

DivElement page = new Element.tag("div");
page.id = "page";
window.document.body.nodes.add(page);
page.style.cssText = "width:1000px; margin:20px auto; background-color:rgba(255,255,255,0.75); border-radius:15px;";

In most practical applications, styling rules would be kept in an easily modified external style sheet unless there is a specific desire to change them at run time or during execution. For illustration purposes, however, we will be using either the internal style sheet or the inline approach in this example. So let's set up our document.

Building a Better DOM

One of the nice improvements put forth by the Dart's creators is the use of factory methods to create new instances of DOM types [6]. Other improvements include superior event handling, better querying (think jQuery without the library), using real collections and simpler naming. Below is an example of adding an event listener in Dart.

document.query('#myButton').on.click.add((e) {
  _foo.fun(new bar());
});

The above code snippet queries the DOM for an element with an ID selector of id="myButton" and, if that button is clicked, executes the fun() method of private class foo, passing a call to the constructor method for bar().

Let's put what we have discussed so far into the beginnings of a comprehensive example. The code below is not meant to show how to code in Dart, but rather to illustrate collectively how one might go about accomplishing a variety of tasks in Dart. The code shows a linear progression of adding an internal style sheet, building an HTML page of elements and adding event listeners to several of those elements.

#import('dart:html');

class htmlInDart {
  num bottleNumber;
  num consumptionRate = 2000;
  InputElement numBottles;
  InputElement mySlider;

  htmlInDart() {
    // The constructor sets up the styles and the document.
    createStyles();
    buildPage();
    addListeners();
  }

First, we have an import directive to import the dart:html library, followed by a class definition htmlInDart with its constructor method. The constructor method calls three functions: createStyles(), buildPage(), and addListeners(). Let's look at each one individually, beginning with our internal style sheet:

void createStyles() {
  // Adds the opening and closing <style> tags, sets the type, then
  // adds it to the head section.
  StyleElement myStyle = new Element.tag("style");
  myStyle.type = "text/css";
  window.document.head.nodes.add(myStyle);

  // Next, define most of the styles used in this example.  
  // A few styles have been defined inline.
  myStyle.innerHTML = "#home {background-color:#E1CF75; " +
               "font-family:Verdana, Geneva, sans-serif;}";
  myStyle.innerHTML += "#page {width:1000px; margin:20px auto; " +
               "background-color:rgba(255,255,255,0.7); " +
               "border-radius:15px; overflow:hidden;}";
  myStyle.innerHTML += "#output {width:50%; height:600px; margin:10px; " +
               "padding:20px; background-color:white; float:right; overflow:auto; " +
               "border-top-right-radius:20px; border-bottom-right-radius:20px;}";
  myStyle.innerHTML += "#titleHeading {margin:30px; text-align:center; " +
               "border-bottom: 2px inset Khaki; overflow:hidden; padding-bottom:10px;}";
  myStyle.innerHTML += "#input1 {width:30%; margin:30px 50px; padding:0 20px 20px 20px; " +
               "border-bottom: 2px inset Khaki;}";
  myStyle.innerHTML += "#input2 {width:30%; margin:30px 50px; padding:0 20px;}";
  myStyle.innerHTML += "h4 {text-align:center;}";
}

Now, it's time to build our document.

void buildPage() {
  // Create a page div that will enclose our example and add it to the body section.
  DivElement page = new Element.tag("div");
  page.id = "page";
  window.document.body.nodes.add(page);

  // Create another div for the output text to be written to.
  DivElement outputCont = new Element.tag("div");
  outputCont.id = "output";
  page.nodes.add(outputCont);

  // Our page gets a heading.
  HeadingElement titleHeading = new Element.tag("h2");
  titleHeading.id = "titleHeading";
  page.nodes.add (titleHeading);
  document.query('#titleHeading').innerHTML = "Welcome to 99 Bottles or Less of Dart Beer!";

  // Now define two divs to hold the user input and provide a title for each div.  
  // Add both to the page div.
  DivElement inputCont1 = new Element.tag("div");
  inputCont1.id = "input1";
  page.nodes.add(inputCont1);
  HeadingElement inputHeading1 = new Element.tag("h4");
  inputHeading1.id = "inputHeading1";
  inputCont1.nodes.add(inputHeading1);
  document.query('#inputHeading1').innerHTML = "Enter the number of Dart beers " +
                  "on the wall (1-99):";
  DivElement inputCont2 = new Element.tag("div");
  inputCont2.id = "input2";
  page.nodes.add(inputCont2);
  HeadingElement inputHeading2 = new Element.tag("h4");
  inputHeading2.id = "inputHeading2";
  inputCont2.nodes.add(inputHeading2);
  document.query('#inputHeading2').innerHTML = "Rate of Consumption:";

  // Now create the user interface elements.
  // The first element is a text field with a submit button.
  numBottles = new Element.tag ( "input" );
  numBottles.attributes = ({
    "id": "numBottles",
    "type": "text"
  });
  inputCont1.nodes.add(numBottles);
  ButtonElement commenceButton = new Element.tag("button");
  commenceButton.attributes = ({
    "id": "commenceButton",
    "type": "button",
  });
  commenceButton.innerHTML = "commence";
  inputCont1.nodes.add(commenceButton);

  // The second interface element is a slider (or range) element.
  mySlider = new Element.tag("input");
  mySlider.attributes = ({
    "id": "mySlider",
    "type": "range",
    "min": "500",
    "max": "8000",
    "step": "20",
    "value": "2000"
  });
  inputCont2.nodes.add(mySlider);

  // Now add labels to the slider and style the labels inline.
  LabelElement labelFast = new Element.tag("label");
  labelFast.innerHTML = "fast";
  labelFast.style.float = "left";
  labelFast.style.paddingRight = "50px";
  inputCont2.nodes.add(labelFast);
  LabelElement labelSlow = new Element.tag("label");
  labelSlow.innerHTML = "slow";
  labelSlow.style.float = "right";
  inputCont2.nodes.add(labelSlow);
}

Finally, we add our event listeners and our top level function main(), which is called by the browser when our page is loaded. Note that for the slider we are using a mouseUp event rather than a change event. This is to prevent registering new values for our variable consumptionRate until the user has actually released the mouse.

  
  void addListeners() {
    document.query('#commenceButton').on.click.add((e) {
      numBottles.value == "" ? numBottles.value = "24" : numBottles.value;
      bottleNumber = Math.parseInt(numBottles.value);
      startConsuming();
    });
    document.query('#mySlider').on.mouseUp.add((e) {
      consumptionRate = Math.parseInt(mySlider.value);
    });
  }
}

void main() {
  new htmlInDart();
}

If you were to execute this code in the Dart Editor with the .html file that we showed earlier, you would see something like the figure below (depending on your browser's support for HTML5 elements):

using-the-slider-with-dart1.jpg

So we have our page, let's have it do something.

The <input> range Attribute with setInterval()


This discussion started with a desire to implement a variable trigger for the setInterval() function. We determined there were three ways to do this, the most general of which is shown in the code below. The case merely clears the setInterval() with each function call and then sets the interval again based on the current value of the delay. You might then ask "Why not just use setTimeout()?". You could, and that would be the second way, and in some cases the recommended way [7]. But in this example you could easily modify the code below to only clear the setInterval() if the event listener attached to the slider actually registered a change - otherwise, setInterval() would not be cleared (which would be the third way). Note that we have declared the variable consumeIntervalID at the top level of the class htmlInDart.

void startConsuming() {
  document.query('#commenceButton').attributes['disabled'] = 'disabled';
  bottleNumber > 99 || bottleNumber < 1 ? bottleNumber = 24 : bottleNumber;
  consumeIntervalID = window.setInterval(consume, 0);
}

void consume() {
  String s, s1, s2, s3, s4;
  window.clearInterval(consumeIntervalID);
  if(bottleNumber <= 0) {
    s1 = "Sorry, there are no bottles of Dart beer left. <br>";
    s2 = "Time for more coding with Dart!";
    s = s1 + s2;
  } else {
    s1 = "$bottleNumber bottles of Dart beer on the wall, <br>";
    s2 = "$bottleNumber bottles of Dart beer, <br>";
    s3 = "Take one down and pass it around, <br>"; 
    s4 = "${bottleNumber-1} bottles of Dart beer on the wall. <br><br>";
    s = s1 + s2 + s3 + s4;
    bottleNumber -= 1;
    consumeIntervalID = window.setInterval(consume, consumptionRate);
  }
  write(s);
}

void write(String message) {
  document.query('#output').innerHTML += message + "<br>";
  document.query('#output').scrollTop = 100000;
}

You can try out this example here and find the source code here. We noted that it would be better to set the slider to have a logarithmic scale to make it more visually intuitive. We'll leave that as an exercise for the reader. The Dart source code has been converted to JavaScript by the Dart Editor, so support across browsers should not be a problem in that respect. However, the range attribute for the input tag, which is part of HTML5 and which we use to implement the slider, is not currently supported by either IE or FF.


Works Cited

[1] HTML5 Input Types at w3schools.com
[2] Dart's Home Page
[3] The Dart Editor
[4] CSS How To at w3schools.com
[5] Dart's CSSStyleDeclaration Reference
[6] Improving the DOM with Dart
[7] window.setInterval() at developer.mozilla.org

With inspiration from 99 Bottles of Dart Beer by Riccardo Brambilla

by Richard Griffith at January 08, 2012 07:17 AM

December 23, 2011

David Chandler

Dart presentation at AJUG

Thanks to the dedicated Atlantans who braved yet another rainy 3rd Tuesday and holiday traffic to learn about HTML5 and Dart at AJUG this week. My presentation slides are available at www.dartlang.org/slides/ along with several other decks by Dart team members. Also, I’ve just posted a 10-min screencast, Getting Started with Dart, which shows lots of goodies from the meeting, including the Dart Editor, frog server, and Dartium (Dart VM in Chrome).

Enjoy!


by David Chandler at December 23, 2011 03:03 AM

December 19, 2011

Richard Griffith

Using Optional Parameters in a Subclass - AS3 versus Dart

Dart [1] and AS3 both allow child classes to have their own constructor methods. Recall that constructor methods act to initialize an instance by executing the methods necessary to perform various setup tasks. Constructor methods are also responsible for initializing variables [2]. When a constructor method resides in a subclass, it must also call the constructor method of its parent by using the keyword super. In addition, a subclass constructor may also include optional parameters which usually have default values assigned to them.

In AS3, a subclass which contains an optional parameter would look something like this:

//AS3
class B extends A { 
  static var DEFAULTNUM = 20; 
  B (initNum = 0) { 
    if (initNum <= 0) { 
      initNum = B.DEFAULTNUM; 
    } 
  super(initNum); 
  } 
}

In the above example, initNum is an optional parameter initialized to 0. In Dart, optional parameters are required to be surrounded by square brackets, []; otherwise they are considered a positional parameter and are therefore not allowed to have initial values. In Dart, we could write the subclass as follows:

//Dart
class B extends A { 
  static final DEFAULTNUM = 20; 
  B([initNum = 0]) : super(initNum <= 0 ? B.DEFAULTNUM : initNum) {} 
}

where we have replaced the if statement block with its inline conditional equivalent (also supported in AS3). Note that in Dart, the call to the parent's constructor is no longer contained within the child's constructor body as in the AS3 example above. This leads to a much cleaner syntax and helps to ensure that the parent is fully initialized before any statements in the child's constructor are executed.

So let's take a look at an example.

Suppose we have a parent class Computer(). The class in AS3 might look like the code shown below (we'll use modifier/retriever methods here and get/set methods for the Dart version just to illustrate multiple ways of accomplishing the same thing. Both ways are supported in both languages):

AS3 Example of Optional Parameters in Subclass

//AS3 - Optional Parameters
class Computer { 
  var someOS; 
  Computer (initOS) { 
    setNum(initOS); 
  } 
  getOS () { 
    return someOS; 
  } 
  setOS (newOS) { 
    someOS = newOS; 
  } 
} 

class Tablet extends Computer { 
  static var DEFAULTOS = "Android"; 
  Tablet (initOS = "iOS") { 
    if (initOS == "iOS") { 
      initOS = Tablet.DEFAULTOS; 
    } 
  super(initOS); 
  } 
} 

//You can then say: 
var myTablet = new Tablet();
trace(myTablet.getOS());  //prints Android 
var myTablet = new Tablet("iOS"); 
trace(myTablet.getOS());  //prints Android
var myTablet = new Tablet("Linux");
trace(myTablet.getOS());  //prints Linux

In Dart, the parent class Computer() is largely similar except that in this example we'll make use of get and set methods:

Dart Example of Optional Parameters in Subclass

//Dart - Optional Parameters
class Computer {
  var someOS;
  Computer(initOS) {
    OS = initOS;
  }
  get OS() {
    return someOS;
  }
  set OS (newOS) {
    someOS = newOS;
  }
}

class Tablet extends Computer {
  static final defaultOS = "Android";
  Tablet ([initOS = "iOS"]) : super(initOS == "iOS" ? Tablet.defaultOS : initOS) {
  }
}

void main() {
  var tablet = new Tablet();
  print(tablet.OS);  //prints Android
  var tablet = new Tablet("iOS");
  print(tablet.OS);  //prints Android
  var tablet = new Tablet("Linux");
  print(tablet.OS);  //prints Linux
}

You can, of course, extend this example to any number of subclasses of Computer(). Using only Dart to illustrate, let's add a laptop and a phone to our list of computer devices:

class Laptop extends Computer {
  static final defaultOS = "Windows";
  Laptop ([initOS = "OSX"]) : super(initOS == "OSX" ? Laptop.defaultOS : initOS) {
  }
}

class Phone extends Computer {
  static final defaultOS = "ICS";
  Phone ([initOS = "Windows"]) : super(initOS == "Windows" ? Phone.defaultOS : initOS) {
  }
}

void main() {
  var tablet = new Tablet();
  print(tablet.OS);
  var laptop = new Laptop();
  print(laptop.OS);
  var phone = new Phone();
  print(phone.OS);
}

Prints:

Android
Windows
ICS

You can find the Dart example at try.dartlang.org.


Acknowledgements

A big thanks to Joao Pedrosa and Vyacheslav Egorov for helping to explain how to implement optional parameters in Dart.
For a more thorough treatment of parameters, including optional, named and default, see Seth Ladd's blog post, Learning Functions for Dart.


Works Cited

[1] Dart's Homepage
[2] Essential ActionScript 3.0 by Colin Moock

by Richard Griffith at December 19, 2011 09:10 PM

Dart Logo

Last updated: May 21, 2012 12:15 AM UTC

Dartosphere channels