If a million monkeys were to type on a million typewriters, would one of them produce Hamlet? That’s the boring question. The intresting one is what would they produce the rest of the time…
RSS icon Email icon Home icon
  • Bugger!!!

    Posted on July 3rd, 2008 silverback No comments

    No net connection for a couple of days, so couldn’t update the blog. Looked at it sunday only to find out that znetindia had let the server that was hosting my home directory go down. Bugger! The blog couldn’t be accessed, and nothing else. In a panic, I deleted my original database, only to find out later from znetindia that the server had only gone down. Oh! and they don’t provide shell access. Finally after a lot of work back up today. Stick with me. I have a couple of ideas for a couple of books that  I think I would start writing soon…

  • Lessons in Language Design III

    Posted on July 3rd, 2008 silverback No comments

    Consider a class written in Ruby.

    class Sandwich
    def  initialize(type_of,rate)
    @type_of=type_of
    @rate=rate
    end
     
    def print_details
    print "A #{@type_of} sandwich costs #{@rate}  Rs."
    end
    end

    Brilliant!!! So here you have a simple class that can make a new person who has a name and print the person’s name.

    1
    2
    
    s=Sandwich.new("Vegetable",30)
    p.print_name

    And the answer unsurprisingly is:

    A Vegetable sandwich costs 30  Rs.

    Now consider returning change. The amount of change you get for a 100 depends on the kind of sandwich you got. A vegetable sandwich will net you 70 Rs. change while a chicken sandwich should get you 50 Rs. (the chicken sandwich costs you 50 bucks). So if you were to write it in code…

    class Sandwich
    def  calculate_change(amount)
    change=amount-@rate
    end
    end
    c=Sandwich.new("Chicken",50)
    print  s.calculate_change(100)
    print c.calculate_change(100)

    And the answer unsurprisingly is:

    70
    50

    Now consider a closure. A closure is an intermediate point of time between defining a function and calling it when on or more arguments have been fixed but the others haven’t.  For every language there are two phases when you call a function. Then function definition where the parameters of the function are defined and then there is a binding phase when the actual arguments are bound to the function. Errmm… Consider the following function:

    def  print_stuff(x)
    print "Hello"+x
    end

    Now print_stuff takes a parameter x. When the function is first defined then it’s a function that has a single parameter named x. Later when you call the function like this

    print_stuff  ("World")

    then the compiler/interpreter binds the value of x to "World", which is another way of saying that it makes print_stuff believe that x is "World". The act of binding of course raises a few questions:

    • When does x start to be “World”
    • When does x cease to be “World”
    • If x had been defined previous to the function call to be 123 then what happens when the function ends

    There can be different answers to these questions, and each leads to a particular flavour of implementation and hence to a particular feature of a language. Now a closure is a particular function that has bound one of it’s parameters to a specific value while the other parameters can be modified. Consider the following function:

    def  calculate_change_for_vegetable_sandwich
    return Proc.new{|amount|  amount-30}
    end

    So calculate_change_for_a_vegetable_sandwich gives you a function that takes a parameter which is the amount you pay and returns back the amount -30. You could create a similiar function for chicken sandwiches…

    def  calculate_change_for_chicken_sandwich
    Proc.new{|amount|  amount-50}
    end

    and call these two functions like this:

    change_for_chicken=calculate_change_for_chicken_sandwich();
    change_for_vegetable_sandwich=calculate_change_for_vegetable_sandwich();
    change_for_chicken.call(100);
    change_for_vegetable_sandwich.call(200);

    and not unsurprisingly the answers are:

    50
    170.

    Now can you generalize the calculate_change_method?

    Of course you can. Here’s how:

    def  caluclate_change(price)
    Proc.new{|amount| amount-price}
    end
     
    calculate_change_for_chicken=calculate_change(50);

    Which means that the calculate_change method takes the price as 50. Binds price to 50 in the function created inside it and returns it. WooHoo!!!

    Now let’s see if we can generalize it further still….

    def  make_Sandwich(type,rate)
    self=[]
    self[0]=type
    self[1]=rate
    self[2]=Proc.new{print  "A #{self[0]} sandwich costs #{self[1]} Rs\n"}
    self[3]=Proc.new{|amount|  amount-self[1]}
    return self
    end

    So now you could do:

    s=Sandwich.create("Vegetable",30)
    s[3].call(100)

    Can you see the similarities with a class. In fact a class is basically syntactic sugar for being able to say s.calculate_change(100) instead of s[3].call(100). Which brings me to the epiphany of the day. All that C++ did over C was to introduce closures to the language and the syntactic sugar to enable classes. Which is also why people who program in lisp laugh when you talk to them about OOPS. They already have it and they seem bewildered that any language language took so much time to implement something so simple could be so widely esteemed. It seems a little stupid as it indeed is.

    A class for those intrested in linguistics seems to do to the language what pronouns do. It makes a handy reference to the object in discussion, while at a meta-level you can talk about the properties of all instances which satisfy the conditions necessary to belong to a class. Sheer luck in naming a feature, but a class does seem to very closely satisfy the dictionary meaning of class.

  • Lessons in Language Design II

    Posted on July 3rd, 2008 silverback 1 comment

    All languages are basically lisp, which is basically a notational structure for lambda calculus. More like Chomsky’s universal grammar. :) Now the question is: what are the fundamental axioms and theoroms of lambda calculus that are necessary and in themselves sufficient for Turing completeness.

  • Lessons in Language Design I

    Posted on July 3rd, 2008 silverback No comments

    There are no isolated computations. They are all continuations of the previous one. When I say
    a=a+2, it doesn’t just stop with incrementing a. What I do is merely pass the result onto whatever comes next. And what if it is the last line of the program. Then I pass it onto the exit continuation. Which continues with whatever the universe is doing! Thank you! I think I understand eternity a little better now.

  • Snoop

    Posted on July 3rd, 2008 silverback No comments

    Okay! I just finished implementing a new language called snoop. Dedicated obviously to my patient wife who has dealt with all the hacking with patience and sensitivity. Snoop doesn’t do much. It was an exercise to understand two three things pretty well. And boy! I have understood that stuff pretty well. Shamelessly inspired by Scheme in 48 hours,  Snoop is a little like javascript, a little like Lisp and a lot like a platypus :).

    Source code will be posted soon. :)