1.1.13

A Linguist trying to Program??

I've been writing miscellaneous scripts in Python for a little over two years now.
I am getting to the point where I can sit down and code a simple and bug-free program in a couple of hours. I, however, always have doubts lurking in the back of my mind whether my skills are in fact adequate, due to a lack of formal training in computer science. At the same time I know I do not right now have the time and energy to go "hardcore" into software design. In fact, it took me a long time to formulate what exactly I thought I was missing in terms of programming. What I think right now is that I need some practice designing algorithms and being able to structure a set of tasks efficiently and within a reasonable time frame.
 Some friends more experienced in the field recommended I work my way through the apparently notorious book Structure and Interpretation of Computer Programs (referred to SICP for brevity according to the general convention). I decided to give it a spin this break.
To the dismay of some of my friends and family members, I spent Christmas reading that book and writing small snippets of Scheme.

First of all, I am thoroughly surprised why introductory computer science courses are not taught in LISP. Its syntax is so simple that one understands the principles of assembling LISP statements within the first hour of reading. I am definitely treading dangerous waters here, trying to weigh in on a discussion about which language should be used to introduce people to computer science. What I am saying here is purely an opinion, not a particularly informed one, to be honest. It is, however, a starting point and I would like to record it, even if only to laugh at it a few years down the road. It seems to me that the usefulness of LISP as an introductory language lies precisely in its simple syntax and the apparent uselessness, when it comes to real-world applications. I think this provides a nice break from the constant interfacing of libraries with user input (be it prompts of files) with yet more libraries that seems to characterize quite a bit of programming today. Instead one focuses more on the actual procedures and processes being discussed and not on reading endless APIs.

I was actually so impressed with the apparent simplicity of LISP syntax, that I decided to write an interpreter for it in Python. This turned out to be a tougher undertaking than I thought and deserves its own post in the future. A quick glance at Peter Norvig's take on the problem seems to indicate that I'm on the right track, however.



But enough of my ruminations, I originally wanted to share what I've learned so far. I would like to start with mentioning that I have been trying to diligently do the exercises in the book, thus my progress has been slow and in a little under a week of more or less continuous reading I have gone through only the first two chapters.

First of all, understanding recursion in its fullness was very exciting. I especially liked that almost any recursive process can have an iterative implementation (see this thread for some examples of recursion that cannot be made iterative), something that should be more resource-friendly in real-life applications of recursion. Tree and list traversal were the tasks I found most difficult to conceptualize and implement, so I will need to revisit those.

Another concept I found mind-stretching was data abstraction. I have heard the term thrown around here and there, probably even looked it up on Wikipedia sometime in the past. SICP covers it fairly rigorously, however.
What I frankly found enlightening was the fact that procedures can be abstracted over either operations or data types. For example, we can try to define a generic operation procedure that will then be performed slightly (or not so slightly) differently depending on the data type of the input. If we wanted to abstract over data types, however, we'd essentially have to define a data type as a procedure that takes another procedure as an argument and modifies its execution based on the constraints we set for that data type.

Well, that's about as far as I've made it so far. After 4 or 5 days of work I have a little under a hundred lines of mathematical operations in LISP and a semi-working python Scheme interpreter.



P.S.
While rummaging in the Internet, I found this post. Turns out even MIT has moved away from using LISP. Am I really 30 years behind?

1 comment:

  1. First, read this (http://blog.aegisub.org/2008/12/if-programming-languages-were-religions.html), because it gives us a much funnier vocabulary with which to talk about programming languages.

    Now, as a Jewish Zen Buddhist who has spent enough time around Fundamentalist Christians to figure out how profoundly f***ed up they really are, I think you're largely on the right track here, and props to you for trying to write a Scheme interpreter in Python I mean Humanism. As for why Scheme isn't taught in intro CS classes, I like Joel Spolsky's explanation (http://www.joelonsoftware.com/articles/ThePerilsofJavaSchools.html):

    "Years of whining by lazy CS undergrads like me, combined with complaints from industry about how few CS majors are graduating from American universities, have taken a toll, and in the last decade a large number of otherwise perfectly good schools have gone 100% Java. It's hip, the recruiters who use 'grep' to evaluate resumes seem to like it, and, best of all, there's nothing hard enough about Java to really weed out the programmers without the part of the brain that does pointers or recursion, so the drop-out rates are lower, and the computer science departments have more students, and bigger budgets, and all is well."

    In other words, you haven't missed much by not getting a deep CS background, since UMass' CS department fails at all the things.

    One good place in addition to SICP to build your programming chops is Stanford's CS107 class (which you can find on Youtube), specifically the C, assembly, and Scheme lectures in that order. Jerry Cain does an amazing job of explaining pointers in C and how they relate to actual memory addresses in the machine, something that, as I recall, isn't discussed in SICP.

    Finally, and I may not have much more software engineering background than you do (UMass' software engineering class and this project I worked on in Kyrgyzstan (https://bitbucket.org/iamsultan/django-monitor/)), but real-world software development really is 40% "reading endless APIs", 40% debugging, and 20% "trying out different inputs and seeing how the code reacts". That last 20%, however, is what separates the boys/girls who went to JavaSchools from the men/women who had something like 6.001. The latter category produces code that is much easier to read and maintain, and it's the kind of code you need to write for fun things like OSes, compilers, networks. Remember, always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.

    Hmm, most of this was a rant, but I hope you got something helpful out of it. Feel free to respond, I love to talk about this sort of thing.

    Mazel Tov!

    ReplyDelete