Monday, February 6, 2012

New Editor and SDK

Just today I was thinking "There's been a large number of changes to the SDK lately and the integration builds of the SDK and Editor haven't been updated. Maybe I'm going to have to start trying the continuous builds..." when low and behold, a thread on the Dartlang misc group indicates that there is a new integration build available. Build number: 3934. So off I go and download that and the new SDK build.

Beautiful. First a couple of things to note: I extracted the editor into the dart/ directory it was in, into my home directory. I extracted the SDK into my home directory as well and left it in the dart-sdk directory. I launched the Editor and in the launch preferences pointed the VM to the /dart-sdk/bin/dart executable. Which worked fine, but the SDK and compiler preferences said they didn't see the SDK installed and thus indicated that frogc would not work correctly. Then I recealled that I had seen somewhere previously in the mailing group that one should extract the dart-sdk into the dart editor directory. So I moved the dart-sdk directory into dart/, relaunched the editor and low and behold under the launch preferences it says there are no launch settings available... that's interesting. I then go in and check the SDK and Compiler preferences. It shows that I have SDK build number 3934 installed. Yay. It's seeing it. But odd there's no launch preferences.....

Or so I thought. Wow. Look at all those options... I opened up a small test file I had from the past and click the little drop down arrow next to the Run button... maybe they added the checked mode flag I had mentioned before. Whoa.. what's all this? Manage launches and I have a nice little dialog to "create an manage launches". Hitting the new button I see I can create a Dart launch in Dartium (don't have that installed at the moment but that's alright, Dart Server launch (primarily what I use for dealing with the dart VM directly) and Dart Web Launch. I go ahead and create a new server launch. Give the launch a name 'Run Test' in this case. Hit browse from the script and choose the only script in this project anyways. But its interesting that it lets you choose which file is the one that contains the main method in such an easy manner. And it appears (though I've yet to test it) that it will only list files associated with your current project). Any arguments I want to pass to the script as well and finally to run in checked mode or not. Wow very nice. I go ahead and create a separate launch just for running in checked mode as well just because I can. I must say I really like that launch interface in this new editor.

And now the SDK also has the IO libraries available to me as well so I will soon have to start playing with these to work on some of the scripting aspects I'm interested in using Dart for, server side.

Thursday, February 2, 2012

Few Updates

So I haven't had the opportunity to write much lately. There's been a lot going on a work and home that have made my time far too sparse. Hopefully I can start getting some of that stuff settled soon. In the mean time there's been lots going on with Dart for me to get caught up with.

Firstly, we're starting to see some server side related API's coming out. Including file and directory libraries and the start of some networking and socket libraries. They are only available in the continuous builds at the moment, however I expect to see them in the integration builds soon (speculation not based on any actual evidence). These are something I was most looking forward to, for both server side scripting and even just generic scripting possibilities. I think in the near future I will try to convert some of my existing applications and scripts from their various options (Javascript, PHP, Ruby) to Dart to see what issues I run into.

With the addition of the new libraries, we see a mass of updates to the current API documentation. Thanks to Mozilla's work documenting the DOM (And releasing it as CC) much of this information is now available in the Dart APIs. Check them out and become enlightened!

Speaking of becoming enlightened, if you have played with Javascript in the past, or perhaps are a bit of a Javascript Guru, check out the Dart Synonym page. Lots of little snippets that show how you accomplish something in Javascript and how you would do the same in Dart. It even includes a small subsection on comparisons between JQuery and Dart.

Also, be sure to check out the new Dart news and Updates site.

Monday, January 23, 2012

Wat?

Yesterday, Seth Ladd posted a link to a humorous video which highlights a few WAT?!?! moments in Javascript and Ruby. He then discussed how Dart deals with some of these moments in Javascript WAT moments and Dart. Please watch the video and read Seth's blog prior to reading.

There are WAT moments in virtually every language. A line from the video says something along the lines of So since it is the plus operator, we can expect the same result if we switch the operands around.. In the case of the video it was discussing how Javascript handles adding an array and a hash, and a hash and an array. However this reminded me of the issue I ran into myself already in experimenting with Dart. Look at the following code:
main() {
  print("wat" + 1);
  print(1 + "wat");
}

What is particularly interesting is running this example in the variety of locations. First lets run it from the Dartboard, without checked mode. We get the result:
wat1
1wat

More or less what you'd expect to get adding a string and a number. We do see a little warning off to the side indicating String is not assignable to num. But being not in checked mode it does run and because its Dartboard it falls back to the Javascript implementation of number + string. Well lets see what we'll get in the DartVM...
wat1
Unhandled exception:
NoSuchMethodException - receiver: 'wat' function name: 'addFromInteger' arguments: [1]]
 0. Function: 'Object.noSuchMethod' url: 'bootstrap' line:360 col:3
 1. Function: 'IntegerImplementation.+' url: 'bootstrap_impl' line:1469 col:32
 2. Function: '::main' url: '/home/mbutler/dart/Test/Test.dart' line:3 col:11

Err WAT? Even more, that runtime error is.. far from clear on just what exactly is going on. Additionally in the VM we do get the same warning as stated above, on the line with the issue so that helps to track it down easy enough. Well lets go back to the dartboard and enable checked_mode:
wat1
Failed type check: type String is not assignable to type Number

Well that's kind of a reasonable error. Must get the same in the Dart VM using the 'enable_type_checks' flag.
wat1
Unhandled exception:
'bootstrap_impl': Failed type check: line 1468 pos 22: type 'OneByteString' is not assignable to type 'num' of 'other'.
 0. Function: 'IntegerImplementation.+' url: 'bootstrap_impl' line:1468 col:22
 1. Function: '::main' url: '/home/mbutler/dart/Test/Test.dart' line:3 col:11

Okay WAT? That error is almost as long as the first one but its a little more obscure I think. I see from the very last line of the error where the issue is in my code (I notice this now in the first error as well. I'm so used to seeing my code point at the top of the error with subsequent library calls following after that, that I didn't realize to look at the bottom of the error for my error). But the error itself is interesting "OneByteString" is not assignable to type "num" of "other"...? Of other what? String not assignable to num is understandable though not necessarily expected. But of other? I'm not sure. Just rambling a little bit at this point as well as I procrastinate getting some work done in the office today.

I'll post again later today if I get the opportunity as Seth has a couple of other blog posts written that I want to follow up on. Particularly on his one about 'this'.

Friday, January 20, 2012

Not So Generic

I was working on a post on Generics in Dart, had a significant amount written yesterday but was running into a couple of bugs (bug reports were, for the most part, previously submitted). Coming back today and looking at my post and trying to pick up where I left off, I decided the best option, for your sake and mine, was to delete it. I had a mess of things jumping from one topic to another, code samples that had far too much fluff and useless elements that it was far from clean, concise and illuminating. So I admitted my mind wasn't as focused as it should have been and deleted the post entirely. It wouldn't serve much purpose to try and clean it up at all.

I've decided for the time being I'm going to leave the generics to Seth Ladd's most capable post: Generics in Dart. I highly recommend reading it and pay particular attention towards the end of the post to help avoid some 'gotchas'. He does a great job explaining covariance and keeping it simple at the same time. The only additional thing I will add is that not only can you use generics on the initialization of a variable but also in the declaration as a type. Doing so will really help, particularly the editor, to keep a close eye on what you are assigning or adding to a variable. The only example I will show is very brief: http://try.dartlang.org/s/lywo
main() {
  var list1 = ["One", "Two", "Three"];
  List list2 = new List();
  List list3 = ["One", "Two", "Three"];
  
  list1.add(4); // No warning because the type isn't specifically declared.
  list2.add(4); // generates a warning
  list3.add(4); // Generates a warning
}

Assuming you are not running in checked mode, all three cases will run properly. However, list2 and list3 will generate errors on the add lines indicating that int is not assignable to a string. The first case, list1 will quietly and happily accept 4 as being added to it, even though we initially specified that the variable of Dynamic type list1 is a List of type Strings. If running in checked mode, all three will fail.

Apart from that, I decided that over the weekend I'm going to start working on an introductory tutorial to Dart. Something for the programmer with little experience. Many of the resources I've seen have been geared towards those experienced with Java programming or heavy JavaScript users. I'm debating if I should go with just VM initially and get the foundations down or just DOM initially so they can get right into results. Because lets face it, when you first start as a programmer we're all about the results and making the computer do something cool rather than all the theory and foundations. However I believe I can offer that with the VM on a starting level.

Thursday, January 19, 2012

Mapping the Future

So yesterday I looked at Lists. Today, I'm onto Maps. As has been the way, this is based off of the information I read from Seth Ladd's Blog series on Dart. Maps and Hashes in Dart.

Maps are a great utility in web programming especially. They are an efficient way to create a relationship between a 'key' to a value. In Dart values can be of any type, and similar to Lists, they do not have to be of the same type. That is a map can contain keys which are strings, numbers, and other classes including Lists etc.

Unlike some other languages though (Ruby for instance), the 'key' in a map must be a string. It cannot be an instance of a class for example. You can't use a number as a key (which would cause confusion with Lists). 99.99998% of the time this won't be a problem as there is only a very rare case you would need anything other than a string. I will admit though I did enjoy the lighter-weight use of 'symbols' in Ruby, particularly for maps. But different roles for the languages. [edit:] I see a note at the bottom of Seth Ladd's blog indicating that this may change in the future. [/edit]

In Dart, as in most (but not all other languages), when you query a map for a key that doesn't exist, null is returned. I much prefer this over the alternative of a runtime 'indexOutOfRange' error as I have seen in another language. So for instance if we have the following:
main() {
  var map = { "Hello" : "World" };
  print(map['Foo']);
}

The result is:
null

We can then do a simple check to see if the value is null and assign it if we have to. Its also extremely easy to add to a map. Even if the key doesn't exist, if we assign to it, it will be added. So for instance we can do the following:
main() {
  var map = { "Hello" : "World" };
  map["Hello"] = "Joe";
  map["foo"] = "bar";
  // Map now contains { "Hello" : "Joe", "foo" : "bar" }
}

So that's nothing new to people familiar with Maps from other languages and with those two methods we have an easy way to check for a value and assign one to it if it doesn't exist otherwise. However there is an interesting function that exists in Dart for Maps: putIfAbsent.
This function allows us to query a map for a key and returns its value. However if the key was not previously defined, it will call the function you pass to it and assign the return value to that key. Lets look at an example:
main() {
  var map = { "Hello" : "world" };
  var res = map.putIfAbsent('foo', assign() {
      // Do some stuff
      return 'bar';
    });
  print(res);
  print(map['foo']);
}
bar
bar

So as you can see map is queried for the key 'foo'. When it does not find it, it then calls the function (in this case I named it assign). You can write some code to calculate a value and then whatever is returned is the value that is assigned to that key in map. That value is then also returned by map.putIfAbsent and assigned to the res variable. Something important to note however: putIfAbsent checks if the key is absent, not the value of that key. That means if the key has already been assigned but is simply null, the method will return null and not call the function that you pass to it. As the following demonstrates:
main() {
  var map = { "Hello" : "world", "foo" : null };
  var res = map.putIfAbsent('foo', () => 'Bar');
  print(res);
  print(map['foo']);
}
null
null

This is the same as the containsKey method. The method verifies if the key exists in the map already, not if it has a non-null value.

Another interesting tidbit is if you want to run in checked mode, or at least generate warnings when working with maps, you have option to specify the types to be expected. As previously mentioned, at the moment the key must be a string, but the capability, using Generics, allows you to catch potential errors or surprises. Seth does a great job explaining the use of generics for Maps on his blog, so check it out there.

Wednesday, January 18, 2012

A List of List stuff

So I continued on reading Seth Ladd's blog post on Lists and Arrays in Dart. One thing I didn't see mentioned that I think should be said, is that Lists are not type dependent. For people familiar with current dynamic languages such as Python, Ruby, and JavaScript that's not a big deal. But for those coming from Java, C, and other similar languages it is important to note that a List doesn't need to be all the same type. For instance the following is entirely valid:
List list = [1, "two", 3.48283008, [4, 4, "four", 4]];

So a List can contact mixed variable types, numbers, strings, even more Lists. However for those familiar with Javascript and other such dynamic languages who are used to associative arrays, its important to know that Lists are not that. As such you cannot assign a value to an index that does not yet exist.
List list = new List();
list[0] = "zero";
list[1] = 1;
IndexOutOfRangeException: 0

However, for extendable arrays, you can call set on length and increase the value. So you can grow, or shrink with more than just the add or addAll methods. For instance the following is valid:
List list = new List();
list.length = list.length + 2; // Now have two null values in the list.
list[0] = "zero";
list[1] = 1;
list.length = list.length - 1; // This removes the last value from the list.

Something important to note however, currently the API does not specifically state that changing the length to a value lower than the current will always have this effect. Currently there is no guarantee that the values will be removed from the end of the List, or even that they will be removed at all. I can see a situation where, if the values at the end are not null, then they may not reduce the size of the List. That or when setting list size, the new value must be greater than or equal to current size. As the libraries are improved and change (and there will be change don't doubt that for a second), we'll get a better idea of what to expect.

There are a number of List methods which can be extremely useful, that require a function be passed to them as an argument. You can create these functions inline or pass the name of another function. I'll cover more on passing functions in another post. Some of these methods are: filter, some, every, sort. Some and Every return true or false values. every returns true if every value in a list meets the criteria defined by the function passed as an argument. some returns true if at least one of the values meets the criteria.
bool isNum(var e) => e is num;

main() {
  var list = [1, 2, "three"];
  print( list.every(isNum) );
  print( list.some(isNum) );
}

Gives the result:
false
true

Something to note is that the some, every and filter methods are defined as part of the Collection interface not specifically in List.

Something to make note of is that filter will return a new list of items that return true from the passed function, whereas the sort method will modify the existing list rather than return a new one. Take the following code as an example of how to use each.
main() {
  var list = [4, 3, 6, 1, 2, 5];
  list.sort(compare(a,b) {
    if (a == b) {
      return 0;
    } else if (a > b) {
      return 1;
    } else {
      return -1;
    }
  });
  // List is now [1, 2, 3, 4, 5, 6]

  var evens = list.filter(f(e) => e % 2 == 0);
  // list is still [1, 2, 3, 4, 5, 6]
  // evens is [2, 4, 6]
}

In the above code the list.sort method modifies the List we're working with, whereas the list.filter method returns a new List and does not make any changes to the existing list. One thing I'm not currently sure of is why the difference. Is it that sort is not removing or modifying the elements of the list where as filter does? To me anything that modifies the existing List, even if it's changing the ordering of the elements, should return a new List, which I can then assign back to the same variable if I so choose. As it stands now, I have to make a copy of the list prior to the sort if I want to keep the original ordering.

Another item to note, based on my limited trials, when iterating over the values of a List, elements are passed as value not reference. Thus if you make any changes to the value, they will not persist outside of the scope of the function. Here's an example of what I mean:
main() {
  var list = [1, 2, 3];
  for(var x in list) {
    x = x*2;
  }
  // List is still [1, 2, 3]
  
  list.forEach(f(x) { x = x*2; });
  // List is still [1, 2, 3]
}

In the first case, using the for loop I can understand that the elements are passed as values and that it does not modify the original list. However in the second case, using the forEach method, you would expect that any changes to the value there would be reflected in the list after the fact.

In any case. I highly recommend reading through the API references for List and for Collection to get an idea as to what other capabilities they hold.

A List of Errors.

Before I get started on this post on Lists (actually, I already started it yesterday but didn't complete it yet ;), I did want to share the information that Seth Ladd recently shared regarding the Dart issue tracker. Sometimes it can be hard to locate or you just can't recall the location to access the tracker. Well never fear! There is a new redirect URL available to use.
dartbug.com
Redirects to the main issue list.
dartbug.com/new
Redirects to the new issue template.
dartbug.com/1199
Redirects to a specific issue number (in this case 1199, the one I submitted and mentioned in my last blog post).
So I'm continuing with Seth Ladd's series on Dart. Today I'm looking at Lists and Arrays. One particular quote from the post particularly grabbed my attention and interest:
Fun fact: As of 2011-12-22, the word "array" does not appear in the Dart spec.'
This interested me as virtually all languages have arrays and refer to them as such. But sure enough a quick search through the current language spec reveals no results for 'array'. Now, as stated in Seth's blog, Dart arrays are Lists. I found it an interesting point none the less.

Interestingly enough however, the VM does output an error which refers to arrays. But when compiled to Javascript (via frog or dartc) the errors properly reflects 'lists'. First I'll demonstrate the code and error then I'll actually provide some additional comments regarding the code.
main() {
  var list = new List(3); // Create an immutable, or 'non-extendable' list
  list.add(4); // Now try to change it (extend it).
}

This results in the following error:
Unhandled exception:
UnsupportedOperationException: Cannot add to a non-extendable array

But when executed on the dartboard we get the following error:
UnsupportedOperationException: Cannot add to a non-extendable list

It surprises me a little that the VM does specifically reference array whereas the code compiled to Javascript, which does have arrays, correctly references a list. There already exists a couple of bug reports. One which I'll only briefly mention, indicates that the word 'array' should be removed from all internal libraries. The second, which I added a comment to regarding the VM specifically is: Issue 1028. This issue aims to be more encompassing removing references from the Libraries as all references which may become visible.

So you may be wondering why it is that List provides an add method if it just generates an error. Well that's because there are two types of lists. A 'non-extendable' list which is created by passing a size to the constructor, or you can create a list without the optional argument to the constructor which creates an empty list you can extend by adding (or removing) values from. An extendable list can also be created from a list literally such as:
var list = [1, 2, 3];

Note however, that unlike some other languages (such as Ruby), you can not call a method on the List literal. Thus the following is not valid code:
var list = [1, 2, 3].add(4);

You'll receive a warning indicating "expression does not yield a value". But it will compile and run (at least until you try to call a List method on list such as length which will generate a runtime error.

However there is a bug in the add method which I have just discovered. The API for List.add indicates that the return type is 'void' (or no return value). This works as expected in the dartboard (javascript). However in the Dart VM, list.add(value) returns the new size of the list. I have submitted a bug report for it here: Issue 1213.