A venue in London in the UK, the Scala hosts live music, mainly from Indie (aka alternative music) bands. On weekends it is also a nightclub, and it has been the home of Popstarz for several years now.

The venue itself is a converted theatre, and it feels like it, with unnecessarily large, sweeping staircases up the front of the building, and like most theatres it is considerably taller than it is wide; the ceiling of the main room is three storeys above.

The main room has a small stage only slightly raised above the audience, with no seating apart from a long bench built into the back wall of the room. In addition to the floor, two other main galleries look out into the main room: one on the first floor is a glass-walled bar (sound-proof, so that the small room isn't crowded with non-drinkers trying to catch the concert) and on the second floor is an open gallery, again without any seating.

The second gallery is extremely high up and does not provide a good view of the stage as lights and rigging tend to get in the way. There is a small open-air balcony on a level with the glass bar that also could provide a good view of the stage, but it doesn't hold too many people. If you want to see the act at the Scala you really need to be on the floor of the main room.

Its transformation to a heavy-duty venue is evidenced by the grubby and worn-down look of the place, as well as the heavy stainless steel, lean-proof railings and other fixtures. However, the venue is generally quite clean and well-maintained (including the toilets) which is a lot more than can be said for its competitors in London, such as the Astoria.

Scala is a modern multi-paradigm programming language designed to express common programming patterns in a concise, elegant, and type-safe way. It smoothly integrates features of object-oriented and functional languages.

http://scala.epfl.ch/

Scala (Scalable Language) is a programming language which has recently been developed at the Programming Methods laboratory of the EPFL (Swiss Federal Institute of technology, Lausanne). It outwardly resembles java, but includes a large number of features which will never belong to other object-oriented languages.

Why design yet another programming language?

The current object-oriented design paradigm doesn't scale well to networked applications: A network-based service will typically involve database access, document transformation and production and "software logic" components. Java and .NET both attempt to glue all these components together, but the result is more an awkward interface than anything else.

Instead of resorting to glue, Scala attempts to recreate a coherent base for solving network-based application problems.

It uses the object-oriented principles of encapsulation, polymorphism and modularisation. Being both pure object-oriented and functional, scala functions are objects ; This makes tree parsing and data transformation a great deal easier than it is in java.

Of the functional languages, scala adopts data type decomposition using pattern matching. This is particularly useful when needing to determine the type of an object at runtime. (Note: Type and Class are the same concept in scala, but sometimes it is more handy to refer to one or the other, especially when referring to other languages for comparison.)

Scala is statically typed, but supports a large number of ways of defining classes and subclasses, allowing the creator of an object to define type variance, upper and lower type bounds, along with a sane way of using polymorphism

Perhaps most importantly, scala allows for easy extensions to the language:

  def loop(def body: Unit): LoopUnlessCond =
    new LoopUnlessCond(body);
  private class LoopUnlessCond(def body: Unit) {
    def unless(def cond: Boolean): Unit = {
      body;
      if (!cond) unless(cond);
    }
  }
  var i = 10;
  loop {
    Console.println("i = " + i);
    i = i - 1;
  } unless (i == 0);
}

A body enclosed in braces is of type Unit. Inside a def, it will not be evaluated until the last minute. So the word loop just becomes a new way of creating a new LoopUnlessCond object. When the unless method is applied to an instanciation of LoopUnlessCond (any method can be applied to an object as an infix operator). Voila! A java-style while-unless is created in scala.

So functions are objects, big deal!

object CurryTest with Application {

  def filter(xs: List[Int], p: Int => Boolean): List[Int] =
    if (xs.isEmpty) xs
    else if (p(xs.head)) xs.head :: filter(xs.tail, p)
    else filter(xs.tail, p);

  def modN(n: Int)(x: Int) = ((x % n) == 0);

  val nums = List(1, 2, 3, 4, 5, 6, 7, 8, 9);
  Console.println(filter(nums, modN(2)));
  Console.println(filter(nums, modN(3)))
}

--------------------

 % scala CurryTest 
    List(2,4,6,8)
    List(3,6,9)     

The function filter takes two parameters: A list of integers and a function which takes an integer and returns a boolean; it then returns a list containing only those members which "passed" the test provided by the predicate.

modN takes two parameter lists: each contains an integer. In scala, this function is of type (Int)(Int) => Boolean. If the parameter lists are incomplete, a new function is created, which takes only those lists which had not yet been specified. So modN(3) is of type Int => Boolean. This new function is passed to filter and is used to select only those values which are multiples of 3.

What is data-type decomposition?

abstract class Expression;
case class Sum(left: Expression, right: Expression) extends Expression;
case class Number(val: Int) extends Expression;
case class Identifier(name: String, val: Int) extends Expression;


   def print(exp: Expression): Unit = exp match {
     case Sum(left, right)    => Console.print("(");
                                 print(left);
                                 Console.print(" + ");
                                 print(right);
                                 Console.print(")");
     case Number(val) => Console.print(val.toString());
                      
     case Identifier(name, _) => Console.print(name);
  }
  val t = Sum(Sum(Identifier(a, 7),
                  Sum(Integer(1),
                      Integer(3))),
              5);
  print(t)


---

  ((a + (1 + 3)) + 5)

Here, we create a class architecture, which says that you can do such and such with Expressions. It also says that Sum, Integer and Identifier are all subclasses of Expression.

One of the problems in traditional object-oriented languages is that, with such a class system, you have to implement any methods that you want applied to objects of class Expression directly within the body of their definition: This means that adding a temporary - or long-term - new method to an API takes considerable effort. The other solution is to use those very nice instanceof clauses. This problem is very elegantly circumvented in scala. You can decompose objects according to their constructors or any of their parameters.

So when constructing a printer for my expressions, I just select the constructor which was used (Including the _ wildcard if desired). This allows values in the constructor to automatically be parameters of that object and grants easy access to their values.

Case clauses can also extract more specific values: for instance, 3 :: tail will match only those lists which start with 3.

You say the scala type system is crazy?

trait Stack[+a] { 
  def push[b >: a](x: b): Stack[b] = new NonEmptyStack(x, this); 
  def isEmpty: boolean 
  def top: a; 
  def pop: Stack[a]; 
} 
object EmptyStack extends Stack[All] { 
  def isEmpty = true; 
  def top = throw new Error("EmptyStack.top"); 
  def pop = throw new Error("EmptyStack.pop"); 
} 
class NonEmptyStack[a](elem: a, rest: Stack[a]) extends Stack[a] { 
  def isEmpty = false; 
  def top = elem; 
  def pop = rest; 
}

This way of implementing classes takes several considerations into account:

  1. Stacks should be generic: At instanciation, I specify what type of element my stack will contain.
  2. Stacks should be co-variant: If ColouredPoint is a subclass of Point then Stack[ColouredPoint] is a subclass of Stack[Point]
  3. One stack should not be able to contain elements both of type Int and of type String. This would not be a sound data-structure.
  4. There is no point in creating several empty stacks: they are all identical
To achieve these aims, Stack is specified as being a co-variant generic type by adding the +a to the first line (trait is pretty much scala for abstract class). The push method is contra-variant and creates a new stack ; In this way, it is impossible to create a stack which contains dissimilar data. You can only push on elements which are of the same class, or a super-class of a. Finally, EmptyStack is an object which instanciates Stack[All] ; in scala, All is a sub-class of all classes.

The result is that I can create a new stack: var mystack = EmptyStack; (scala has local type inference and will automatically work out that mystack is of type Stack[All]. This object has a method push[b >: All](elem: b): Stack[b], which I can use to add a ColouredPoint to my stack: mystack.push(new ColouredPoint);. mystack is now of type Stack[ColouredPoint] and has a method push[b >: ColouredPoint](elem: b): Stack[b]. I can then add a Point, thus yielding a Stack[Point]. As another example of variance, let's take the case of function inheritance:

def apply(a: Atype, b: (Ctype, Dtype) => Btype): [unit = {}

// Asubtype extends Atype, Btype extends Bsupertype, etc

def f1(Csubtype, Dsubtype): Bsubtype;
def f2(Csupertype, Dsupertype): Bsupertype;
def f3(Csubtype, Dsubtype): Bsupertype;
def f4(Csupertype, Dsupertype): Bsubtype;

val p1: Asubtype;

apply(p1, f1);
apply(p1, f2);
apply(p1, f3);
apply(p1, f4);

Which of these apply calls will work? Clearly, just as the type of p1 must subtype Atype, then the type fn must subtype the type of parameter b: a function which takes a Ctype and a Dtype and returns à Btype. To understand even better, suppose that b will be called in the body of apply. The function was written assuming that, when b is called, it will return a Btype; so the type returned by fn must subtype Btype - thus eliminating f2 and f3. The return parameter is co-variant in function inheritance.

And again, the function was written knowing that b would accept parameters of type Ctype and Dtype. This means that fn may not be more restrictive: It can accept Csupertype and Dsupertype, but cannot say: I only take Csubtype and Dsubtype. Thus, the parameters of a function are contra-variant in function inheritance.

Scala in the real world

The people who invented scala know quite a lot about writing compilers. As a result, the language is already usable and uses complex techniques to maximise tail recursion - even when it is not already present, and thus complete recursive calls in constant stack space. Scala is designed to interact with java and .NET; in fact, scala currently compiles to java bytecode and it is possible to use all the java libraries.

Because of this - and because a lot of scala features are really useful for parsing and writing XML, I'll be using scala in a project next semester. Hopefully my faith in scala will be vindicated!

Sca"la (?), n.; pl. Scalae (#). [L., a ladder.]

1. Surg.

A machine formerly employed for reducing dislocations of the humerus.

2. Anat.

A term applied to any one of the three canals of the cochlea.

 

© Webster 1913.

Log in or registerto write something here or to contact authors.