Wednesday, January 30, 2008

Guide to the Scala Community

One of the most intriguing things about Scala is the people who are working with it. I have been following Scala mailing lists over a year, and was impressed by the helpfulness and positive attitude of the people involved. Very few are the times I've seen personal attacks, if any. Also the people at EPFL who are responsible for creation of Scala have given lots of insight why things are done way they are, or why is feature X not implemented. They have even changed Scala rapidly to support other people's ideas.

This blog entry is mainly meant for a Scala beginner as a guide. I try to familiarize you with different ways of interaction with other's in Scala related things, and to get you know about user written faciliation tools and (upcoming) libraries. Any suggestions how to extend this post are appreciated, of course.

First of all, there are the mailing lists. At the moment there are many of them, and it's hard to tell sometimes to which should one post, because the ambiguity of division. But better to post somewhere than to nowhere. Here are the most important:

The main list is scala, and it's for general Scala related discussion, e.g. standard library, language changes, or implementation issues.

scala-user is mostly for newbie questions, and also for specific technology related discussion, also stories of experience of Scala programming.

scala-debate is mostly for discussion that is specific in kind, in which not many people are interested. It's also excellent place to discuss programming theory, future and ideas of improvement for Scala. The discussion seems to be there the most relaxed of all lists, and lots of 'lambda the ultimate' kind of persons are lurking there.

To see guidelines how to interact with the above mentioned and other mailing lists see this page.

The mailing lists are the best places for you to ask questions, or give suggestions, and of course help others. But if you have found a bug e.g. in the compiler, the lists are rarely the best place to announce them. You should just see if there exists a bug report in Trac, and if not, create one. It won't go unnoticed, and will most definitely be appreciated! But in special circumstances it's ok to discuss them too, or ask whether you have found a bug or not.

Please don't get offended if nobody answers your question; it's likely that the question is hard to answer, or it was sent at an unfortunate time, and was forgotten. It's not crime to ask again...

For those who like to chat, the irc channel #scala @ freenode is the place to go. There's at least couple of active guys who try to give their best in helping you. Again, please be patient with your question.

The blogs about Scala are of course not to be forgotten. Here's the most interesting ones I've come up with:

If anyone knows other good ones, I'd be happy to hear about them.

Now you know some of the people dealing with Scala. Next I'll give you some pointers to faciliation tools:

One of the most useful tools is a simple seach facility for Scala API. Even though it could be so much more, it's already good as is: API Seach tool. And for those who need to show short samples of code to others, e.g. in IRC discussion, a pastebin is very useful, and this one can even colorize the Scala syntax: Scala Pastebin.

Moreover, even though Scala standard library is very important, there's huge amount of useful general tools a programmer needs that can't be found from the standard library. Of course there's also Java API that can be utilized, but it doesn't let use all Scala features smoothly unless wrappers are explicitly written. That's why some clever guys started a community based library, called Scalax. I emphasize it's in its early phase, and encourage you to just wait until it's in better shape, unless you're enthusiastic and want to contribute to it. Moreover, there's another non-related publicly available Open Source code project named Scalaz, which somewhat overlaps with Scalax in its functionality. The design is however different, and you can get the better of both worlds if needed.

Of course I shouldn't forget the best open source real world example Scala has to offer yet: Lift webframework. There's also Scala-tools.org where Scala Open Source projects can be added, as far as I know.

Text editing tools, including IDEs, are numerous. For lightweight editors you can find a Scala configure file in the Scala distribution in [Scala]/share/scala/support/. IDEs are at the moment in development, but some are usable, for example Eclipse plugin which will have its newest, highly improved version out soon (update: it's in public testing now, see wiki. You can also read the progress of Netbeans plugin here.

I hope these descriptions helped you to get a better understanding where to go in the Scala world. By writing articles like this I try to give my humble support to this community, which I so enjoy being part of.

Monday, January 28, 2008

Meet the scala.xml book if you haven't yet

If you don't use scala for XML processing, you can stop reading now.

I moved the scala.xml book to a new location (and removed the highlighting).

For all those who do not know this book, it describes the scala.xml library. Read it, or better yet link to it in your blogs.

For all those who know it, there are no new chapters, only minor corrections.

Apart from the book, revision r13821 now has the support for using Option[Seq[Node]] in nullable attributes (which may be somewhat preferable to passing null). The scala.xml draft book mentions that change and contains a small fix (the concat method was replaced for ++, and the code example uses the proper sequence escape).

All full code examples compile with scala 2.6.1. Suggestions, any kind of feedback welcome.

Monday, January 14, 2008

Roman numerals in Scala

I just read about converting Ints to Romans numerals in Python and Haskell and thought... gee... I can do that in Scala:


def romanize(number: Int) = {
val numerals = List(("M", 1000), ("CM", 900), ("D", 500), ("CD", 400),
("C", 100), ("XC", 90), ("L", 50), ("XL", 40),
("X", 10), ("IX", 9), ("V", 5), ("IV", 4),
("I", 1))

def next(in: Int) = numerals.filter(_._2 <= in) match {
case (s, v) :: _ => Some((s, in - v))
case _ => None
}

unfold(number)(next).mkString("")
}

def unfold[T, R](init: T)(f: T => Option[(R, T)]): List[R] = f(init) match {
case None => Nil
case Some(r, v) => r :: unfold(v)(f)
}



The 'unfold' function is not part of the standard Scala distribution, but looks to be darned useful. It takes an initial value and a function that returns the "next" thing and unrolls the initial value into a List. Nifty.

The actual "romanize" function contains a local definition of the roman numerals and the "next" function which finds the next match in the list of roman numerals. This function, along with the initial value are passed into unfold which returns a List of Roman numerals. mkString turns the list in a single String.

Short, sweet, and to my eye, the Scala and Haskell versions are very similar in complexity.

Monday, January 7, 2008

Announcing lift 0.4

Folks,

The lift team is pleased to announce the release of version 0.4 of the lift web framework.

lift is an expressive and elegant open source framework for writing web applications. lift stresses the importance of security, maintainability, scalability and performance, while allowing for high levels of developer productivity.

lift borrows from the best of existing frameworks, providing

* Seaside's highly granular sessions and security
* Rails fast flash-to-bang
* Django's "more than just CRUD is included"
* Wicket's designer-friendly templating style (see Lift View First)

And because lift applications are written in Scala, an elegant new JVM language, you can still use your favorite Java libraries and deploy to your favorite Servlet Container. Use the code you've already written and deploy to the container you've already configured!

Version 0.4 marks a few major milestones for lift. It's the first time-based release we've done for lift. We're planning to do a monthly release between now and the 1.0 release of lift.

Version 0.4 also marks the first time folks other than me have made the largest contributions to lift during a release. Maciek's PostgreSQL support and DavidB's <head> rewrite contributions are amazing and important to lift. SteveJ continues his messaging rampage with XMPP support. Additionally, DavidB and Eric Torreborre (who has just joined the lift team) have been working on a test framework for lift.

So, please try lift 0.4, join the lift community and give us some feedback.

Thanks,

David

Changes in this version include:

New features:
o Added XMPP support for lift applications. see the package net.liftweb.xmpp
o Added support for switching XHTML MIME type serving off. See LiftServet.useXhtmlMimeType
o Adding support to H2 to lift-ORM
o Adding support to PostgreSQL to lift-ORM
o /html/body//head are merged into /html/head, to allow html fragment inlined into body to contribute to /html/head
o Adding a new lift archetype, lift-archetype-basic that will generate a lift template with basic database and users functionality.
o Adding LiftConsole to archetype to play with lift-based application in console mode
o Adding mock for HTTPRequest and Co
o Adding first Specs test to test lift-core


Changes:
o Upgrade to scala-2.6.1
o Support for PosgreSQL 8.1 and some tests
o The look of the maven site generated (for lift itself and for archetypes)

Removed:
o Removing deprecated new_proj (replaced by archetypes)
o Removing lift-archetype-hellolift (replaced by lift-archetype-basic (and the sample application hellolift))

Friday, January 4, 2008

maven for scala

I'll try to provide a mini-guide about maven for scala's project. For more info, go to maven home or plugin's home.

Introduction to maven


Maven is a builder like make or ant, written in java. It's a commande line tool, IDE (Eclipse, Netbeans, IDEA) have plugins to handle and integrate project powered by maven. It could be used to create lib (jar), webapps (ear) and any other type of "artifact". It prefers convention over configuration, and configuration over instruction. What that mean exactly ?
  • every action have a default configuration (= the convention).
  • every action is a goal defined into a plugin (aka mojo), and for common case, you will try to use existing plugin instead of calling (more) low level instruction (like copy file,...)
Before creating your first scala project, You need to know some info:

a command line tool
"mvn" is the name of the command line tool to call maven 2.x. To display help, run mvn help
the project descriptor : the file [prj]/pom.xml
It's the file when every project information are stored (name, version, dependencies, license, mailing-list,...)
the build lifecycle :
The build lifecycle is defined by a sequence of phases, the main are :
  • compile - compile the source code of the project
  • test - test the compiled source code using a suitable unit testing framework. These tests should not require the code be packaged or deployed
  • package - take the compiled code and package it in its distributable format, such as a JAR.
  • integration-test - process and deploy the package if necessary into an environment where integration tests can be run
  • install - install the package into the local repository, for use as a dependency in other projects locally
  • deploy - done in an integration or release environment, copies the final package to the remote repository for sharing with other developers and projects.
A phase is depend of the previous one, so when you request the phase test, then the phase compile is done before,...
Directory layout
see below for a scala project
repository
Maven use repositories (local and remote) to store and to retrieve artifacts and their descriptor (pom). Artifacts are jar, war,... and they could be used as dependencies, maven plugin,...
By default, maven search artifact in the central repository. A "dedicated" repository for Scala stuff is available at http://scala-tools.org/repo-releases/.

Your first scala project with maven


In the following, we will run maven for the first time. Maven download what it need to work from remote repositories, and cache the downloaded artifact into its local repository (default is $HOME/.m2/repository). It only download what it need for the requested phases/goals (lazy downloading). So the first runs could be very long.

Step 0: installation


  • install jdk 1.5+ (eg : on my box $HOME/bin/soft-linux/jdk-1.5.0_03)
  • install maven 2.0.8+ (eg : on my box $HOME/bin/soft-java/apache-maven-2.0.8)
    • download it
    • unarchive it
    • add the apache-maven-2.0.8/bin directory to your PATH
    • check that maven is in the path:
      • go into any directory outside the maven installation
      • run mvn help, you should see
        usage: mvn [options] [<goal(s)>] [<phase(s)>]

        Options:
        -q,--quiet Quiet output - only show errors
        ...

Step 1: create a project


You could create a project skeleton with your favorite file system tools (following directory layout as below) or you could use archetypes. Maven Archetypes are project'skeleton that could be used to create new project.
mvn org.apache.maven.plugins:maven-archetype-plugin:1.0-alpha-7:create \
-DarchetypeGroupId=org.scala-tools.archetypes \
-DarchetypeArtifactId=scala-archetype-simple \
-DarchetypeVersion=1.1 \
-DremoteRepositories=http://scala-tools.org/repo-releases \
-DgroupId=your.proj.gid -DartifactId=your-proj-id

At the end of the process you should see something like
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 second
[INFO] Finished at: Sat Jan 05 17:39:47 CET 2008
[INFO] Final Memory: 6M/63M
[INFO] ------------------------------------------------------------------------

!! Success you now have a empty project under your-proj-id directory with the following directory layout :
your-proj-id/
|-- pom.xml
`-- src
|-- main
| `-- scala
| `-- your
| `-- proj
| `-- gid
| `-- App.scala
`-- test
`-- scala
`-- your
`-- proj
`-- gid
`-- AppTest.scala

In fact, the project is not empty it contains an helloworld application (App.scala) and a JUnit test (AppTest.scala).
In the next step, you will request phase (or goals). The results will be put under your-proj-id/target directory. The target directory is the working directory where every plugin put the result of computation. If you want to clean up, request the goal "clean"
mvn clean

Step 2: compile the project


# only compile
mvn compile

If it's the first time you use maven with scala, the build should failed with a message like
...
[ERROR] FATAL ERROR
[INFO]
------------------------------------------------------------------------
[INFO] The PluginDescriptor for the plugin Plugin [org.scala-tools:maven-scala-plugin] was not found.
[INFO]
...


Cause :

the pom.xml (autogenerated) doesn't specify wish version to use for maven-scala-plugin, so maven try to use the latest available localy, and none was previously downloaded.

Solutions :
  • edit the pom.xml and define a version for the plugin

  • request to download the latest available on remote repositories


I prefer the second solution (in this case):
# only compile
mvn -U compile

now you should see
...
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
...

Step 3: compile and running test


The skeleton create a JUnit test AppTest.scala as sample, try to compile and run it
# compile + compile test + run test
mvn test

you should get :
...
-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running your.proj.gid.AppTest
Tests run: 2, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 0.054 sec <<< FAILURE!

Results :

Failed tests:
testKO(your.proj.gid.AppTest)

Tests run: 2, Failures: 1, Errors: 0, Skipped: 0

[INFO] ------------------------------------------------------------------------
[ERROR] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] There are test failures.

Please refer to /home/dwayne/tmp/your-proj-id/target/surefire-reports for the individual test results.

BUILD FAILURE, it's not good! So read the log on console :
  • there is 2 tests and one of them failed
  • the failed test is the method testKO from the class your.proj.gid.AppTest
  • see the content of the directory .../your-proj-id/target/surefire-reports for details

So you could read the problem in .../your-proj-id/target/surefire-reports/your.proj.gid.AppTest.txt
...
testKO(your.proj.gid.AppTest) Time elapsed: 0.01 sec <<< FAILURE!
junit.framework.AssertionFailedError
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.assertTrue(Assert.java:20)
at junit.framework.Assert.assertTrue(Assert.java:27)
at your.proj.gid.AppTest.testKO(AppTest.scala:26)
at your.proj.gid.AppTest.testKO(AppTest.scala:26)
...

So edit the test and fix it (it's easy), and rerun test until it pass.
Why the empty project is created with a failed test? to check that test are running and are used.

Step 4: generate the jar


# compile + run test + generate the jar
mvn package

If you fixed the test in Step 3, then a jar should be generated under the target directory. The jar doesn't contains the test classes, only the classes from src/main/scala/...

Step 5: start coding


  • add scala file under src/main/scala/... or src/test/scala/...
  • run the phases or goal you wish,...
  • if you need more lib (dependencies), edit the pom.xml and add <dependecy> node. By default you could declare dependency available on central repo (I suggest to use mvnrepository as a search engine in central repo), or in http://scala-tools.org/repo-releases/ (browse the directory, no search engine available :()

Conclusion


I expect this overlook and quick tutorial could help you to start playing with maven and scala. I plan to write other articles about "maven for scala" (about, the pom.xml and repositories). If you want to know more about maven and don't want to wai futur article, I suggest you browse the documentation of maven. I also suggest you to take a look at the maven-scala-plugin 2.x documentation, you'll see how to generate scaladoc, choose the scala version, or run a scala console with the project dependencies.

If you have question ask, If you want I detail some point here or in a futur article, ask.