Tuesday, February 21, 2012

Function Branching and Looping

Many newer languages support a more functional style of programming. And often that includes functional branching and looping. That is rather than an if statement and for statement, you now have an if function and a for function. And these functions return a value.
The if/then/else Function
The if/then/else function won't be too big of a paradigm shift for most developers because it is just a more verbose form of ?: ternary operator. Here is an example in scala:
String s = if(age <= 21){
  "Minor"
}else if(age >= 21){
  "Prime"
}else{
  "Wise"
}
The for Function
Looping functions (not statements - functions) go by different names (list comprehensions, map, transform to name a few). They typically take one collection as input and transform that into a different collection. For example, transforming a list of Person object into a list of html TRs. Some languages implement looping functions with a dedicated language construct (like Scala with yield keyword). Or it can be implemented as a function (typically called map) where you pass the function a collection and a transformer function. This feature works best with languages that support passing around functions. But even Java can support this operation.
For functions are typically used to transform one collection into another.  The example below uses the keyword yield:
List<String> listLowerCase = ['a','b','c'];
List<String> listUpperCase = for (s in listLowerCase)
yield s.toUpperCase()
Here is a slightly more complex example, that transforms a Person list into a list of html TR strings:
List<Person> personList = [
new Person('Dave','Ford'),
new Person('Joe','Blow')];
List<String> trList = for (s in personList)
yield "<tr><td>${p.firstName}</td><td>${p.firstName}</td></tr>"
You can also implement this without a special keyword using a map function that takes transformer function (in red below) as an argument:
List<String> list1 = ['a','b','c'];
List<String> list2 = listLowerCase.map( (s) => s.toUpperCase() );
Attached: Function Branching and Looping
Google Docs makes it easy to create, store and share online documents, spreadsheets and presentations.
Logo for Google Docs

1 comment:

Eric Leese said...

There problem with .map() is that anyone who implements an IEnumerable needs to implement that too if they want people to be able to do it, even though it's trivial and the same for pretty much any IEnumerable. The other problem is when you throw in other operations like filter and sort you end up with a series of functions that each have to re-define x even though it means the same thing in all of them.

I like C# LINQ, though I think it would be better if the syntax of for statements and queries were merged as much as possible -- I can't tell you how many times I've written "for (x in from x in [...] select x)".

Maybe:

IEnumberable query = for (x in list) where x.a > a orderby x.b select x.c;

And the loop version:

for (x in list) where x.a > a orderby x.b {
doSomethingWith(x.c);
}