Monday, September 14, 2009

SICP digital circuit simulator in scala Part II

Please first read part-I of this post to get the context.

Here I am comparing the differences between my version of the simulator and Martin Odersky's version presented in his book "Programming in Scala" in chapter-18(Stateful Objects).

Overall, It is same as my version(we both are porting the same thing from same source :)). But, yet there are some differences worth noticing..

1. Inside the Simulation class(in my code its the Agenda class), he defines a type
type Action = ()=>Unit
What this does is that it creates an alias Action for the type procedure that takes no arguments and returns Unit. Now he can use Action instead of ()=>Unit everywhere and this enhances readability of the code. I did not know of this concept because its covered in a later chapter(20) in the book and I'm at chapter 18 :).

2. Another trivial difference, He made afterDelay procedure a part of Simulation class itself... I could have done same and its better.

3. He used currying in afterDelay so as to make the calls look as if its a built-in syntax. I don't agree with it... As a code reader I would not want to be confused into understanding a method call as language syntax. But, may be, As I get more experienced with this concept... I'll probably change my stand.

4. Trivial, but he exposes the usage of @unchecked in the match expression when getting next item on the agenda to suppress the warning that case set is not exhaustive as we no for sure that the missing case in question is never gonna happen.

5. Whenever I wrote scala classes and there was a collection(let say List) to be stored, I had two choices...
val l:mutableList
var l:immutableList
Now here is the conflict.. functional style says
- Prefer val over var
- Prefer immutable object over mutable object
As you can see, We can't have both here.
In the Wire class, author choses the second approach of using immutable object with var reference for storing actions. Incidentally I did the same in my code, I was not sure about my decision at the time of doing it but seeing him making the same choice tells me which rule to give preference to in case of conflict :).
However, The reason I chose immutable object was that I felt if its a mutable object and my reference(actions) is exposed publicly, anyone can get hold of it and modify the object(actions List) without Wire knowing about it.

6. The most visible(and important) difference is in the way how he managed agenda items. I implemented it exactly same as in SICP by making Segment(a pair of time, Queue) stored in a priority queue. But, he simplified it. He stored items simply in a single list making sure a new item with smaller(not matching any other item time on the list) time is added before the next later time item in the list. And, a new item is added in the end of other items added for the same time so that they are accessed in FIFO order. Now, accessing the items is so simplified.

7. For constants like delays, he uses the naming convention(described in the book also) of keeping first letter capital as in ConstantVariable.

The biggest learning for me(from point 6), I guess, is that when I port... I more or less map the code from one language to another without changing any implementation detail conceptually. I should actually see if the some implementation detail can be simplified due to new target language features or simply because it can be simplified.

2 comments:

  1. "The biggest learning for me(from point 6), I guess, is that when I port... I more or less map the code from one language to another without changing any implementation detail conceptually."

    Bingo!
    This is what I was saying about the other Scala project you were working on.
    It is key to understand each languages's abstractions and use them.

    Good Work! And doing a before after comparison to a master programmers work is a great way to improve your coding style.

    ReplyDelete