Sonntag, 11. Januar 2015

A software engineer does for a dime what any fool can do for a dollar - SICP Finished

Done! Done! Really, no kidding. It took longer than expected but eventually I'm done with my self study of the online material of Computer Science 61A, Spring 2014 edition. The course is a modernized version of the material in "Structure And Interpretation Of Computer Programs" (SICP).

For more informations on why I initially started the course see my post from March 2014.

This post is about my lessons learned, findings and experiences.

General Software Engineering Findings

A great quote from the lecture (for a geek T-shirt maybe?): A software engineer does for a dime what any fool can do for a dollar.  The key to such an efficiency is abstraction and separation of concerns.

This wasn't knew to me but it was good to see that those concepts were not invented by the "object-oriented people". They've made the idea popular but you also can achieve nice abstraction layers in your code by only using functional programing, see this section of the original SICP book for a good example.

Recursive Thinking

Before I started the course I probably never wrote a recursion - at least not by intention. In SICP recursion is an important concept and I had solve many different exercises on that topic. Over time I believe I can say I've adopted the recursive thinking.

The most important idea here is the leap of faith. This is a way of thinking which help dealing with recursion: Since it is hard to play a whole recursion through in your head (particularly for complicated tasks) develop your code with a simpler variant of the original problem in mind and believe that the recursion will also work for the more complex variants.

Read Eval Print Loop (REPL)

These days I wouldn't start a bigger programing project without having a REPL available. A REPL gives you an interactive way to try out some pieces of code before adding it to your actual program.

Ideally you can interact with your programming language line by line - like in Python: Type in python and you're inside the REPL where your can program interactively. For Javascript on the server side node.js offers something very similar. For client side Javascript just use the console of the browsers development mode (F12).

For Java I utilize the Eclipse Scrapbook, for C I sometimes use codepad.org. Those last two examples are no REPLs since they are not interactive but at least they provide some convenient way to try out code. For C I might use straight gdb next time - we'll see how well that goes.

Functional Programming

SICP is heavily relying on the power of higher order functions. That is due to the Scheme heritage of the course material. In the original SICP book (the wizard book) the possibility to assign values to a variable is mentioned somewhen in the middle of the book. This modern version of the course is not as puristic.

The further you work your way through the course material you see functional programming being used side by side with classic procedural and object oriented programming. In my opinion this is what makes Python such an interesting language: you pick the programing paradigm (the tool) which fits best for the job to be done.

I did some Javascript coding recently and used this occasion to re-read Eloquent Javascript. After having taking SICP this whole fuzz about Javascript functions is now much less confusing. The syntax could be more elegant though ;-)

Object Oriented Programing

Due to my efforts in structuring my work code I was aware of Abstract Data Types (ADT) before. In the course we've pushed this idea further: We've been using Python to implement an own object model including inheritance. This object model stood beside the build-in OO-features of Python.

This was an impressive and eye opening experience. Now I eventually know how to give the bash OO-capabilities ;-)

To quote the teacher, Professor Hillfinger: Object oriented programing is just a disciplined way to structure your programs.

Declarative Programing

The last quarter of the course had a huge emphasis on declarative programing. We've learned the concept, discussed a simple interpreter of a small invented declarative language written in Python. This language was a mix of Prolog (the structure) and Scheme (the brackets).

I saw that this is a very different way to approach solving a problem and that you should be aware of it. However, for my taste we've spend too much time on coding exercises with this little academic teaching.

Python as The Courses Main Language Language

Many years back my first programing language was Perl which impressed me with the power of a couple of code lines. Python is for me Perl done right - a multi purpose high-level scripting language with an easy to read syntax. At least Python doesn't share Perl (bad) reputation for cryptic one-liners.

Writing some Java after having done Python makes me feel like "Is the handbrake still pulled?" - not to mention my emotions going from Python back to application programing in C.

Scheme - Your Fathers Brackets

The original material of the course was entirely held in Scheme. In the new version the main programming language was Python but Scheme was still very present.

After doing some Scheme syntax and coding exercises the last project was about writing an own Scheme interpreter in Python. I wouldn't say that I'm now an expert in designing programming language but if I would ever get the task to implement an own language I definitely have a clear idea of the basic concept - a constant (meaning recursive) evaluation and application of a stream of input tokens.

This concept is so fundamental that it made it on the originals book title:
Quelle: http://icampus.mit.edu/files/2011/12/xTutor1.jpg
I have to say that I haven't become a big Lisp/ Scheme enthusiast. I still found the syntax rather confusing. However, I can image that it could be fun coding a bigger project and thus spending more time with the language..

Time Management

I started the course when I was off on parental leave for two months. At the beginning of that time I appointed one full day per week for the course work, in the second month I increased to two days per week. Additionally, I was watching the lecture screencasts in the evenings at home.

To stay focused I tried to study at my local universities library as often as I could.

When I started working again things slowed down. I tried to shift my study time to the evenings but my performance is not the best after 8:30 pm, particularly when you're not "just coding" but trying to solve tricky lab tasks. Additionally, work (a lot of mighty C programming) was quite involving.

The trick was to believe in small steps and to celebrate every complete homework, discussion or lab assignment.

At the beginning I tried to do all homework tasks, also the extra credits. When I saw my pace going down I decided to be just an average student and to focus only the compulsory work. My pace increased again and I realized that to be average in my situation was a good decision. It was my trade off being a full time worker, committed family father and a remote student at the same time.

Self Paced Learning

The course wasn't designed as a self study course. However, the lecture screencasts where great, I watched them all, some of them more than once. I found out that my brain digests new ideas better if new material is first presented/ explained to me and then I start practicing on my own.

The study guide Composing Programs also helped a lot to approach a topic from a second side (first listen to the screencast, second read in the book).

When we've learned about environment diagrams, the Online Python Tutor was very helpful.  It's basically a graphical debugger for smaller code snippets which nicely illustrates the environment frames involved  and their content.

Most of the hands-on assignments (labs, homework, projects) came with unit tests which described the intended behaviour of the functionality to be implemented. This way I could always check my implementation. Solutions were also available (with the exception of the projects).

Maybe the biggest problem for me was the lack of support from somebody else. As an enrolled student there are assigned teaching assistants (TAs) to help you. If I had questions I only had the Google search on my side which wasn't always as effective.

Particularly when I got into writing recursive functions I was sometimes fighting for hours to finish a task. Of course I only could have looked up the solution but this wasn't my intent - the whole purpose of my studies was to deeply understand the material.

Bigger projects where intended to be work on by small teams. As a one man team I did all the tasks on my own. This was also one reason why I took my longer then planned to finish the course.

Next Steps And Follow Up Courses

Online courses are great. They have their limitation once you get into project or group work. But e.g for learning a new programming language or library sites like codeschool.com are nowdays first choice for me. Infact, I would rather take a week off and work my self through a quality online course than attending a real life training. Check out this AngularJS course as an example for what I mean.

I was a bit disappointed that CS169.1x had already started when I finished: CS169.1x teaches the fundamentals of software engineering using Agile techniques to develop Software as a Service using Ruby on Rails. They have now the archived material available so I might work my self through that course again - we'll see.

Conclusion

It was fun and I definitely would do it again. Also for me the modern Python version of the course was more appealing than the pure text book based study of the old Scheme book.