Smalltalk’s design and existence is due to the insight that everything we can describe can be represented by the recursive composition of a single kind of behavioral building block that hides its combination of state and process inside itself and can be dealt with only through the exchange of messages. Philosophically, Smalltalk’s objects have much in common with the monads of Leibniz and the notions of 20th century physics and biology.
Its way of making objects is quite Platonic in that some of them act as idealizations of concepts - Ideas from which manifestations can be created. That the Ideas are themselves manifestations (of the Idea-Idea) and that the Idea-Idea is a-kind-of Manifestation-Idea which is a-kind-of itself, so that the system is completely self-describing would have been appreciated by Plato as an extremely practical joke [Plato]
If you have a desk job, you probably have come across ergonomic chairs and desks and what not.
In my opinion, the simplest commandment to prevent injuries arising out of bad posture is “Stand up and stretch!”
Stretching regularly is easier said than done, because you might often get into a flow state (which in itself is a very good thing!) for long periods and forget to do it.
So, I have setup a simple reminder on my Mac that tells me to “Stand up and stretch” every 30 minutes.
I found it was super easy to set this up using AppleScript, and thought I’d share it with the world.
So, if you are a Mac user, open up the AppleScript editor (comes pre installed on OS X, just search with Cmd+Space) and paste this simple code snippet:
Run the script you just created and voila you have a reminder that will be spoken out loud every 30 minutes!
This was a slow week for SICP. I managed to read 20 pages (thru section 1.1.6) and solve exercises 1.1 thru 1.5. As an aside, I also read the foreword by Alan Perlis which was a pleasure to read and the preface to both the first and second editions (both worth reading IMO).
I find the book incredibly dense with insights and learnings and am happy to read at a leisurely pace absorbing as much as I can.
The 1st chapter titled Building Abstractions with Procedures begins with a quote:
The acts of the mind wherein it exerts its power over simple ideas are chiefly these three: 1. Combining several simple ideas into one compound one, and thus all complex ideas are made. 2. The second is bringing two ideas, whether simple or complex, together, and setting them by one another so as to take a view of them at once, without uniting them into one, by which it gets all its ideas of relations. 3. The third is separating them from all other ideas that accompany them in their real existence: this is called abstraction, and thus all general ideas are made.
It seems that abstraction is going to be a strong theme through the book. We dive into things with an introduction to ‘computational processes’ and by introducing the Lisp programming language.
One section of note asks the question: If Lisp is not a mainstream programming language, why are we using it as the framework for our discussion of programming?
The answer: Lisp descriptions of processes, called procedures, can themselves be represented and manipulated as Lisp data.The importance of this is that there are powerful program-design techniques that rely on the ability to blur the traditional distinction between "passive" data and "active" processes
The next section begins with the general idea of language itself:
… Every powerful language has three mechanisms for accomplishing this:
primitive expressions -> which represent the simplest entities the language is concerned with. means of combination -> by which compound elements are made from simpler ones, and means of abstraction -> by which compound elements can be named and manipulated as units.
Last week, I read a bit about the lambda calculus *PDF and realized that the above is in fact a translation into English of the formal definition for lambda terms! Very interesting to note that the document linked above states clearly that the two branches of programming languages - The Fortran derivatives and The Lisp derivatives are essentially manifestations of the Turing Machine (Alan Turing) and the Lambda Calculus (Alonzo Church) respectively. Math is awesome stuff indeed :)
The rest of the sections introduce the Scheme dialect of Lisp, which seems to be easy to pick up once you get used to the prefix notation and parentheses!
The concept of tree accumulation, substitution model and the examples of applicative order and normal order substitution are introduced with examples.
The application of these concepts is made clear in example 1.5 whose solution I have pasted below:
I am not sure about the format for these notes. They will probably evolve as I continue reading. But for now, they are akin to a chronological walk through the book itself.
I have been wanting to read
SICP for a
while now, and I had gotten started last year but didn’t get past
chapter 1. This time I intend to read it through. So I’m setting
myself a quest of reading SICP through. Each Monday I will blog
about the progress I made in the previous week. I will also push my
solutions written in Scheme to my Github repo
I was looking around for others who might have done the same and found
two most excellent folks:
Eli Bendersky
and
Bill the Lizard
who have walked the walk and been meticulous about blogging their
learnings along the way.
To begin the quest, I am going to put forth my goals quoted verbatim
from
Eli
(because it doesn’t get any clearer than this):
Read the book
See all the video lectures by Sussman and Abelson themselves
available from
here
Do most of the interesting exercises in the book
Do some of the larger projects listed
here and
here
That said, I spent my first day getting things setup. I now have a
Github repo to host my solutions, an Emacs setup with Scheme mode and
a Scheme REPL (which I got out of the box!) and a physical copy of the
book (I’m old school like that!).
I’m excited about this quest and hope to be regular at it. If any of
you is following along, please do pester me if I don’t post at regular
intervals!
On my current project, after a bit of prodding by Sunit we decided to experiment with using a virtual
machine setup managed through Vagrant and Virtual Box for our development
environment.
In this post I will try and outline the pros and cons and
lessons learnt over the past week while pairing with
Ginette and setting up our own VM
managed with Vagrant.
Why Vagrant?
Our project uses Rails with Postgres and Nginx/Passenger. We also use RVM to manage Ruby versions.
The reasons to use Vagrant were primarily these:
Use one VM per project without cluttering your main machine with the sundry dependencies (MySQL, Postgres, Redis,
Apache, Nginx, Passenger, et al) that projects invariably have.
Have a 5 minute setup for any new developer who joins our team to
get up and running. This should be as easy as running a single
command: vagrant up. No installation, no troubleshooting. It
should “just work” ™
Have a consistent environment across all developers machines.
Have a simple command line based workflow: vagrant up, vagrant ssh,
vagrant halt
Create reusable configuration scripts using Puppet that could be used on Test/Staging and Production environments as well. (Ambitious)
TL;DR version
Advantages
vagrant up“just works” ™ ! Excellent for hiding details and
letting people focus on GTD. This also improves productivity by
avoiding “it doesn’t work on my machine” delays! Because everything
“just works” ™ on the VM.
Setting up a Vagrant base box
is not hard. If you setup a minimal base box with a operating system
(sans GUI) and SSH, you can reuse it on every project and do the provisioning through Puppet/Chef.
We recommend using a pre-existing base box, installing dependencies
with a package manager (apt-get, etc.) and then hosting it somewhere
on your local network for fellow devs to use as a pre-packaged VM.
This is a quick and easy way to get setup.
Disadvantages
Our biggest roadblocks were with getting Puppet to do our bidding. We
tried to reuse existing Puppet modules for installing dependencies.
We managed to get RVM and Postgres installed through Puppet.
But we just couldn’t seem to get Nginx/Passenger to work.
Puppet modules tended to be either poorly documented / not
maintained or just did not work! Maybe we were doing something
wrong, but it was really hard to tell!
Base boxes for your choice of operating system might not be readily
available! (This is not a major disadvantage as it is quite easy to
create your own base box, but it is time consuming)
Background
We started by watching a short but informative
presentation by Cyril
Rohr about using Vagrant with Puppet. It was enough to convince us to
pursue the magical vagrant up!
How to setup Vagrant
Just follow these simple
getting started
instructions on the Vagrant site. You can try it out using the
lucid32 base box that the creators of Vagrant have provided. If the
setup was easy enough, you should already be convinced that Vagrant is
a useful tool ;-)
Customizing the VM for your project
Setting up Vagrant was easy. The more complicated part was
setting up a Virtual machine for use on the project.
There were two strategies that we thought of:
Create a fully loaded base box with all the dependencies pre-installed. This base box can be hosted on a URL that can be
shared with the team and added to the Vagrantfile as well. The first
time someone does a vagrant up, the base box will be downloaded to
their machine and stored locally.
Create or reuse a minimal base box with only the OS and SSH
installed. Provision the dependencies for your project through
Puppet/Chef. Ideally reuse existing Puppet modules/Chef recipes.
Option 1 is relatively easier and faster for these reasons.
There are quite a few base boxes that people have already created and
shared on the Vagrant Boxes site.
It is straightforward to use a package manager (apt-get, et .al) to
install whatever you need on the base box
Once your installation is done, you can freeze it on the VM
and no one else needs to do it. So less troubleshooting, etc. is likely.
Option 2 was more interesting because we wanted to experiment with
Puppet! So thats what we went with. Here is our experiences:
Puppet uses the concept of Resource Abstraction Layer to abstract
away OS level details for resources like: Files, Packages, Services,
Users, Executables and so on.
Puppet provides a language to specify configuration and one can
maintain a “manifest” file with per-project requirements.
Puppet modules are a way to reuse other people’s code to avoid the
nitty-gritty of setting things up. There is a PuppetLabs module
repository as well as a number of modules available on Github.
However, we were not too happy with the documentation and support
for most modules that we used.
We ended up using Puppet modules for RVM and Postgresql
installation. In order to tell Puppet to install RVM, all we needed
to do was: include 'rvm' in our Puppet manifest. The same was true
for Postgresql.
In conclusion, we realized that Puppet modules are nothing but
collections of OS specific installation instructions for various
packages and services. It is not too difficult to write your own
module that delegates to the OS you are using. And that is probably
a better way to go than rely on some obscure module that might not
be properly tested/maintained.
Bottomline/Conclusion
Using Vagrant to manage VM’s is a great idea.
However, until I become a Puppet/Chef expert or I there is one on the team, I would go for a fully-loaded base
box option it is less time consuming.
I am planning to re-start reading
SICP, so I
was looking around for some online course structure that I could
follow. I found that UC Berkeley offers a course
CS 61A titled SICP which uses Python
as the language of instruction rather than Scheme. I was going through
the course page and found a rather interesting homework problem
Pick a positive number n
If n is even, divide it by 2.
If n is odd, multipy it by 3 and add 1.
Continue this process until n is 1.
The number n will travel up and down but eventually end at 1 (at
least for all numbers that have ever been tried – nobody has ever
proved that the sequence will always terminate).
The sequence of values of n is often called a Hailstone sequence,
because hailstones also travel up and down in the atmosphere before
falling to earth. Write a function …
I have always been fascinated by the shapes generated by equations, so
I wanted to ‘see’ this hailstone shape for myself. I wrote a
little Ruby script to generate a hailstone sequence.
I generated the sequence for the first 100 numbers.
I then used the Grapher utility on the Mac to plot the resulting series. I found
that the shape was like a sawtooth curve, oscillating up and down for
a while before gracefully dying down to 1. This behavior was
pronounced for odd and prime numbers more than even numbers (which
tend to damp down quicker). Here’s a picture (click image to enlarge) of the hailstone series
for 11, 59 and 89 (all odd and prime by choice):
I stumbled upon an
interesting article
about Bertrand Russell’s philosophy. Here is a ‘Note to self’ that is
probably going to be one of the foundations of my lifes philosophy!
Perhaps the essence of the Liberal outlook could be summed up in a new decalogue, not intended to replace the old one but only to supplement it. The Ten Commandments that, as a teacher, I should wish to promulgate, might be set forth as follows:
Do not feel absolutely certain of anything.
Do not think it worth while to proceed by concealing evidence, for the evidence is sure to come to light.
Never try to discourage thinking for you are sure to succeed.
When you meet with opposition, even if it should be from your husband or your children, endeavor to overcome it by argument and not by authority, for a victory dependent upon authority is unreal and illusory.
Have no respect for the authority of others, for there are always contrary authorities to be found.
Do not use power to suppress opinions you think pernicious, for if you do the opinions will suppress you.
Do not fear to be eccentric in opinion, for every opinion now accepted was once eccentric.
Find more pleasure in intelligent dissent than in passive agreement, for, if you value intelligence as you should, the former implies a deeper agreement than the latter.
Be scrupulously truthful, even if the truth is inconvenient, for it is more inconvenient when you try to conceal it.
Do not feel envious of the happiness of those who live in a fool’s paradise, for only a fool will think that it is happiness.
One of my life goals is to be an excellent programmer. I believe Peter
Norvig when he says that it takes a
lot of time (10 years?) and effort to get there!
In order to achieve a mastery over the craft (and computer programming is
definitely a craft!) it is important to continuously grow and improve.
The million-dollar question is HOW? How do I go from here to there?
I am going to start with the beginner’s mind approach. What if I knew
nothing about computer programming and had to start from scratch? What
would I do? I have been reading about
deliberate practice
and I’m convinced that it is the only way to go from here to there.
Deliberate practice can be briefly summarized as below (excerpt from
Cal Newport’s blog):
It’s designed to improve performance. “The essence of deliberate practice is continually stretching an individual just beyond his or her current abilities. That may sound obvious, but most of us don’t do it in the activities we think of as practice.”
It’s repeated a lot. “High repetition is the most important difference between deliberate practice of a task and performing the task for real, when it counts.”
Feedback on results is continuously available. “You may think that your rehearsal of a job interview was flawless, but your opinion isn’t what counts.”
It’s highly demanding mentally. “Deliberate practice is above all an effort of focus and concentration. That is what makes it ‘deliberate,’ as distinct from the mindless playing of scales or hitting of tennis balls that most people engage in.”
It’s hard. “Doing things we know how to do well is enjoyable, and that’s exactly the opposite of what deliberate practice demands.”
It requires (good) goals. “The best performers set goals that are not about the outcome but rather about the process of reaching the outcome.”
So, I must identify deliberate practice activities that I perform on a
regular basis, get feedback and get on a path.
The really hard question is determining good goals. This is where a
mentor can play a part.
My next post will be about what specific goals I have set up for
myself in the days to come and how I intend to apply the principles of
deliberate practice to get from here to there!