Friday, May 30, 2014

Case study in Scala: Avoiding imperative programming (does it pay off?) -> Part 1, The Ugly

Just for fun, let's consider the imperative example of counting words in a string, as presented in the Chapter 17 of Programming in Scala book by Odersky et al. In it, we have:

scala> def countWords(text: String) = {
  val counts = mutable.Map.empty[String, Int]
  for (rawWord <- text.split("[ !.,]+")) {
    val word = rawWord.toLowerCase
    val oldCount =
      if (counts.contains(word)counts(word)
      else 0
    counts += (word -> (oldCount + 1))
  }
  counts
}
countWords: (String)scala.collection.mutable.Map[String,Int]
 

scala> countWords("See Spot run! Run, Spot. Run!")
res30: scala.collection.mutable.Map[String,Int] =
Map(see -> 1, run -> 3, spot -> 2)
 

Let's try and do it in a recursive/functional way, without mutable Maps:

scala> def countWords(s:String):Map[String,Int] = {
   def countW(str:List[String], 

              acc:Map[String,Int]):Map[String,Int] = {
     if (str.isEmpty)
       acc
     else {
       val k = str.head
       if (acc.contains(k)) {
         val wCtr = acc(k)+1
         countW(str.tail,acc-k+(k->wCtr))
       } else
        countW(str.tail,acc+(k->1))
     }
   }
  countW(s.split("[ !,.]+").toList,Map[String,Int]())
}
 

scala> countWords("See Spot run! Run, Spot. Run!")
res21: Map[String,Int] = Map(see -> 1, spot -> 2, run -> 3)

Neither of these implementations are pretty. The recursive one essentially does the same thing as the iterative one but it does it in a "clunkier" way - we actually have to throw out the (String,count) pair and re-add it every time the same word is encountered. However, it does the job,

Let's see if we can improve on this in the next installment.

Thursday, May 22, 2014

Hacking on a FreeBSD port

I have been trying to check out the CURRENT branch of FreeBSD so that I can start playing with the kernel - ran into a tiny problem: for some reason FreeBSD folks use subversion (yuck) to manage the code. The port of subversion in the ports tree, however, segfaults on my machine. It does generate a core so I recompiled the port with debug symbols and then ran gdb on the program and the core file and got a file/line within the file where it is segfaulting. All I want to do is insert a printf() statement there.

Below is the sequence of commands to do it - I am sure there are better ways but hey...

(as root):

cd /usr/ports/

make clean distclean fetch

make extract

cp work/(path/filename) work/(path/filename).orig

vim work(/path/filename)
make the change
wq!

make makepatch (this will add your change to /usr/ports//files/ for "next time")
rm -rf work

make fetch
make extract
make build

The produced executable under /usr/ports//work/ should now have your change in it.

Wednesday, May 21, 2014

FreeBSD ports compile with DEBUG symbols (so you can gdb the core files later ;)

make WITH_DEBUG=yes STRIP= install

After this, if your port's executable generates a core file you can do
gdb /usr/local/bin/(port executable name) ~/(port executable name).core