Posts tagged with actor.js

Introduction to Case Classes

December 11th, 2009

I’ve been recently chatting with the creator of match-js about how his library and caseclass.js might work together and I ended up writting quite a bit about case classes. Enjoy.

Scala is a newish object-oriented/functional hybrid language that runs on the JVM. It actually takes a lot of concepts from Erlang, such as its actor library. One of its key features is pattern matching, which at the most basic can be used to test equality. With the match operator that means you have something like switch/case in most languages:

val myVal = 3;
myVal match {
  case 1 => "one"
  case 2 => "two"
  case 3 => "three"
  case _ => "other"
} // returns "three"

Case classes at a glance are just simple classes that be created without the new operator and automatic getters and setters:

case class Person(name, age)
val peter = Person("Peter Robinett", 25)
peter.age == 25 // -> true

However, you can do a lot more advanced stuff:

unknownVar match {
  case n: String => println("unknowVar is a String with value: " + n)
  case n: Int if n > 0 => println("unknownVar is an Int with a value greater than 0")
  case Person(name, 100) => println("unknownVar is a Person case class where property age is 100 and name is: " + name)
}

The last case example shows a cool use of a case class. Scala knows that when a case class instance is created in a case, you are testing for matching. So, it calls the class’s unapply method (any class can have one, case classes just have them automatically) to compare the instance based upon its properties. If the parameters match, the two instances are equal. However, you can also not specify properties to match. If you don’t care about them all you can just give a wildcard (the _ character) or not give any parameters (case Person or case person: Person) but if you’d like to extract the value, you can. This is what I did. By giving it the undefined variable ‘name’, it knows that I am not comparing the name properties but instead want to assign unknownVar.name to name (assuming that unknownVar is an instance of Person!), which is then within the scope of the subsequent code block.

So, that’s a lot of Scala. What do I have in Javascript? Right now you can match based upon object types:

CaseClass.create("Person", ["name", "age"]);
var peter = CaseClass.Person("Peter Robinett", 25);
peter.match(
  {
    caseTest: "Car",
    caseFunction: function() { return 0; }
  },
  {
    caseTest: CaseClass.Person,
    caseFunction function() { return 1; }
  }
); // -> return 1 – I'm not a Car!

Parameter definition and extraction also works, though it’s limited:

var undef;
peter.match(
  {
    caseTest: CaseClass.Person("Barack Obama", 47),
    caseFunction: function() { return 0; }
  },
  {
    caseTest: CaseClass.Person("Peter Robinett", undef),
    caseFunction function() { return age; }
  }
); // -> return 25

As you can see, matching works fine though I need pass an uninitialized variable to Person() to indicate that I want to extract the corresponding property in peter. Because I cannot discover the name of this variable, I just have to create variables based upon the property names. I’d like to improve this, but the consensus seems to be that it’s impossible with Javascript today (ironically, earlier versions could). Beyond extractors, I’d like to be able to do more complex matching (better support for different object types, conditional stations) and be able to extend native objects to support my matching. I also like that your Match() method can stand alone, letting it be used as a callback and meaning that it acts as a sort of partial function, which is very cool. In Scala partial functions are functions that needn’t always return a value:

def myPF(num: Int) = {
  case 1 => "one"
  case -1 => "negative one"
}

To be honest, I’m not sure if our libraries could or should work together but they’re similar enough in spirit that I thought it might be exploring how they can complement each other. I see you’re doing stuff with web workers. I’ve also tried to take Scala’s actors and use them to do something in Javascript. actor.js is the result and is a place where I think case classes would be great for message passing (this is a key use case for case classes in Scala). However, actors are both more complex and something that I have less experience with, so I haven’t put as much time into it as caseclass.js. However, the demo does work and is, in my opinion, pretty cool!

Javascript Console

September 3rd, 2009

With all my recent Javascript experiments, I wanted a browser-independent Javascript console more and more. I found Rhino and have been using it for the last month or so. It’s proven pretty useful, and it was quite easy to install: I simply copied js.jar to /usr/local/rhino/ and then added the following to my .profile for convenience: alias js="java -jar /usr/local/rhino/js.jar"

I just learned about jsc, a console Apple includes with the JavascriptCore library that I believe every version of OS X has installed by default. It’s found at /System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc, so again you’re going to benefit from an alias or adding the directory to your PATH.

While Rhino has more features, namely the ability to load Java libraries, the jsc experience is better: the console strikes me as more responsive (it definitely launches much faster), a command history is available and you can use ctrl+a and ctrl+e to jump to the beginnings and ends of lines. Whoever made jsc seems to have a functional bent, as every expression’s return value is printed out. This means you get undefined on screen a lot if you’re doing lots of loops and/or prints, which can be annoying.

Update, 2010-06-22: Using rlwrap (e.g. alias js="rlwrap java -jar /usr/local/rhino/js.jar") solves many of the problems I had with Rhino.

Speaking of that, I think they handle the return values of loops incorrectly. As I understand it, all loops should return undefined, i.e. nothing. But consider this jsc session:

> var a = 1; while (a < 4) { print(a); a++; }
1
2
3
3

3 is printed out twice because it is ‘returned’ by the while loop. Of course, while does not really return a value, as this session shows:

> var a = 0; var b = while (a < 4) { a++; }
Exception: SyntaxError: Parse error

But where does the 3 come from, the a variable or the loop’s condition? From the following sessions, I believe it comes from the last time the condition evaluates to true:

> while (1 != 1) {}
undefined
> var a = 1; while (1 != 1) { a; }
undefined
var a = 1; while (1 != 1) { a = 2; }
undefined
> var a = 1; while (a != 2) { a = 2; }
2

Note that when the condition never is true, there is no defined value outputted. Likewise, assignment within the loop has no effect on what is ‘returned’. Or rather, I wish it was that way. Consider this:

> var a = 0; while (a < 2) { a = 2; }
2
> var a = 0; while (a < 2) { a++; }
1

To be honest, I really am confused about what jsc is doing here. It seems wrong, though irrelevant since these values printed out cannot be assigned to a variable and used. Perhaps someone from the jsc team can explain this?

actor.js

August 29th, 2009

I just pushed actor.js to GitHub. It’s an easy-to-use wrapper of Firefox 3.5′s Web Workers, giving you a nice way to pass messages between threads via Actor objects which can listen to other Actor objects. It’s inspired by Scala’s Actor library, though beyond the name there’s probably nothing much in common – mine is surely much worse. Patches welcome!