Loading...
An error has occurred

An error has occurred in Orbeon Forms. You may want to try one of the following:

  • Close this dialog and continue to use this page.
  • If this does not work, press the ctrl key (or command key on a Mac) and click on the Reload button in the toolbar.
  • Return home.

Erik's Ponderings

First Prev Next Last Showing entries 1 to 4 of 100.

Scala partial functions (without a PhD)
Permalink

Posted under category
Last updated

If you have done some Scala for a while, you know about pattern matching and match/case. Things like:
value match {
  case 
Some(value) ⇒ …
  case 
None ⇒ 
}
But there is another use of the case keyword, without match, as in:
map foreach { case (k, v) ⇒ println(k + " → " + v) }
The first time I saw this kind of things I was a bit puzzled: in which situations could case be used without matchWell, it turns out [1] that a block with a bunch of case inside is one way of defining an anonymous function.

There is nothing new with anonymous functions of course, and Scala has a very compact notation for those that doesn't involve case. But this particular way of defining anonymous functions gives you a lot for free, namely all the good things of pattern matching like casting-done-right, guards, and destructuring. The example above, with foreach, shows how case can be used for destructuring the tuples of the map into key and value components.

But there is more. Consider:
scala> List(41, "cat") map { case i: Int  i + 1 }
scala.MatchError: cat (of class java.lang.String)
As expected this crashes, because the pattern match doesn't know what to do when the string "cat" is passed to it.

On the other hand, this example doesn't crash:
scala> List(41, "cat") collect { case i: Int  i + 1 }
res1: List[Int] = List(42)
So what's the difference? Does collect just catch the MatchError and proceed? That would be clumsy and inefficient. In fact, the apparent magic lies in the fact that case blocks define special functions called partial functions. [2]

Now you might wonder, coming from a "normal" programming language background, what that means, for a function to be "partial". Well, it comes from mathematics, where it's opposed to "total" functions.

But even though it comes from math it's actually simple. Take for example this function:
def inc(i: Int) = i + 1
It is defined for any Int input value. That means for that any Int argument, it produces a resulting Int result. [3]

A partial function on the other hand is defined only for a subset of the possible values of its arguments:
def fraction(d: Int) = 42 / d
is not defined for d == 0 and fraction(0) will throw an exception. Think also of the square root function, which is not defined for negative real numbers. Examples abound. And it's true also for the collect example above, where the anonymous function is only defined for an Int argument but not for a String (or any other) argument.

So you get  the idea about some values not "making sense" as the argument of a function because they can't yield a significant result.

Now if you think about it you will notice lots of situations like this in your programs, where functions are expected to work properly only for some input values. If the function is called with a disallowed value, it will typically crash, yield a special return value, or throw an exception (and this should better be documented). In short, partial function are very common in real-life programs even if you don't know about it.

So here fraction is defined as a regular function, but conceptually it is a partial function. The good thing is that Scala has built-in support for partial functions thanks to the PartialFunction trait. And here is one way of defining such a partial function:
val fraction = new PartialFunction[Int, Int] {
    def apply(d: Int) = 42 / d
    def isDefinedAt(d: Int) = d != 0
}
PartialFunction must provides a method isDefinedAt, which allows the caller of the partial function to know, beforehand, whether the function can return a result for a given input value:
scala> fraction.isDefinedAt(42)
res2: Boolean = true
scala> fraction.isDefinedAt(0)
res3: Boolean = false
And if you call the function:
scala> fraction(42)
res4: Int = 1
scala> fraction(0)
java.lang.ArithmeticException: / by zero
This takes us back to the use of case to define partial functions. The exact same function can be written:

def fraction: PartialFunction[Int, Int] =
    { case d: Int if d != 0 ⇒ 42 / d }
(Notice that you must specify that the PartialFunction[Int, Int] type. It would be great if Scala had a syntax to make this even more compact but it doesn't as of Scala 2.9.)

And if you call the function:
scala> fraction(42)
res5: Int = 1
scala> fraction(0)
scala.MatchError: 0 (of class java.lang.Integer)
(Note that there is one visible difference from the outside when you use the case way: you get a MatchError as you usually do with pattern matching.)

The idea doesn't apply only to numbers. In our collect example above, the partial function implicitly defined looks like this:
def incAny: PartialFunction[Any, Int] =
    { case i: Int ⇒ i + 1 }
The function takes an Any as parameter because List(41, "cat") is a List[Any]. But it is only defined for inputs that are of type Int:
scala> incAny(41)
res6: Int = 42
scala> incAny("cat")
scala.MatchError: 41 (of class java.lang.String)
Passing a String didn't go too well, as expected. But now you can check this before calling the function with:
scala> incAny.isDefinedAt(41)
res7: Boolean = true
scala> 
incAny.isDefinedAt("cat")
res8: Boolean = false
So we now have the explanation for the difference in behavior between collect and map, which is that collect expects a partial function. It asks incAny whether it is defined for 41 and then "cat", and so automatically filters out "cat". Another cool thing here is that the Scala compiler can even infer a clean resulting collection type: List[Int]!
scala> List(41, "cat") collect incAny
res9: List[Int] = List(42)
Also, as you notice, if you define the partial function inline, the compiler knows that it's a partial function and you avoid the explicit PartialFunction trait.

Notice that partial functions can lie:
scala> def liar: PartialFunction[Any, Int] =
    { case i: Int ⇒ i; case s: String 
 s.toInt }
liar: PartialFunction[Any,Int]
scala> 
liar.isDefinedAt(42)
res10: Boolean = true
scala> liar.isDefinedAt("cat")
res11: Boolean = true
scala> 
liar("cat")
java.lang.NumberFormatException: For input string: "cat"
Here liar says incorrectly that it's defined for "cat". It would probably be better to write:
scala> def honest: PartialFunction[Any, Int] =
    { case i: Int 
 i; case s: String if isParsableAsInt(s)  s.toInt }
honest: PartialFunction[Any,Int]
scala> 
honest.isDefinedAt("cat")
res12: Boolean = false
So now you see how partial functions defined with case can be used for things like collect with a super compact  notation. You will see them in other places, including catch expressions.

There is another situation in Scala where partial functions are "just there" and you might not know it. Take the following List:
val pets = List("cat", "dog", "frog")
In Scala, any instance of Seq, Set or Map is also a function. So you can write
scala> pets(0)
res13: java.lang.String = cat
But:
scala> pets(3)
java.lang.IndexOutOfBoundsException: 3
Wouldn't that mean that the pets function is, hum, only defined for values 0, 1, and 2? Sounds familiar? Wouldn't it be cool to look at pets as a partial function then? Well you can because in Scala any instance of Seq, Set or Map is actually a partial function. So you can write:
scala> pets.isDefinedAt(0)
res14: Boolean = true
scala> 
pets.isDefinedAt(3)
res15: Boolean = false
And if you had a list of indexes and wanted to safely collect values for these indexes in a new list, you could write:
scala> Seq(1, 2, 42) collect pets
res16: Seq[java.lang.String] = List(dog, frog)
Here it works well because collect handles everything for us. But it can be a pain to check isDefinedAt all over the place. If anything, it feels a bit like a null check, and we hate those in Scala. The good news is that in Scala the PartialFunction trait supports the lift method, which converts the partial function to a normal function that doesn't crash:
scala> pets.lift(0)
res17: Option[java.lang.String] = Some(cat)
scala> pets.lift(42)
res18: Option[java.lang.String] = None
As you see the lift returns a function that returns an Option of the value. This allows you to safely process values without null checks and without calling isDefinedAt yourself:
scala> pets.lift(0) map ("I love my " + _) getOrElse ""
res19: java.lang.String = I love my cat
scala> pets.lift(42) map ("I love my " + _) getOrElse ""
res20: java.lang.String = ""
I hope this helps make some sense of partial functions in Scala.

[1] From The Scala Language Specification: "An anonymous function can be defined by a sequence of cases […] which appear as an expression without a prior match."
[2] This is not to be confused with partially applied functions, which are a completely different topic.
[3] In Scala, it is defined even for Int.MaxValue, as Int.MaxValue + 1 == Int.MinValue. The result is just plain wrong but it's defined!

Continuations in Scala (without a PhD)
Permalink

Posted under category
Last updated
With @avernet we have been thinking lately about continuations, for a few reasons:
  • Continuations pop up on the web as a concept that could help with event-based programming
  • Scala has a continuations plugin, and we're wondering what the deal is with that.
  • It just seems like fun to try to understand this (alongside things like monads).
The main idea of continuations is the ability to interrupt a program, save its control state, and resume it at a later point in time.

One thing to realize is that there are many ways to implement this idea and variations around it. Google a bit and you will find a lot of material on continuations, some of which goes deep into computer science. Here we don't care about the big picture: we just want to get at least some insight into Scala continuations.

The main source of information on Scala continuations is the EPFL paper describing how continuations were designed in the Scala compiler. But if you google "scala continuations" and hope to find right away a clear explanation, you might be disappointed. You will find the following example (I am not kidding):
reset {
  shift { k: (Int ⇒ Int) ⇒
    k(k(k(7)))
  } + 1
} * 2
This proudly produces the flamboyant result: 20. As a commenter says, "these are convoluted ways of adding numbers and I have no idea what is being gained or accomplished". @djspiewak echoes this when he says that continuations in Scala are "powerful ...but useless". It's a bit like explaining how a combustion engine works, but not that it could be used to, say, move your car from home to work.

So let's try to look at something concrete. Imagine a read() function which returns a byte from the network:
def read: Byte
This is typically the signature of a synchronous (blocking) function. After all, it has a return value and in normal programming languages, that means waiting for that value to be available. A program that reads two bytes in a row and prints them looks like this:
val byte1 = read
println("byte1 = " + byte1)
val byte2 = read
println("byte2 = " + byte2)
The issue is that in a web browser or node.js or any other single-threaded, event-driven environment, this is not acceptable: you simply cannot block for a long time, otherwise nothing else can happen in the system. So instead, the read() function is made to take a callback, something like:
def read(callback: Byte => Unit): Unit
You must now write your program like this:
read { byte1 ⇒
  println("byte1 = " + byte1)
  read { byte2 ⇒
    println("byte2 = " + byte2)
  }
}
The issue here is that you must write in a funny style, even with Scala's lightweight syntax for closures. Note also how each callback typically causes a new level of indentation. Some programmers manage to get used to this style, but it does not represent the control flow in a very natural way, and the issue grows with the size of the program.

Enter Scala continuations:
import scala.util.continuations._
reset {
    val byte1 = shift(read)
    println("byte1 = " + byte1)
    val byte2 = shift(read)
    println("byte2 = " + byte2)
}
And voilà: you can write the program again in imperative style without callbacks and closures.

You notice the reset and shift constructs. These terms don't make any sense to a newcomer, but they were introduced a long time ago in an academic paper so are reused in Scala. Basically, reset delimits the continuation. With full continuations, the entire rest of the program would be under control of the continuation, but here, whatever is before and after the reset block has nothing to do with continuations at all. (Also, reset can return a value, although here we don't care about it.)

shift is the construct that does the real magic. Mainly, it smartly hacks around to pass the continuation, that is a closure containing whatever-code-follow-shift-until-the-end-of-the-reset-block, to its body. If you run that closure, you actually run that code after the shift. If you store that closure somewhere, you gain the ability to decide when to run that code at a later point. This is the general idea of continuations: interrupt, then resume a program. Here it's all done with functions and closures behind the scene.

To see how our example really works, let's look a the control flow. First, how would you go about implementing the non-blocking read() function? Obviously it would have to work hand in hand with an asynchronous framework of some sort. Let's say it's roughly equivalent to something like this:
var myCallback: Byte ⇒ Unit = null
def read(callback: Byte ⇒ Unit): Unit = myCallback = callback
The key here is that read() is passed a callback function. read() just stores the callback in a variable and then returns immediately. There is just no waiting. This simulates what a real async framework would do.

In our example, shift calls read() with the continuation as a callback, and as we have seen  read() returns right away. But then what does shift do? Does it just hang around? No: shift returns right away as well, and then control continues right after the reset block, and control should then return to the async framework. So it's as if the user program had paused just in the middle of calling shift(read).

Now say that 5 minutes later, a byte (say 42) is available from the network. The async framework figures this out, notices myCallback is registered, and so calls it with the value 42. The result of calling the callback is to run the continuation, that is the code that follows the first shift runs, with byte1 set to the value 42. Did you see what happened there? It's as if the user program had resumed. And in effect it has.

What happens next? There is a another shift, so the scenario repeats: a new continuation is stored into myCallback. This time, it contains the code after the second shiftread() returns, shift returns, and control returns to the async framework, this time via the call to the initial callback. When the framework receives another byte from the network, the user program runs up to the end of the reset block and has in effect terminated. We are happy because:
  1. We never blocked our single thread.
  2. We wrote the program in a clear, understandable style.
  3. We actually did something (read and processed bytes from the network)
Obviously to make this real you want a framework and a function library with a set of useful asynchronous functions besides read(). Also, note that you can hide the use of shift from the programmer, and expose the read function like:
def aRead = shift(read)
And the program becomes:
reset {
    val byte1 = aRead
    println("byte1 = " + byte1)
    val byte2 = aRead
    println("byte2 = " + byte2)
}
By the way, it also works within while loops. With this specific use of continuations where shift never calls the continuation directly, control unwinds the stack back to the top, and there is no stack explosion. This is good news:
reset {
  var value = -1
  while (value != 42) {
    value = aRead
    println(value)
  }
  println("done")
}
So I would say that this at least appears to be a very useful (if not mainstream at this point) use of continuations in Scala. They will become even more useful when used as part of a reactive programming DSL.

48 hours of Nexus One
Permalink

Posted under category
Last updated
I just used a Nexus One for 48 hours (thanks Pierre). Here are a few quick notes/thoughts from the perspective of an iPhone 3G user.

Getting started
  • Take the SIM card out of the good old iPhone 3G, put it into the unlocked Nexus One, and voilà, you are done (sans 3G since the Nexus One does not support AT&T's 850 MHz 3G band)!
  • The phone asks you to log in with a Google account. Since my contacts were synced with Google already, all that information was transferred right away to the phone.
First impressions
  • Build. The Nexus One looks beautiful and solid.
  • Display. The iPhone's clearly pale in comparison (especially resolution). On the other hand the OLED screen doesn't perform as well in plain daylight.
  • Speed. The Nexus One is snappy. I don't have an iPhone 3G S, but the Nexus One is definitely way faster than the iPhone 3G (which often feels impossibly sluggish).
  • Android. The OS requires some getting used to, but you quickly figure out how to do most operations, especially if you are a bit computer-savvy. The four buttons at the bottom of the screen are not as elegant as the iPhone's single button, but they usually make sense and you get used to them quickly. I had very little difficulty adapting.
 The cool stuff
  • Multitasking. A few examples:
    • Upload pictures in the background.
    • Play Pandora while using any other app.
    • Switch between a few open apps in an instant.
  • Notification panel. It tells you quickly of things like new emails, tweets, completed downloads, and more. The iPhone needs UI improvements in this area.
  • Text completion. It is different than the iPhone's, and often better as you can quickly pick words from a list.
  • Web browser URL completion. Android seems to use something like Google Suggests to help you enter URLs.
  • Voice input. This works only part of the time, but it's a good start and it's available in any text field.
  • GMail. It is excellent and supports starring and conversations, unlike the iPhone's mail app.
  • Navigation. I didn't have time (or 3G) to really try it, but the GPS navigation app must be quite cool.
  • Google Voice. No need to fight with Apple here, Google Voice is fully integrated.
  • Camera flash. That seems pretty basic, but it is not a feature of the iPhone so far.
  • Programming. I haven't tried to program anything on the Nexus One, but I like the idea of being able to use Java (or even Scala) instead of Objective-C.
  • Openness. Open source OS. Multiple hardware vendors. No approval process like Apple's (you can even change the default web browser on Android). This has some appeal.
The OK stuff
  • Web browser. Safari on the iPhone is still better overall.
  • App market. It is easy to use, but is nothing to call home about.
  • Bluetooth. My Bluetooth stereo headset was setup quickly and usually worked ok, but:
    • I had an issue whereby at some point the sound started coming out of the phone speaker again in spite of the Bluetooth connection being active. Later things started working again.
    • My Bluetooth headset suffers from the "jeans pocket" syndrome: if you put your phone in your pocket and start walking, the sounds starts breaking (yeah I know, crazy). This happened more with the Nexus One than with the iPhone 3G. This tells me that the Nexus One's Bluetooth signal might be weaker.
The not so cool stuff
  • Apps. Clearly there are less apps and of lesser quality. A few examples:
    • I missed OmniFocus, Jott , and Instapaper / Read it Later.
    • The Facebook app (not that I use it much) is still inferior.
    • Twitter clients clearly don't beat Tweetie on iPhone (Seesmic was ok though, and I hear that Twitdroid is pretty good but I didn't want to spend money to try it).
  • Multitouch. There is no multitouch (especially no "pinch"), and the Nexus One screams for it. UPDATE: Google has just released an update with multitouch!
  • Copy/paste. This is pretty bad compared to the iPhone: text selection is difficult and not available everywhere.
  • Media. The audio and video players are not as easy to use as the iPhone's. There is no built-in support for podcasts (you can try Google Listen for that or other apps). (I used doubleTwist to copy some mp3s and videos to the phone and it worked fine.)
  • Trackball. The trackball is almost exclusively used to move inside and between text fields/areas. My feeling is that it does a poor job at this and Google should just abandon it and use another way of navigating.
  • Screenshots. There is no built-in screenshot capability. The iPhone does this out of the box. Apparently you have to root your phone to install 3rd-party screen capture apps. This would have been useful for this post.
  • Landscape mode. This is only possible in one direction instead of two, unlike the iPhone. It took me a while to figure out why landscape mode worked some times but not others.
Is it better than the iPhone?

I have no complaints about the hardware except for the trackball (concept and implementation), and the CPU and display give Nexus One the edge until this summer when Apple hopefully releases a new iPhone.

As for the software, it's not easy to determine a winner. Clearly a lot of thoughtful work went into Android, but it doesn't feel as polished and slick as iPhone OS. Often the phone feels more like a regular desktop computer. This can be good or bad depending on your perspective.

On the apps side, iPhone still wins hands down, but the Google stack of applications, including GMail, Navigation, and Google Voice, works best on Android, and that might win the hearts of some. Anyway there is little doubt Android will soon have enough good third-party apps that this won't be as much of a problem anymore (except maybe for games).

Most likely my next phone will still be an iPhone because of the apps and ease of use, but this short Android adventure was quite refreshing!

2009: Products I Can’t Live Without
Permalink

Posted under category
Last updated
Mike Arrington has just posted his 2009 list of products he can't live without. After my own 2008 list, here is my update for 2009 as I think it's fun to observe how our computing environment evolves from year to year. First, the new entries:
  • OmniFocus is the best to-do list application I know of. I use the desktop application daily to handle work and personal tasks. It is worth the whole of its $80. As a pure desktop application without an online counterpart it is a step back, but the benefit is flexibility and speed, both crucial to GTD.
  • Twitter, which I couldn't figure out at all a year ago, has seen 1,778 personal updates so far, and we use it at Orbeon too. I use Twitterrific on iPhone and twhirl on the Mac, but I am not married to either of these clients. Beware: Twitter most likely will kill your personal blog (as if it needed that!).
  • iPhone 3G: I simply can't imagine switching to anything else before a long time. I use pretty much the whole of it: phone, SMS, web, email, iPod, maps, camera, Yelp, music apps, book readers, dictionaries, you name it. Its biggest flaws are the inability to run more than one application concurrently (e.g. for music apps) and the lack of background notifications (e.g. Twitter and IM clients). I don't care how Apple does it, but these have to be addressed.
  • Safari has become my second browser of choice after Firefox. WebKit is great (with some quirks), Safari itself not so much. To be really usable, a browser needs: 1) something like the Firefox "awsome bar", 2) an ad blocker and 3) proper tab save/restore. Safari does have some add-ons partly addressing these shortcomings, but Firefox remains the king in this area. So I use Safari for certain specific sites or applications only.
  • Google Sites handles the new Orbeon Forms wiki. Sites can do better, and it is frustrating that it is incompatible in subtle ways with Google Docs, but it is a start.
The strong values:
  • Firefox version 3 for Mac is a winner. It is hard to imagine we had to deal with the quirky version 2 for so long.
  • GMail: I still use it mostly through OS X's Mail app through IMAP, but I had to disable the "All mail" folder to make it usable. The big change is that I use it through the iPhone mail application as well. I often process (archive) my incoming email on the go, but rarely write more than one-liners on the phone.
  • Delicious: I am now at about 4100 entries (was 1900 entries a year ago). Version 2.0, delivered in July, is a success. I add entries mostly through the Firefox extension.
  • Skype: VoiP, chat, video, SkypeOut, SkypeIn and soon, I hope, usable screen sharing.
  • Google Calendar and Google Maps remain essential.
  • Google Docs is strong and getting stronger. The new offline support is excellent.
  • SlimTimer: it is still impossible to live without it at work, although report performance is an issue and development seems to have stalled.
  • iTunes is frustrating in many ways but unavoidable if you have an iPhone. The new grid view for albums in version 8 is good, and it is still probably the best podcast client around.
  • iTunes Store: yesterday's announcement of 100% DRM-free music was long due and I may buy again music through iTunes (other than by accident). Movie rentals rock, but the movie selection is appalling.
  • Amazon mp3 Store remains appealing because of price, selection, the ubiquitous mp3 format, and the web-based interface.
  • Picasa is my favorite photo application. I had been using it recently through CrossOver, but I now use the new native version. I wonder if iPhoto 2009 will displace Picasa for me this year? In particular, the flickr integration is very promising, and Google has less incentive than Apple to promote flickr support.
  • Flickr is still my photo site of choice, but improvements have been slow to come this year.
  • Google Reader holds about 270 feeds as of now (was 200 a year ago). The recently introduced new look is refreshing. I find myself using it less heavily as lots of news come from Twitter.
The disappointments:
  • Basecamp: we still use it at Orbeon to communicate with our customers. I no longer use it as a personal to-do list as it sucks at that. Basecamp is reliable and cheap, but there are issues with messages, to-do lists, time management, and the writeboards that really don't leave me very satisfied with it at the moment. 37signals is good at rhetoric, but less so at regularly updating their applications (at least Basecamp, which is rumored to represent 60% of 37signals's about $8m revenue for 2009).
  • OmniFocus for iPhone is in some ways a better GTD tool than the desktop version. For example it has a built-in notion of next action, and its relative simplicity is attractive. But stability and performance make it about unusable. It often takes 30 seconds or more to start, and much more after a synchronization. I am not the only one with this problem. A GTD app must be snappy and reliable, so this is a big letdown.
  • Jott: I haven't used it as much as I thought, especially since the iPhone app is unable to send notification emails even with the paying plans. If they fix that I will pay $3/month without even thinking.
  • Adobe Acrobat Connect seemed like the best affordable screen sharing application out there, but it can cause browser crashes and handling of screen dimensions is frustrating (try sharing when using a 30" monitor!). Unfortunately, WebEx remains the most stable and powerful solution out there, but it is outrageously priced.
  • Google Chrome could replace Safari as my second browser of choice if there was a Mac version. I suppose it is coming soon. Or is it, given that it took Google years to release Picasa for Mac?
  • Blogger hasn't seen a single visible improvement since last year. Frankly, it is not a very good blogging service anymore.
  • Feedburner is not that useful anymore given the general decrease in personal and work blogging activity.
  • YouTube has not really moved beyond its lowest common denominator position. I watch videos mostly through iTunes podcasts, iTunes video rentals, or other sources.
Social networks:
  • I have been going to the Facebook site more (but not really "using it" more) because many less geeky friends use it. I mostly go to the site when I get an email notification. My guess is that photo sharing and tagging will be the first feature of Facebook I might actually appreciate this year.
  • I have about 200 connections on LinkedIn (from about 150 a year ago). I still haven't found any actual use for it.
  • Dopplr: I entered a few more trips there but it hasn't been really useful so far.
Like last year, I fail to find most social networks either really useful or exciting, Twitter remaining the notable exception.

See you next year!

$xforms-template-label$

Posted under category
Last updated
Refresh...

Flickr

IMG_6146
Taken
framechannel

Erik Bruchez posted a photo:

IMG_6146

IMG_6060
Taken
framechannel

Erik Bruchez posted a photo:

IMG_6060

IMG_6030
Taken
framechannel

Erik Bruchez posted a photo:

IMG_6030

Result of the first "solid food" experiment
Taken
framechannel

Erik Bruchez posted a photo:

Result of the first

$xforms-template-label$
Taken
Refresh...