Sonntag, 3. Juli 2011

Simple Problem, Simple Solution(s)

Borrowed from :
http://learnyouahaskell.com/starting-out#im-a-list-comprehension
Which right triangle that has integers for all sides and all sides equal to or smaller than 10 has a perimeter of 24? 


Haskell
[ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, a+b+c == 24]


Scala

for {c <- 1 to 10; b <- 1 to c; a <- 1 to b; if(a+b+c == 24 && (a*a) +(b*b) ==(c*c))} yield (a,b,c)



C#

var result= from c in Enumerable.Range(1, 10)
from b in Enumerable.Range(1, c)
from a in Enumerable.Range(1, b)
where a+b+c == 24 && (a*a) + (b*b) == (c*c)
select a+" "+b+" "+c;


More on comprehensions:
http://patternsinfp.wordpress.com/2012/01/19/comprehensions/
Haskell
[2 * a + b | a <-[1,2,3], b <- [4,5,6],  b `mod` a == 0]


Scala
for{a <- 1 to 3; b <- 4 to 6; if (b % a == 0)} yield(2 * a + b)

Radical Simplicity by Stuart Halloway

Yet another talk by Stuart Halloway, his presentation style and pronunciation are really good. And personally I find it comforting and pleasant to listen to his voice which makes it for me really easy to follow. Putting not too much emphasis on the technical aspects, this talk raises a number of important questions, in my opinion. I want to name two aspects here in a bit more detail:
1. Simplicity
Around 00:53 reflection API Example is given to demonstrate what simplicity means. I think it is important to define, even simple (hu?, ha!) terms like simple because again, it becomes apparent that different people have different meanings and perceptions for terms. Maybe its obvious to some maybe not but simple does not easy or beauty. Now how can we grasp simple in terms of programming or rather API's? The reflection example demonstrates this quite nicely. The API should consist of small reusable parts which can be used to build higher level functionality or abstraction.

In the following he asks: Why we don't have radical simplicity?
And to observe the answer or even pursuing the question is a very worth goal for every programmer.
Stuart names Pressure (about 1:09) and the lack of trust. Could you justify to build 4 Prototypes in your curent/next project (Even if the first worked)? How do we, that is the programmer side and the stakeholder side define and agree on 'good enough'?


2.  (simple) Foundations of programming
On 1:03 these four foundations are listed:

  • functions
  • logic
  • relational model
  • associative model

and it is concluded that all these have a mathematical foundation.  But actually OOP has none. It is pointed out that OO is inherently complex and there could be a potential danger by having features that could do harm if abused. Specifically applied to Java he claims Java is: compound, complex and complicated.

Eventually this talk has inspired me to sharpen my point of view on API's and to question for simplicity in my programming job, consciously.

http://skillsmatter.com/podcast/java-jee/radical-simplicity/js-2051

Samstag, 4. Juni 2011

Code use and re-use

One of the things that may seem trivial is how in software systems reuse is achieved. I'm going to write about some thoughts of mine in this regard.


OOP
I think that most people would agree with the OO(Object Oriented) Paradigm, it is common to use inheritance (implementation inheritance).  So you define code in a class, now if you extend that class from another one you can use the code from the parent class just fine.

Did you reuse the code from the parent class or are you now just using it?


It is quite important to pay attention to this. You can now use the code from the parent class but just in the child classes. So there is a dependency from child to parent class. I would argue that this is code use.

FP
In functional programming reuse is achieved through composition. Which means if you have a function which takes an Int and results in an array of chars and another one which takes an array of chars and results in a String, I can create yet another function which takes an Int and results in a String. Again this seems trivial and one might ask why same can't be done with OOP?

RT
The answer to this is (I guess) referential transparency. The fundamental principal of  FP is that if I  invoke a function with the same arguments I will always get the same result (or type therefore). This guarantees me re-usability.

Code use and re-use is about granularity and scope.  To identify clearly what you need in a specific situation is important.

So these are quite different approaches and there are many other aspects involved (besides re-usability) in software development. But for now I like the FP approach better. Because when composing functions I can rely on referential transparency while with OOP state and functions are usually mixed up.

Mittwoch, 27. Oktober 2010

99 Problems in Scala

99 Problems originated from Prolog [1] but I came across it here [2] where SCala is used to solve the problems.


==03==
def findMe(l:List[Int], i:Int):Int = { if(i==0) l.head else findMe(l drop 1,i-1) }


==04==
l.foldLeft(0) {(a,b) => a+1 }


==05==
def myRev[A](l:List[A]):List[A] = l.foldLeft([List[A]()) { (a,c) => c :: a}


==14==
l.foldLeft(Nil.asInstanceOf[List[Int]]) {(c,a) => (a :: a :: c) }


==15==
def consmore (l:List[Int], count:Int, element:Int):List[Int] = if(count==0) l else consmore(element::l,count-1, element)


==28==
ll=List[List[Int]] = List(List(1, 2), List(1, 2, 3), List(4, 5), List(5), List(3, 4, 5), List(7), List(1, 2, 3, 4, 5), List(1, 2, 3, 4))
val r1=ll.foldLeft(List[(Int,Int)]()) { (a,b) => (b.length,ll indexOf b) :: a}
val r2= r1 sortWith ((t1,t2)=> t1._1 > t2._1)
val finalResult=r2.foldLeft(List[List[Int]]()) { (a,b) => ll(b._2) :: a }


The level of difficulty rises along. So while beeing lazy because I didn't want to solve all 99. I pick P50 as an quick exercise to solving a more complex task with scala.
==50==


class Node(val h:Int, val char:Char){
def this(h:Int) = this(h,'1');
private var left:Node = null
private var right:Node = null
def getLeft() = left
def getRight() = right
def setLeft(k:Node) = {left = k}
def setRight(k:Node) = {right = k}
def setLeftRight(l:Node, r:Node)= {left = l; right = r}
def hasEdge() = left != null || right != null
def isLeaf() = !char.isDigit
override def toString() = h+" L:"+left+" R:"+right
}
import scala.collection.mutable.HashMap
def findFreq(s:String):HashMap[Char,Int] = {
val r=new HashMap[Char,Int];
s.distinct.foreach(x=> r+= (x -> (s count(y => y==x)) ) );
r
}

def sortNodes(a:Node,b:Node) = a.h < b.h

val fr=findFreq(”MISSISSIPPI”)

val t2=(for {b <- fr; fre =b._2; element=b._1 } yield new Node(fre,element)).toList
val r2=t2 sortWith(sortNodes)
def transform(var l:List[Node]) = {
val r=l take 2
if(r.size > 1)
l=new Node(r(1).haeuf+r(2).haeuf)::l
}

Neu gefunden:


[1]http://sites.google.com/site/prologsite/prolog-problems/
[2]http://aperiodic.net/phil/scala/s-99/
[3]https://github.com/etorreborre/s99

Dienstag, 7. Juli 2009

Evaluation Strategy and Laziness

Coming from Java I guess I'm used to "simple" strict evaluation

Scala allows for three kinds of evaluation


  1. List.range(a, b) - strict evaluation
  2. Stream.range(a, b) - lazy evaluation, evaluated once and cached
  3. (a to b) - lazy evaluation, evaluated each time it is used
Call by name parameter

def someMethod(test:Boolean, findMe:String,  expensiveSearch:String ) = {

if(test)
  true
else
 expensiveSearch contains findMe
}

Instead of the type String for expensiveSearch use => String or () => String

You can choose which is most appropriate for your situation.

[2] Refers to a Haskell example which demonstrated that you have to turn your program quite a bit upside down to get real benefit from laziness. Is it worth?

[1]http://dcsobral.blogspot.com/2009/05/scalas-projections.html
[2]http://debasishg.blogspot.com/2009/03/learning-haskell-laziness-makes-you.html

Sonntag, 14. Juni 2009

Practically Functional

A very nice read up by Daniel Spiewak[1].
Scala combines OOP and FP. But how to use FP in practice? Practically Functional gives a fine introduction starting with the following "functional trademarks":

  • referential transparency
  • higher order functions
  • closures
  • immutability

Which then are described as "functional idioms" using a classification that looks like this:
Recursion -> HOF -> Combinators -> Monads
where each Level raises the level of abstraction.

Recursion
If functional programming does not allow loops then how do you do something repeatedly? The answer  is via recursion. To assist the programmer with that Scala offers nested methods.


Higher Order Functions
HOF are functions which take functions as their arguments. Some examples are:

  • foldLeft, foldRight ( catamorphism)
  • map ( "mapping" over a collection)
  • flatMap ( "map" and afterwards "flatten")
Combinators
There are three kinds of Combinators:

  • Sequential ( first a, then b)
  • Disjoint (either a or b)
  • Literal(exactly foo)
Monads
Properties:
  • Typ constructor
  • Single argument constructor
  • flatMap / >>= (bind)

It is really nice to see such eye opening examples which really help you to understand code better and still do the job:

def readPeople(files: List[String]): List[Person] = {
  for {
    file <-files
    props <-readFile(file)
    firstName <-props get"name.first"
    lastName <- props get "name.last"
    ageString <- props get "age"
    age <- toInt(ageString)
  } yield new Person(firstName, lastName, age)
}


[1] pdf file

Samstag, 13. Juni 2009

Ioke

Programming language, that seems like a abstract term because in most cases programmers just use it as a tool in their job. What motivations could be reason for creating a programming language.
Today I watched[1] Ola Bini talking about his creation Ioke. He discusses several properties of Ioke among them how close Ioke normal syntax is to its AST representation or Homoiconicity[2]

[1]http://blip.tv/file/2229441
[2]http://en.wikipedia.org/wiki/Homoiconicity