Scala

I recently learned about Scala, a language for the JVM which tries to smoothly integrate object oriented and functional programming features.

I find it particularly interesting because of two reasons: first it is integrated with the Java platform and thus can use all the Java code already available. Second, it can be used almost as a Java evolution where you can gradually add functional concepts and more advanced features of the type system.

Scala is a static language, and lately the whole world is excited about dynamic languages, so this might seem a bit backwards, but I think sane static languages have their place in the world. And Scala has some very nice features (pattern matching on objects, flexible syntax) to make it appealing to me. I’d like to try to use it at work, integrating it with the bulk of Java code we already have.

To experiment a bit with the language I tried translating some examples from Haskell. The result is kinda pointless and probably not a good example of Scala programming, but it helped me get a feeling of the language.

package test.sort

object QuickSort {

  def qsort1[A <% Ordered[A]](xs: List[A]): List[A] = xs match {
    case y :: ys => {
      val lt = for (val i <- ys; i < y) yield i;
      val gt = for (val i <- ys; i >= y) yield i;
      qsort1(lt) ::: List(y) ::: qsort1(gt)
    }
    case Nil => Nil
  }

  def qsort2[A <% Ordered[A]](xs: List[A]): List[A] = xs match {
    case Nil => Nil
    case z :: zs => {
      def part(z: A, zs: List[A], parts: Tuple3[List[A], List[A], List[A]]): Tuple3[List[A], List[A], List[A]] = zs match {
        case Nil => parts
        case y :: ys => {
          if (y > z)
            part(z, ys, {parts._1, parts._2, y :: parts._3})
          else if (y < z) 
            part(z, ys, {y :: parts._1, parts._2, parts._3})
          else 
            part(z, ys, {parts._1, y :: parts._2, parts._3})
        }
      }
      val parts = part(z, zs, Tuple3(Nil, List(z), Nil))
      qsort2(parts._1) ::: parts._2 ::: qsort2(parts._3)
    }
  }

  def qsort3[A <% Ordered[A]](xs: List[A]): List[A] = {
    def qsort3b(ys: List[A], acc: List[A]): List[A] = ys match {
      case Nil => acc
      case List(z) => z :: acc
      case z :: zs => {
        def part(ps: List[A], parts: Tuple3[List[A], List[A], List[A]]): List[A] = ps match {
          case Nil => qsort3b(parts._1, parts._2 ::: qsort3b(parts._3, acc))
          case z :: zs => {
            if (z > ys.head)
              part(zs, {parts._1, parts._2, z :: parts._3})
            else if (z < ys.head)
              part(zs, {z :: parts._1, parts._2, parts._3})
            else
              part(zs, {parts._1, z :: parts._2, parts._3})
          }
        }
        part(zs, {Nil, List(z), Nil})
      }
    }
    qsort3b(xs, Nil)
  }
}

PHP ain’t that funny after all

I don’t like PHP. I use it on the web because it’s everywhere and you can find a busload of code to do pretty much whatever you want. But I really dislike how it’s designed. It’s inconsistent, you’ll never know what might happen when you call that new function you just found.

Take my Technorati Cosmos Textpattern plugin for example. Sometimes Technorati returns duplicated results and I wanted to filter them: when looping over the list of links received from the Cosmos API call, I added them to an array and then looked there before printing the other links.

I looked PHP documentation and found the nice array_search() function. The documentation says:

mixed array_search (mixed needle, array haystack [, bool strict])

Searches haystack for needle and returns the key if it is found in the array, FALSE otherwise.

nice, the function returns FALSE if the item is not in the array, so I went and wrote my check:

if (!empty($cosmo->permalink) and array_search($cosmo->permalink, $items)) {
    // Skip the item if we have already seen it
    continue;
}

where’s the problem with that? Let’s see some examples.

$a = array(1, 2, 3, 4, 5);

var_dump(array_search(3, $a));
var_dump(array_search(1, $a));
var_dump(array_search(8, $a));

this prints, as expected:

int(2)
int(0)
bool(false)

but what happens if we put this in an if statement?

if (array_search(3, $a))
    echo "3 found\n";
else
    echo "3 not found\n";
if (array_search(1, $a))
    echo "1 found\n";
else
    echo "1 not found\n";
if (array_search(8, $a))
    echo "8 found\n";
else
    echo "8 not found\n";

the result is:

3 found
1 not found
8 not found

Why? Because 0 == FALSE and the second test doesn’t pass. Ok, let’s make it more specific.

if (array_search(1, $a) != FALSE)
    echo "1 found\n";

Wrong again, because 0 is still the same as FALSE. Don’t despair, a solution isn’t that far, any of these will work:

if (array_search(1, $a) !== FALSE)
    echo "1 found\n";
if (array_search(1, $a) >= 0)
    echo "1 found\n";
if (is_int(array_search(1, $a)))
    echo "1 found\n";

Functions that returns different data types are just evil, and they are everywhere in PHP. In this case, for example, they force you to use and grasp datatypes in a language which shouldn’t care much about them.

I just uploaded a new release of the Cosmos plugin to fix the duplicates detection.

PHP ain’t that funny, after all.

FlickrUploadr

FlickrUploadr

FlickrUploadr is a tool to upload your pictures to Flickr. There are some official tools for this task, but they aren’t available on Linux, so I wrote my own.

Please note that FlickrUploadr doesn’t currently work if you have a Yahoo! account. I’ll try to update it soon.

This version of FlickrUploadr is written in Python and Gtk, using the PyGtk bindings, to install it, download the tarball, unpack it and install the package:

# python setup.py install

in the directory where you just unpacked it. If you get an error about a missing Makefile, you need to install the Python development package from your distribution.

Then you can run it from a shell:

$ Uploadr

Just drop files over the window to upload the pictures.

A window will pop up asking your login details (which you can optinally save) and the picture’s metadata (title and tags). At the end of the upload a web browser window (currently Firefox is hardcoded, sorry) will open with the pictures you just uploaded, allowing you to add descriptions and change the captions one by one.

History

30 August 2005

FlickrUploadr 0.6.0 – Finally the much requested configuration saving (optional for login credentials). Removed the hardcoded firefox. No longer sets default title. Changed license to GPL to comply with xmltramp.

18 March 2005

FlickrUploadr 0.5.2 – Fixed to work with Python 2.4. If the previous version worked for you, you don’t need to download it again.

21 October 2004

FlickrUploadr 0.5.1 – Fixed to accept files dropped from Konqueror. Fixed long integer exception and crash. On some systems it will have a black background instead of white and look uglier, but I don’t know ho to fix this for everybody.

12 October 2004

FlickrUploadr 0.5 – Installable and runnable from anywhere, login details asked when needed, can drop pictures or pass them on the command line, can set pictures as private, opens Flickr after uploading allowing editing of pictures’ data.

16 September 2004

FlickrUploadr 0.1First release: uploading works, you have to pass the login details on the command line, can’t be installed must be run from its own directory.

FlickrClient

FlickrClient is a Python interface to the Flickr API.

Using it really simple: create a FlickrClient instance passing your API_KEY to the constructor and then call the methods on the returned instance, replacing dots with underscores.

Example:

client = FlickrClient(API_KEY)

person = client.flickr_people_getInfo(user_id=USER_ID)
photoSets = client.flickr_photosets_getList(user_id=USER_ID)

print person.username, "has", len(photoSets), "photosets:",
print ', '.join([str(set.title) for set in photoSets])

I used xmltramp to parse the responses and I return the created xmltramp object, so accessing the data is really simple: you access sub-elements just as if they were attributes of your node and attribute access is done as a function call on the node: person('id'), to retrieve the text element of a node, convert it to string: str(person.username).

The client dynamically creates the calls, so it shouldn’t break when new functions are added to Flickr or if parameters change (you’ll have to change your calls, of course).

I also have developed a Python FlickrUploadr to upload your pictures from Linux (or anywhere else you can get Python and PyGtk to build).

Download