Archive

Posts Tagged ‘functional programming’

JS 101 – Week 3

February 15, 2011 Leave a comment

In Javascript, functions are first class objects. What does it mean to be a first class object?

A function can be used anywhere an object can be used; in particular, you can pass functions as method arguments. (We did this in last week’s homework by passing the print function into the iterateAndOperate method). This is in contrast to a language like Java where functions are not first class objects, and the programmer must use interfaces and anonymous classes to get around this problem. For instance, in Java, to delay the invocation of a function, you might do the following:

SwingUtilities.invokeLater(new Runnable() {
    @Override
    public void run() {
        System.out.println("I was run!");
    }
})

whereas in Javascript, you could do something like

invokeLater(function() { print("I was run") });

assuming there was an invokeLater function.

Functions and variables share the same namespace. What does this mean and what important implication does this have?

This means that you must take care in not defining variables in the global namespace that have the same name as a function. For instance,

// global variable
x = 5;

function x(args) {
    alert(args);   
}

// The global variable is shadowing the function name;
// the function is not called
x(5);

Douglas Crockford equates Javascript functions with Lambdas, and also mentions that they are a secure construct. Can you do some research and reflect on what he means by ‘secure construct’?

A lambda basically means that you can pass a function as an argument to another function; this is due to the aforementioned first class nature of functions. They are a secure construct because the scope of the functions is such that private variables in function A cannot be accessed by function B when A is passed into B. In other words,

function outer(func) {
  // "undefined", since the ‘privateVariable’
  // field is scoped only to the inner function.
  return func.privateVariable;
}

function inner(a,b,c) {
  var privateVariable = 25;
  return a + ", " + b + ", " + c;
}

alert(outer(inner("cat","dog","bear")));

f

Can you explain the concept of a closure.

A closure means that an inner function continues to have access to variables defined inside of an outer function, even after the outer function has finished. I wrote an example you can view on jsfiddle.

What is the difference between a function and a method?

A method is a function that is bound to an object, and thus it has an implicit “self” reference.

In Javascript there is no implicit type checking of arguments passed to functions. This could lead to bugs if programmers are not careful about what they pass to functions. If you create a function, how would you protect it from well meaning but careless programmers?

You can do defensive checks within the function. For instance, if a method is supposed to take in a number, you could do the following:

function numericalFunction(x) {
    if (typeof(x) != "number") {
        throw("Expected numerical value for numericalFunction; got " + x);
    }
    // Proceed as normal
}

You can also use the arguments implicit variable in the function to check that the number of arguments the user passed in is equal to the number of arguments that the method expects.

Javascript functions have implicit access to something called this. this points to different things depending on how the function was created. Can you explain why we need this, and what it represents in different type of functions.

If a function is created globally, its this pointer will be to the DOMObject. If it’s created and bound to an object, the this pointer points to that object. The following illustrates this:

function f() {
  return "f's this: " + this;
}

function nested() {
  function inner() {
    return "inner's this:" + this;
  }
  return inner();
}

// o is an object; add a method do it
var o = {};
o.f = f;
o.nested = nested;

o.newFunc = function() { return "newFunc's this: " + this; };
o.nestedFunc = function() { 
  var inner = function() {
    return "nestedFunc's inner this: " + this;
  }
  return inner();
}



print(f());
print(nested());
print(o.f());
print(o.nested());
print(o.newFunc());
print(o.nestedFunc());


// prints
// f's this: [object DOMWindow]
// inner's this:[object DOMWindow]
// f's this: [object Object]
// inner's this:[object DOMWindow]
// newFunc's this: [object Object]
// nestedFunc's inner this: [object DOMWindow]
//

Note that only the non nested functions that have been bound to object o point to that object as opposed to the DOMWindow.

The reason we want the this pointer is to be able to introspect on the type and contents of the object that is calling the function. For instance, in my last assignment, I used the this variable to produce a nice representation of an object:

nick = {name:"Nick",age:23};

// This function returns a string representation of whatever
// is invoking it
function selfStringRep() {
  var str = "";
  for (var v in this) {
    // This is not an inherited property
    if (this.hasOwnProperty(v)) {
      str += "’" + v + "’: " + this[v] +"\n";
    }
  }
  return str;
}
Object.prototype.toString = selfStringRep;
print(nick.toString());
// prints
//’name’: Nick
//’age’: 23

4.1

The solution for the cat problem talks about a ‘set’ of names. A set is a collection of values in which no value may occur more than once. If names are strings, can you think of a way to use an object to represent a set of names?

Show how a name can be added to this set, how one can be removed, and how you can check whether a name occurs in it.

var cat_set = {};
// Add a cat
cat_set["Tigger"] = true;
// remove a cat
delete cat_set["Tigger"];

// Check if cat exists
cat_set["Frog"] != undefined

// Wrap it all up nicely: in an object with functions:
var cat_set = {};
cat_set.add_cat = function(cat) {
    this[cat] = true;
}
cat_set.remove_cat = function(cat) {
    delete this[cat];
}
cat_set.cat_exists = function(cat) {
    return this[cat] != undefined;
}

cat_set.add_cat("Frisky");
// prints "true"
show(cat_set.cat_exists("Frisky"))
cat_set.remove_cat("Frisky");
// "false"
show(cat_set.cat_exists("Frisky"))

4.2

Write a function range that takes one argument, a positive number, and returns an array containing all numbers from 0 up to and including the given number.

An empty array can be created by simply typing []. Also remember that adding properties to an object, and thus also to an array, can be done by assigning them a value with the = operator. The length property is automatically updated when elements are added.

// Assumes n >= 0
function range(n) {
    var array = [];
    for (var i = 0; i <= n; i++) {
        array[i] = i;
    }
    return array;
}

4.3

split and join are not precisely each other’s inverse. string.split(x).join(x) always produces the original value, but array.join(x).split(x) does not. Can you give an example of an array where .join(" ").split(" ") produces a different value?

[" ", " ", " "].join(" ").split(" ");
// equals ["", "", "", "", "", ""]

4.4

Write a function called startsWith that takes two arguments, both strings. It returns true when the first argument starts with the characters in the second argument, and false otherwise.

function startsWith(string, pattern) {
    return string.slice(0,pattern.length) === pattern;
}

4.5

Can you write a function catNames that takes a paragraph as an argument and returns an array of names?

Strings have an indexOf method that can be used to find the (first) position of a character or sub-string within that string. Also, when slice is given only one argument, it will return the part of the string from the given position all the way to the end.

It can be helpful to use the console to ‘explore’ functions. For example, type "foo: bar".indexOf(":") and see what you get.

// The sentence is in the form "Blah blah: cat1, cat2, …, catN."
function catNames(paragraph) {
    var colonIndex = paragraph.indexOf(":");
    // Skip the colon and the following space
    var catListString = paragraph.slice(colonIndex + 2);
    return catString.split(", ");
}

/*#p2pu-Jan2011-javascript101*/

An introduction to Scala

July 15, 2010 1 comment

Functional programming plus Object Oriented Programming = Scala

An Introduction to Scala

Overview

  • Introduction
  • Why is it gaining popularity, and why should you care?
  • History
  • Functional programming
  • Syntax
  • Data structures
  • Benefits
  • Drawbacks
  • Conclusion

Introduction

  • Scala = scalable language.
    • From scripts all the way up to enterprise
  • Runs on JVM
  • Combines functional and object-oriented paradigms

Scala was designed to be both object-oriented and functional. It is a pure object-oriented language in the sense that every value is an object. Objects are defined by classes, which can be composed using mixin composition. Scala is also a functional language in the sense that every function is a value. Functions can be nested, and they can operate on data using pattern matching. Language creator Martin Odersky

Why?

  • Productive like a scripting language, but with type safety and speed
  • You can express yourself in fewer lines of code than equivalent Java.
  • Well suited to multithreaded environments
    • Actors and message passing

Less boilerplate

// Scala
case class Person(firstName: String, lastName: String)

// Java
public class Person implements Serializable {
    private final String firstName;
    private final String lastName;

    public Person(String firstName, String lastName) {
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public Person withFirstName(String firstName) {
        return new Person(firstName, lastName);
    }

    public Person withLastName(String lastName) {
        return new Person(firstName, lastName);
    }

    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Person person = (Person) o;
        if (firstName != null ? !firstName.equals(person.firstName) : person.firstName != null) {
            return false;
        }
        if (lastName != null ? !lastName.equals(person.lastName) : person.lastName != null) {
            return false;
        }
        return true;
    }

    public int hashCode() {
        int result = firstName != null ? firstName.hashCode() : 0;
        result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
        return result;
    }

    public String toString() {
        return "Person(" + firstName + "," + lastName + ")";
    }
}

Samples where Scala code is significantly shorter than Java

History

  • Martin Odersky created it
    • Functional programming and compiler background (wrote current javac reference compiler)
    • Worked on adding generics to Java
  • Design began in 2001, released in 2003
  • Version 2.80 Final released July 14, 2008

Functional programming

  • Avoid state and mutable data
  • Every variable is a constant
  • Lends itself to parallelization; avoid locking and deadlocks
  • First-class functions – functions can serve as arguments and results of functions
  • Recursion is primary tool for iteration
  • Heavy use of pattern matching
  • Lazy evaluation – infinite sequences

Who’s using Scala

  • Twitter uses for performance critical code; replaces Ruby in that regard
  • FourSquare uses Scala and Lift web framework
  • Xerox uses Scala and Lift
  • Etherpad uses Scala in its real time document collaboration software (acquired by Google for Google Docs; Scala code is now opensourced)

Syntax:

Hello world in Scala:

object HelloWorld extends Application {
  Console.println("Hello World")
}

No semicolons needed

Variables declared with val and var

val x = 0 // immutable
var y = 0 // mutable
x = 1 // compiler error
y = 1 // fine

Type declarations occur after the variable

int x = 0; // Java
val x: Int = 0 // Scala

Generic type arguments occur within square brackets rather than angle brackets

List<Integer> intList = ...; // java
val intList: List[Int] =  ..// scala

Array indexing is done through use of parentheses rather than square brackets

// Java
int[] x = {1,2,3,4};
x[0] // 1

// Scala
val x: Array[Int] = Array(1,2,3,4)
x(0) // 1

Method definitions

scala> def square(x:Int) = { x * x }
square: (Int)Int

scala> square(5)
res38: Int = 25

No such thing as a ‘void’ method, every method returns a value. void = “Unit” in Scala

scala> def printIt(x:Any) = { println(x) }
printIt: (Any)Unit

Type inferencing – note that I haven’t been declaring what types my methods take

// Compiler infers that the return type must be int
scala> def square(x:Int) = { x * x }
square: (Int)Int

// I can explicitly indicate what it returns if I prefer
scala> def squareExplicit(x:Int):Int = { x * x }
squareExplicit: (Int)Int

No need to explicitly return values

scala> def square(x:Int) = { x * x }
square: (Int)Int

scala> def squareExplicit(x:Int):Int = { return x * x }
squareExplicit: (Int)Int

// The result of last expression is returned.

Conditionals as values

// BAD.  Java style, mutable value
var x = 0
if (someCondition) {
    x = something
}
else {
    x = somethingElse
}

// GOOD: Scala style, immutable
val x = 
    if (someCondition) {
        something
    }
    else {
        somethingElse
    }

// or if short enough
val x = if(something) something else (somethingElse)

All operations are method calls

Scala doesn’t technically have operator overloading, because it doesn’t actually have operators in the traditional sense. Instead, characters such as +, -, *, and / can be used in method names. Thus, when you typed 1 + 2 into the Scala interpreter in Step 1 you were actually invoking a method named + on the Int object 1, passing in 2 as a parameter. As illustrated in Figure 3.1, you could alternatively have written 1 + 2 using traditional method invocation syntax (1).+(2).
“Programming in Scala, p. 39”

What good does that do me?

If your domain objects make sense to add, multiply, divide, etc., you can treat them in a much more natural way.

// BigInt is a wrapper around Java's BigInteger, providing arithmetic methods
scala> BigInt("103058235287305927350") + BigInt("288888203959230529352")
res16: BigInt = 391946439246536456702

// In Java you're stuck calling .add, .multiply, etc
scala> new java.math.BigInteger("103058235287305927350").add(new java.math.BigInteger("288888203959230529352"))
res21: java.math.BigInteger = 391946439246536456702

Data structures

Lists

More powerful than Java lists. Expose a whole raft of Functional Programming paradigms, such as map, reduce, filter, folds, etc.

// Note the syntax; you do not call "new".  This is because there is
// an apply ("()") method defined in the List object.
scala> val a = List("hello","how","are","you")
a: List[java.lang.String] = List(hello, how, are, you)

// Explicit
val nums:List[Int] = List(1,2,3,4)

scala> a.size
res40: Int = 4

scala> a.mkString(" ")
res41: String = hello how are you

scala> a.map(x => x.toUpperCase())
res42: List[java.lang.String] = List(HELLO, HOW, ARE, YOU)

scala> a.map(x => x.length())     
res43: List[Int] = List(5, 3, 3, 3)

scala> a.filter(x => x.startsWith("h"))
res44: List[java.lang.String] = List(hello, how)

scala> a.forall(x => x.length() > 0)
res46: Boolean = true

// Singly linked list
scala> a.head
res67: java.lang.String = hello

scala> a.tail
res68: List[java.lang.String] = List(how, are, you)

// add to head
scala> 1 :: List(2)      
res70: List[Int] = List(1, 2)

// reverse
scala> a.reverse  
res72: List[java.lang.String] = List(you, are, how, hello)

Tuples

Tuples are a good data structure to pack up multiple variables to return from a function, without the need to define a helper class to do so. Slightly syntax to create them, as well as to access the elements contained therein.

// Explicitly create the tuple; never really a need to do this
scala> val a:Tuple2[Int,Int] = (5,6)
a: (Int, Int) = (5,6)

// The parentheses indicate it's a tuple
scala> val b = (5,6)
b: (Int, Int) = (5,6)

// Yes, I know it's a strange syntax.  And it's 1-based rather than 0-based.  This is because Haskell has 1-based tuple ordering and Odersky wanted to stay true to that.
scala> a._1
res48: Int = 5

scala> a._2
res49: Int = 6

// You can have an arbitrary number of elements, of any type you want
val listTuple = (List(1,2,3), "hello", new java.awt.Color(255,0,0))
scala> val listTuple = (List(1,2,3), "hello", new java.awt.Color(255,0,0))
listTuple: (List[Int], java.lang.String, java.awt.Color) = (List(1, 2, 3),hello,java.awt.Color[r=255,g=0,b=0])

Maps

Scala provides immutable maps as well as a syntax for creating map literals.

scala> val theMap = Map("hello"->5,"world"->5)
theMap: scala.collection.immutable.Map[java.lang.String,Int] = Map(hello -> 5, world -> 5)

scala> theMap("hello")
res50: Int = 5

scala> theMap.getOrElse("world",2)
res51: Int = 5

scala> theMap.getOrElse("worldly",2)
res52: Int = 2

scala> theMap.keySet  
res54: scala.collection.Set[java.lang.String] = Set(hello, world)

scala> theMap.values
res55: Iterator[Int] = non-empty iterator

scala> theMap.values.toList
res56: List[Int] = List(5, 5)

// Mutable map:
var mutableMap = Map[Int, String]()
mutableMap += (1 -> "1")
mutableMap += (2 -> "2")

Arrays

Internally map to Java arrays. Idiomatic Scala code tends to prefer Lists to Arrays, but they are necessary for interacting with a lot of Java code. Create in same way as lists.

scala> val array = Array(1,2,3)
array: Array[Int] = Array(1, 2, 3)

Benefits

  • Static type checking but with improved type inference

    // Java
    private Map wordCount = new HashMap();
    // Scala:
    var wordCount:Map[String, Int] = Map()

  • Much faster than Python/Ruby and other interpreted languages, but just as expressive

  • Duck typing support
  • Conciseness
    • Functions as first class objects; no need for anonymous classes and extraneous interfaces Unified types
  • Traits are a cross between interfaces and abstract classes, allowing you to provide default implementations. Allows for ‘mix-in’ composition, as well. Solves problems with multiple inheritance, while giving flexibility. Avoid repeating yourself.
  • Console REPL environment allows you to quickly iterate and test
  • Of theoretical interest
    • Combines functional and object-oriented in statically-typed environment

Drawbacks/Complaints

  • Immaturity of tool chain
  • Binary/source incompatibility from rapid change of language
  • Type system is very complex
  • Functional programming can be hard to wrap head around for people familiar with OOP
  • Syntax can be so concise as to be cryptic

    For instance, the following example comes from StackOverflow post.

    def scanLeft[a,b](xs:Iterable[a])(s:b)(f : (b,a) => b) =
    xs.foldLeft(List(s))( (acc,x) => f(acc(0), x) :: acc).reverse
    

    And then use it like this:

    scala> scanLeft(List(1,2,3))(0)(_+_)
    res1: List[Int] = List(0, 1, 3, 6)
    

Conclusion

Scala is a very intriguing language due to its combination of object orientation with functional programming concepts. The programmer is not forced to choose between the expressiveness of objects and immutability; he can switch between the two paradigms as the situation warrants.

While binary/source incompatibility is a very real problem for enterprise adoption, it is an issue that the creators are working on.

Scala provides a great framework in which to explore functional programming methods, especially through the use of the interactive console environment.

Resources

Images: