Sunday, April 06, 2008

I was speaking with a friend the other day and we were talking about the interaction of effects and how to explain them.

One informal way to explain some additions to languages are that they are scale down localized structured versions of features that were largely available for the whole program. Let me explain: Did you start programming with an imperative language with global variables? (There is one called C that affected the minds of many people.) When you switch to an object oriented language, someone might have explained to you that there is no longer any need for real global variables. You may make these wannabe globals members of a class. You can turn methods that need the globals into members of that class as well. So they are global as far as the methods in question go, but they are not truly global.

In much the same way, we can explain yield. Programming languages have always had input and output operators - scanf-printf, gets-puts etc. However these operators are global with respect to your program. When you execute a printf, it is the output of the whole program, not of any one part of it. Yield on the other hand can be thought of as a localized input output operator. You can yield values from one part of the program to another part of the program. You get input from one part of the program. A method that yields is a packaged up opaque entity, a little sub-program, that communicates using yield with its consuming-context, the rest of the program.

We can explain exceptions in this way as well. In the absence of exceptions when there was a fault, the whole program would come down. It would core dump, modulo global error handlers. The whole machine does not come down, just the program that faults does. The environment that hosts the program may realize that there is a fault and do something about it. Its much the same with exceptions, but with the difference that only a part of the program "core dumps". Its a localized failure of the program that the environment (the rest of the program) can handle (or not handle, thereby making it a global failure).

So can you play this game or any other global program features, turning them into powerful localized structured operators?

Sunday, April 06, 2008 9:55:25 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Wednesday, November 28, 2007

An odd idea from a few days ago:

I watched this video a while back, this is Richard Feynman giving a lecture about discovering laws in physics -

He is talking about laws in physics. (the underlying Philosophy of Science that Feynman describes here is due to Karl Popper)

What Feynman is describing seems fundamentally different from what we do in the formal sciences like math/logic/cs. In the later we usually choose an axiom set that we believe to be right, based on our aesthetics, and then go on to prove other things that are right wrt our axioms.  Only things that are provable are taken to right and things that are right are irrefutably so. The system is inconsistent if we deduce False from the rules that we have. Inconsistent systems are not interesting. All formal methods work like this, in spirit - they keep track of what is right.

In what Feynman is describing, they don’t have a formal notion of right. They have a notion of what is wrong and as long as something cannot be constructively (by experiment) shown to be wrong, they can temporarily accept it to be not-wrong. If you look at this as a formal system, this is one where “what is not wrong yet” is known instead of what is right. Something is not wrong because 1) We don’t know a proof by which we can construct F from it or 2) Given our current inference rules there is no proof for it. But, we may add a new inference rule to the system in the future which may invalidate the belief that something is not wrong. It’s a feels like the opposite of what we do with logics.

Imagine a formal system or a model of computation based on notion like this. We are, in a fundamental sense, giving up the notion of consistency and completeness when we do this. I wonder if there exists a computational model that corresponds to such a “co-logic” of the sort they use in the *real* sciences. Such a system, in spirit, might be able to deal with partially correct data, incorrect assumptions etc. in a natural way. Absolutely correct data (or properties about the data) would be the exception.

(I wonder what this implies for the incompleteness theorem and such. I have been told that the "co-logic" I refer to here is actually co-induction. I see some similarities there, but I am not sure if its exactly that. )

A Tutorial on (Co)Algebras and (Co)Induction - Jacobs, Rutten

A Tutorial on Co-induction and Functional Programming

Wednesday, November 28, 2007 12:03:05 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  | 
 Sunday, November 18, 2007

Being at Indiana University, which is an old time Scheme hub, every now and then I am exposed to some of the turmoil in Scheme community over the new Scheme standard, R6RS. Essentially the community is having a hard time agreeing on what should be in the new standard. There are some very smart, very accomplished, very opinionated people who belong to this community and the language spec is a bit of a battle ground, from what I hear. (As are all language specs... some battles, I suspect, lack the intellectual quality of this one)

I am not very much of a Schemer myself, I sometimes indulge the language on a need basis. I hear from some my more intensely-Scheme-happy friends about some of the latest news at Scheme-spec land. One of the names that was mentioned in recent times is that of Will Clinger. Apparently, Will Clinger set into motion some of the discussion that formed the origins of the new standard, called R6RS (that is short for Revision-6 of the Report on Scheme - or something approximately like that). Over the years the formalization of R6RS has had its ups and downs. Of the many differences of opinion on the standard, some resulted in the formation of a group that decided to create an alternate standard. This group is called SchemePunks, apparently headed by Will Clinger himself (*). While this is mostly hearsay, it seemed amusing none the less. I also, sort of, like Scheme - so I listen in when one of these conversations come up.

Today I was searching for something and I came across the SchemePunks webpage/wiki. I didn't realize they had a webpage. Better yet no one told me that it written in excellent Hitchiker style! I read this and burst out laughing - what a way to motivate a language standard! I don't know any of the design decisions they have made, but the introduction here is sheer genius. Despite not being a Schemer, I am almost tempted to join in. :)

From the SchemePunks webpage:

On 29 August 2007, the Revised Revised Revised Revised Revised Revised Report on Scheme was ratified by the Steering Committee. This has made a lot of people quite angry and has been widely regarded as a bad move.

Many programmers believe that it was created by some sort of community process, though the Jatravartid people of Viltvodle VI believe that the entire Standard was in fact sneezed out of the nose of a being called the Great Green Arkleseizure. This theory is not widely accepted outside Viltvodle VI, and so, standards being the puzzling documents that they are, other standards are being designed. And this wiki, which is called SchemePunks, is definitely not part of the Scheme Underground, even if it is, which it isn't.

Which is very odd, because without that fairly simple piece of knowledge, nothing that is written on here could possibly make the slightest bit of sense. We hope to develop an alternative specification for the Family of Programming Languages known as Scheme. Watch this space.

Being somewhat bowled over, I had to look for the man - William Clinger, Professor of Computer Science, Northeastern U.
http://www.ccs.neu.edu/home/will/Personal/western1.jpg

:)

I wish more languages where designed in H2G2 spirit. Aah!

From his webpage:
http://www.ccs.neu.edu/home/will/R6RS/essay.txt

More than twenty years have passed since I wrote this [1]:

Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary. Scheme demonstrates that a very small number of rules for forming expressions, with no restrictions on how they are composed, suffice to form a practical and efficient programming language that is flexible enough to support most of the major programming paradigms in use today.

I have to say, I am compelled to agree, though I wonder how of it applies to the Scheme of today. The essay is worth a read, even if you are not a Schemer. You can skip over the Scheme specific parts and just look at the language design philosophy.

Sunday, November 18, 2007 11:11:35 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Saturday, November 03, 2007

I get irritated because too many people in the "computing" business don't understand the word "lambda". Its just irritating because at the heart of it, its just a simple fundamental idea, like the notion of natural numbers or counting. So just spend a few minutes, understand what it means and stay educated. In a few years (if not already), almost every language is going to expose something like a lambda to its programmers. So just pick up the idea ok?

This is a working description, it wont make you an expert on the Lambda Calculus. It might give you some intuitions about it though. Lets get started.

So assuming you are familiar with a C-like language, how do you write a function that takes an integer and returns it?

int foo(int x) {
    return x;
}

Now lets look at what this is saying, it says there is a function called foo, it takes an int which it names x and it returns an int. the body of the function has a single statement called return x. Great! Now, this function is a very famous one and is called the identity function (usually goes by the nick-name id). Also when we talk about functional programming we dont really care very much for the C-style types. So let's rename the function and drop the types.

id(x) {
      return x;
}

Don't worry too much about the types. Typed functional languages usually have a different notion of types from the C like languages. The types will come back, but in a bigger and better form. We however wont discuss any type theory in this article.

So now, what it is saying? It says here is a function called id, it takes some value that it calls x and it returns x. Ok, now lets take a look at this closely. In the syntax that we have here, the name of the function is part of the syntax. We would like to say - here is a function and then assign it the name id. So that we are able to look at the function and its name as two different things. Lets do that by introducing the keyword called "function". Javascript, for example, has such a keyword.

id = function(x) {
      return x;
}

Ok. Now lets make one more simplification. Lets say that the language is a little like Ruby or so where that last statement in a functions body is its return value. Did you get that? That means that we no longer need the keyword return. We can simply make the last statement x and by that we know that the return value from the function will be x.

id = function(x) {
      x;
}

Great, lets rewrite this a bit:

id = function(x) { x; }

Now for one more simplification (really C like languages are so complex!) - lets assume that we can write only one statement inside each function. Just one. If that's the case it can be much like a if with just one statement - we don't need the curly braces anymore. We also don't really need the semicolon.

id = function(x) x

Great! Congratulations ladies an gentlemen, you are looking at a lambda. Simply rename the keyword function and call it lambda and we are all set.

id = lambda(x) x

If we drop the name assignment and look at it we have:

lambda(x) x

This is a function that has no name. It take one argument and return it. Various functional languages use slightly different syntax for writing out their lambdas. The lambda calculus, the underlying calculus of these systems, usually uses a \ instead of the verbose name lambda. It also uses a dot to separate the arguments from the body of the function. A little like this:

\x.x

The functional language Haskell uses an arrow to separate the body from the arguments.

\x->x

The language(s) ML, OCaml, SML, (maybe F#) etc. use the name fun to stand for lambda.

fun x -> x

The language Scheme uses the name lambda and lots of parenthesis.

(lambda (x) x)

Ruby lets you write something very similar to a lambda like this:

lambda {|x| x}

Most of these languages give you some mechanism by which you can give a name to your lambdas (otherwise most of the time you are a little hard pressed to refer to them).

Haskell

id = \x -> x

ML

let id = fun x -> x

Scheme

(define id (lambda (x) x))

There are some alternate syntaxes for writing named lambdas in most languages:

Haskell

id x = x

ML

let id x = x

Scheme

(define (id x) x)

So what is a lambda? It is usually a name used to define a function. The function is a value that can be assigned to a variable name. Just like any other value in your language.

A lambda is an abstraction form. Normally in a program you can read the value of a variable to which you have not assigned a value. In other words is you write (x + 1), it does not have any meaning if x has not been assigned a value already. One way to look at what lambda says is that it abstracts the value of the x. So \x.(x+1) means - give me a value for x and then I will give you the value for x+1. The value of x is abstracted in the body of the lambda. This description comes very close to our informal notion of a function in a C like language.

The lambda calculus usually allows only for lambdas that take one argument. Hence to write functions that take multiple arguments we nest lambdas. We write \x.(\y.(x+y)) for a function that adds two numbers. Most functional languages support multi-argument lambdas. In Haskell this would be \x y -> (x+y).

So what's the big deal? Nothing much and quiet a lot. Nothing much because the notion of functional abstraction is something we learn from high-school math which we port over to programming languages. This is an old and familiar notion.

That said, in the functional programming community, it has long been realized (it is a large community with varying beliefs, secret cults, traditions and practices) that lambdas are the only abstraction form required for a lot of things.  One can do away with loops and conditionals (if, switch) and assignments and numbers and object oriented programming and pretty much everything you can think of (and some things you cant) - they can all be encoded using lambdas. Hence lambdas form a sort of foundational building block for a large number of programming paradigms. At the heart of all of this is the notion of a function - hence the name functional programming.

Saturday, November 03, 2007 6:03:52 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2]  | 
 Sunday, October 28, 2007

This is a great slide deck from Benjamin Pierce, Professor Computer Science at UPenn, that shows what the world of programming languages research is doing especially in the context of types.

http://www.cis.upenn.edu/~bcpierce/papers/tng-lics2003-slides.pdf

Also from Pierce is a really good introduction (the best I have found to date) about polymorphic lambda calculi and actually programming in some of those languages. This describes the hierarchy starting with the simply typed lambda calculus (F1) and describes F2, F3, etc and Fw (F-omega). He also talks about encodings of various sorts of types and a whole lot of neat stuff. All of that written in a very readable fashion. I spent my weekend on this and it was time well spent.

http://www.cis.upenn.edu/~bcpierce/papers/leap.pdf

(For some reason this pdf seems to be back to front, but its just fine when printed)

Pierce's webpage is a gold mine of information for the PL student, including neat things like a 'Great Works in Programming Languages' list. He is also a pretty good photographer. I did see him in person when I was at MSRC in summer of 2006. I believe he was visiting those days. I now regret not having walked up to him and saying hi.

Sunday, October 28, 2007 10:25:11 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Friday, October 19, 2007

"Can you recommend any C++ books?"
"I don't recommend C++."

Afterwards I reluctantly come up with some names. I beginning to notice that I eventually end up mentioning the Scott Meyers "Effective C++" books. The last time I did this I started to wonder why I say this?

When I first read "Effective C++" I was horrified. If I derived any pleasure out of it, it was comparable to the morbid curiosity of going to witness an execution (I probably would not do that though, if I ever got such a chance. I don't have the stomach for it). Back to C++ - Firstly there was no way I was going remember all of that. Secondly I felt deeply uncomfortable. In time I realized that the whole book was written in the style of demonstrating "effective" usages of C++, while what it truly was is a careful documentation of the flaws of the language. Every chapter in that book talks of a language flaw in excruciating detail and how to live with it. That book should have been called "Defective C++".

Then there was "More Effective C++" which essentially did more of the same.  Here is what the language does, here is what you think it would do, here is what you'd like it to do and you put these together and it blows up in your face. In time, my intellectual immune system kicked in and started erasing most of my memories about all this.

So why do I recommend the "Defective" and "More Defective" books? My first recommendation would be to get out of the situation, don't deal with the language if that's possible. If not, and you intend to get it to serve you (instead of the converse) you need to quickly understand that most of the abstractions it provides are leaky. There are hardly any non-leaky abstractions that C++-land provides. (Some people associate this behavior with some notion of "freedom" - I trust evolution will take of those folk.)

So if your abstractions are leaky, in that they are going to have strange interactions with each other under-the-hood, then you should quickly start developing an understanding of what happens under the abstractions you are given. Your effectiveness as a developer becomes proportional to your understanding of what happens under the surface. Hence the "defective" C++ books are a useful read.

Friday, October 19, 2007 12:05:29 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Tuesday, October 16, 2007

Today Aziz mailed me a build of his Ikarus compiler for Windows. Though I don't have much to do with software as such these days, I was excited. Ikarus is Aziz's Scheme Compiler. I use Petite Chez Scheme on my machine. Petite  is Kent Dybvig's Scheme interpreter, part of the Chez Scheme compiler system. I don't have Chez Scheme itself because it sells, I am told, for several thousands of dollars and hence I cant afford it. I expect Ikarus to be comparable to full Chez in many ways and surpass most other Scheme systems out there.

What Aziz sent me was a zip file that extracted to a 128k exe and 4mb "boot" file. He says the boot file says the same between windows, linux and mac. The bootstrap executable changes. This is amusing because the "boot" file is actually the compiler binary. It contains the compiled x86 code.  He able to get away with this because he only relies on the OS to load his little bootstrap exe. After that point he simply allocates memory pages from the OS and relies on the OS for almost nothing that he can do himself. So the exe loads the boot file into memory which then acts as its own loader, sets up its own stack, lays out its own code and data areas, does its own GC and such.

Of course, all of this is written in Scheme itself. There is probably a small C file somewhere that acts as the main() and the initial call into some ASM code that transfers control to Scheme. Fun fun.

I have talked to Aziz about many parts of this system and almost always the design has seemed to be of very high quality. His management of code objects, the runtime stack, continuations and on and on. The system has a large part of R6RS implemented and is already a superset of R5RS as far as I understand. Depending on how the development process stabilizes (after all, this is all one persons implementation), I might move over Ikarus altogether and maybe use it exclusively. 

Tuesday, October 16, 2007 10:49:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, June 15, 2006

 

One of the solutions that did not make it into my yield paper (though I sort of liked it) was one that used “braiding”.

 

The problem here is to do a breadth first traversal of a binary tree. I was looking for a solution using my pet control operator yield. The braiding solution occurred to some months back as a consequence. The solution that finally made it into the paper was one based on a more traditional queue based breadth first traversal (BFT from now on) which did have better perf than the braiding solution. I am however documenting the braiding solution here because I think its elegant at some level.

 

So how would one do a BFT of a binary tree? Look at this entry for a slightly more detailed problem description. Simple, we start out by defining braiding.

 

Say you have two yield based iterators. These are just computations that yield values during their process of evaluation. These iterators yield values of type Maybe. For those unfamiliar with the Haskell type “Maybe”, here is a definition –

data Maybe a = Just a | Nothing

 

It simply says that a value of type maybe is either some actual value or the special value nothing. If you desperately need an analog, think of it as a pointer or a reference – it either points to some object or its null.

 

So a stream of maybe-values looks like this

x1 x2 # x3 x4 x5 # # x6 # ..

 

where the ‘x’ denote actual values and the # denotes occasional ‘Nothing’. If one had two such streams of values, then one can braid them as follows. Consider the stream of xs’ and the stream of ys.

 

x1 x2 # x3 x4 x5 # # x6 # ..

y1 # y2 y3 # y4 y5 # y6 y7 # ..

 

On braiding gives a single stream with that switches between the original streams every time it sees a Nothing. This results is a single stream like this –

 

x1 x2 y1 # x3 x4 x5 y2 y3 # y4 y5 # x6 y6 y7 # ..

 

This is how braiding works.

 

So how does one do a BFT? Simple, one recursively traverses the tree as follows –

  • If you are at a leaf, yield the leaf value and then yield a Nothing.
  • If you are at a branch, yield the branch value, a Nothing and then braid the iterators of the left and right branches.

 

Simple – that’s a breadth first traversal. If you look at the algorithm closely you will realize that final stream produced will be in the breadth first order but will also contain occasional Nothing values – the Nothing values will be precisely in the those places when values of one level deeper in the tree are being produced. (Of course, you don’t want to expose the Nothings you can add a filter and remove them).

 

The other important observation, which is also a requirement of the problem, is that the values used to resume the iterator will be available to the branches or leafs that yielded the corresponding value – hence tree reconstruction is trivial.

 

-- This a breadth first tree walk that reconstructs the tree from the

-- the return values of the yield. It is expands the tree one level at

-- a time and internally uses Nothing to communicate level changes.

bfTreeWalk :: Tree a -> Yield i a (Tree i)

bfTreeWalk tr = suppressMaybe $ bft tr

    where

    bft (L v) = do (Just v') <- yield (Just v);

                   yield Nothing;

                   return (L v')

    bft (B v t1 t2) = do (Just v') <- yield (Just v);

                         yield Nothing;

                         (t1',t2') <- braidMaybe (bft t1)(bft t2);

                         return (B v' t1' t2')

 

Here is the tree walk in Haskell. Even if you are not able to run or fully grok the Haskell code above, you should be able to use it as a guide to reconstruct the solution in your pet language.

 

The supporting braid and suppress functions are below –

 

-- Convert maybe values into real values by ignoring the Nothing.

-- 1 2 10 # 3 30 # 5 6 70 50 # 8 ...

-- Becomes

-- 1 2 10 3 30 5 6 70 50 8 ...

suppressMaybe :: Yield (Maybe i) (Maybe o) r -> Yield i o r

suppressMaybe yb = runMapY yb sM

    where

    sM Nothing = return Nothing

    sM (Just v) = do r <- yield v;

                     return (Just r)

 

-- Alternates two iterators, every time one yields a Nothing

-- 1 2 # 3 # 5 6 # 8 ....

-- 10 # 30 # 70 50 # 80 ....

-- and makes (where # is a Nothing)

-- 1 2 10 # 3 30 # 5 6 70 50 # 8 .. 80 ... ....

braidMaybe :: Yield (Maybe i) (Maybe o) r  -> Yield (Maybe i) (Maybe o) r -> Yield (Maybe i) (Maybe o) (r, r)

braidMaybe yb1 yb2 = bM (runYield yb1) (runYield yb2) True

    where

    bM (Iterator (Just v) k) it ord = do i <- yield (Just v); bM (k i) it ord

    bM it1 it2 False = do yield Nothing; bM it2 (resume it1) True

    bM (Iterator Nothing k) it True = bM it (k Nothing) False

    bM (Done v1) (Done v2) True = return (v1, v2)

    bM (Done v) it True = bM it (Done v) False

    resume  (Iterator Nothing k) = (k Nothing)

    resume it = it

 

The code above uses a monadic yield implementation and can as easily be expressed by any language which supports a good yield operator. (As of now I have a yield implementation for Haskell and Scheme and I believe Sid has ones for Python and Ruby (?))

 

At this point I should note that I was referred to the naïve implementation of BFT using nested lists by Simon Peyton Jones. The cods is below

 

breadthFirstTW :: Tree Int -> [Int]

breadthFirstTW t = concat (bft t)

  where

     bft :: Tree a -> [[a]]

     bft (L x) = [[x]]

     bft (B t1 t2) = b_zip (bft t1) (bft t2)

 

     b_zip :: [[a]] -> [[a]] -> [[a]]

     b_zip [] ys = ys

     b_zip xs [] = xs

     b_zip (x:xs) (y:ys) = (x++y) : (b_zip xs ys)

 

The essential idea behind the braiding traversal is not very different from that of the nested solution with the operational encoding of nested lists using Maybe. However looking at the nested list solution, at this point, it is not apparent to me how it can be extended to reconstruct the tree.

 

The implementation of the monadic yield that this relies on is documented in my paper which I hope to put up on my academic website soon enough.

Thursday, June 15, 2006 1:48:43 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Monday, June 12, 2006
  Rotor 2.0 

I was attending a talk by Andrew Kennedy today when I heard that Rotor 2.0 has been released. So it has the Shared Source version of the cool new C# compiler and such. Fun Fun.

Download

Monday, June 12, 2006 12:22:49 PM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  | 
 Monday, June 05, 2006

Work at MSRC has been moving slowly, though I have been busy.

 

Parallel GC for Haskell

Not much to say on the Haskell parallel GC front except that I am yet to actually start writing any code. I have been trying to understand the existing code base and it has been a little over whelming. This is certainly not one of the best code bases that I have seen. Actually quiet far from it. There are functions of several hundred lines in length. The main GC function itself is 800+ lines long. I have been told that several people have got their PhDs of that GC.c file. I was expecting a pure functional language to contain a couple of core object types and everything else to be built around them. Far from it, there are 70+ types of objects in the system – they have special cased almost everything they can think of for efficiency sakes. Being a pure lazy language these things matter I guess.

 

That aside the source is littered with lots of interesting ideas. The problem with something so interconnected is that its hard to build incrementally on this. So I am little stuck. The GC has a copy collector and a mark compact collector in the same code base – they share a large amount of code. For a long time this confused me. The system switches from a copy collector to a mark compact collector depending upon memory usage of every step of every GC. The number of generations is runtime configurable. The number of steps per generation is runtime configurable. It’s a crazy, interesting system.

 

I have been making some notes over here, which I hope to continue updating over the period of my internship –

http://cvs.haskell.org/trac/ghc/wiki/GarbageCollectorNotes

 

Papers - Quantum

That aside, I helped complete – or rather didn’t help complete – a paper on Quantum Computing since I landed in Cambridge. I actually didn’t do much for that paper. I had some interesting ideas, but they remained undeveloped enough to not go into the final paper (though we initially thought it would). So well, in some sense my first paper is not really my first paper. :)

 

Papers - Yield

I finished my second paper since landing at Cambridge this past weekend. The paper is about yield, (yes, finally!). It is coauthored with Simon Peyton Jones and Amr Sabry, though most of the actual writing was done by me. So in many senses this paper will not be of comparable caliber to most Amr Sabry or Simon Peyton Jones papers. Writing this paper was quiet an experience – as it is, it was my first real paper. Usually, I am told, people don’t write their first papers completely themselves, they write a section or so. Secondly I had the names of two very respected computer scientists on this and I was afraid of writing accidental stupidity. They however did give me lots of comments over email. And at the end of it I think I have come out braver, a tab bit less afraid of writing papers.

 

The paper has been submitted to the Haskell Workshop 2006. Haskell is probably the most difficult language to suggest a new control flow operator. Being the pinnacle of pure functional programming, with monads and lazy evaluation it is a very very hard language to make a value proposition to in terms of adding control flow operators. All the same, I think we may have one or two interesting arguments in favor of yield.

 

Breadth First Renumbering

As an example of control flow based on lazy evaluation consider this problem: You are given a binary and asked to renumber the nodes in breadth first order, thus creating a new tree of the same structure but with changed node values.

 

 to

 

Think about it. See if you can do this by only one traversal of the tree and use constant space etc. Basically the best solution you can think up.

 

In Haskell, lazy evaluation is used as a control flow operation. But one that is an implicit control flow operation – in the sense that the programmer doesn’t have to specify the order of evaluation the system will figure it out, driven by need.

 

Here is the lazy Haskell solution -

 

data T a = B a (T a) (T a) | L a

       deriving Show

 

bfn :: ([Int], T a) -> ([Int], T Int)

bfn (k : ks, L a) = (k + 1 : ks, L k)

bfn (k : ks, B x a b) = (k+1 : ks'', B k a' b')

    where (ks', a') = bfn (ks, a)

          (ks'', b') = bfn (ks', b)

 

bfnum :: T a -> T Int

bfnum t = t'

    where (ks, t') = bfn (1 : ks, t)

 

It is just mind boggling that something like this can work – and work so perfectly. If you know how to read Haskell and you haven’t seen this solution before, get ready for a mild surprise. :) The implementation is adapted from the appendix of Chris Okasaki’s  paper –

http://portal.acm.org/citation.cfm?id=351253&dl=ACM&coll=ACM

 

Even if you don’t understand Haskell, try to solve this in your pet language and see what you come up with.

 

Haskell

Since I am in a mood for writing a bit – here is a little bit about Haskell. A tiny tiny intro. Haskell is a pure functional language. If you don’t know what that means, there is good chance that you haven’t seen one before. Also Haskell is one of the few languages that are lazy evaluated. Values are computed only on a need basis – hence one gets to write all sorts of crazy circular dependencies between function parameters and their results – if one is careful. Also it is strongly typed – Haskell is a laboratory for stuffy of type systems, if nothing else.

 

Lets do some examples. Immediately following the example, I write what it means.

 

n = 5

n is a function that takes no parameters and returns the value 5.

 

 

f n = n+1

f is a function that takes one parameter, namely n and return n+1. Hence if one writes (f 1) it is the equivalent of calling f with the parameter 1 and will return 2.

 

If you write code like the above, it will work. But usually people write the types of everything they write. If you miss out the types, Haskell has a type inferencer which will automatically figure out the types (and might occasionally complain if there are ambiguities).

 

So here is the definition of the function f with its type signature.

 

f :: Int -> Int

f n = n+1

So the type of f is written by putting two colons after f and is “from Int to Int”. In other words the function f takes an Int and returns an Int.

 

Here is the type of the function even, a function that checks if a number is even.

even :: Int -> Bool

It takes an Int and returns a Bool.

 

So what is the type of the function n?

n :: Int

n = 5

Simple? The type of n is simply Int.

 

Here is a function g that takes two parameters, namely x and y and returns their sum.

g :: Int -> Int -> Int

g x y = x+y

The type says that g takes an Int and yet another Int and returns an Int. The value of (g 5 10) is 15.

 

The interesting this is that in haskell, unlike in many other languages, the expression (g 5)  by itself has a meaning.

g5 :: Int -> Int

g5 = g 5

(g 5)  is a function that takes an Int  and returns an Int. Here I assigned the name g5 to be (g 5) hence is I say (g5 20) the result will be 25. The general idea behind applying only some of the parameters of a function thereby result in a new function that awaits the remaining argument is called “currying” – named after Haskell B Curry.

 

Does this interest you? If so you should consider reading up about Haskell a bit. Maybe I will drop a few simpler examples of lazy evaluation based niceties sometime.

 

Monday, June 05, 2006 4:42:30 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Friday, March 03, 2006

Why Haskell?

So how long does it take for a completely fledgling Haskell programmer to implement a weird language? 2 nights.

 

Its pretty amazing if you think about it – and it fun and not stressful as well. If I did as much in C or Cpp it would have been significantly more stressful and would have take a over a weekend for sure. And even after that it wouldn’t be as flexible as this is.

 

In some sense, in my current limited opinion, Haskell is to Scheme what Ruby is to C++. To add to it, it is purely functional than scheme, is lazy, comes with A REAL library, allows for pattern matching and discriminated unions etc… the goodness goes on – as matter of fact, it can even pretend to be imperative for a bit. Also, GHC generates actual Win32 exes that I can run. If you are a languages person you might think it’s a moot point, but for someone who likes to build tools and wants to sometimes share them with his (less inclined) friends, this is essential.

 

So I think Haskell is going to takes its place in my bag of tools. The only thing I really miss from Scheme land are macros. I wish Haskell had macros – better, I wish Haskell had multistage evaluation.

 

Being a almost ‘pure’ imperative programmer when I joined college, Prof Dan Friedman’s Programming languages class hurt my head really badly. And I was coming to terms with functional programming.

 

Last semester I also took a class with Prof Amr Sabry – Quantum computing – and this was my first real introduction to Haskell. I am working with him this semester and of late I have been trying to understand Monads. Its one thing to have working knowledge of a concept, and its quiet another to formally study it. Monads hurt like few other things hurt before – and the fact is that it makes you look at imperative programming in this totally other way.

 

So that’s the context for why this is in Haskell. The blog entry is really about this little language I wrote in .. in all fairness a little more than a late night. And I haven’t used the parser generator or other tools before this.

 

Yield Language 1.0

So whats the language like? Well, you’re not going to want to use it at all. But all the same it is the lambda calculus with the following additions (some of which take away its purity) – yield (with all the right behavior in place), if-then-else, numbers (+, -, ==), strings (+, ==). In other words, it’s a simple higher order language with strings and numbers and fancy control flow operator called yield, which is the only “impure” part of the language.

 

To support yield I introduce a funny tagging operator I call ‘pi’ to tag a sub-expression that can yield. A pi-expression can be called like a normal application, or can be used as a coroutine using co, next and run.

 

The actual internal implementation is what is best described as “stackless”.

 

 

f = \x ->

  ((("x = " + x) + ", ") +

  if (x == 0)

    "zero"

  else

    "not zero");

 

(f 10)

 

This evaluates and returns “x = 10, not zero”

 

Basic syntax

e =     \x->e

| x

| e1 e2

| if e1 e2 else e3

| (e1 + e2)

| (e1 – e2)

| (e1 == e2)

| <num>

| <string>

| x = e1; e2

 

The above syntactic categories as basically all pure. The last rule is a let. There is no fixed point operator and you will need to add one of your own to do recursion. Evaluation is strict, applicative order. The following are the extensions for yield support.

 

      | pi e

      | yield e

      | co e

      | next e1 e2

      | run e1 as x1 x2 -> e2 or x3 -> e3

 

Some more examples, assume that we have an applicative order Y combinator called “fix”.

-- Applicative Y combinator

fix = \f -> ((\x -> (f \y -> ((x x) y)))

          (\x -> (f \y -> ((x x) y))));

 

Here  is a relatively simple function that takes a number and yields as many times. I have used the fixed point operator so that I can loop inside the pi block.

-- An iterator that yields 'x' times

iter = \x ->

  (pi  (((fix \loop -> \x -> \s ->

                  if (x == 0)  s

                  else v = yield x;

                        ((loop (x-1)) (v+s)))

            x)

      0));

 

One can call this function in two ways – simple invocation –

((iter 1000) \x->(x+x))

 

Or using the coroutine-like behavior, that is sometimes called external-iterators or generators.

call = (fix  (\call -> \c ->

                  run c

                  as (x1 x2) -> (call (next x2 (x1 + x1)))

                  or x1 -> x1));

 

 

v1 = (call (co (iter 1000)));

 

So one can save the following code into a file and execute it from command line using the command –

langy.exe < filename.txt

 

[update: made some simple syntactic niceties to the language]

 

-- Applicative Y combinator

fix = \f -> (\x -> (f \y -> (x x y))

             \x -> (f \y -> (x x y)));

 

-- An iterator that yields 'x' times

iter = \x ->

       (pi  ((fix \ loop x s ->

              if (x == 0)  s

              else v = yield x;

              (loop (x-1) (v+s)))

             x 0));

       

                                  

-- Call will invoke an iterator any number of times

-- At each point it thunks the return value and then uses that as the

-- next value paramter.

call = (fix  \ loop c ->

        run c

        as x1 x2 -> (loop next x2 (x1 + x1))

        or x1 -> x1);

                        

 

v1 = (call co (iter 1000));

                      

v2 = (iter 1000 \x->(x+x));

                      

("Values are " + v1 + ", " + v2)

 

And this outputs –

"Values are 1001000, 1001000"

 

Downloads

 

 

Friday, March 03, 2006 2:37:42 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Tuesday, February 28, 2006

(A much delayed part 2. Previous article is here)

 

Pipelines

 

This article primarily describes the pipeline construct. The simplest way to describe a pipeline is to say the way the trampoline models the interaction between a caller and iterator and, the pipeline models a call tree. One can think of a pipeline as a cascade of trampolines.

 

Suppose one had a call tree where each frame in the call tree corresponded to that of an iterator. As each iterator yields or returns to a yield, what the program effectively does is that it moves values up and down the call tree.

 

Consider the following function –

def bits(n)

      if n == 1

            yield 0

            yield 1

      else

            bits(n-1){|v|

                  yield v*2

                  yield v*2+1

            }

      end

end

 

Here invoking bits with a value n, causes it to yield every possible n-bit binary number. Now this sort of thing is not easy to model with a trampoline. A trampoline lets one process in the trampoline act as a iterator and the other as a caller (though the device itself does not introduce an asymmetry).

 

To do something equivalent to code snippet above, one needs to maintain a chain of iterators. How does control transfer between iterators in call chain, assuming that none of the iterator return? Control can move up and down the call tree corresponding to when a caller returns the value to a yield statement higher up the tree OR the iterator can yield a value to a caller further down the tree. Something like  the diagram below – each up arrow being a return to a yield called by a block on top and each down arrow being a yield. (The direction of the arrow indicates which way control transfers.)

pipe-call-tree.gif

 

The pipeline device gives every process in it to communicate with the process to the left of it or to the process to the right of it. One can choose a convention here where the process to the left of a process can be considered it callee and the process to the right can be considered its caller.

 

The picture below gives a comparison of what the pipeline device does.

 

pipe-device.gif

Every process in a pipeline device is created using a lambda-pipe. A lambda-pipe, unlike the lambda-iter, makes available the binding ‘left’ and ‘right’ in the scope of its body.

 

A process can call left to pass control to the process to its immediate left. It can call righ to pass control to its immediate right. The ‘left’ and ‘right’ are similar to the yield in the sense that they take a parameter and return a value.

 

If a process in a pipe, executes a right with a values ‘v’, the value is made available to a process to its left as the returned value of a ‘left’ executed by it. Hence left and right alls by the process have to match up to facilitate control flow.

 

This is the basic idea behind the pipeline device.

 

Example:

Consider the following function basis, which is basically a rewrite of bits, but for usage in a pipe.

 

(define basis

  (lambda-pipe ()

    (let ((v (left)))

      (if (eq? v 'end)

          (right 'end)

          (begin

            (right (cons #f v))

            (right (cons #t v))

            (yield-all (basis)))))))

 

One can put multiple instances of basis into a pipe and have an initial process that will start the cascade by right yielding a empty list, immediately followed by the end marker.

 

    (foreach (command-shell-pipeline (gen-pipe '() 'end)

                                     (basis)

                                     (basis)

                                     (basis))

             (printf "num: ~a~n" (port-value it))))

 

This produces –

num: (#f #f #f)

num: (#t #f #f)

num: (#f #t #f)

num: (#t #t #f)

num: (#f #f #t)

num: (#t #f #t)

num: (#f #t #t)

num: (#t #t #t)

num: end

 

In the above code a gen-pipe, will simply right yield each of it arguments in the same order. One may notice that I use the command-shell-pipeline in a foreach, which means that it is itself an iterator. The pipe device wraps values in something called a ‘port’, to extract the value from the port, one uses the port-value function.

 

The Pipe device is an iterator: To understand why the command-shell-pipeline is itself an iterator (while trampoline is not) one has to look at the diagram above for the pipe device. The left yield of the left most process (or topmost depending on how you look at it) and the right yield of the right most process are yields that transfer control outside of the pipe device. Hence the pipe device itself is an iterator.

 

[updated] The interesting thing about the pipeline is that each process in the pipeline gets state management for free.

 

The pipe device lets you build only a linear data structure, in the sense that each process in the pipe can only communicate with its left and right neighbors. One can use pipe nested in other pipes or in trampolines to make arbitrarily complex control flow structures.

 

Caveats: In retrospect, to be honest, I haven’t really used the pipe much in actual code. It was created more to fill a missing link in the usage of yields that a device than out of practical usage patterns. One might actually resort to nesting trampoline usages more often that one might use the pipe.

 

Also, the more I think about this device I can see more than one ‘correct’ behavior in the model that it presents to the user which sometimes makes it rather un-intuitive to program with. Desipte this it is easy to see how many problems can be implemented as a pipeline of filters that can each maintain state and back track. I need to try and express more problems with the pipe to see how well they can be expressed.

 

Due to some of these concerns the code for the actual pipe device implementation, takes as a parameter a ‘semantics’ function so that the user can describe the behavior required from the pipe externally. One predefined pipe available is what I have called the command-shell-pipe.

 

 

I am also interested in finding analogous constructs to this – one of the things that I should look at is a non-determinism monad used with a monad for state threads. The processes in the pipeline device are similar to what is described as an ‘online transducer’ by Olin Shivers and Matthew Might in Continuations and Transducer Composition. After putting this up online I see that the transducers are studied in detail by many people.

 

Download code.

 

Tuesday, February 28, 2006 8:02:14 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Saturday, February 04, 2006

This is a series of blog entries that introduce three devices written using the yield operator for Scheme. Previously I had the following entries that described the requisite features of a complete yield operator and an implementation of such a yield operator for Scheme.

 

Yield the Magnificent

Yield Implementation for Scheme

 

Trampolines, Pipelines and Pi are programming devices or constructs that are built on top of the yield and purely the functional subset of Scheme.

 

There are many ways one can look at the power provided by the yield operator. One way to look at the yield is that it is a call-tree walker. It can move information up and down the call tree. If the yield implementation is sufficiently flexible, it can walk up and down several call-trees which exist concurrently.

 

Another way to look at the yield is to think of it as adding input and output capabilities to a function in functional system. A function during the process of computing its value changes state, creates temporary variables etc. When the result or return value of the function is computed the state of the function collapses and the value is returned. Yield offers a way for functions to do input and out with other functions while they maintain state. More about this later.

 

Trampolines

I want to start off by introducing the simplest of the three devices, the trampoline – sometimes I refer to this construct as the trampoline process as well. (Note: The name trampoline is used only in the context of the yield based programming device I describe here and is not a logical extension of other trampoline constructs you may have encountered before.)

 

The trampoline was introduced to address the following scenario – in a purely functional context what is the meaning of a parameter code block that is passed to an iterator cannot affect the caller’s state. Such a parameter code block is always a closure, in a functional context. On invoking a closure, the closure cannot maintain or modify state in the caller without resorting to some sort of a side effecting operation such as an assignment.

 

The trampoline packages such a computational effect so that the programmer need not think in non-functional terms when using the yield. Instead of using a set! or an assignment as the computational effect, the trampoline device uses a jump as the computational effect.

 

To illustrate what I mean, one has to look at the relation ship between the caller and a yielding callee in an imperative language. The flow of control is almost always as follows for a Ruby or C# yield (yes, I am abstracting out many details here) –

  1. caller calls iterator, control transfers to iterator
  2. iterator does some computation and produces a values, yields it
  3. control transfers to caller,
  4. caller does something with the value – this something is usually a side effect
  5.  caller returns a value to iterator, control transfers back to iterator
  6. steps 2 to 6 can repeat any number of times till the iterator returns.

 

The problem with this functional programming land is that the there is no use in yielding the value if the caller cant to anything with it – an alternative is pass an environment back and forth between the caller and iterator or some such thing, which is always tedious to manage.

 

The trampoline does the following. The trampoline becomes the caller for two functions, both of which are iterators that concurrently maintain state. One iterator place the role of the caller in the imperative case and the other one plays the role of the callee. Since the function playing the roles of the caller is an iterator, its free to maintain any sort of local state it chooses.

 

The trampoline device is a simple device, but to see the correct analogy that argues its purpose is a little tricky. Another way to look at a trampoline is to look at it as two iterators such that when one yields control passes to the other and when the other yields control passes back to the first. The process terminates when one of the two iterators terminate.

 

yield-tramp-1.GIF

 

Here is an example of code that uses the trampoline. When the trampoline process terminates, a list of values that are the return (or last yielded values) of both iterators is returned.

 

This is an iterator that adds values that it gets yielding the current sum at any point.

(define adder

  (lambda-iter ()

     (let loop ((s 0))

       (loop (+ s (yield s))))))

 

This is an iterator that yields the first ‘n’ Fibonacci numbers

(define fibonacci

  (lambda-iter (n)

    (let loop ((a 1)(b 1)(n n))

      (if (not (zero? n))

          (begin

            (yield a)

            (loop b (+ a b) (sub1 n)))))))

 

To sum the first n Fibonacci numbers, one create a simple trampoline between the iterators

(printf "Sum = ~a~n"

        (cadr (trampoline-process (fibonacci 10) (adder))))

 

The cadr is there because the trampoline returns a list of two values, the last value obtained from the Fibonacci and the last value obtained from the adder. We are interested in the sum yielded by the adder and so we take the cadr.

 

The trampoline process that is implemented in the library that I have shared below is a slight generalization of this idea – the generalization being that the trampoline process can take any number of iterators as arguments creates a circular list of control transfer using yield. While having two iterators in a trampoline can be thought of as the equivalent of an imperative caller and callee, there is no simple parallel I can think of for three of more iterators in a trampoline. Below is a diagram of trampoline with three iterators.

 

yield-tramp-2.GIF

 

I frequently use a trampoline while programming in scheme using yield. While it may not be easy to see why trampolines are useful just by using a simple example like the above, they useful in managing code complexity when each of the iterators involved has to do a non trivial computation.

 

As an example I wrote a CPS transformer for a subset of scheme last semester, at the heart of which was a trampoline. One iterator would recursively walk down the source expression tree and would yield out values. The other iterator would reconstruct a CPSed expression. So it gives you the conceptual clarity of writing a two pass CPSer while in effect only one pass happens. (Of course I could mash both the analysis and construction phases into one big hairy ball of mutually recursive functions, but that would not let me focus on one problem at a time and possible build them up as reusable iterator components. This of course was a little non traditional and might not have been easy on the evaluator of the assignment).

 

Download Sources for Yield, the Trampoline and the Sample Code above.

 

In the next related entry I hope to discuss the Pipeline device (aka the Pipe device).

 

Saturday, February 04, 2006 1:26:54 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Sunday, January 29, 2006

What is the Y combinator? I have seen lots of discussions on the web but nothing that seemed like a simple explanation of how it works or why it is needed. I finally understood the Y combinator a few days back and a lot of things snapped in place. So here I will try and explain it from my perspective. In this entry I am taking liberties with various syntaxes – please bear with me.

 

This is the Y-combinator for a normal order lazy language –

Y = \f.((\x.(f (x x))) (\x.(f (x x))))

 

(Here, the ‘\’ denotes a lambda). Scheme is an applicative order language and the above combinator cannot be used as such in scheme because it will lead to an infinite expansion. More on this later.

 

Let’s start from some basics – say we are writing a mathematical expression and we said

a = a + 1

While the above means something in imperative programming languages (like C), it does not mean anything in mathematics.

 

Now say I want to write the factorial function in mathematics, I would say something like this

fact(0) = 1

fact(n) = n * fact(n-1)

And this definition is perfectly valid. However you notice that it is similar to the a = a + 1 expression in the sense that in describing the value of something, we refer to that very thing.

 

This general principle, called a recursive definition, has a problem in the context of pure functions (like the lambda calculus). The problem is as follows – a function is a nameless entity – the only named entities that a function can use are function’s parameters (the variables introduced by the function itself) or parameters of a parent function that it is define in the scope of.

 

For example

(lambda (x y)

      ; can use x and y here

      (lambda (a)

            ; can use a, x and y here

      )

)

 

Now for a recursive definition, a function needs to be able to refer to itself (or like we say in some languages, a functions needs to ‘call’ itself).

 

So, the only way that one can define a recursive function would be to receive the function itself as one of the functions arguments. Think about this for a bit – if you are not used to programming in a language where you can pass a function, or return a function as though it were a value (similar to how you treat an integer), then this might be a hard idea. If you are from a programming background that wherein you are used to ‘higher order’ programming, then I am only stating the obvious here. (The general idea with higher order programming is that functions are first class values, like integers – which means that they can be passed as arguments, returned from functions, stored in data structures etc).

 

So we define a function such that it takes an additional argument which is itself.

Lets say

 

factorial0(factorialx, n) = if n == 0 then 1 else n * factorialx(factorialx, n -1)

factorial(n) = factorial0(factorial0, n)

Does this make sense? If it does not, then don’t bother read further. You notice that the factorial0 function takes 2 arguments one of which is the function itself.

 

Let me rewrite this in scheme-style syntax

(let ((factorial0 (lambda (fact, n)

                    (if (zero? n)

                        1

                        (* n (fact fact (sub1 n)))))))

 (let ((factorial (lambda (n)

                    (factorial0 factorial n))))

      ; I can use factorial here

  ))

 

Make sense? Ok, so now let me write the interesting function factorial0 as a nested lambda as follows -

(lambda (fact) (lambda (n)

(if (zero? n) 1 (* n ((fact fact) (sub1 n)))))

 

You notice that fact is applied to fact, to generate the inner lambda which is then invoked with n-1.

 

So now, suppose one has a handy function of the following form

omega = (lambda (x) (x x))

 

One can define factorial as follows

 (let ((factorial

       (omega (lambda (fact)

                (lambda (n)

                  (if (zero? n)

                      1

                      (* n ((omega fact) (sub1 n)))))))))

  ; use factorial here

  )

 

There you go – so now we have a way of defining recursive function definitions even if your language did not directly allow a recursive definition.

 

So why do we need the Y combinator? You notice that in the definition of factorial we had to do something that looks very strange in the definition of the function – we call the function omega to return a function that we can call. The Y combinator does away with this for us.

 

To start thinking about the Y combinator, think about things this way – suppose the parameter ‘fact’ was already ‘(omega fact)’ then we wouldn’t have to call omega inside the definition of factorial correct. Right?

 

If we wanted that we simply need to rewrite omega this way right –

(lambda (x) (x (x x)))

Such that the first parameter is already applied to itself. But then this is not enough, because when the recursive call is made, the second time the parameter is only fact and not (fact fact) or (omega fact). Well, so we can fix this by having one more level in the definition of omega, such that omega looks like this –

(lambda (x) (x (x (x x))))

 

But then the third time this would not be the correct parameter… ideally we need an infinite application of x, because we don’t know how many times the function will call itself. In other words the omega should look a little like this

(lambda (x) (x (x (x (x (x … ))))

 

This is exactly what the Y combinator does. To see how it does this consider OMEGA defined as

OMEGA = (omega omega)

(or expanding for little omega we get)

OMEGA = ((lambda (x) (x x)) (lambda (x) (x x)))

 

If you haven’t seen this before, look at this device for a bit – do you see how it is infinite self application? If you do then consider the following

((lambda (x) (f (x x))) (lambda (x) (f  (x x)))

It doesn’t matter what f is right now, but see what this does. After one reduction this would look like this -

(f (term term))

Where term = (lambda (x) (f (x x)))

The second reduction would look like this and so on

(f (f (term term)))

(f (f (f (term term))))

 

This, if you notice is similar to what we required earlier, where instead of ‘f’ we used ‘x’.

 

This is the basic mechanism for the Y combinator. And the Y combinator is simply

Y = (lambda (f) ((lambda (x) (f (x x))) (lambda (x) (f  (x x)))

 

So how do we define a recursive function using the Y? Here is factorial

(let ((factorial (Y (lambda (fact)

                      (lambda (n)

                        (if (zero? n)

                            1

                            (* n (fact (sub1 n)))))))))

  ; use factorial here

 )

 

Nice?

 

Now in the beginning I said that this Y is the Y for the last normal order language. Scheme is applicative order and non lazy. What that means is that  if you use the Y combinator defined above in scheme, during the definition of factorial it will try to do the infinite expansion and will never terminate.

 

Instead one just eta-expands the definition to get the applicative order Y combinator. Suppose you say that term is (lambda (x) (f (lambda (y) ((x x) y))))

And we define the combinator as

Y = (lambda (f) (term term))

Then we have the applicative order Y that is usable from scheme and other applicative order languages.

Look at its expansion to see what I mean

(f (lambda (y) ((term term) y))

So the first parameter to ‘f’ (recursive function we are interested in is a lambda – the application inside the lambda is done only if f calls it.

 

Let me define both the Y combinators described here in lambda form

Y = \f.((\x.(f (x x)) (\x.(f (x x)))

Y = \f.((\x.(f (\y ((x x) y))) (\x.(f (\y ((x x) y))))

 

Once you see why the Y combinator is needed and you understand omega – its easy to see what the Y is and how it useful in defining recursive functions in a mathematically pure way.

 

The Y combinator is described as a fixed point function or combinator. The idea is that is lets a function describe its behavior in terms of itself until the function reaches a fixed point – like in the case of factorial the function reaches 0 and does not need to recurse any more.

 

References –

http://en.wikipedia.org/wiki/Y_combinator

http://www.dreamsongs.com/NewFiles/WhyOfY.pdf

 

Though I myself had looked at the Y many times before I never really understood it until I had to write recursive functions in the pure lambda calculus and I used omega to do it. I then happened to mentioned to Prof Friedman that I did not understand the Y and in a minute he set my thinking right.

 

I understand that in the description above I have taken some liberties with syntax and something are described in a hand wavy sort of way. However if you have suggestions about how I can better explain this, let me know. Of course I require that you understand scheme style syntax and higher order programming (at least minimally).

 

Sunday, January 29, 2006 12:57:21 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2]  | 
 Saturday, January 28, 2006

Some context –

 

The other day in Prof Dan Friedman’s Advanced Programming Languages class we had an assignment where we had to write a lambda calculus interpreter that did non deterministic application and we had to write the factorial in it. Also, reduction was to continue even if the top level term was value.

 

As a consequence of working on this we were expected to discover a method of encoding numbers using pure lambda terms. A really long time back Alonzo Church (creator of the lambda calculus) created an encoding now called the Church numerals. I created the following set when working on the factorial problem.

 

t = \a.\b.a     true

f = \a.\b.b     false

 

zero = \x.t

zero? = \x.(x f)

 

s = \x.\b.((b x) b)      successor

p = \x.(x t)             predecessor

 

(Like in Haskell the ‘\’ represent lambda). So we have a way of saying zero, we have a way of checking if a number is zero and we have the ability to add one and subtract one. That gives us all the natural numbers including zero.

 

If you notice, the predecessor define above returns a value that is an invalid number when applied to zero. An alternate ‘type safe’ definition is the following –

p = \x.(((zero? x) x) (x t))

 

Here (p zero) is zero.  

 

Now you may think that that’s not great way of implementing numbers – its inefficient etc. Yes that’s true, but remember that the lambda calculus is a formal system, it’s a mathematical formalism and hence has no notion of cost. In the study of formal systems (other than the study of their complexity) we are interested in asking questions about what the system can do and cannot do. The above encoding I believe is equivalent to the encoding of Church numerals.

 

Following the definition of numbers, I can define ‘add’ in the following obvious way -

add = (Y \add.\a.\b.(((zero? a) b) ((add (p a)) (s b)))

 

Here ‘Y‘ is the fixed point Y combinator and this is equivalent to

add(a, b)  { if a == 0 then return b else return add(a - 1, b + 1) }

 

Similarly one can define ‘mul’ and ‘factorial’ as well.

 

I went ahead and defined operators so that I have scheme/lisp style lists. I am told that there are very similar to Church’s definitions.

 

cons =  \x.\y.\b1.\b2.((b1 f) ((b2 x) y))

car =   \ls.((ls #f) #t)

cdr =   \ls.((ls #f) #f)

null =  \x.x

null? = \ls.(ls #t)

 

Hence we have –

(null? null) -> #t

(car null) -> undefined

(cdr null) -> undefined

(car (cons a b)) -> a

(cdr (cons a b)) -> b

 

Can you shoot yourself in the foot using these definitions? Of course you can – but if you are careful you can write meaningful programs as well. To do other sorts of checks, like to prevent us from doing (s cons) we need some kind of type system or validations rules – but these are not relevant to the discussion of the pure lambda calculus.

 

Here is a basic lambda calculus reference - http://en.wikipedia.org/wiki/Lambda_calculus

Here is a Church encoding reference - http://en.wikipedia.org/wiki/Church_numeral

 

Saturday, January 28, 2006 1:56:34 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, December 08, 2005

FooGroup Algebra is a little ‘algebra’ that I created while trying to solve a problem. It seemed sufficiently interesting to describe by itself. I would have liked to call it group algebra, but it seemd like the name would already have been taken, and it also seemed like that’s too nice a name to dedicate to something like this :)

 

FooGroup Algebra

 

A term in this algebra consists of one or more symbols enclosed in [] or (). An expression is a set of terms. The enclosing [] or () are called the type of the term. The symbols the enclose are called base of the term. The ordering of symbols inside a term is of no significance. The ordering of terms in an expression is of no significance.

 

Here are some expressions:

(a b c)[c d]

(a b)(c d)(a d)

 

An expression is said to be solved, if all the terms in the expression have only one symbol. The following is a solved expression:

(a)[b](c)(d)

The value of each symbol is the type of the term that it is held.

 

An expression is invalid or is a contradiction is there atleast two terms of different type but same base. The following expressions are contradictions:

(a b)[a b]

(a)(b c d)[a]

 

Term Reduction and Solving: One can solve and expression by reducing each term in the expression until every terms contains only one symbol. Terms can be reduced as follows –

(X Y) => (X)[Y] and [X](Y)

[X Y] => [X][Y] and (X)(Y)

Where X and Y are any set of terms.

 

Since a term can be reduced in two ways, there maybe more that one solution for a given expression. A valid solution cannot have a contradiction. Here are some example reductions –

(a b c)[c d]

(a)[b c][c d]

(a)(b)(c)(d)

 

This is another solution for the same –

(a b c)[c d]

(a)[b c][c d]

(a)[b][c][d]

 

This is another solution for the same –

(a b c)[c d]

[a](b c)[c d]

[a](b)[c][d]

 

This is another solution for the same –

(a b c)[c d]

[a](b c)[c d]

[a](b)[c][d]

Independent Variables: When reducing a term we select one variable and assign it both type values. The values of other symbols/variables might be get fixed as a consequence of this. Such variables are referred to as independent variables. In the general case, the maximum number of solutions than an expression can generate is 2^n where n is the number of independent variables. Since one or both choices of type assignment may result in a contradiction the number of actual solutions maybe lesser than this.

 

In the above example, there were two independent variables a and b. c and d values were fixed by the selection of values for a and b. Hence there were 4 solutions.

 

Ex:

(a b)(b c)(c a)

(a)[b](c)[a] <-- contradiction

[a](b)[c](a) <-- contradiction

This expression has no solutions.

 

(a b)(a c)(a d)[b c d]

(a)[b][c][d] <-- this is one solution

[a](b)(c)(d) <-- this is a contradiction.

The above expression has only one solution

 

End.

 

That’s it. That’s all I know about this thing. I would like to create a method to predict how many solutions an expression may have. I don’t know how to do that.

 

I also would like to explore extensions to the algebra in terms of adding more types to the algebra.

 

Adding More Types: Right now I have only two types () and []. One can think of the relation between these as that of the relation between –ve and +ve, or as odd and even.

 

()() = [] or odd odd = even or - - = +

()[] = () or odd even = odd or - + = -

 

One can consider adding three types (), [] and {} such that

() = []{} and {}[]

[] = (){} and {}()

{} = []() and ()[]

I don’t know what sorts of types map to.

 

One can consider +, -, +i and –i as four types as well and so on.

 

What is this useful for?

I was working on solving another problem and the search space for that was too large. I was looking for a way of reducing the search space and for compactly representing this search operation when I realized that I could express the problem like this.

 

The original problem was that I had a matrix like the one below. I could assign and + or negative sign to any variable such that the matrix when multiplied by its transpose would generate the identity matrix. (The transpose of a matrix is the matrix you get when you flip it along its diagonal).

a b c d

b a d c

c d a b

d c b a

 

Then I had to solve the problem for the larger 8x8 version of the same matrix –

a b c d e f g h

b a d c f e h g

c d a b g h e f

d c b a h g f e

e f g h a b c d

f e h g b a d c

g h e f c d a b

h g f e d c b a

 

These matrices are generated as a consequence of simple XOR order, that can be easily expressed by the following ruby program –

syms = %w(a b c d e f g h i j k l m n o p q r s t)

v = 8

v.times{|m|

      v.times{|n|

            printf("%s ", syms[n^m])

      }

      puts ""

}

 

The fact is that I had to solve the problem for matrices of any dimension that is a power of two and I couldn’t see any pattern that would help me automagically generate the signs for matrices of higher dimensions.

 

So I though about how to search the space of all possible sign assignment and then realised that I can group elements into groups of four such that each group would have 4 variables and would be of type (). As an example here is the expression in FooGroup algebra which when solved would give all the solutions possible.

(r1c0,r1c1,r0c0,r0c1)(r1c2,r1c3,r0c2,r0c3)(r2c0,r2c2,r0c0,r0c2)(r2c1,r2c3,r0c1,r0c3)(r2c0,r2c3,r1c0,r1c3)(r2c1,r2c2,r1c1,r1c2)(r3c0,r3c3,r0c0,r0c3)(r3c1,r3c2,r0c1,r0c2)(r3c0,r3c2,r1c0,r1c2)(r3c1,r3c3,r1c1,r1c3)(r3c0,r3c1,r2c0,r2c1)(r3c2,r3c3,r2c2,r2c3)

Where r0c1 is the symbol for the sign that should be given to element at row 0 column 1. (I further go on to fix my first row to be all positive numbers. )

 

Finally, if you are interested I have a .Net library to solve expressions in the algebra. I also have a ruby program that generates C# programs which get the library to solve the above matrix problem.  The build command takes as parameter the dimensions of the matrix that you wish to solve (this should be a power of 2).

Download FooGroup Algebra and the Matrix Solver

 

Running the solver on a 4x4 matrix generates 16 solutions. 2048 solutions for a 8x8 matrix.

Solving :(r1c0 r1c1)(r1c2 r1c3)(r2c0 r2c2)(r2c1 r2c3)(r1c0 r1c3 r2c0 r2c3)(r1c1 r1c2 r2c1 r2c2)(r3c0 r3c3)(r3c1 r3c2)(r1c0 r1c2 r3c0 r3c2)(r1c1 r1c3 r3c1 r3c3)(r2c0 r2c1 r3c0 r3c1)(r2c2 r2c3 r3c2 r3c3)

Solution 1 : (r1c1)(r1c3)(r2c2)(r2c1)[r2c3](r2c1)(r3c3)[r3c1](r3c2)[r3c1][r3c1](r3c2)[r1c0][r1c2][r2c0][r3c0]

Solution 2 : (r1c1)(r1c3)(r2c2)(r2c1)[r2c3](r2c1)[r3c3](r3c1)[r3c2](r3c1)(r3c1)[r3c2][r1c0][r1c2][r2c0](r3c0)

Solution 3 : (r1c1)(r1c3)[r2c2][r2c1](r2c3)[r2c1](r3c3)[r3c1](r3c2)[r3c1][r3c1](r3c2)[r1c0][r1c2](r2c0)[r3c0]

Solution 4 : (r1c1)(r1c3)[r2c2][r2c1](r2c3)[r2c1][r3c3](r3c1)[r3c2](r3c1)(r3c1)[r3c2][r1c0][r1c2](r2c0)(r3c0)

Solution 5 : (r1c1)[r1c3](r2c2)[r2c1](r2c3)[r2c1](r3c3)(r3c1)[r3c2](r3c1)(r3c1)[r3c2][r1c0](r1c2)[r2c0][r3c0]

Solution 6 : (r1c1)[r1c3](r2c2)[r2c1](r2c3)[r2c1][r3c3][r3c1](r3c2)[r3c1][r3c1](r3c2)[r1c0](r1c2)[r2c0](r3c0)

Solution 7 : (r1c1)[r1c3][r2c2](r2c1)[r2c3](r2c1)(r3c3)(r3c1)[r3c2](r3c1)(r3c1)[r3c2][r1c0](r1c2)(r2c0)[r3c0]

Solution 8 : (r1c1)[r1c3][r2c2](r2c1)[r2c3](r2c1)[r3c3][r3c1](r3c2)[r3c1][r3c1](r3c2)[r1c0](r1c2)(r2c0)(r3c0)

Solution 9 : [r1c1](r1c3)(r2c2)[r2c1](r2c3)[r2c1](r3c3)(r3c1)[r3c2](r3c1)(r3c1)[r3c2](r1c0)[r1c2][r2c0][r3c0]

Solution 10 : [r1c1](r1c3)(r2c2)[r2c1](r2c3)[r2c1][r3c3][r3c1](r3c2)[r3c1][r3c1](r3c2)(r1c0)[r1c2][r2c0](r3c0)

Solution 11 : [r1c1](r1c3)[r2c2](r2c1)[r2c3](r2c1)(r3c3)(r3c1)[r3c2](r3c1)(r3c1)[r3c2](r1c0)[r1c2](r2c0)[r3c0]

Solution 12 : [r1c1](r1c3)[r2c2](r2c1)[r2c3](r2c1)[r3c3][r3c1](r3c2)[r3c1][r3c1](r3c2)(r1c0)[r1c2](r2c0)(r3c0)

Solution 13 : [r1c1][r1c3](r2c2)(r2c1)[r2c3](r2c1)(r3c3)[r3c1](r3c2)[r3c1][r3c1](r3c2)(r1c0)(r1c2)[r2c0][r3c0]

Solution 14 : [r1c1][r1c3](r2c2)(r2c1)[r2c3](r2c1)[r3c3](r3c1)[r3c2](r3c1)(r3c1)[r3c2](r1c0)(r1c2)[r2c0](r3c0)

Solution 15 : [r1c1][r1c3][r2c2][r2c1](r2c3)[r2c1](r3c3)[r3c1](r3c2)[r3c1][r3c1](r3c2)(r1c0)(r1c2)(r2c0)[r3c0]

Solution 16 : [r1c1][r1c3][r2c2][r2c1](r2c3)[r2c1][r3c3](r3c1)[r3c2](r3c1)(r3c1)[r3c2](r1c0)(r1c2)(r2c0)(r3c0)

 

Thursday, December 08, 2005 12:18:21 AM (Eastern Standard Time, UTC-05:00)  #    Comments [7]  | 
 Monday, October 24, 2005

This article is relevant in the context of

Search for Yield the Magnificent

Yielding to Magnificence

 

Other relevant articles include:

Iterators that listen (for Python, by Sidharth Kuruvila)

Implementing a generator in Ruby (by Sidharth Kuruvila)

Implementation of Iterators in C# 2.0

 

I finally got down to ironing out the issues in the previous (rather hasty) entry about scheme iterators. I have code that is a little better tested.

 

To sell any idea, you have to demonstrate the value that believers in the idea get, before you discuss the cost. So here is the value –

 

Iterators support a style of programming where you separate producers of streams of data from consumers of these streams. For example you want to do a certain something on strings of text, irrespective of where the text comes from. In a more general case, iterators are a more powerful programming device, they can be thought of call-tree walkers, they can be thought of the notion of structured programming as applied to continuations. (Refer: Warming up to Iterators, Ruby: Containers, Blocks and Iterators, C#: Create Elegant Code with Anonymous Methods, Iterators, and Partial Classes)

 

The following is a demonstration of yield (similar to yield in Ruby, C# or Py) as a device to create iterators in scheme. There are some extensions to the idea, so the yield implementation here can do more things than the any of the other implementations can do (refer here for details). The implementation below is however useful in a functional context (its easy to see the use of yield in a imperative context). All of the code snippets below are functional in nature, the actual implementation of iterators need not be, but these internal details are abstracted away from you.

 

lambda-iter, yield, foreach

Iterators (functions that use yield) are defined using lambda-iter

 

(define even

  (lambda-iter ()

        (let loop ((i 0))

          (printf "even recieved ~a ~n" (yield i))

          (loop (+ i 2)))))

 

; Using foreach

(foreach (even)

         (printf "it = ~a ~n" it) ; ‘it’ is the yielded value

         (if (> it 20)

             (break 0)) ;break out if we has enough

         it) ;return the yielded value to yield

 

The even above is an produces an infinite stream of even numbers. The parameter to break is the return value of the foreach. ‘it’ is the value of the value that has been yielded. This common to many languages (Groovy, COmega etc). Everything else should be easy to understand.

 

coroutine, co-move-next, co-value, co-return, co-finished?, co-not-finished?

Iterators can be turned into first class entities as follows –

 

; Using coroutines explicitely

; Here the control flow mechanism is something we control

(let loop ((co (coroutine (even)))) ;create the corotuine object

  (let ((co (co-move-next co))) ; start/advance the execution

    (printf "Yielded ~a ~n" (co-value co)) ; print the yielded value

    (loop (co-return (co-value co) co)))) ;return the yielded value

 

There, that’s said, you have all the devices that you need for a yield the magnificent implementation for scheme. There are more things in this implementation to make it useful for general purpose programming, but this much covers all the intellectual content. What follows is some essential documentation after which we have some of the extra forms.

 

Documentation

lambda-iter

(lambda-iter <params> <body>)

Same as lambda, except that you can do a yield in its body

 

yield

(yield <value>)

Yields a value to the caller

 

foreach

(foreach <iterator> <body>)

Takes an iterator and list of expressions, the expressions are invoked everytime the iterator yields. The value yielded is available as ‘it’. The expression can abort from the foreach by calling break. The parameter to break is the return value of the foreach. If the iterator returns, before break is called, the foreach returns the value of the iterator. Tha value of the last evaluated expression in the expression list is the return value into the iterator.

coroutine – wraps the iterators into a coroutine object

 

coroutine

(coroutine <iterator>)

Wraps the iterator into a first class object and returns it.

 

co-move-next

(co-move-next <coroutine>)

Executes the iterator in the coroutine, till it yields or till it returns. The new coroutine is returned.

 

co-value

(co-value <coroutine>)

Retrieves the current value of the coroutine. This might be a yielded value or a return value of the iterator.  Functional programmers may want to use the analogy of car and cdr for co-value and co-move-next.

 

co-return

(co-return <value> <coroutine>)

Sets a return value into the coroutine and returns the new coroutine object. The return value is the value that will be avilavle as the return value of a yield call inside the iterators. Example (let ((a (yield 10)) … ) here the value of a will be the value that was set using a co-return in the coroutine object. 

 

co-finished?, co-not-finished?

(co-finished? <coroutine>)

Returns a bool to indicate if the coroutine has returned. If it has yielded and can potentially do something meaningful for subsequent co-move-next calls, co-finished will return #f. co-not-finished is the complement.

 

Recursive yields

;; recursive yielding

; yields all combinations of true and false for n bits

(define states

  (lambda-iter (n)

               (if (eq? n 1)

                   (begin

                     (yield '(#f)) (yield '(#t)))

                   (foreach (states (- n 1))

                            (yield (cons #f it))

                            (yield (cons #t it))))))

 

(foreach (states 5)

         (printf "state = ~a ~n" it))

Here is an example of recursive yielding. The states function returns all the values of a bit vector of size ‘n’ bits.

 

yield-all

yield all is a useful pattern sometimes when you recursively call iterators. Here is a tree walker that is implemented using yield-all and yield.

(define walk-tree

  (lambda-iter (tree)

               (cond

                 ((null? tree) '())

                 ((atom? tree)

                  (yield tree))

                 (else

                  (yield-all (walk-tree (car tree)))

                  (yield-all (walk-tree (cdr tree)))))))

 

(foreach (walk-tree '(1 2 3 (5 6 7) (4 5) 8))

         (printf "value ~a~n" it))

There is an intuitive way to think about these sort of programs – each node is a tree yields itself if it is a a leaf (an atom). Else it asks each of its children to yield-all.

 

Solving the Same-Fringe problem

The same fringe problem is the problem of comparing two trees to see if they have the same leaf values, irrespective of the structure of the trees. One way of solving the same fringe problem is to use the walk-tree defined above and create two couroutines, to represent the two trees that are to be compared.

(define same-fringe

  (lambda (t1 t2)

    (let loop ((t1 (coroutine (walk-tree t1)))

               (t2 (coroutine (walk-tree t2))))

      (let ((t1 (co-move-next t1)) (t2 (co-move-next t2)))

        (if (and (co-finished? t1) (co-finished? t2))

            #t

            (if (or (co-finished? t1) (co-finished? t2))

                #f

                (if (eq? (co-value t1) (co-value t2))

                    (loop t1 t2)

                    #f)))))))

 

The intuitive way of looking at this is that it created two coroutines and advances both of them. If they both finish, then the trees have same fringe. If only one of them have terminated then the trees are not equal with respect to fringe values. If neither of them have terminated and the values they yielded are the same, then we can loop and ask for the next value. As an aside, I find the code above to be far more readable that the equivalent in the Dorai Sitaram text.

 

coroutines, co-all-move-next, co-all-finished?, co-any-finished?

Here is a solution to the same fringe using some handy helper routines that help with dealing with collections of coroutines. These functions are usually useful only when all the coroutines are similar or related in some way.

(define same-fringe2

  (lambda (t1 t2)

    (let loop ((ts (coroutines (walk-tree t1) (walk-tree t2))))

      (let ((ts (co-all-move-next ts)))

        (cond

          ((co-all-finished? ts) #t)

          ((co-any-finished? ts) #f)

          ((eq? (co-value (car ts)) (co-value (cadr ts))) (loop ts))

          (else #f))))))

 

Solving the repmin problem

The repmin problem requires that you trake a tree and construct a new tree where every leaf is replaced by the global minimum leaf value  of the original tree. (This is the problem that started this saga off and was the one that none of the C#, Ruby, Py yields could handle)

The solution below can repmin trees not only binary trees, but trees of any arity. This shows of the flexibility of the some of the couroutine list comprehension functions  that are available –

;a powerful repmin that works on trees with arbitrary numbers of leaves

(define repmin

  (lambda-iter (tr)

               (cond

                 ((atom? tr) (yield tr))

                 ((null? tr) '())

                 (else

                  (let* ((co-trs (co-all-move-next (map coroutine (map repmin tr))))

                         (co-vals (co-values co-trs)))

                    (co-values

                     (co-all-move-next

                      (co-all-return (yield (apply min co-vals)) co-trs))))))))

 

 

;Test

(define tree1 '(3 ((2)) (3 4) 1))

(printf "Repmin of ~a is ~a ~n" tree1 (foreach (repmin tree1) it))

 

Documenting the extra forms

yield-all

(yield-all <iterator>)

Equivalent of (foreach <iterator> (yield it))

 

coroutines

(coroutines <iterator>+)

Create a list of coroutines. Equivalent of (map coroutine <iterator list>)

 

co-all-finished?

co-none-finished?

co-any-finished?

(co-all-finished <coroutine list>)

 

co-values

(co-values <coroutine list>)

Returns a list of values, which are the value sof each of the coroutines

 

co-all-move-next

(co-all-move-next <coroutine list>)

Moves all the coroutines in the list to the next value and returns the new list of coroutines.

 

co-all-return

(co-all-return <value> <coroutine list>)

Applies a return value to all of the coroutines and returns the new list of coroutines.

 

co-each-return

(co-each-return <values list> <coroutine list>)

Applies a return value from the values list to each of the coroutines and returns the new list of coroutines.

 

 

Implementation

Here is the implementation of coroutine, yield and all the support stuff…

 

;Roshan James (Mon 10/24/2005)

;call/cc based implementation of Yield the Magnificient for Scheme

;

;Yield the Magnificient:

;http://www.thinkingms.com/pensieve/default,date,2005-10-11.aspx

;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;

;A coroutine is represented by a list of 3 values. The first of these is a

;proc(1), the second is a value(2), the third is a bool(3). According to

;different stages in the lifetime of a coroutine, these have different values.

;

; Values of proc(1)

;1) When a corotuine is created the proc is the 'first lambda'

;2) When the iterator is running, the proc is the continuation of the iterator

;3) When the iterator has returned, the proc is the null-proc.

;

;Values of value(2)

;1) When the coroutine is created, it is simply #t

;2) When the iterator is running, it is the current yielded value

;3) When the iterator has returned, it is the final return value

;

;Values of bool(3)

; The bool of #f after the iterator has returned. Until then the bool is #t.

;

;Coroutines can be sent return values, by replacing value(2) in the list

;before calling co-move-next. Once a coroutine has terminated, co-move-next can be

;called an infinite number of times without having any effect. The return

;value is preserved (all these calls are sent to null-proc).

 

 

(define coroutine

  (lambda (prod)

    (list (lambda (ret) ;first lambda

              (letrec ((esc (car ret))

                       (null-proc (lambda (x)

                                    (cons null-proc (cdr x)))))

                (let ((stopped (list null-proc

                                  (prod (lambda (it)

                                          (let ((res (call-with-current-continuation

                                                      (lambda (k)

                                                        (esc (list k it #t)))))) ; iterator k

                                            (set! esc (car res)) ;Evil!

                                            (cadr res))))

                                  #f)))

                  (esc stopped))))

          #t #t)))

 

(define co-move-next

  (lambda (co)

    (call-with-current-continuation

     (lambda (esc)

       ((car co) (list esc (cadr co) (caddr co)))))))

 

;There is no intellectual content past this point, the rest of the code is required

;to provide abstractions that I thought are are useful from my experince with using

;yield.

 

(define co-value

  (lambda (co) (cadr co)))

 

(define co-finished?

  (lambda (co) (not (caddr co))))

 

(define co-not-finished?

  (lambda (co) (caddr co)))

 

(define co-return

        (lambda (val co) (list (car co) val (caddr co))))

 

 

;Some useful macros

 

;create a producer that has a implicit curried yield

(define-syntax lambda-iter

   (lambda (f)

     (syntax-case f ()

       [(_ (x* ...) body body* ...)

        (with-syntax ([yield-syntax (datum->syntax-object (syntax _) 'yield)])

          (syntax

             (lambda (x* ...)

               (lambda (yield-syntax)

                   body

                   body* ...))))])))

 

;can be called in an iterator to yield all the values yielded

;by an iterator it is calling

(define-syntax yield-all

   (lambda (f)

     (syntax-case f ()

       [(_ iter)

        (with-syntax ([yield-syntax (datum->syntax-object (syntax _) 'yield)])

          (syntax

             (iter (lambda (it) (yield-syntax it)))))])))

 

;a foreach that mostly useful only in an imperative context

(define-syntax foreach

   (lambda (f)

     (syntax-case f ()

       [(_ iter body* ...)

        (with-syntax ([it-syntax (datum->syntax-object (syntax _) 'it)]

                      [break-syntax (datum->syntax-object (syntax _) 'break)])

          (syntax

           (call-with-current-continuation 

            (lambda (break-syntax)

              (break-syntax (iter

                      (lambda (it-syntax)

                        body* ...)))))))])))

 

;reduce

(define reduce

  (lambda (proc ls)

    (cond

      ((null? (cddr ls)) (proc (car ls) (cadr ls)))

      (else

       (proc (car ls) (reduce proc (cdr ls)))))))

 

;useful functions for dealing with lists of iterators

(define coroutines

  (lambda ls

    (map coroutine ls)))

 

(define co-all-finished?

  (lambda (ls)

    (reduce (lambda (a b) (and a b))

            (map (lambda (iter) (co-finished? iter))

                 ls))))

 

(define co-any-finished?

  (lambda (ls)

    (reduce (lambda (a b) (or a b))

           (map (lambda (iter) (co-finished? iter))

                ls))))

 

(define co-none-finished?

  (lambda (ls)

    (reduce (lambda (a b) (and a b))

           (map (lambda (iter) (co-not-finished? iter))

                ls))))

 

(define co-values

  (lambda (ls)

    (map co-value ls)))

 

(define co-all-move-next

  (lambda (ls)

    (map co-move-next ls)))

 

(define co-all-return

  (lambda (ret ls)

    (map (lambda (iter) (co-return ret iter)) ls)))

 

Here are the files for download.

 

What is the value of all of this?

The value of all of this would be to look at the above as a general way of implementing yield in languages where the approach is to pass a closure from the caller to the callee. Ruby is another language in this category and I believe the Generator class was an attempt to solve this problem.

 

The real value in all of this is in setting a base for further exploration of the style of programming that yield lends itself to. Is it sufficiently expressive to express all implementation of certain classes of problems? If so, then yield maybe useful as a primitive building block for large classes of control structures in programming languages. If not, all of this was fun anyway. :)

 

Download

 

 

Monday, October 24, 2005 5:40:28 PM (Eastern Standard Time, UTC-05:00)  #    Comments [6]  | 
 Saturday, October 15, 2005

Python

Firstly, halfway across the planet, Sid created what could be for most part Yield the Magnificent for Python. (I am not fully convinced that he hasn’t lost property 6, but he has fixed 3 and 5.) But that should not come as much of a surprise to me because I have met few Py programmers like Sid :) Here is Sid’s Iterators that Listen

 

Scheme

Here is something that I have for scheme. It needs to have details ironed out. But effectively this does a coroutining “transform” of the caller. This puts it in the same category of ‘solution’ as ruby’s ‘generator’ class. This is also the operational equivalent of what py and c# have done. In the scheme world resume state is maintained by a continuation. In the Py or C# world, state is maintained by creating an object. For the scheme solution below, the basic ideas came from the brain storming session with William Byrd and Matt Ellis on this Friday.

 

Here is the scheme code:

(define coroutine

  (lambda (prod)

      (list (lambda (ret)

        (let ((esc (car ret)))

          (list (lambda (x) x)

                (prod (lambda (it)

                        (let ((res (call-with-current-continuation

                                    (lambda (k)

                                      (esc (list k it #t))))))

                          (set! esc (car res)) ;Evil!

                          (cadr res))))

                #f)))

            #t #t)))

 

(define move-next

  (lambda (co)

    (call-with-current-continuation

     (lambda (esc)

       ((car co) (list esc (cadr co) (caddr co)))))))

 

(define valueof?

  (lambda (co) (cadr co)))

 

(define finished?

  (lambda (co) (caddr co)))

 

(define set-return

        (lambda (co val) (list (car co) val (caddr co))))

 

Writing a Producer / Generator / Iterator

One this is in place one can write an iterator that looks like so –

(define even

  (lambda ()

      (lambda (yield)   

        (let loop ((i 0))

          (display (yield i))(newline)

          (loop (+ i 2))))))

 

It is conceivable that we can have a macro to hide the currying of the inner lambda (yield). However it is easy to see that One can write producers that assume that they have a yield keyword handy.

 

Writing the consumer

To use the use the iterator as a first class object, you simply do –

(let loop ((co (coroutine (even))))

  (let ((co (move-next co)))

    (display "Yielded ")(display (valueof? co))(newline)

    (loop co)))

 

Consumer code like the above is free from any forced invocation by the producer and hence does not need a ‘break’.

 

Functional programming

The co objects are first class and can be passed around – they are not bound to any syntactic structure. Hence having a yield facility is now meaningful in a functional context (which was one of Will Byrd’s concerns). The implementation of the coroutine is itself is not functional.

 

Lockstep iteration / apply-iterator / Iterator composition

It is conceivable that when you have a one one producer you might want a syntactic structure that also gives you a break.

 

However I don’t think its meaningful to create a general purpose apply-iterator. The reason is simple: Iterators are blocks of code that can yield a arbitrary number of values. If you decide to lockstep with each iterator producing a different number of yields, when should the composition of these iterators stop? There would be problems that need all of them can halt when the first one halts. There would be others where you might want the last iterator to stop before the the whole structure stops. So at the least you need at least ‘and’ and ‘or’ semantics between the finished cases. There might be algorithms where you need other behaviors.

 

Instead of defining these syntactic structures and defining rules for composition it is sufficient to convert individual iterators into coroutines. You can see that it would be very handy to have some nice list comprehensions to make it easy to use several coroutines in combination. As a matter of fact, all sorts of useful macros could be devised. However, there maybe no useful apply-iterator operator.

 

Now who can fix my imperative favorites, C# and Ruby?

Saturday, October 15, 2005 9:39:12 PM (Eastern Standard Time, UTC-05:00)  #    Comments [4]  | 
 Wednesday, October 12, 2005

Last night I was writing some for OS161 – I was implementing a fork(), execv(), getpid(), waitpid() and exit() for the OS161 kernel. I was using Visual Studio Express VC++ edition beta2 to write the code and I had a little ruby script to upload changed file to my linux (gasp!) box and a little script there that would build the kernel whenever the files changed. That way I get to develop code on an OS that has a notion of a unified clipboard and such pleasantries and get to build it wherever the tools are available. I also got a minimal shell like first process done.

 

Don’t get me wrong when I say this, but I sometimes like to think of myself as a fairly decent imperative programmer – I would be comparably good to many people you might meet. Ever since I came to college functional programming has been rewiring my brain. And its beginning to hurt. And I am enjoying it. And sometimes you need a break.

 

Hence writing missing pieces in a simplistic os kernel is a nice break. And I am going “Ooh! Look I have variables! Ooh! Look I can reassign the value of this thing. Look, I have loops”. And that’s a nice world to be in, if you can think in terms of state well – for those of you imperative programmers don’t know what that is, it means that things have changable values (like x=5 and x ++;) – and those of you who don’t realize you are imperative programmers, here is a simple test: if you are not a Haskell (and similar) programmer Or Scheme programmer (without set!) Or mathematician Or someone who goes from day to day without anything in the world affecting you, you are a imperative programmer of some device.

 

So I was enjoying being imperative for a while and then when I had it all going halfway into the night – I had multiple processes forking and execing and waitpiding and exiting – the whole crashes. And then it crashed again. And this was crazy, because all the of the pieces were things I had tested separately and yet they crashed when they came together. Somewhere in the back of my head there was this little elephant called lambda laughing on the floor ignoring his cons-kit for a bit. But wait a minute, I thought all this functional programming was making me a better programmer – I thought I could think more clearly about composition.

 

After about 2hours of meditation and atleast one or two sets of forays into the debugger as a last recourse, I realized what the problem was that I was not writing things back onto the user space stack in the correct alignment in some cases – and the this was some dword alignment requirement of this machine that was not mentioned anywhere. Lambda and the Turing tape looked down, looking a little sorry. I was in a bad mood by the end of it and that wasn’t fair – that was my little imperative break.

 

All of this, gets me to some of the conversations with some of my professors here. Dan Friedman is one of the kindest gentlest people you can talk to – and pretty much every other sentence some brain mutilating idea, said in the kindest subtlest way possible. So it happened that I needed to prove that something is not possible (it is related to the hypothetical apply-iterator operator I speak of here). Fifiteen minutes after the conversation I am thinking about higher order programming with continuations and my brain is hurting. (do you know what that means? If you don’t you need to go though the experience of hitting upon an idea that changes the way you look at the world. Changes the way you look at the world does not mean that the next time you eat a burger you look at it slightly more from the left, it is a little more encompassing an idea.)

 

An idea isn’t responsible for the people who believe in it.

 

Programming languages are devices to express thought. The fact that you can also create software using them are only secondary to this larger idea. Languages carry ideas of meaning and operation and you can compose these things together to create larger meanings and wider operations, or compose them to narrow down their scope. If you are a starting C programmer or an accomplished C# or Java programmer, it maybe hard to see things this way – but that is ok, you don’t always have to know the full import of what you could be doing. (I will write about Haskell and the wizard called Prof Amr Sabry some other time.)

 

One of the hardest things or like Prof Friedman says it is probably the simplest of all things is the idea of a continuation. It is an idea so simple that it drives you crazy trying to understand it. Imagine that if you did something, anything, it has rippling effects across the rest of all time – now imagine that you can take this ‘rest of all time’ and assign it to a variable and pass it around through all the operations you do, such that at some time you can go back to that rest of the world. That is a continuation. That as a programming device is good way to inflict some brain damage if you try to internalize it.

 

That’s about when I thought I should quit. That I probably should not go functional. All of this was too hard – you start out with something because you feel that there is some beauty and some truth in it. And when that fails you, maybe its time to betray you way of thinking – maybe its time to quit. By this point, you realize, that I might be quiet crazy, and that it might be rubbing off on you since you are still reading this. Betray the temple of Lambda?

 

That’s when Judas’s song from Jesus Christ Super Star (which I have been listening to a lot these days) plays in the back of my mind, when he does to Caiphus to betray Christ -

Now if I help you, it matters that you see

These sordid kinda things are coming hard to me.

It's taken me some time to work out what to do

I weighed the whole thing out before I came to you.

I have no thought at all about my own reward.

I really didn't come here of my own accord.

Just don't say I'm ... damned for all time.

 

I came because I had to; I'm the one who saw.

Jesus can't control it like he did before.

And furthermore I know that Jesus thinks so too.

Jesus wouldn't mind that I was here with you.

I have no thought at all about my own reward.

I really didn't come here of my own accord.

Just don't say I'm ... damned for all time

- Damned for All time, Judas’s Song, JCSS.

 

And then something snapped back in place and I was at it again. Why have such a device as continuations? Why bother? Well we understand little of continuations in my opinion. They are a thinking tool for the future. How can something so mind bogglingly hard be useful?

 

A long time back I remember seeing a beginner book about BASIC programming. That book had an example of the quicksort algorithm in basic written using gotos. It was a only a few lines. I spent a whole evening trying to understand what that was doing. And I didn’t succeed. I could execute the statements in my mind and see how they work, but I could see how such a beast could be created. I couldn’t see the way you would have to think to create something like that. Several years later I saw copper bars by Tylisha C Anderson and it was the same death by gotos. I could not understand it.

 

Many years ago they got together and killed off gotos and created a new-kid-on-the-block called structured programming. They took gotos and created a set of patterns that are sufficiently expressive to do anything that you could do using gotos. And then they killed off goto. The offspring forms the basis of almost all imperative programming today.

 

The real value of something powerful that we cannot tame yet is in what you can derive out of it. That’s when you say, in the conventional sense, that something is sufficiently mature – when people who don’t understand the first thing about it can use it to solve their programs (that’s the sense in which I sometimes say that windows is more mature than linux…). I think I should stop now. As you can see, college has been fun so far.

 

What then to do about this Jesus-mania?

Now how to we deal with a carpenter king?

 

Where do we start with a man who is bigger

Than John was when John did his baptism thing?

- This Jesus must die, Song of the Priests, JCSS

 

I dreamed I met a Galilean;

A most amazing man.

He had that look you very rarely find:

The haunting, hunted kind.

I asked him to say what had happened,

How it all began.

I asked again, he never said a word.

As if he hadn't heard.

                        - Pilate’s Dream, JCSS

Wednesday, October 12, 2005 9:37:40 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Tuesday, October 11, 2005

After a long time, one missing piece in the yield (iterator) puzzle fell in place in my head. It should have been obvious because it had been staring at me in the face for a while now. I am not sure, but it seems to me at this moment, that some of this might be of lasting importance beyond the scope of this blog entry.

 

Time warp 3 or 4 years back to when Sid and I were discussing ruby iterators and python list comprehensions. Sid had this notion that there was something missing in the Python implementation that made ruby iterators more powerful. We however could not place it at that time and we let it be. And we missed it for years after that. I am going to make some claims that some languages can and cant do certain things – I might be wrong and I hope that I am – if I am do show me how and maybe we can take this forward.

 

The most powerful yield (iterator) construct that I can think of, needs all of these –

1)     the parent function that takes arguments

2)     the parent function yields values

3)     the parent function can return a one or more values finally and terminate

4)     the parameter block of the yield should be able to ‘break’

5)     the yield should be able return values into the iterator

6)     it should possible to iterate two or more iterators in an interleaved manner.

 

1 and 2 are obvious. Almost all implementations of yield do this.

 

3 means that there is a notion of the function returning a value as the exit case of the function (such that the function instance terminates and that it will not produce any more values).

 

4 means that you should be able to do this

x.each {|y| break }

 

5 means that you should be able to do this

def foo

      n = yield 5

      puts n

end

 

6 means that you should be able to do this

a = foo1()

b = foo2()

puts a.next() + b.next()

puts b.next() + a.next()

 

Now, here is the search for yield the magnificent – I don’t a language that gives me a yield that can do all of the above and I am upset.

 

C# and Python rely on transformation of iterator (the callee) into an object that models the the state machine of iterator code. They use the objects state to maintain the environment for their closure (their state machine transformed iterator function). Read more about C# 2.0 iterator implementation here. The ruby way as I understand is that the callers block is passed to the callee as a closure. Scheme does not intrinsically have a yield, but you make an equivalent by passing a closure to a callee function. I am aware that there are other languages that implement the yield – Comega and Groovy, Icon and CLU – I don’t much about these (except that I believe that Cw is similar to C# in this regard), and so I wont discuss them here. Ever since ruby popularized the construct, it has found its way into many languages.

 

All of these support 1 and 2 above.

 

C# and Python support 4 and 6. They don’t support returning values from the function and do not support sending values into the iterator. This means that you cannot write code similar to the powerful inject and other similar ‘reduce’ like constructs. Here is what the inject (courtesy of smalltalk looks like)

 

class Array

      def inject n

            each { |v| n = yield n, v }

            return n

      end

end

 

def sum ls

      v = ls.inject(0){|n, v| n + v }

      return v

end

 

Inject is very powerful as it enables creating a large number of reduce like behavior. Inject itself is only one example of many things you can do if you can control the execution of iterator by passing it values from its consumer. The argument in favor of the return is weaker, but it is sufficient to say that it it important to separate a final value, from that of the last yielded value.

 

(I am not sure that Py cannot return a final value. If I am correct it terminates iteration of next() calls by throwing an exception. It don’t know if it captures a return value in the function object)

 

 

Scheme iterators, the simplistic approach that I have in mind is

(define iterator

       (lambda (x cls)

             (cls (+ 1 x)) ; yield 1

             (cls (+ 2 x)))) ; yield 2

(define caller

       (lambda ()

             (iterator 10

                    (lambda (n) ; this lambda is in the lexical scope of caller

                           (display n)))))

 

Should be equivalent to

def iterator  x

      yield x + 1

      yield x + 2

end

def caller

      iterator {|n|

            puts n

      }

end

 

The limitation in scheme is that you cannot do a ‘break’ the block of the caller. Atleast there is no easy way to do this without grabbing a continuation at the point of the call of the call to ‘iterator’, and then invoking the abortive continuation in the closure argument cls.

                       

If if it given that the abortive continuation is a natural way to do this, it is not obvious about how two iterators can created to lockstep iterate into a single block of code. I will discuss this further below.

 

So scheme can do 1, 2, 3 and 5. It can’t ‘break’ without continuations and cannot interleave or lockstep iteration in any obvious way.

 

Ruby, by far comes out with a lot of the above – the only thing it can’t do is 6, that you cant interleave iterations. The fact that you cannot interleave or lockstep iterations means that there whole classes of problems that you cannot solve. The simple case is the classical example of co-routines or continuations, the problem of comparing leaves of two trees. To compare the leaves of two trees the standard solution is write a routine that traverses the tree recursively and yields leaf values out of the recursive structure. You can then write a simple compare routine that initializes two instances of this procedure with two trees you want to compare, and then it merely compares the yielded values. This is the solution in Comega –

 

//the int* represents a stream of 0 or more ints. It is not a int pointer.

static int* getleaves(node n)

{

       if(n != null)

       {

             if(n.value != null)

                    yield return n.value;

             else

             {

                    if( n.left != null) yield return getleaves( n.left );

                    if( n.right != null) yield return getleaves( n.right );

             }

       }

}

 

static bool samefringe(node tree1, node tree2)

{

       en1 = getleaves(tree1).GetEnumerator();

       en2 = getleaves(tree2).GetEnumerator();

 

       t1 = en1.MoveNext();

       t2 = en2.MoveNext();

      

       //this is the lockstep iteration

       for(; t1 && t2; t1 = en1.MoveNext(),  t2 = en2.MoveNext())

       {

             if( en1.Current != en2.Current )

                    return false;

       }

       return !t1 && !t2;

}

 

As you can see, the class of problems that fall into the above category is fairly large and its annoying that they cant be solved in ruby.

 

Note: Ruby provides something called a generator to solve the problem of lockstep iteration. I like the language they describe this in –

Generator converts an internal iterator (i.e. an Enumerable object) to an external iterator.

Note that it is not very fast since it is implemented using continuations, which are currently slow.

 

The first problem is that it grabs continuations over something that already manages state. Lets assume that that’s transparent to us and is a non-issue, there is a larger problem that generator created iterators violate some of the other requirements, specifically 5: how you can send values into the iterator.

g = Generator.new { |g|

      n = "hello"

      loop {

             n = g.yield( n ) 

             puts n

             break if n == nil

      }

}

g.each {|n|

      puts n

      n + "."

}

This code does not work as expected (does not generate hellohello.hello..hello…). If there is something amiss above that you can point out, let me know.

 

All of this brings us closer to the conclusion – you will notice that there are two approaches to the implementation of iterators – one where the callee (the iterator) is closure converted (like C#, Python…) and the approach to grab a closure in the caller with a light-weight or heavy-weight abortive construct (as in Ruby and Scheme). Here is a pleasant discussion on iteration styles.

 

Finding Yield the Magnificent

 

Fixing the C# and Py approach requires two potentially simple changes. Make the C# MoveNext() or the Py next() functions take an argument. This is not strictly semantically correct, because this means that if MoveNext or next are used to start the computation then the first value passed is ‘hanging in space’. This fixes requirement 5. To fix 3 it is enough to create a new member in the closure object that retains the return value.

 

While this might be all very well in Py, its probably not as easy in C# or other strongly typed systems since you hit a syntactic limitation about where you express the return type of the function and the types of the value that yield returns to the function.

 

 

Fixing lockstep in a blocks/internal iterators/scheme-ruby-style approach can be done if it is possible to create a combinator that takes multiple iterators and a block that takes multiple values and does an iterator equivalent of scheme’s ‘apply’. I don’t if such an apply-iterator operator exists. Maybe this was the difficulty they weren’t built into ruby in the first place. I don’t have a solution to interleaved iteration when it’s the caller that is closure converted – there is probably no valid general purpose transformation of this sort possible.

 

 

There, I am glad all of this is said finally. I knew it all at the back of my mind as a shapeless dark area in my understanding of yield from which I could derive working knowledge, but nothing quantified. What started off all of this is that I finally needed a yield that did all of the above – that seemed to be the only natural way to express a particular algorithm. Now that all of this is said its quantified, weather it is all right or wrong. I will be happy to see what ideas you can contribute to the above discussion. I would also like work of the apply-iterator operator or if such a beast exists and you know about it, let me know.

 

I will get down to proof-reading this soon.

Monday, October 10, 2005 11:44:25 PM (Eastern Standard Time, UTC-05:00)  #    Comments [13]  | 
 Friday, October 07, 2005

This is an implementation of the Mini Kanren logic system for the CLR. This was done last night, so you can take it with a pinch of salt. It does not cover the full set of constructs that original MK system covers. Here is a overly simplified introduction to miniknaren.

 

This implementation is done in Cw, the experimental language from MSR. You will need the COmega compiler if you wish to compile the source.  

 

This implementation covers the basic ‘run’, ‘all’ and ‘conde’ constructs. You do not need a ‘fresh’ because I use the Cw type system and scoping to give me the equivalent of fresh. MiniKanren is implemented as an embedded language in scheme – so you get to do relational programming and then drop into scheme’s functional host language as need be. Since this implementation runs over Cw, this extends and hence you get a combination of a declarative logic programming system on top of everything that is Cw.

 

I am considering adding some more constructs and maybe a relational arithmetic system. I am also considering extending Cw syntax using an external precompiler so that it becomes as little more natural to write relational programs. The present ‘syntactic beauty’ is well a little lacking..

 

All that said, here are the sources from last night.

 

q = new Var();

a = new Var();

b = new Var();

c = new Var();

 

res = Mk.run( q,

      Mk.eq( q, new object[]{ a, b}),

      Mk.eq( a, c ),

      Mk.eq( c, 10),

      Mk.conde(

            new goal[]{ Mk.eq(b, 5) },

            new goal[]{ Mk.eq(b, 10) },

            new goal[]{ Mk.eq(b, 20) },

            new goal[]{ Mk.eq(b, 25) },

            new goal[]{ Mk.eq(a, 50) }

      ));

 

//res is the potentially infinite lazy evaluated set                            

r  = res.{ return Var.ToString( it ); };

r.{ Console.WriteLine( it ); };

 

A logic programming system is a great way to implement solutions to several kinds of problems like dependency analysis, all searching any relational space (ex: A Type Discipline for Authorization Policies)

 

Disclaimer:

(I am not responsible for your divergences).

(I am also not responsible for any halting problems with your compilation process).

(The full credit of MK goes to its original authors. This implementation is merely a transliteration with a certain imperative flavor added).

Friday, October 07, 2005 1:45:47 PM (Eastern Standard Time, UTC-05:00)  #    Comments [4]  | 
 Monday, August 01, 2005

I just finished reading Erik Meijer and Peter Drayton’s work-in-progress paper on programming languages and type systems. The paper as correctly noted in the beginning is written-to-provoke and I think this line of work is required today when technologies like .Net and the JVM have opened up possibilities of experimenting with languages and language systems and potentially reduced barriers for acceptance of new languages. The value proposition the expressiveness of a new language provides can be more readily accepted today in frameworks like .Net where a programmers existing knowledge/use of an API and an existing code base will not be lost by switching over to the new language.

 

The paper touches a large variety of topics and is more in brain dump of thoughts around the general area of type systems in dynamic and static languages. They also have some very interesting pointers and references.

 

The papers discusses type inference, programming by contract as opposed to having the type system as the only means of contract, subtyping and potentially expressing subtyping as programming by contract, type-directed lifting in Cw and how that can be used as opposed to non-intuitive reflective code.

 

The paper talks mentions the SqlDataReader – even if you don’t grok anything else in the paper, try and understand this part and try and see the need to a better programming language model – especially if you have ever worked on the data tier or business logic tier of an n-tier data centric application.

 

The paper also mentions lazy evaluation and about potentially deprecating the need for using eval if you have a better system in place for most of the common uses of eval.

 

On the whole it’s a paper that worth your time if you have started thinking about why when using C++ its so damn hard to get anything right, why C# cant be a little more flexible when handling collections, XML like or SQL like data and why languages like your pet python or ruby don’t make the mainstream.

 

http://pico.vub.ac.be/~wdmeuter/RDL04/papers/Meijer.pdf

Monday, August 01, 2005 2:30:34 PM (Eastern Standard Time, UTC-05:00)  #    Comments [3]  | 
 Saturday, May 07, 2005

For a long time I have been using this little program misnamed netshortcut. It’s a little command line that pops when you press a key-combination; commands that it supports are configured into a rules file using a rudimentary declarative language that evolved ‘as-appropriate’. Read more about it here

http://www.thinkingms.com/pensieve/homepage/work/netshortcut/netshortcut.htm

 

While I had been using NS for a while, there was this growing frustration that it could be made to do more things – if it had a better designed language underlying it. This frustration continued for a long time, until sometime early last year I got to working it out. I had lots of help from Sid, against whom I would bounce the creations of my genius.

 

Today the notebook in which we had worked out our plans resurfaced after a year. I didn’t want to loose this stuff again, though it was going to be an embarrassment for the future – and hence this blog entry.

 

I remember Sid saying that is some south american there are a sort of monkeys that have really long tails that hang down branches when they sit. And I say “so?”. And he says ‘So maybe you can use that idea in your language’. I ponder that for a while and then figure that I won’t be so useful. I hindsight, maybe Sid was right after all…

 

So here is the language, in wonderfully non formal description -

 

<pattern> {

      do ( <args> ) { <code> }

      is { <value> }

 

      comment <string>

 

      def <ident> {

            render <password | list | text>

            include <filename>

            alias <pattern> <name>

            code { <code> }

            <one or more pattern blocks>

           

}

}

 

That’s it. All programs have to begin in some scope, so this language’s global scope is same as the scope that corresponding to the inside of an def <ident> { <this is the global scope> }.

 

Remember that this language is fundamentally declarative is used primarily as metdata for a command line. The standing idea was the code blocks inside do() {} and is {} would be handled by a regular programming language that allowed interpreter hosting – the idea was to go with ruby then.

 

There is also the notion that braces can be eliminated except for do and is blocks. If a var does not have a do or is block is its value is simple returned back up the tree.

 

Here is a definition for supporting invoking the browser to do a google search. The user at the NS command line would type something like this –

gg <what to search for>

 

Imagine we have a file called library.rb that has

def browser(url)

      # invoke browser with specified url

end

def urlEncode(value)

      #return a urlEncoded version of value

end

 

This will be the NS rules file –

 

include “library.rb”

 

gg {

       do (arg ) { browser(“www.google.com?q=#{arg}”) }

       comment “Search Google”

       def arg {

              * {

                     is { urlEncode(value) }

              }

}

}

 

Note that ‘value’ that is passed to the urlEncode() is a special variable that holds the value of the current match (* matches to anything).

 

Now this does look a little clunky (and yes unintuitive) but with the defaults and with some braces reduction it would look like this –

 

include “library.rb”

 

gg do(arg){ browser(“www.google.com?q=#{urlEncode(arg)}”) } comment “Search Google”

 

Neat?

 

The language actually allows for a LOT of flexibility for controlling what gets executed for what the user types, what comments are displayed, how the UI gets rendered etc. I cant really describel all of that here, but this is the essence -

-          The lowest do() {} block that is satisfied is executed wrt a command.

-          The is{} block at any level computes a value that may serve as a argument value to a do block higher up the tree.

-          The code {} blocks are executed in pre-order (when going down the tree)

-          The do(){} and is{} blocks are executed in post-order after the command is completed.

-          Any {} other than for do, is and code can be skipped. Doing so reduces the rest of the line to the scope of the starting instruction’s block.

 

The new NS is also to support a notion of setting scope. You use

@ <rest of command here>

to set scope. For example, if you are going to be doing a lot of google searches, you do a

@ gg

And from that point on whatever you type at the command line will the value of the arg parameter of the do(){} of the gg pattern.

 

I have not really go down to implementing this yet.

Someday…

Saturday, May 07, 2005 12:32:28 PM (Eastern Standard Time, UTC-05:00)  #    Comments [9]  | 
 Wednesday, April 13, 2005

Refers:

Part 1 - The weekend ‘Scheme’ compiler in C#

Part 2 - Compiling Scheme style function dispatch to IL

 

This is fun. I added variable argument support. So everything is of type void foo(object[] args) now.

 

Effectively I can have the full set of lambda signatures -

(lambda () <code>)

(lambda (a) <code>)

(lambda (a b) <code>)

(lambda a <code>)

(lambda (a . b) <code>)

 

Lambda’s now have a preamble that maps formal parameters and does arity checking. In the cases of lambda’s I populate I create one local variable each to represent each parameter. When there is a variable number of arguments I create a scheme list out of the section of the object[] and assign the list to the local variable.

 

I hope all this is consistent with scheme.

 

Download

Wednesday, April 13, 2005 9:49:55 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 

Refers:

Part1 - The weekend ‘Scheme’ compiler in C#

 

The compiler as of now does not do functions with variable arguments. In scheme functions like + can take any number of arguments.

 

Function Definition and Variables

You right a function – more correctly a lambda in scheme like this (lambda <arguments> <code>) and you bind it to a variable like so

(define foo (lambda <args> <code>))

 

Effectively foo is a variable that can hold any type – at this point of time it is bound to the lambda. The way I represent this in the compiler is by creating foo to be of type object and then assigning to it a delegate instance which will invoke the function generated corresponding to the lambda.

 

The equivalent of

object lambda1(<args>)

{

}

delegate object call_lambda1(<args>);

 

object foo = new call_delegate1(lambda1);

 

This means that every function call via foo, basically causes a type cast from object to the corresponding delegate type and then an invocation via indirection. This is certainly slower than direct function calls, but this is atleast a close enough mapping to the semantics of scheme.

 

Function Dispatch

Looking at the above its easy to see that I will need delegates types of various arities and function dispatch will happen accordingly. So when compiling

(foo 1 2)

I know that foo is some value that is of delegate type that will take two arguments. I don’t really have to know the function that its bound, I just need a guarantee of the arity of the function and then I can invoke it.

 

The above call will get compiled to the following in IL

ldsfld     object Program::foo

castclass  [SchemeLibs]SchemeLibs.call2

ldc.i4     0x1

box        [mscorlib]System.Int32

ldc.i4     0x2

box        [mscorlib]System.Int32

callvirt   instance object [SchemeLibs]SchemeLibs.call2::Invoke(object, object)

- where call2 is a predefined delegate that takes two parameters.

 

Problems with variable argument dispatch

The problem with functions with variable arguments is this. When the compiler sees (foo 1 2)

what can it conclude about the arity of the function? With variable arguments, it can only say that foo is a delegate that points to function that requires not more that 2 mandatory arguments.

 

But that’s not too good in the IL world because the opcodes that you need to call functions with variable arguments are different from the opcodes that take a fixed count of arguments.

 

In the clr world there are two approaches to passing variable arguments to functions that I am aware of.

 

params array

Firstly what C# officially does which is

void foo(params object[] args)

{

      foreach(object arg in args)

      {

      }

}

 

foo(1, 2, 3, 4);

 

If you look at this in IL the compiler basically creates an array in the caller, fills it with the arguments and then calls the function with an array as the parameter.

 

arglist

The second approach - unofficially what C# does is the real way of supporting variable arguments at the CIL level using the IL instruction arglist. Here is an example from Vijay Mukhi’s book on IL –

.method public hidebysig static vararg void abc(int32 i) il managed

{

       .locals (value class [mscorlib]System.ArgIterator V_0)

       ldloca.s   V_0

       //create the arglist object

       arglist

       call       instance void [mscorlib]System.ArgIterator::.ctor

(value class [mscorlib]System.RuntimeArgumentHandle)

       br.s       IL_001d

       //get one argument at a time

       IL_000b:  ldloca.s   V_0

       call       instance typedref [mscorlib]System.ArgIterator::GetNextArg()

       refanyval  [mscorlib]System.Int32

       //do something with the value here

       ldind.i4

       call       void [mscorlib]System.Console::WriteLine(int32)

       //get the next ones index

       IL_001d:  ldloca.s   V_0

       call       instance int32 [mscorlib]System.ArgIterator::GetRemainingCount()

       ldc.i4.0

       bgt.s IL_000b

       ret

}

 

This does have an equivalent in C# via an undocumented (yes!! <insert swear word here>) keyword called __arglist. For more on this take a look at Vijay Mukhi’s discussion on Arrays and Undocumented C# Types and Keywords by Peter Bromberg (a C# MVP).

 

If you look at both of these, you see that the code generator of the compiler has to be able to look at the call (foo 1 2) and determine what instruction to generate. There is really no way I can determine the runtime type of foo. (Yes there are optimization possible in certain limited cases, but in a general sense no).

 

This has me thinking that the only way to solve the problem might be to always treat all function calls as calls with variable arguments. Yes, I know that’s bad. So now function dispatch will have to go through the overhead of

-          type casting a an object to delegate type

-          create a data structure for the variable arguments (for both the params and arglist case)

-          call indirectly via a delegate

 

I am tempted to go with params instead of arglist for implementing variable arguments for a bunch of reasons. Both create some sort of GC managed list structure for extra parameters. Its just that params has a more logical mapping in the C# world – so it would be easier to implement some library functions in C# that take only one argument of the form object[].

 

If you have a better idea about how to do function dispatch that accommodates for variable arguments, let me know.

 

 

Wednesday, April 13, 2005 4:53:37 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Monday, April 11, 2005

This blog isn’t dead, it just smells that way. Actually, we have been having trouble with our ISP – something configuration has changed that causes the worker process in which context out web-application runs, to not have write permissions to the web folder where the entries and comments are stored. So that means that I cannot make blog entries and no one cane post comments. We need to have this sorted out or move to another ISP real quick. For now my solution is to generate the blog entry xml file on my local computer and upload it via ftp. That’s how you are seeing this entry.

 

Now to the real topic of this post - I have been toying around with Scheme for some time now – I would like to say a long time – but considering how long scheme has been around (as opposed to say C#), my time is not that long.

 

Over the weekend (literally) I have made for myself a compiler that compiles a language that has a lot of braces. I would really like to say that it is scheme – it is not – but it is very scheme-like. Why it is not scheme -

-          It is a subset of the language

-          It has some differences in semantics even in the subset that I managed to implement

 

Sometime last Thursday I watched a 90 minute video that shows how one can write a Scheme to C compiler. Sidharth originally pointed me to this. Well, I didn’t watch all 90 minutes – shortly after the 60th minute or so I jumped up all charged up, ready to write a scheme compiler.

 

What the video showed me is how to solve some hard problems in scheme compilation – basically how get rid of closures and continuations. The video shows you how to do a closure conversion and CPS conversion. Those very two issues about scheme compilation that I had nagging for sometime – watching the video took them away.

 

This is the subset of scheme that I implemented so far. It has support for lambda, define, if and lists. In terms of library which is in C# and is extensible and I have +, =, car, cdr, cons, display, remainder, newline etc.

 

So effectively I can compile code like this

(define print (lambda (s)

      (display "Value is ")

      (display s)

      (newline)))

 

(define gcd (lambda (a b)

      (if (= b 0)

            a

            (gcd b (remainder a b)))))

 

(print (gcd 50 70))

 

and compile it to generate a .Net exe that actually runs :)

 

This has been really good fun and a rather creative thinking exercise. I currently plan to take it forward and implement a few more things I am curious about. Its good fun to see what code like this does to your thinking about things.

 

Right now the code flow of the compiler is structured like this –

Scanner -> Parser -> [Abstract Syntax Tree] -> Code generator -> exe

 

The once I have a stable code generator, I am expecting that instead of focusing on being able to compile every construct in scheme, I can translate constructs down into the simpler constructs which the code generator already handles.

 

For example I don’t intend to compile a ‘cond’ statement – instead I would take the AST that has the ‘cond’ and transform it into an AST which can the ‘cond’ replaced with a nested ‘if’. Similar closure conversion and CPS conversion (continuation passing style conversion) would be other AST transforms.

 

So the code flow would be like this –

Scanner -> Parser -> [AST] -> AST Transforms -> [AST] -> Code generator -> exe

 

Once I have the present code a little stabilized and I have a framework for doing tree transforms, I should have a fairly complete implementation of a scheme like language.

 

 

Things I cant solve -  

Why I say scheme-like language is because I doubt if I will ever actually implement a whole standards compliant system – simply for the sheer effort. That aside I presently don’t know enough to be able to compile some aspects of the language.

 

In scheme not many things have special status. As an example variable name is simply a binding to some value.

 

So I can say -

(define x (lambda (a) (+ a 10)))

which binds variable x to a lambda (a function) that takes a parameter and adds 10 to it and returns it.

 

Now I can call it and assign the result to another variable ‘a’ -

(define a (x 10))

 

Now in the same program I can define x to be something else, say just a number…

So typing of variables go for a toss. Similarly I cannot really hardcode any function calls in the generated code – I have to indirect them through a variable that holds a delegate, because at runtime I cannot really know which function that variable is bound to. But those are solvable problems.

 

The hard problem comes up when you deal with what scheme calls special forms. As an example ‘if’ is a special form.

(if (= a b) (display a) (display b))

Here either value of ‘a’ is displayed, or value of b is displayed.

Now it is not possible to implement ‘if’ using a function call. Because whenever you call a function, all the arguments to the function are fully evaluated. So if there was a function called ‘if’ the condition, then and else parts would be evaluated before the ‘if’ function is called. So in this case the user would see both ‘a’ and ‘b’ being displayed. So ‘if’ has to be treated differently by the compiler and I have to generate test and branch instructions for the ‘if’.

 

The problem comes in the fact that the user can perfectly well say something like this –

(define if 10)

So from now on ‘if’ is 10.. that’s crazy because that’s a runtime condition, whereas my compiler has already generated test/branch code for the if.

 

When writing a compiler and I see ‘if’ I emit intermediate code which tests a condition and braches to the right code block for execution. If at runtime the meaning of the ‘if’ itself changes then the branching and compile time generated code has no meaning.

 

You may argue that in the case of ‘if’, I can solve the problem by having variable that indicates the current value of ‘if’ and at compile time I can generate code for an additional check with this variable. However that’s a limited hack… and it doesn’t explain what I will do when at runtime the meaning of ‘define’ changes or the meaning of ‘lambda’ changes.

 

I cant solve this problem right now, I don’t know how to – so I have given define, lambda and if a special ‘keyword’ like status – similar to keywords in other languages where keywords cannot be redefined to mean something else at runtime.

I don’t know if this is a problem I will be solving also.

 

Things I hope I can implement

-          closures

-          continuations

-          more special forms (list, quote)

-          a better function dispatch mechanism (generate the delegates types)

-          tail calls

-          cond, let, letrec

 

Here is my early ‘over-the-weekend’ quality scheme compiler for download. Use with caution.

This also requires the elusive .Net 2.0. I am not releasing source just yet, but it will come.

 

However, if you are looking for an actual full fledged compiler scheme compiler for .Net GotDotNet lists the following -

Scheme

Northwestern University Hotdog Scheme

Scheme

Tachy (Scheme-like) language

Scheme

Indiana University Scheme.NET

You may have more luck with these.

 

You may not be able to leave comments on my blog right now.

Do send me mail for now roshan -dot- james -at- gmail -dot- com.

 

Monday, April 11, 2005 9:29:27 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2]  | 
 Sunday, January 09, 2005

The little public information about Vulcan –

 

MSR-TR-2001-50

Vulcan: Binary transformation in a distributed environment

Andrew Edwards; Amitabh Srivastava; Hoi Vo

April 2001

http://research.microsoft.com/research/pubs/view.aspx?type=Technical%20Report&id=455

 

Sunday, January 09, 2005 11:41:30 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Monday, November 22, 2004

Over the months I had slowly lost touch with Scheme, with so much happening in life. Today I saw some scheme code again and somehow just looking at it made me happy. Some kind of inherent simplicity in seeing those brackets and that indentation style – something vague familiarity of old friendship. It was weird.

 

No no, I am not cracking up and I am still a good old pure imperative languages programmer at heart and yes (Small talk guys please stand to the corner), I believe that C++ is a OO language and I still like .Net and C#. But all said and done, I think I like scheme – need to get back to some old scheming as soon as time allows.

 

Digressing - been musing about dynamic languages a bit more. The real reason I have not been writing too much about it is because of the feeling that I am going to sound stupid because I don’t know enough. I think I am going to let go of that and take the risk of looking foolish for a bit and start writing down things as I go ahead.

 

Here is a bunch of things that could/would fall under the general umbrella of the lose term – dynamic languages –

1)       closures

2)       iterators

3)       coroutines

4)       continuations

5)       mutable types

6)       typeless variables

7)       dynamic method dispatch

8)       eval

 

I don’t want to get into method dispatch and sub-classing mechanisms here, but I think the above is a general list. Any biggies I have missed? Lets see if there are any appropriate mappings we can find in the CLR and such.

 

The iterators and closures are solved problems – or atleast are largely solved problems in C# 2.0 (yes I know we can’t do ref variables – I think that’s ok for now – I will be happy if you have an answer)

 

There are solutions to most of the others lying around in one way or the other in Jim’s IronPython and the lesser loved Jscript.Net compiler that ships in source form with Rotor.

 

Does anyone know where I can find a readable description of how a scheme compiler (not interpreter) would work?

Monday, November 22, 2004 8:51:44 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 

Dynamic Languages on the CLR – Part 1

 

Today I came across a paper written in 1996 at MIT that spoke of Dynamic Languages implementation on the JVM. The paper is an interesting read and pleasant because it isn’t dotted with arcane notational jing-bang and actually talks about real implementation issues.

 

The paper is written by Olin Shivers of MIT, interesting person – ha ha, actually this is the real link.

 

The first section address the issues of optimization of small scalar data types like integers which cannot actually afford to have dynamic lookup. The solution he proposes entails an assumption to be imposed on pointer types – so that small values can be held immediately rather than via indirection. For this purpose he recommends the addition of a type called an ImmediateDescriptor. I could not help smiling because this seems so much like a solved problem in the CLR of today – value types.

 

The second big issue that the paper brings is one of custom operations that a particular language may require that the runtime may not support. I don’t really have an answer for this. The paper goes onto compare this as being the inherent contradiction between RISC and CISC systems and adds the angle of safety of the end programming construct. This is by far a brilliant piece of thinking and these are the two suggestions primarily

1)       Build it up in API

2)       Enable the VM to have an extendable instruction set – similar to micrcodes in a processor

a.       Enable compilability of such new instructions by compiling to a lower level more RISC instruction set than the high level instruction set of the runtime…

 

I am hoping to offset this second part by not affording extensibility in the runtime and instead believing in some magical set of primitives. I don’t know about work that is actually being planned by the CLR team in this regard, I wonder what they are planning.

Monday, November 22, 2004 3:45:54 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 

It has been on my mind for a long time, to write about this – supporting dynamic languages on the most advanced runtime on the planet. I have been having this pet project on the back of my mind, and figured that I should probably write about it now. I was wondering how hard it would be to extend the CLR in a fundamental way to support dynamic languages – the idea here is not to add a whole bloat of features to the CLR, but to try and identify a set of primitive or simple rules/abstractions which when added to the CLR would enable implementation of dynamic languages efficiently on the CLR.

 

Why the CLR? Because the CLR is one of the fastest runtimes/VMs out there; it was inherently designed to run multiple languages; runs on a whole bunch of hardware and software platforms and has a very wide acceptance in the industry; it is an open standard that is not owned by any company; and there are atleast two publicly available implementations in source form – which means that it enables a language that previously had to lug along its own VM/interpreter to boldly go where no previous version has gone before.

 

Some smart languages like Groovy are doing this with the JVM. I was hoping for a while that Ruby would – but it turns out, after several mails on the Ruby mailing list that Matz the creator of Ruby, has other plans. Matz is writing his own VM for Ruby.

 

It looks like it’s a season for writing multi-language runtimes – head of the pack being Parrot, the new VM for Perl 6. There is of date, little or no information available about the actual architecture of Rite – ruby’s VM that Matz is working on.

 

What makes a runtime that supports dynamic languages different from runtimes that are built to support statically typed OO languages – I don’t have enough of a formal education or personal experience to answer that straight out. That is one of the things that I hope to teach myself in coming time. I can throw terms like dynamic method dispatch at you… but essentially I don’t know if I can nail it down to a set of fundamental primitives that make all the difference.

 

This is a blog entry about some of my early ramblings on the topic. I am hoping to teach myself some of the difference by looking at the opcode design for Parrot. I am expecting that there would be opcodes for runtime type lookup, runtime method invocation etc etc – does that solve the problem, I don’t know. It provides features that can be used to mitigate the problem, yes. In conjunction with studying the architecture of Parrot, I am hoping to compare and contrast that with what the CLR supports and see what is missing in the CLR. Again I am not expecting much to be missing – what I am expecting to be seeing be seeing is that a lot of what Parrot provides as opcodes, the CLR would not natively provide, but would instead be available as framework API.

 

There is another source – Jim Hugunin’s IronPython. Sometime early this year Jim Hugunin shocked the Python community and a large part of the dynamic languages world by implementing a python version that ran on the CLR – it was faster that the classical C Python. Jim previously was known for his Jython – a Python that ran on the JVM – but was a rather slow implementation. What Jim has essentially done is that he has written a bunch of libraries to augment what the framework provides and has used these liberally along with regular IL. Jim now works for the CLR team at Microsoft.

 

Once I think I have an understanding of how the Parrot opcodes makes it a better runtime for dynamic languages, looking at Jims work (which is openly available) should give me a good idea of what primitives can be derived and can be pushed into the CLR. That should be a good fun project to work on.

 

A lot of what I have typed would be plain common sense for someone who was actually following the field. A whole bunch of things are getting in the way of getting started, else I would have already.

Monday, November 22, 2004 3:44:47 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Monday, June 28, 2004

I have been putting more of my free time into digesting Scheme. I am now working on XEmacs. After several stops and starts with emacs in the past, I am finally using it (might I add - productively) to write scheme code. I figured that even if emacs is of no use to me for most of my work, I could atleast use it to write scheme code. It should be good for that for sure.

 

Don’t misunderstand me when I say this, because you may have different opinion, especially if you have lived in Unix for a long time – which I haven’t. XEmacs still leaves me feeling like I am taking piano classes. I use Scite and Visual Studio for most of my day to day work.  Of course, if I am writing a document, then it is Word. I also have a love-hate relationship with Rob Pike’s Sam editor.

 

For a long time I used the old Turbo C++ IDE in DOS (yes I am not ashamed to confess) and it served me rather well. After which it was Visual Studio 5... it was a pain to use in some cases, but with this plug-in called ‘Whole Tomato’ that I used, it was a killer.

 

When I got started on Linux, editing was a real pain – it was like I had to learn to type all over again. That was major put-off. As a matter of fact I figured that I could not suffer the ‘miserable’ editors they have there and so decided to write my own editor. (Yes, I was crazy enough to try and write an editor instead of learning arcane key combinations…) Of course, since I could edit code on Linux, I decided to write my editor in a portable way in DOS and then figure out how to take it to Linux.

 

As most DOS code was written those days, I wrote interesting text mode menu libraries and such other things that assumed that I had access to VGA text buffer to access. Finally when I actually had something going, I decided to make the big switch – Prot to Linux. Almost immediately, I hit a blank wall.

 

The entire style of programming, with direct access to video memory that was used to write large Text-UI based apps on DOS, was simply non-existent in Linux. That, I still remember, was such a major put off that I was going around cursing Linux to anyone who would listen to me. The only alternatives that I was left with, was to use some editors that did old Word-Star like CTRL-K based key combinations, which was rather irritating. I also spent half a day looking at the ncurses lib that time, hoping for a way out. All I got was buggy behavior and one buggy lib after the other and numerous dependencies on some .so or the other which I had to go and find on the net .

 

Finally my entire work on the editor on Linux got scratched and I decided to turn it into a DOS only thing – which I used for much after that as file viewer. The thing was distributed as w.exe to my friends and the default config file used to display multicolor menu and the title “The Zen Masters Workbench”. In w.exe was viewer that could be given C like structures and could read data out of binary files to match the structures. That became the original basis for the implementation of my DDL language.

 

 

 

I don’t know why I typed all that down… anyway here is the little bit of scheme code that implements a for-loop as a macro. I know it is not much, but its good fun.

 

(require (lib "defmacro.ss"))

 

(define-macro for

  (lambda (init  cond  step  code)

    (let ((loop (gensym)))

      `(let ,loop ,init

             (if ,cond

                 (begin

                   ,code

                   (,loop ,step)))))))

 

;see nested for loops

(for ((i 1)) (< i 10) (+ i 1)

     (begin

       (for ((j i)) (< j 10) (+ j 1)

                (begin

                  (display i)

                  (display j)

                  (display " ")))

       (newline)))

 

Of course, written entirely in xemacs. One reason to use xemacs over Scite is that it gives me this really nice syntax driven indentation. The syntax high-lighting, for what I have seen, is pretty corny though. But on the whole, good enough to write scheme code for now. :-)

 

If you are starting out on Scheme and already know how to program, I recommend Dorai Sitaram’s “Teach Yourself Scheme in Fixnum Days” as a starter. The SICP is a lovely text as well and full of ideas, but if you don’t have lots or free time on your hands and are not the sort who likes letting an idea go without giving it its due thought, then I wouldn’t recommend SICP. It will be a while before you get down to scheme-ing. Also Prof Kent Dybvig’s book on Scheme is good, but again if you are the impatient sort, the DS book is the better choice.

 

In a few weeks I should get my copy of the Little Schemer, I intend to be ready for it by then :-)

Monday, June 28, 2004 6:19:28 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Friday, June 25, 2004

(The following article was originally written for the .Net Developer Journal where it featured in the Nov 2003 issue. This was co-written by Pooja and me and basically serves as an intoroduction to our DDL language. The original language was co-written by us and two of our friends Rakesh Nandakumar and Tony Sakariya as our final year college project. The DDL in its present .Net avatar is work by Pooja and me. The copyright perios of this article has expired, hence this post. You can find the article hosted on the magazine website here: http://www.sys-con.com/dotnet/article.cfm?id=460. I hope Pooja will be mirroring this article too)

 

Enter the Data Definition Language: a developer perspective

Roshan James & Pooja Malpani

(Authors of the DDL)

 

Greetings, In this short write-up we are going to discuss our new language for the .Net platform called the Data Definition Language (DDL). We hope that by the time you have finished reading this, you will want to log onto the internet, download the DDL and try it for yourself (and drop us mail about it).

 

The DDL is a unique language that aims at solving a common problem. We all would have faced situations where we needed to read data from a file of some given format and there are no real library routines for this purpose, other than the standard file handling libraries. In such cases, we would have to develop code that will calculate the addresses of various values that we want to retrieve from the file and write file handling code that will retrieve the data. While this is probably feasible for simple file types, the need to support a complex file type, or multiple file types or a changing file type can easily become a development bottleneck.

 

Once, we had to work with a development team that was creating an application for analyzing data collected in aircraft black boxes. Data dumps from black boxes have very complex formats. The team needed to read values of various aircraft parameters such as left-aileron-angle, right-engine-exhaust-temperature etc, which were scattered across various bits that seemed to have no respect for word boundaries or any such thing. To add to the fray there was no apparent standard between black box formats of the same manufacturer, version of the same aircraft or any such thing. The team needed to have their product support multiple black box formats without a huge development cycle between these. A little thought made it apparent that there was no real solution to supporting data retrieval from arbitrary file formats. This is the problem that the DDL was designed to solve.

 

How does the DDL understand the format of the file I want to read data from? The DDL is a language. It is designed to be simple and intuitive for expressing data formats. To develop a solution with the DDL a developer needs to first write a DDL script that represents the file format. Once the script is developed, you can run the DDL engine/interpreter on the script, provide the engine with your data file and you are ready to start reading information out of the file.

 

So how can I use the DDL in developing an application? The DDL engine is designed to be an interpreter that be hosted by any .Net application – which means that your VB.Net or C# programs can act as hosts for the DDL. A typical DDL solution would consist of your parent application that does all the UI and has all the business logic. This would host the DDL engine with which you can programmatically interact. The DDL engine simply acts as a substitute for your complex file handling code; it does not dictate what you do with the data that you have retrieved.

 

Hosting the DDL.

 

Once you have hosted the DDL engine, you tell it to do tasks such as ‘load this ddl script file’, to make it understand your file format. Then you tell it to ‘use this data file’ so that it can apply your ddl script (which defines the data format) of the actual data file. Then you tell it ‘give me the value of left-aileron-angle’ and the DDL engine looks at the script, understands where in the data file ‘left-aileron-angle’ would exist and reads out the value for your host application.

 

What are the DDL script files like? The DDL language provides you with primitive types that represent bits – these are available from single bit definitions to 32 bit definitions. These are named i1 i2, i3 etc to i32. Variables can be declared to represent any of these types.

            i16 width

This represents a 16 bit value called width.

 

Now declarations like this should be grouped into DDL structures. Structures would look like this:

 

struct Window

{

i16 width

i16 height
}

 

A DDL script file can contain multiple structures like the one above. Similar to the declaration of primitive bit types you could also define a structure to contain a member of another structure type.

 

struct Bitmap

{

      i8 BitsPerPixel

      Window w

}

 

The DDL script requires that you mark one structure in the script file as the ‘init’ structure. The DDL uses the “init” structure as the first structure of your data file – the init structure is mapped to offset zero of your data file. The init structures and its members (which maybe instances of some of the other structures declared in the script file) are expected to represent the entire data file.

 

The tree-like structure formed by structures in a DDL script file.

 

The DDL structures are different in concept from structures in languages such as C. The first difference is that a DDL structure can contain members depending on conditions. Secondly, a member in a DDL structure simply represents a region in the data file; an i8 type member would represent a byte-sized region. Members in a structure have their offset addresses from the base address of the structure automatically calculated or can have explicit addresses provided. This little script demonstrates both of these.

 

 

 

struct EmployeeData

{

      i32  empNumber

      i1   fPhoneNumberProvided

      i7   fUndefined

      when( fPhoneNumberProvided == 1 )

      {

            i8[10]      phoneNumberString

      };

      @ 0,0 i24 empSerialNumber

      i8 empDesigCode

}

 

This simple script demonstrates some interesting things. An instance of the EmployeeData structure will contain a member called phoneNumberString of 10 bytes, only if the fPhoneNumberProvided flag bit is set. Similarly the notation “@ 0,0” is an explicit address specification that causes the address of the declaration immediately following it to fall at an offset of 0 bits from the start of the structure. Thus, with respect to little-endian Intel architecture, the lower 3 bytes of empNumber are the empSerialNumber and the most significant byte stands for the employee’s designation code.

 

Layout of the structure with respect to the bits of the data file.

 

The script also demonstrates a simple array of i8 (or byte) type of ten elements. Unlike C, the size of an array can be specified via an expression. To illustrate the power of arrays consider the following snippet that uses the above employee structure.

 

struct EmployeeHeader : init

{

      i16 empCount

      EmployeeData [empCount] emps

}

 

The first member decides the number of employees whose data is provided and ‘emps’ represents as array of EmployeeData types. You can now ask the DDL engine for the designation code of the 5th employee and DDL engine sets about to determine the location of the 5th employee and retrieve its ‘empDesigCode’ value for you. Now remember that the EmployeeData had a member that would occur conditionally – this means that the size of each EmployeeData instance can be different. The DDL engine internally determines that there is a dependency and checks the flag in each of the preceding EmployeeData instances to determine the actual location of the 5th instance that you requested.

 

The ddl script provides only a minimal set of programming constructs whose purpose is centered on being able to define data formats. The present ddl language is rich enough to support a wide variety of common file formats. There may however be some format types that may not be expressible in the ddl or are hard to express.

 

The DDL language has constructs for representing address specs, size specs, conditional dependencies, different kinds of array constructs etc. This is a just a brief description of the language, the complete language description document is available from the homepage.

 

Hosting the DDL Interpreter: This is probably the simplest part. Imagine that EmployeeHeader and EmployeeData together formed a ddl file called employee.ddl and that we had a data file in this format called empinfo.bin. The following C# snippet is all you will need to start off using the DDL.

 

using System;

using System.DDL;

 

class DDLTestClass

{

       static void Main()

       {

              //initialise the DDL

              ManagedDDLEngine ddl = new ManagedDDLEngine();

              ddl.LoadSourceFile("employee.ddl");

              ddl.OpenDataFile("empinfo.bin");

              ddl.InterpretData(); //this call is needed to map the scoure to the data

             

              Console.WriteLine("No of employees = {0}",

                     ddl.GetValue("empCount")); // GetValue() read the value of a variable

             

              //contents of emps[0]

              ddl.Seek(".emps:0"); //seek changes path into a member

              Console.WriteLine("Data of 0th Employee \n\t "+

                     "empNumber={0}",

                     ddl.GetValue("empNumber"));

             

              //contents of emps[5]

              ddl.Seek(".emps:5");

              Console.WriteLine("Data of 5th Employee \n\t "+

                     "empNumber={0} \n\t "+

                     "empDesigCode={1}, \n\t "+

                     "empSerialNumber={2}",

                     ddl.GetValue("empNumber"),

                     ddl.GetValue("empDesigCode"),

                     ddl.GetValue("empSerialNumber"));

 

              ddl.Dispose(); //clean up

 

       }     

}

 

This little snippet loads the ddl with the script file and a data file and reads values from it. This snippet does not show any of the error handling code that would be required in a production quality application. One concept you need to be familiar with is that of path.

 

The init structure is represented as “.” (dot). Any member under it is represented using its member name. Any child of that member is separated by a dot, and so on. If there is an array in the path, then the array instance is separate by a “:” (colon).

Ex

init.emp[0] will be represented as “.emps:0”

 

At any point the GetValue() call will return the values on any of the variables in the current path. The Seek() is used to set the current path to another location, subsequent GetValue() calls will read values from that location. Bit values that are read are treated as unsigned integer types. All values are returned as ‘double’ type.

 

A document describing the API exposed by the DDL is available on the homepage for details.

 

What is available? The DDL engine itself is currently for download as System.DDL.dll. This is a mixed mode .net assembly developed in Managed C++ and can be hosted in any .net application. The entire source code of the DDL is also available for download. The DDL is offered for use free of cost and is currently not under any licensing or royalty restrictions. We however expect that in return we get feedback that can help improve the DDL. If the DDL is used for commercial purposes we hope that the authors drop us a note and possibly give credit where credit is due – this would help in popularizing the DDL. You are however not required to do any of these and are free to use the DDL without any acknowledgements at all.

 

Also a console program is available which can be used to test-run DDL scripts that you are developing. This is also available in source form as an example of hosting the DDL. The site also has tutorial material about the DDL console as well as documentation about the language, API, internal algorithms and such.

 

Present and Future: The DDL in its .Net avatar is presently in Beta 1 status and is the work of two people. We believe that the idea of a generally useful DDL system has substance and are hoping to work towards it.

 

For future development we are hoping to strengthen to the DDL language so that the language can be used to express data formats that are currently not expressible or are hard to express. Also plans are underway for a compiler for the DDL language. The compiler is expected to take a .ddl file as input and generate a .net assembly as output that will be code streamlined for your ddl script, rather than be a general purpose ddl interpreter.

 

We are hoping to build a community around the DDL and would like to invite you to join the DDL development project. Inputs for future design aspects, known issues etc would be appreciated.

 

The DDL project homepage is http://ddl.sscli.net .

Contact us: spark at sscli dot net, dolly at sscli dot net.

 

(Download the article and related code sample here

The homepage for the DDL project remains http://ddl.sscli.net

You may also want to visit: http://www.thinkingms.com/pensieve/homepage/work/system.ddl/index.htm

And http://www34.brinkster.com/mpooja/work/Other/ddl/index.htm

A complete description of the language is available at http://www34.brinkster.com/mpooja/work/Other/ddl/html/DDL-Language.htm)

 

Please give us feedback about the language and what you would like to see implemented. One of the plans we have for the future is a compiler for the DDL – this has been postponed because various other projects kept getting in the way.

 

Friday, June 25, 2004 7:07:53 AM (Eastern Standard Time, UTC-05:00)  #    Comments [7]  | 
 Wednesday, June 23, 2004

Almost every macro demonstrates a flaw

in the programming language,

in the program, or in the programmer.

        - Bjarne Stroustrup

 

I find it unbearably restrictive

to program in languages without macros ...

        - Paul Graham

       

It took me some good time today getting my mind around macros in scheme. The discussion in Dorai Sitaram’s book is a not very descriptive. I had a look at Prof Kent Dybvig’s chapter about syntax and figured that that is something I want to look at only later.

 

However after a bit of mucking up I think this would work.

 

(require (lib "defmacro.ss"))

 

(define-macro let* (lambda (args . code)

        (if (null? args)

                `(begin ,@code)

                `(let

                        ,(list (car args))

                        (let*

                                ,(if (null? (cdr args))

                                        ()

                                        (cdr args))

                                ,@code)))))

 

(display

        (let*

                ((a 2)(b (+ a 10)))

                (+ a b)))

               

 

Thinking in scheme needs some getting used to.

 

Wednesday, June 23, 2004 8:44:10 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  | 
 Saturday, June 19, 2004

A few days back I found what seemed to be a book about Ruby. This was being discussed on the Ruby mailing list. It’s called “A Little Ruby” or more precisely “A Little Ruby. A Lot of Objects”. You can find it here:

http://web.archive.org/web/20030618203059/visibleworkings.com/little-ruby/

(Someday it will be available here: http://www.visibleworkings.com/little-ruby/ )

 

Instead of writing the whole thing myself or copy paste it, I ask you to simply go read the book. That is my blog entry for the day.

 

The “Little Ruby” book is a conversation between two people where some sublime ideas about the design philosophy of the Ruby language are discussed. The book itself is a pleasure to read and more importantly, to think about. (It is an incomplete book, only 3 chapters – the author Brain Marick said on the Ruby list that he hopes to complete it sometime).

 

Reading “Little Ruby” put in a phrase in my thinking – “Model of Computation”, I don’t know if this sounds sober, but I think this is what I am really looking for.

In all my tinkering around languages, compilers, runtimes and other things – I am looking for a Model of Computation, a fundamental set of programmatic thought abstractions that are beautiful and can encompass various forms of programming.

 

The Little Ruby book talks about a model of computation where all computation is simply built around the idea of passing messages to objects. It is a simple concrete idea with which the rest of the Ruby world is built (apart of syntactic sugar). I don’t know if you are used to thinking in this way – but it is a powerful form of thought.

 

Let me quote from one of the conversation toward the end of the third chapter (the last chapter that is written so far):

 

“A language that provides lots of features

will always be missing that one feature you

need.”

 

“But a language that chooses the right

simple rules for you to combine lets you

build the features you need.”

 

This is the basic idea of composition – small integral units that compose to produce powerful behavioral entities. Have you ever thought why a unix command shell guy never really thought much of a Win/Dos user – because somewhere the way the shell forces you to thinking terms of composition of small do-one-thing-well tools and create powerful meta-tools, is a greater thought pattern.

 

You might have heard this being said about tools in the old unix culture (I say ‘old’ because I have different opinions of ‘unix’ culture as it is now)

 

"This is the Unix philosophy. Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface."

--Doug McIlroy

 

The “Little Ruby” book is inspired by the old book “The Little LISPer”. Something that is now on my reading list – I can’t seem to get a copy of this anywhere. The present edition of the book is called “The Little Schemer”. The book is co written by Prof Daniel P Friedman of Indiana University and Prof Matthias Felleisen of Rice University. The Little Schemer discusses a different model of computation from what the “Little Ruby” describes.

 

I did not know this then, but sometime last year I was in email correspondence with Prof Friedman. That time, had I known that he is author of a respected LISP text book, I might have been frightened off the prospect of asking this -  but in one of the mails I had asked “why Lisp?”

 

Roshan,

 

The most fundamental building block of computation is composition. If the language does not support composition in a trivial way, then I have no use for it.  ML, Haskell, LISP, and Scheme each give a kind of composition.  Composition is the building block of Category Theory, which is a unifying tool that helps clarify much of mathematics. and logic.  So, thinking that it would be okay to use a language that does not support composition is impossible for me.

 

(I quote this here presently without his permission, I believe he would be ok though).

I didn’t understand him then. But now after a year, I think I am closer to understanding him.

 

What would a unified model of computation be? Can such a thing exist? Can we think of all computation using a set of minimal and powerful abstraction such that every other form of computation can be built out of it. Can this be one that is easy and fun to use that we could interact with this force on a day to day basis.

 

And what forms the underlying foundation for computation then might also form the underlying basis for other systems of organized thought as well. This is like the dream of Grand Unified Field Theory in physics. Can something like that exist in the computational systems as well?

 

I don’t know enough to guess. But however I believe that as long we keep pursuing computing in a way that is fun and simple, we are probably on the right track.

 

 

To end this entry I want to quote from the preface of the little ruby:

 

Welcome to my little book. In it, my goal is to teach you a way to think about computation, to show you how far you can take a simple idea: that all computation consists of sending messages to objects. Object-oriented programming is no longer unusual, but taking it to the extreme - making everything an object - is still supported by only a few programming languages.

 

Can I justify this book in practical terms? Will reading it make you a better programmer, even if you never use "call with current continuation" or indulge in "metaclass hackery"? I think it might, but perhaps only if you're the sort of person who would read this sort of book even if it had no practical value.

 

The real reason for reading this book is that the ideas in it are neat. There's an intellectual heritage here, a history of people building idea upon idea. It's an academic heritage, but not in the fussy sense. It's more a joyous heritage of tinkerers, of people buttonholing their friends and saying, "You know, if I take that and think about it like this, look what I can do!"

 

As a closing note, sometime last year I was looking to do research under someone working with the SSCLI code base and work on virtual machines and runtimes. I wanted to do my Masters.

 

At that time the best way I could describe what I wanted to do was to say that I was looking runtimes and virtual machines research with a specific interest in SSCLI. Now, maybe I can describe myself a little better.

 

The only way I could think of doing this that time was to ask around in online forums and mailing lists about universities doing work with Rotor. That accompanied by a barrage of mails to everyone who I thought might know, or point me in the right direction. One name that came up was of Prof Ralf Johnson of UIUC. Right now I was looking for Brian Marick (author of little ruby) on Google, Brian is research student doing his PhD under Prof. Johnson.

 

Saturday, June 19, 2004 2:50:25 AM (Eastern Standard Time, UTC-05:00)  #    Comments [2]  | 
 Saturday, June 12, 2004

With some things cleared up and some ground work done, here is one of the first the things I want to talk about in Monad – the new Microsoft Command Shell(msh).

 

In my first article I talked about ‘cmdlets’ and that they return .Net objects. Here is one other smart and subtle thing they did with Monad – Parameters to cmdlets come not only on the command line but can also come from objects in the input object pipeline.

 

Some basic stuff on cmdlets and parameters which might help set the stage for understanding things. A command-let can define fields/member variables as part of the command let class. These fields can then be decorated by attributes so that they can be treated as parameters to the commandlet.

 

In code it actually looks like this:

 

[CmdletDeclaration( "demo", "cmdlet" )]

public class HelloWorld : Cmdlet

{

        [ParsingPromptString("Enter a string to echo: " )]

        [ParsingParameterMapping(0)]

        [ParsingMandatoryParameter]

        [ParsingAllowPipelineInput]

        private string message;

(This snippet is a modified version of code from the beta documentation)

 

Now this might look a little over decorated with attributes, but the thing I want you to notice is that that is a member called ‘message’ which simply has a few attributes applied. Applying those attributes causes ‘message’ of type System.String to be a parameter required for our command let.

 

Unlike traditional command line exes, the responsibility of parsing the command line options and assigning them to internal variables is not the responsibility of the program but is automatically done for you by the Monad shell.

 

Which is to say that by the time code that you write in the cmdlet is executed, values are already assigned to the parameter variables by the shell. (Not strictly, but almost).

 

The shell can let you assign parameter values either by specifying them at a certain postion in the command line – for example argv[1] will be the value for ‘message’, argv[2] will be the value for something else and so on. Or the shell lets you  specify the parameter name and then the value

> demo-cmdlet –message “hello world” -< parameter name >  < value >

 

The other good thing (which is new and what this log entry was about) is that the value for a parameter can be extracted from an object on the pipeline if the object has a field/member of the same name. (The types have to be consistent)

 

So if I have a command let that generates an object of type foobar that has a member of name ‘message’, I can pipe the output to the commandlet that required a parameter of name ‘message’ and it would all work.

> create-foobar | demo-cmdlet

Would create foorbar instances that get piped to demo-cmdlet which uses the ‘foobar.message’ as its message parameter.

 

Where would this be used?

 

For an example there is a command-let called ‘get-process’. It lists the running processes on the system. To be more precise it returns a collection of process instances which get standard formatted to the console.

MSH 5 C:/>get-process

 

ProcessName                  Id   HandleCount   WorkingSet

-----------                  --   -----------   ----------

CcmExec                     288           480     14008320

cmd                         804            22      1421312

csrss                       464           669      4743168

dfssvc                      316            70      3260416

DWRCS                      1444            44      2560000

explorer                   3520           366     20926464

FrameworkService           1544           303      9367552

Idle                          0             0        16384

 

Similarly to see all the instances of notepad that are running I would simply say

MSH 16 C:/>get-process note*

 

ProcessName                  Id   HandleCount   WorkingSet

-----------                  --   -----------   ----------

notepad                    3912            16      1912832

notepad                    4044            16      1912832

notepad                    3056            16      1912832

 

Now there is a cmdlet called stop-process which can terminate a process if you pass it the process id as a parameter. The parameter name that stop-process expects is called ‘Id’.

MSH 11 C:/>command stop-process

 

Command: stop-process

Command Parameters:

        Id                    : Int32[]         : Optional

        ProcessName           : String[]        : Optional

 

So with all the earlier talk you can conclude that if I simply wanted to kill all the instances of notepad that are running I could type

MSH 11 C:/>get-process note* | stop-process

 

Now isn’t that clean? Just to add a bit of garnishing to that, Monad defines ‘ps’ as an alias to get-process and ‘kill’ as an alias to ‘stop-process’.

So now you can say

MSH 11 C:/>ps note* | kill

 

Cool? This works on Monad today.

 

Prev:

Introductory entry about Monad 

 

Next:

ObjShell: A precursor of Monad?

Saturday, June 12, 2004 6:54:31 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, June 10, 2004

For a little less than a week now, I have been playing with the March build of the new command shell that Microsoft will be releasing in the Longhorn time frame. Being a command line/console enthusiast, I find this rather exciting news. Indeed it has been years since MS actually did anything significant to better its command shell – Monad is it.

 

I don’t really know how much I am allowed to talk about Monad itself because of some NDA material, but if you look around on the net you will find a pretty much a lot. One thing about the way the NDA was explained to me recently was that they said – if you can find the material on the web then assume its not under NDA !! (whatever .. )

 

One thing that Monad does differently from other command shells, be it cmd.exe or bash/ksh/csh is that Monad is centered around the idea of an object pipeline. Let me explain:

 

Traditionally one of the ways of defining a console application is to say that it is an application that was access to three streams by default – usually numbered 0,1 and 2 and called the stdin, stdout and stderr. These are text streams. This means that you can read/write text data from these streams.

 

When you pipe the output of one program to another program on the command line, what you are basically doing is that you are ‘connecting’ the stdout of the first process to the stdin of the second process. So text that it is outputted from one process is treated as input text for the next process. This is known territory.

 

For a long time I appreciated the beauty and simplicity of this approach – what could be better, well Monad could be.

 

Monad provides ‘applications’ (I use this term loosely here) on the shell with three streams – but these are not text streams but object streams. Applications that read and write objects in the object pipeline are not traditional processes but are called ‘commandlets’. A cmdlet is actually just a .Net class that is decorated by certain attributes (etc etc).

 

When cmdlets are executed from the msh command line, these classes are instantiated and are given access to the object streams. So one cmdlet writes objects to the output object stream which is read in through the input object stream of the other commandlet. In essence the same idea of piping as with text streams, but this time what passes around are full blown .Net objects.

 

Giving this idea a little thought, you will realize that this makes for much richer shell programming. Like for example a lot of time effort is spent in shell programming (traditionally a unix forte) is scrapping out meaningful values from the output of other commands. Even entire languages (awk) have been created largely for this kind of text scrapping. For example if you do a ps –ax, then you really need to cut out (literally) the columns of text where the process id falls so that you can automatically call a kill command with it.

 

This kind of difficulty completely disappears with Monad simply because the cmdlets down the object stream get full objects and so they can examine the fields of these objects for the parameters they want.

 

Of course this kind of functionality would have been near impossible in the pre .Net era because there was no understandable concept of a ‘type’ that was applicable across languages. The shell being purely a .Net shell the command-lets can talk .Net and can thus consume any .net type. (Remember this is one of the basic tenets of the .Net platform - that its tries to provide a level playing field for languages to interact).

 

When a command let returns a set of types and there are no more command lets in the pipeline to consume to objects then the objects are formatted in some standard way to the console. What that means is that if we have a command called ‘ps’ it would be expected to return a collection of objects each of which represent a running process. Now if at the console I type simply

> ps

then there are no more commandlets that receive the process objects returned by ‘ps’. These objects are formatted in a standard manner to the console so that user can see them. Nice?

 

Monad has really appealed to me in the short time I have spent with it. Traditional shells like bash may have some catching up to do in the light of power like this. Of course Monad is presently at a nascent stage. However for an early pre-beta, Monad is already a very sophisticated and elegant system.

 

I don’t know if I have crashed any NDAs already. I need to check up on that before I continue.

 

 

Next:
Cmdlet parameter binding in Monad 

Other:
Some of my ranting about NDA

Clarifications on NDA related issues about Monad
Pooja on deployment of Monad on 'unsupported' OSes

 

Thursday, June 10, 2004 6:25:24 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, June 03, 2004

Antonio has a post about generalizing environment classes (that capture state of a closure) with using generic types, such that the class itself captures only the arity of the environment.

 

To quote:

http://rotor.di.unipi.it/cisterni/Lists/My%20Blog/DispForm.aspx?ID=15

In general we may think that the compiler generates several environment classes, for the needed arities; for instance:

 

class Environment3<A, B, C> {

  A a;

  B b;

  C c;

}

 

There is one issue that I can think of, off the top of my head – the CLR has a an excellent approach to generics (among the best I have seen) and is well described in Don Syme’s paper here:

The Design and Implementation of Generics for the .NET Common Language Runtime

http://research.microsoft.com/projects/clrgen/generics.pdf

 

the thing about CLR generics is that they are very efficient for all reference types, because for reference types there is no specialization of templating behavior (as with classical c++ style generics). All reference types use the class definition during runtime.

 

However value types cause the runtime to generate specialized classes to handle type of a value type that is used is a templated entity. Classes definitions are shared by value types only when they share the same foot print with respect to the GC.

 

So it would be better is compiler actually generated specialized classes to hold environment state whenever is knows that the types the environment needs to hold are value types. This simply provides for a performance benefit, because the specialization of the class will not happen at runtime, instead will be done at compile time.

 

 

Antonio also discusses a private member access issue – again I don’t think I fully get him. Assuming the new delegate mechanism is in place we could have classes that look like this

 

class Env

{

        //have only public members

}

 

class Foo

{

        //original method

        void bar()

        {

        }

       

        //anonymous compiler generated method

        void anon_bar()

        {

                //access all members of Foo here

                //access all public members of Env here

        }

}

 

Is there a need to make members to Env private? The entire point of having Env is simply to act as a place holder for some values. Better yet (I don’t know if the old friend method mechanism works), but if friend decls are possible then the anonymous method can be declared as a friend in class Env. This does not add to the class definition in any way, it would simply allow for member access.

 

 

You might want to look at these links to follow the sequence of these posts –

1)       Closures in CLR 2.0

2)       Implementation of Closures (Anonymous Methods) in C# 2.0 (Part 6)

3)       More on CLR 2.0 closures

4)       Closure implementation enhancement in CLR 2.0 using the new delegate mechanism

5)       Again on closures

6)       this post

Thursday, June 03, 2004 12:58:34 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Wednesday, June 02, 2004

This is a tremendously exciting time to be thinking about programming languages and language research. I recently I have come across a lot of material that has made me think a lot.

 

Polyphonic C#

http://research.microsoft.com/%7Enick/polyphony/

            This is a C# like language that is built for concurrency control. Amazing piece of thought exercise there. I recommend looking at Modern Concurrency Abstraction for C#.

 

Xen/X# from Microsoft Research

Xen basically proposes to extend the C# language to better data handling support into the language. 

Unifying Tables Objects and Documents

This should give you a good idea of X#. This is by Erik Meijer of MSR.

Programming with Circles, Triangles and Rectangles

More – interesting reading.

 

C Omega

http://research.microsoft.com/Comega/

A combination of Xen and Polyphonic C#.

You might want to download this ppt that discusses C Omega by none other than Damian Watkins of MSR.

 

Groovy

http://groovy.codehaus.org/

            Groovy is the Ruby like language for the JVM. Ruby itself takes from the power of dynamic object oriented-ness that was so characteristic of smalltalk and whips a powerful expressive language on it. The thing is that Groovy also builds in Xen like concepts.

You might want to download this ppt that discusses Groovy by James Strachan co-author of groovy.

 

Self

http://research.sun.com/self/language.html

An old language from Sun Microsystems. Reading up about self makes you appreciate the spirit of many message passing and prototypes and cloning based pure object oriented systems.

 

 

 

I am not mentioning functional languages here because it is not fair to put up stuff I have no clue about. I must say this is an amazing time to be interested in programming languages.

 

Wednesday, June 02, 2004 7:35:22 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Friday, May 28, 2004

I had dropped a link to Antonio Cisternino’s blog entry about Closure support in CLR 2.0 when I was writing a description of how the C# compiler (Whidbey release) implements closures.

 

I was completely wrong about what Antonio’s blog entry was about. For some reason, my head being so full of C# that it is, I assumed he was talking about the how closures were implemented in C# for the Whidbey release. Closures in the Whidbey release (Visual Studio 2005) are officially called anonymous methods. So apologies Antonio, I had missed the point.

 

That said, what Antonio was referring to was a subtle change in the implementation of the delegates in CLR 2.0 so that the future CLR can be better used to implement closures and support functional languages and constructs. I exchanged some mails with him and I think I get what he was talking about.

 

Before I go any further I would recommend you reading Antonio’s original entry

Closures in CLR 2.0, my entry about the implementation of closures in C# 2.0 using delegates as they are available in CLR 1.x and Antonio’s follow-up entry that speaks of the distinguishing aspect of the new delegate implementation: More about Closures in CLR 2.0

 

The following are derived from mail exchanges with Antonio.

 

A delegate can be thought of as an entity that holds a pointer to a function and optionally a reference to the object for which the function is supposed to be an instance function. In CLR 2.0 a simple and subtle change has taken place where in the constraint that the instance pointer has to refer to the object for which the function pointer is member function, has been removed. The function pointer and the object reference don’t have to be related to each other.

 

In functional languages delegates are often implemented by having a pointer to a function which is the block of code that belongs to the closure and a pointer to an instance of the environment. The environment is the entity that holds the state for the code in the closure block.

 

In C# 2.0 the environment object is implemented by creating a class for every function that wraps a closure and shares state with it. Such a class is generated name-mangled as __LocalsDisplayClassXXX in C# 2.0.

 

The code that is part of the closure is now part of the environment class. When a closure is created an instance of the environment class is created and a delegate is returned to the instance and its member function that wraps the closure code. This is what could be done with CLR 1.x delegates as the function had to be a member of the environment class.

 

With CLR 2.0 delegates, what the compiler writers now have the option of doing is that they can generate a common environment class for all functions that wrap closures that need to capture similar information about its environment.

 

Here is an example and some notes courtesy of Antonio:

 

Closures in functional programming languages are often implemented with pointers pairs (env, func) where env is the pointer to the environment of the closure, and func is a pointer to a function whose first argument will be env.

 

With CLR 1.0 this cannot be achieved because delegates are pairs but with an additional constraint: func should be declared in the class of env.

The problem with this additional constraint on delegates is that you tend to define a class for each closure you make. In a functional programming language you'll pay a significant overhead because for each closure you have to introduce a private class with the environment and the code.

 

Besides removing that constraint (as it has been done in CLR 2.0) you can define a class with plenty of static methods, one per closure and define a type for each possible environment. This reduces the number of types you need to have.

 

For instance:

 

void foo() {

 string s;

 Cmd d = { Console.WriteLine(s); }

 //...

}

 

void baz() {

 string s;

 Cmd d = { Console.WriteLine("Hello {0}", s); }

 //...

}

 

The current compiler generates two classes both having a single int field.

With CLR 2.0 the compiler could use a single class as follows:

 

class Env_String {

 string f;

}

 

void f(Env_String env) { Console.WriteLine(env.s); }

void g(Env_String env) { Console.WriteLine("Hello {0}", env.s); }

 

void foo {

 Env_String env = new Env_String();

 Cmd d = (Cmd)Delegate.CreateDelegate(typeof(Cmd), env,

GetType().GetMethod("f"));

 //...

}

 

void baz {

 Env_String env = new Env_String();

 Cmd d = (Cmd)Delegate.CreateDelegate(typeof(Cmd), env,

GetType().GetMethod("g"));

 //...

}

 

In the above case the environment class need be only one, as in both the closures, the environment needs to capture the state of only a string variable. The environment class itself can be kept free of the closure specific code and the methods that are generated for the closure can be placed in the class that the original enclosing method was a part of.

 

This subtle thing had escaped my thinking for sometime. I guess when you are doing your PhD with a university that hosts one of the worlds largest .Net user-groups and are working with matters related to MSR Cambridge, you tend to pick up subtle things a lot easier. :-)

 

There is one thing that has me thinking is about the implementation of closures in the case of closures being defined inside instance methods. If you refer here, I show a screen shot of an ildasm of that case.

 

When an instance function is being used the environment will have to have a ‘this’ pointer member that the closure block can access to access any class data members. When the C# compiler is generating one class per function wrapping a closure the ‘this’ can be statically typed to the type of the class that contained the parent method.

 

 

If the environment class is to be shared across multiple classes that implement closures, then what will be the type of the ‘this’ pointer?

 

I am guessing here, but I would expect that they might choose to create the environment class as generic class that is type independent on the ‘this’ pointer. Do you think that sounds right? What are the possible fallouts with that approach? Generic environment classes.

 

As a matter of fact when you dive into the possibility that generics opens up, it’s rather interesting. We could have the entire environment as a class that contains templated / generic types for every reference type member. This might be efficient to implement because the implementation of generics in the .Net framework does not involve specialization of the runtime class for reference types. Even for value types, I believe it does optimizations to avoid class duplication if the value types have similar footprints as far as the GC is concerned.

 

One thing is for sure, the future looks interesting for functional and dynamic languages leveraging the CLR.

 

Among other things, I am looking forward to the MVP India summit that should be happening this weekend 28th May to 31st May.

 

 

Friday, May 28, 2004 1:16:56 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Saturday, May 22, 2004

C# 2.0 has support for closures.

 

This article discusses the implementation of the closures in the C# language and how this has been done using pure compiler magic without any CLR changes. I had previously mentioned C# closures in an earlier blog entry and had linked to Antonio Cisternino’s blog entry:

Closures in CLR 2.0

This is an interesting entry and worth a read. Unfortunately, IMO, Mr. Cisternino’s entry is a not correctly titled. The support for closures is a C# only thing not a CLR level addition.

 

I intend to start off where his blog entry ends. Here I shall look into how it is done.

 

Features such as closures have been taken to legendary fame in languages like scheme and ruby. Recent language developments like Groovy also ship with closure constructs.

 

Microsoft, for some reason, has been calling the new feature of the language as anonymous methods. I don’t know why this feature hasn’t been publicly been spoken of as closure or lambda support in the C# language. Maybe there are subtle differences in the theoretical definition of closures and what the C# language achieves.

 

That said – let’s jump into the matter.

This is C# code that shows off a closure:

 

Code Showing One Anonymous Method / Closure that shares variables with its scope

//closure.cs

//Compile: csc closure.cs

using System;

 

class CMain

{

      delegate void Closure(int n);

     

      static Closure CreateClosure()

      {

            int c = 0;

            return delegate(int n) {

                  Console.WriteLine("Closure: n = {0}, c = {1}",n,c++);

            };

      }

     

      static void Main()

      {

            Closure c1 = CreateClosure();

            Closure c2 = CreateClosure();

            c1(1);

            c1(1);

            c1(1);

            c2(2);

            c2(2);

            c2(2);

      }

}

 

This code is very similar to the groovy snippet I had posted sometime back. When executed, this is the output:

 

> closure.exe

Closure: n = 1, c = 0

Closure: n = 1, c = 1

Closure: n = 1, c = 2

Closure: n = 2, c = 0

Closure: n = 2, c = 1

Closure: n = 2, c = 2

 

If you don’t know what closures are about, the easiest way to appreciate them is to take a careful look at the C# code above. Notice the function CreateClosure() is returning a delegate to a block of code that is part of the function itself. (Normally you would create a delegate to a function). If you don’t understand what a delegate is, let it be. What you need to understand is that the function returns a block of code that is a part of the function.

 

The block of code accepts an integer parameter. Also, you will notice that the local variable of the function (variable ‘c’) is being used in the code block.

 

When the block of code is returned to the caller (in this case main), the Main() can invoke the variable that represents the block of code, causing the code to run.

 

Once upon a time you could create a delegate to an independent function only and not to a code block within a function. A delegate to a function had to have the same signature as the function. The delegate could be thought of as an old C style function pointer. When the delegate is invoked, the function pointed to is called. Delegates came with the additional merit that they were type safe function pointers – most people did not think much more than that about delegates.

 

Now it is a little different. While the anonymous method within the CreateClosure() method actually looks like it simply has a nested function that does not have a name explicitly provided its not that simple. You might venture to guess that the compiler actually goes on to create a new method (by extracting this code block) and simply creates a delegate to the new function, the same way delegates once used to behave.

 

However, notice that the code block uses variable ‘c’ that is defined locally to the enclosing function. If this code block is going to be carved out of the enclosing function, how can it access variable ‘c’? Better yet, take a closer look at the output.

 

It looks like a closure returned from a call to CreateClosure() is seems to remember its value of the variable ‘c’. Some how, the state of the function CreateClosure() is captured in the delegate/closure that it returns. So much so, that the state of two invocations of CreateClosure() seemed to be maintained independent of each other.

 

This is in violation of the way simple C like functions work, where the function state is stored on the stack and the functions stack frame is torn down from the stack and state is lost when the functions return. (Refer ‘The Big Deal about Iterators’)

 

Functions that return closures seemed maintain state even after they have returned. The closure object is maintains a reference to that state. This requirement of maintaining is similar to the implementation of iterators (if you give it some thought).

 

Implementation

This is what our closure.cs looks like under ILDASM.

 

 

Notice the new class called __LocalsDisplayClass$0…1 that has been created. This is interesting culprit.

 

In essence how closures work in C# 2.0  is that the compiler creates a new class that contains member variables correspond to the local variables of CreateClosure() that are being used in the closure/anonymous method that it defines. Thus you can see the local variable ‘c’ of method CreateClosure() can be seen in class __LocalsDisplayClass$0…1.

 

So calling the CreateClosure method creates an instance of the __Locals… class. It then creates an old (classical) delegate to the __AnonymousMethod$0… method of the class. So the actual support for delegates in the CLR hasn’t changed at all. The delegate that is returned from the CreateClosure() method is a normal (old C# 1.x type) delegate.

 

All access to variables that are shared between the CreateClosure() method and the anaymous method are accesses to members of the __Locals… class.

 

Here is IL code of CreateClosure()

 

.method private hidebysig static class CMain/Closure

        CreateClosure() cil managed

{

  // Code size       30 (0x1e)

  .maxstack  3

  .locals init (class CMain/__LocalsDisplayClass$00000001 V_0,

           class CMain/Closure V_1)

  IL_0000:  newobj     instance void CMain/__LocalsDisplayClass$00000001::.ctor()

  IL_0005:  stloc.0

  IL_0006:  ldloc.0

  IL_0007:  ldc.i4.0

  IL_0008:  stfld      int32 CMain/__LocalsDisplayClass$00000001::c

  IL_000d:  ldloc.0

  IL_000e:  ldftn      instance void CMain/__LocalsDisplayClass$00000001::__AnonymousMethod$00000000(int32)

  IL_0014:  newobj     instance void CMain/Closure::.ctor(object,

                                                          native int)

  IL_0019:  stloc.1

  IL_001a:  br.s       IL_001c

  IL_001c:  ldloc.1

  IL_001d:  ret

} // end of method CMain::CreateClosure

 

Notice some things in the above code

- An object of __LocalsDisplayClass$00000001 is created.
- Access to the variable is actually access to the member ‘c’ of this class.
- The delegate is created to the instance of the __LocalsDisplayClass$00000001 class that was created and its __AnonymousMethod$00000000 method.

 

This is the code of the anonymous method, which has now become CMain/__LocalsDisplayClass$00000001::__AnonymousMethod$00000000(int32)

 

.method public hidebysig instance void  __AnonymousMethod$00000000(int32 n) cil managed

{

  // Code size       39 (0x27)

  .maxstack  5

  .locals init (int32 V_0)

  IL_0000:  ldstr      "Closure: n = {0}, c = {1}"

  IL_0005:  ldarg.1

  IL_0006:  box        [mscorlib]System.Int32

  IL_000b:  ldarg.0

  IL_000c:  dup

  IL_000d:  ldfld      int32 CMain/__LocalsDisplayClass$00000001::c

  IL_0012:  dup

  IL_0013:  stloc.0

  IL_0014:  ldc.i4.1

  IL_0015:  add

  IL_0016:  stfld      int32 CMain/__LocalsDisplayClass$00000001::c

  IL_001b:  ldloc.0

  IL_001c:  box        [mscorlib]System.Int32

  IL_0021:  call       void [mscorlib]System.Console::WriteLine(string,

                                                                object,

                                                                object)

  IL_0026:  ret

} // end of method __LocalsDisplayClass$00000001::__AnonymousMethod$00000000

 

This is quite exactly the code that we had written into the CreateClosure() function. Except that the local variable ‘c’ is not a local variable any more.

 

What do you think will happen when there is a function that defines two anonymous methods within it?

 

Code Showing Multiple Anonymous Methods / Closures that share variables with its scope

//closure2.cs

//Compile: csc closure2.cs

using System;

 

class CMain

{

       delegate void Closure(int n);

       static Closure t1,t2;

      

       static void CreateClosure()

       {

              int c1 = 0;

              int c2 = 0;

              int c3 = 0;

              int c4 = 0;

              Console.WriteLine("c4 = {0}",c4);

             

              t1 =  delegate(int n) {

                     Console.WriteLine("Closure: n={0}, c1={1}, c2={2}",

                                n,c1++,c2++);

              };

              t2 = delegate(int n) {

                     Console.WriteLine("Closure: n={0}, c1={1}, c3={2}",

                                n,c1++,c3++);

              };

       }

      

       static void Main()

       {

              CreateClosure();

       }

}

 

 

This is what happens:

 

 

Notice:

- There is still only one class that maintains state.
- The class has two methods (one for each of the anonymous methods)
- The variables that are being used by either of methods are part of the class (c1,c2, c3).
- Variables that are not being used from either closure are not part of the class (c4 is omitted).

 

One final look, what if the closure does not use any variables of its enclosing scope, how would this work?

 

Code Showing an Anonymous Method / Closure that is stateless

//closure3.cs

//Compile: csc closure3.cs

using System;

 

class CMain

{

       delegate void Closure(int n);

      

       static Closure CreateClosure()

       {

              int c = 0;

              return delegate(int n) {

                     Console.WriteLine("Closure: n = {0}",n);

              };

       }

      

       static void Main()

       {

              Closure c1 = CreateClosure();

              Closure c2 = CreateClosure();

              c1(1);

              c2(2);

       }

}

 

The code generated looks like this:

 

 

As expected there is NO hidden class generated in this case. Why? Because these is no need for the anonymous method to save state. The anonymous method itself is added to the class that contains the CreateClosure().

 

 

One more case to look at: what happens when the closure accesses both a local variable of the enclosing method as well as a member variable of the class that the enclosing method is a part of? Because state is persisted in a new class instance, how will the member variables of the original class be accessed?

 

This is C# code that shows this situation:

Code where closure accesses locals and class members

//closure4.cs

//Compile: csc closure4.cs

using System;

 

class CMain

{

       delegate void Closure(int n);

       int a = 10;

      

       Closure CreateClosure()

       {

              int c = 0;

              return delegate(int n) {

                     Console.WriteLine("Closure: n = {0}, a = {1}, c = {0}",n,a++,c++);

              };

       }

      

       static void Main()

       {

              CMain main = new CMain();

              Closure c1 = main.CreateClosure();

              Closure c2 = main.CreateClosure();

              c1(1);

              c2(2);

       }

}

 

This is what the generated code looks like:

 

 

Notice that there is a member in the _Locals… class that is called < this >. The this pointer/reference refers back to the original enclosing class where the anonymous method belonged. Thus it can access member variables.

 

Notes

I think C# closures were created as a by product of trying to implement iterators into the language. The implementation of iterators involved this sort of temporary class creation that preserved state of functions. (A little like Bjarne Stroutrup’s Function Objects).

 

I don’t know if there are reasons why this implementation of anonymous methods cannot be called as proper closures. Anonymous methods cannot use any ref or out type parameters of its enclosing function – this is a limitation. Does this limitation imply that they cannot be called closures? I don’t know. But other than that, it seems to serve the purpose of closures pretty well.

 

The fact that closures have been implemented as a compiler level hack means that there is no overhead at all for code that does not take advantage of these sort of feature. So there is no performance penalty on the CLR itself. Maybe in time, when these features gain adequate popularity there will also exist efficient means of integrating these features into the CLR in a way that does not affect functioning of traditional code.

 

Once we have closures, we can implement a large variety of constructs in the language (iterators being one of them). However since the syntax is a little clunky and the actual implementation a little slow (because there is a hidden managed class involved) this may never happen. All the same this is one amazing feature to have in a mainstream language like C#. Maybe even a little too advanced for some folk, so don’t be surprised is the coding guidelines of your company say NO to anonymous methods, the way they said to C++ macros once upon a time.

 

 

Saturday, May 22, 2004 1:10:56 AM (Eastern Standard Time, UTC-05:00)  #    Comments [4]  | 
 Friday, May 21, 2004

Today I had a rather shocking realization. I realized that C# 2.0 supports closures.

 

It was rather shocking, because here I was running up and down obscure languages looking for features like this and bang C# has it. I was pointed to this blog entry by a good friend of mine at Microsoft: Antonio Cisternino's Blog: Closures in CLR 2.0.

A lot of the content on Mr Cisternino’s blog is rather interesting and I would recommend a visit to

http://rotor.di.unipi.it/cisterni/Lists/My%20Blog/AllItems.aspx

 

The entry on closures is an interesting read. A quick search on google, showed me that the rest of the world seemed to have realized that C# has closures, a long time before I did.

 

 

 

Looking at closures brought back something from hazy old memory from a time when I was more ignorant:

 

Function Objects in C++

 

What is a function object?

 

An object that in some way behaves like a function, of course. Typically, that would mean an object of a class that defines the application operator - operator().

A function object is a more general concept than a function because a function object can have state that persist across several calls (like a static local variable) and can be initialized and examined from outside the object (unlike a static local variable). For example:

 

                class Sum {

                                int val;

                public:

                                Sum(int i) :val(i) { }

                                operator int() const { return val; }                  // extract value

 

                                int operator()(int i) { return val+=i; }           // application

                };

 

                void f(vector<int> v)

                {

                                Sum s = 0;             // initial value 0

                                s = for_each(v.begin(), v.end(), s); // gather the sum of all elements

                                cout << "the sum is " << s << "\n";

                               

                                // or even:

                                cout << "the sum is " << for_each(v.begin(), v.end(), Sum(0)) << "\n";

                }

 

Note that a function object with an inline application operator inlines beautifully because there are no pointers involved that might confuse optimizers. To contrast: current optimizers are rarely (never?) able to inline a call through a pointer to function.

Function objects are extensively used to provide flexibility in the standard library.

 

This is written by none other than Bjarne Stroustrup and you can see the full FAQ here:

http://www.research.att.com/~bs/bs_faq2.html

 

You might relate this to the brief discussion on method instances in the previous entry ‘The Big Deal about Iterators

 

Hopefully I will have a better understanding of how C# does closures, soon enough.

 

Friday, May 21, 2004 4:55:20 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Wednesday, May 19, 2004

This is an entry I have kept pending for a long time. I should have had this out much earlier.

 

Here I am going to talk about why iterators are a hard feature to implement in a conventional stack based language. This will probably help you understand some of the design decisions with respect to implementing iterators in a language and, on the whole, make you a better programmer with respect to this programming construct.

 

I am assuming that you have read Parts 1 and 2

Iterators in Ruby (Part - 1)

Warming up to using Iterators (Part 2)

 

After you have read this entry you should be in better light to grasp Parts 4 and 5.

SICP, Fiber api and ITERATORS ! (Part 4)

Implementation of Iterators in C# 2.0 (Part 5)

 

 

Method Calls and the Stack Frame

Since you have seen some samples of iterator based code in Part 2 lets take a look at how an iterator works. Before we delve into the related issues, first let us take a look at how method calls work on the C stack. (We could have taken an stack based language here, for example .Net IL, but I figured it is easier to stick to C).

 

Consider the following functions

 

void caller()

{

        int a;

        int b;

        int sum = callee(a, b);

}

 

 

int callee(int a, int b)

{

        int temp = a + b;

        return temp;

}

 

That is amazingly simple. However what happens here? When I say what happens here, I mean to ask what happens here at the system stack level.  To do that lets take a look at the dissembly of these functions. If you were to compile this code with the vc++ compiler, you could use the following switch to generate assembly code.

>cl /Facode.cpp.asm code.cpp

 

?callee@@YAHHH@Z PROC NEAR                      ; callee

; File d:\roshanj\work\cpp\iter\func.cpp

; Line 2

      push  ebp

      mov   ebp, esp

      push  ecx

; Line 3

      mov   eax, DWORD PTR _a$[ebp]

      add   eax, DWORD PTR _b$[ebp]

      mov   DWORD PTR _temp$[ebp], eax

; Line 4

      mov   eax, DWORD PTR _temp$[ebp]

; Line 5

      mov   esp, ebp

      pop   ebp

      ret   0

?callee@@YAHHH@Z ENDP                           ; callee

 

?caller@@YAXXZ PROC NEAR                        ; caller

; Line 8

      push  ebp

      mov   ebp, esp

      sub   esp, 12                             ; 0000000cH

; Line 11

      mov   eax, DWORD PTR _b$[ebp]

      push  eax

      mov   ecx, DWORD PTR _a$[ebp]

      push  ecx

      call  ?callee@@YAHHH@Z              ; callee

      add   esp, 8

      mov   DWORD PTR _sum$[ebp], eax

; Line 12

      mov   esp, ebp

      pop   ebp

      ret   0

?caller@@YAXXZ ENDP

 

 

The stack frame of the caller function looks like this:

 

 

And the when the caller() is calling the callee() then both the methods have their stack-frames mounted.

 

 

In Intel based systems the C stack grows downward in memory, which means that each item that is added to the stack causes the top of the stack (SP) to have a lesser address value. So the right way to draw these diagram would have been to draw them upside down. But that detail is not relevant here and so I have depicted them as a conventional stack that grows upwards.

 

When the callee() returns, the stack looks like the initial stack diagram and the variable ‘sum’ contains its required value.

 

 

To reiterate, what happens is that a method that is currently running uses the stack for storing its local variables – or more generally the state of the running method is preserved on the stack. When a method is called, it builds its own stack frame on top of whatever was already on the stack. The called method uses the stack frame to save its state, irrespective of what other methods are already on the stack.

 

You might have heard of this concept called a stack-overflow. That happens when methods calls happen to such an extent that there is not more free space left on the stack for the stack frame of a new method to be created.

 

Whenever a method returns, the part of the stack that is used for its variables is freed up – or so to speak, the methods stack frame is torn down. So when a method returns, its state information, that was on the stack is completely lost. This is necessary, because the parent function or method, might go on to call other methods that go on to use same stack space subsequently.

 

So let us say there is a calling pattern like this

 

function a()

        return

       

function b()

        call a()

        return

       

function caller()

        call a()

        call b()

        return

 

The stack usage will look like this –

 

 

Now that we have a reasonable idea of how the stack is used across method calls (though in reality there are so many many approaches), lets move on to iterators.

 

Iterators

Look at the following ruby snippet that shows an iterator. If you have an interest in C/Cpp/C# and couldn’t care less about Ruby, don’t throw your hands up in the air – the language is used here as an example of a language that implements iterators (and rather well at that), which I am using to communicate the idea.

 

def callee()

        for i in 1..10

                yield i

        end

end

 

def process(v)

        return (v * 10)

end

       

       

def caller()

        callee() {|value|

                value = process(value)

                print value

        }

end

 

If you recall the behavior of the iterator from Part 1 and 2, you will remember that when caller() calls callee() and the callee() invokes the yield statement, the control is back at the caller(). In this case, the value of ‘i’ is yielded from callee() which is received in caller() as value.

 

In C code, when the control returns to the calling function the assumption is that the called function is dead on the stack and that the stack frame is free for subsequent method calls, as shown in the stack diagram above.

 

If we have a similar diagram for the this ruby code, how would we draw it?

 

 

This is where we hit our first wall.

 

Assume that the caller() calls callee() and the callee() has yielded value 1. Now the stack frame of callee() is torn down in the old C way and the process() method is called which goes on to use the same area of the stack that was one used by callee(). After that caller() has done whatever it needs to do with the value it received from callee() it tries to invoke callee() again so that it can get the next value. This is where we hit the wall. The callee() cannot return the next value simply because the previous value it has for ‘i’ is lost when its stack frame got torn down.

 

In other words, on a conventional C stack, the callee() state is lost and therefore cannot resume execution from the point of a yield.

 

What work arounds do we have to this issue?

Let us assume that what Ruby does is simply a compiler hack – let us assume that it never really tears down the stack frame of the callee() at all, but instead it ensures that function returns back to the caller() but with the callee() stack frame still in place. That would look like this

 

 

While this is a nice diagram to look at, what does this mean? Where will the stack frame of the subsequent call to process() go? It cannot over-write the callee() stack frame – so it has to go above it. Like this?

 

 

Woo, now wait a minute, how does the caller() function know how much of the stack the callee() function is using to be able to do this? This is a difficult question to answer. Remember that the callee() is a proper function that can be using a variable amount of the stack at any point of time. So the caller() cannot predict the stack usage of the callee() but lets assume that the callee() passes back the information of its stack usage back along with the value that it is yielding.

 

Ok, so that would solve the problem of how the process() function uses the stack. But there is one more issue. What is the code block inside the caller() (the one that receives the yielded value) needs to push a value onto the stack?

 

If the code block inside the caller, needs to push a value onto the stack, then the pushed value will go on to overwrite the stack-frame of the callee above it. The obvious way to fix the problem is to shift the entire stack pointer to the top of the stack, above the callee() also. You can visualize it like this:

 

 

While this could work, there is one more issue – the local member variables of a function are accessed via EBP offsets. Now this is fine when local variables occur at known distances from the base of the stack frame for the function. To see this happen, you might want to refer back to the assembly code I posted towards the beginning of this article. You notice that most of the member variables are being accessed as _a$[ebp] or _b$[ebp], or similar syntax. The _a$ here does nothing but add a fixed positive offset to the EBP pointer. For the access of local variables when code is in the yield’s parameter block region of the caller() these rules would have to change, as there is an issue of adding an additional offset. The additional offset is introduced because now there is the stack frame of the callee() sitting squarely in the middle of what should have been the stack frame of the caller().

 

These issues crop up when using single iterators. If using multiple iterators or nested iterators and when used in conjunction with stack intensive operations like recursion, the picture because very complicated.

 

Alternative approaches of State maintenance and the concept of Method instances

While it should be clear that, to implement iterators in a language the must support the idea of functions maintaining their state even after they surrender control to their calling methods – it is not very clear as to how this can be implemented on a conventional C stack.

 

One approach is to go for a ‘stackless’ implementation. What that means is that function activations or stack frames are treated as allocated memory blocks on the heap and each function instance (when you call a function it needs to create a stack frame and that can be considered a function or method instance) lives on the heap like any other dynamically allocated object. These mini stacks as specific to function instances and so have no real concept of colliding with each other due to sharing a larger OS/platform maintained stack.

 

I believe languages like lisp/scheme behave in this manner with respect to the language stack. (I have been told this and I hope this is correct).

 

 

Another alternative is to approach the problem like this. Assume that the callee used only static variables. Immediately, the issue of maintaining state of variable of the callee on the stack is eliminated. The only issue then, is to resume execution of the function from the correct place (immediately past the yield) when the function is called again. This can be easily achieved by saving the resume position into an additional variable and implementing a switch case goto construct at the beginning of the function.

 

Now since it is persisting state in static variables we cannot use this recursively or in any other fashion. But we could fix this if we created a structure/class that contains member variables corresponding to the local variables of the function and use an instance of this structure in the function instead of using proper static variables.

 

Languages such as C# and Python use a similar approach to maintaining state of iterators between calls. You can read more about this in the Part 5 of this series.

 

For constructs like iterators to be supported in .Net and similar runtimes, in a native way, will require substantial changes in the way the runtime manages stack-frames and similar entities. Basically languages and runtimes need to be retro-fitted with a concept of function and code block instances the same way object oriented programming is fitted with concepts of class instances called objects.

 

Languages like Sun Microsystems’ Self build on similar concepts for methods/function instantiation.

 

If you give some of the ideas here a little thought, you should be well on your way to dreaming about new languages and fancy programming constructs.

Wednesday, May 19, 2004 9:09:21 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Thursday, April 29, 2004

I thought of putting together some of my old mails and user group posting as blog entries, with some patches so that they are’ blogopatible’. They would have ended up on my blog, if I had a blog when I made these posts. I feel some of these are of lasting importance, at least with respect to the impressions they had on me.

 

All of these are personal opinions, probably more relevant in the context that they were originally written.

 

-----Original Message-----
From: James, Roshan
Sent:
Tuesday, December 09, 2003
11:57 PM
 Subject: XAML and markups: Introducing WFML - WinForms Markup Language

Hi Folk,

 

Ever since Linux Bangalore I have been thinking about something that Miguel de Icaza had demoed on stage. He was showing Mono’s UI, Glade, and showed how Glade generates UI from XML markup. They (Miguel and Nat) were also joking as to how XAML is an idea that they had thought of 6 years back – the idea of using XML markup for representing UI and separating 'business logic' from UI.

 

            He also went on to show how Glade is used to generate GTK# UI in linux. A '.glade' file is simply an xml file that contains tags that correspond to the properties of the controls (or widgets as they call them).

 

(I pulled glade file off the net to give you an idea of what it looks like

 

< widget class="GtkWindow" id="window2">

  < property name="visible">True< /property>

  < property name="title" translatable="yes">window2< /property>

  < property name="type">GTK_WINDOW_TOPLEVEL< /property>

  < property name="window_position">GTK_WIN_POS_NONE< /property>

  < property name="modal">False< /property>

  < property name="resizable">True< /property>

  < property name="destroy_with_parent">False< /property>

 

  < child>

    < widget class="GtkButton" id="button1">

      < property name="border_width">10< /property>

      < property name="visible">True< /property>

      < property name="can_focus">True< /property>

      < property name="label" translatable="yes">button1< /property>

      < property name="use_underline">True

      < property name="relief">GTK_RELIEF_NORMAL< /property>

    < /widget>

  < /child>

< /widget>

 

)

 

The strange thing was how they used glade files - in XAML you compile the xml file to generate a class (or what MS calls a partial class, one that can be extended elsewhere). In glade they did no such thing, they simple wrote a cs file and called one Glade API function passing it the name of '.glade' file. That returned some kind of object and presto they had their UI. Now the claim was that this really separates the UI from the code and as a matter of fact the XML can be chnaged after the exe file has been compiled. Changes to the XML will reflect in the UI without recompilation of anything. They also mentioned that Microsoft hasn’t figured out how to do this yet.

 

(Here is fragment of c# code that uses the .glade

 

                using Gtk;

                using Gnome;

                using Glade;

                using GtkSharp;

 

        public class GladeTest

                {

                                /* If you want to access the glade objects you have to "import" them.

                                 * This is not required, but else you can only work with the

                                 * pre-defined signal handlers */

                                [Glade.Widget]     

                                Button button1;

 

                                public GladeTest (string[] args)

                                {

                                                Application.Init();

 

                                                /* This loads the glade file glade.glade,

                                                 * selects window2 and connects it to the current object,

                                                 * which is the class GladeTest here. */

                                                Glade.XML gxml = new Glade.XML ("file.glade", "window2", null);

                                                gxml.Autoconnect (this);

 

                                                button1.BorderWidth=10;

 

                                                Application.Run();

                                }

)

 

            Now this got me thinking about how they implemented this dynamic behavior - as result of which WFML was born. It was rather surprising how easy this was to do. I am sure Miggy's code will be better and more optimized, but I think my general direction is correct.

 

WFML, in short provides (or at least hopes to provide) a markup language for UI that simply does not have to compiled (in the conventional sense). WFML UI is actually WinForms based UI, WFML by itself cannot add any features that are not present in WinForms. What it does is that it lets you write very clean looking code that does not have a clutter for UI itself. The entire UI of the program is expressed in an external XML file, called a .wfml file. Now if you have ever tried writing a Win forms application by hand without studio, you will remember how hard it is to remember so many of the house-keeping things required - take a look at some WFML based code:

 

//win.cs

using System;

using System.Windows.Forms;

using System.Windows.Forms.Markup;

 

 

class CMain

{

        static void Main()

        {

                IAttachable win = new Wfml().CreateUserInterface("win.wfml","MainWindow");

                Application.Run((Form)win);

        }

}

 

Simple ? This is a C# file that uses the WFML library. The markup lib being a pure .Net assembly can be used by any .Net language, - C#, VB, C++, Jscript, VJ# etc. Now what you need is a WFML file that specifies the UI. And you simply write the .wfml file like this (win.wfml):

 

 

        < Window

                Name="MainWindow"

                Height="200"

                Width="400"

        />

 

As you can see, the WFML is simply an XML file with certain tags that the WFML library understands. The advantage of using something like WFML is that you can completely change this XML at will and the UI of your program can be completely changed.

 

Now compile the cs:

   

csc /t:winexe /r:System.Windows.Forms.Markup.dll win.cs

 

Run win.exe and you will see an empty window

 

The following .wfml code displays a button and a text box for the same win.exe program. The program need not be edited or recompiled, only the .wfml file needs to be changed.

 

< Window

        Name="MainWindow"

        Height="200"

        Width="400"

       

        Text="Main Window"

>

        < Button Name="mybutton"

                Top="10"

                Text="Click Me"

        />

        < TextBox

                Name="tbox"

                Top="40"

                Left="5"

                Width="200"

        />

 

(What tags and attributes are allowed within a WFML? Every attribute that you set in a tag has to be a property of the corresponding WinForms type. That is to say that if you want to put a attribute called ‘Text’ in the ‘Window’ tag, then the class System.Windows.Form.Window should support a property called Text. WFML being a very simple system is case sensitive and provides no error feedback if something is wrong.)

 

And you can even attach event handlers and write back to the UI:

 

using System.Windows.Forms;

using System.Windows.Forms.Markup;

using System;

 

class CMain

{

        public TextBox tbox;

         

        public void clicked(object sender, EventArgs e)

        {

                tbox.Text+="+ ";

        }

        

        static void Main()

        {

                IAttachable win = new Wfml().CreateUserInterface("win.wfml","MainWindow");

                CMain cm = new CMain();

                win.AttachConsumer(cm);

               

                Application.Run((Form)win);

        }

}

 

Do try some WFML, the supported types are Button, TextBox and Label - but I guess the rest can be added easily.  Now I don't think this was anywhere as hard as they were making it out to be on stage.

 

Roshan James

------------------------------

 

 

You can download the WFML.zip file here. This also contains the demos that I had for this UG post.  While I never did continue on the WFML, folk did mail me back asking about the WFML assuming it was part of a larger UI framework.

 

Of course, capital negatives of the approach are that there is no IDE to ease development of WFML and such, but the idea itself is rather interesting.

 

How WFML actually works, as you might have guess is that it uses reflection API to dynamically generate a System.Windows.Form type that is customized according to the WFML file. This runtime generated type also runs reflection based code on its caller and appropriately latches up event handlers dynamically. Also it uses reflection to assign references of the caller to classes to the actual objects created in the generated Form class.

 

You however need not compare XAML to WFML or like approaches because XAML is a whole different beast. Differences start with be67ing vectored based don’t stop any time soon.

Thursday, April 29, 2004 5:49:08 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  | 
 Sunday, April 25, 2004

Iterators in Ruby (Part - 1)

Warming up to using Iterators (Part 2)
< I am yet to write a part 3 >
SICP, Fiber api and ITERATORS ! (Part 4)

 

I had a look at the implementation of iterators in C#. What follows is based on code generator I have seen on the C# Whidbey post PDC release. Things might have changed by now as things are moving to technology preview phase.

 

This is example code that is present in MSDN:

 

// yield-example.cs

using System;

using System.Collections;

public class List

{

    public static IEnumerable Power(int number, int exponent)

    {

        int counter =0;

        int result = 1;

        while(counter++ < exponent)

        {

            result = result * number;

            yield result;

        }

    }

 

    static void Main()

    {

        // Display powers of 2 up to the exponent 8:

        foreach(int i in Power(2, 8))

            Console.Write("{0} ", i);

    }

}

 

Notice the introduction of a nice little ‘yield’ keyword? The behavior of C# iterators in this context is a lot like ruby iterators that I have been talking about in previous articles. Knowing a little about the state management requirements for iterators and the fact that the CLR is stack based, how are iterators implemented in C#?

 

The implementation of iterators in C# is not driven by the CLR in any way, it is completely implemented in the language as a compiler construct.

 

Let me explain what the compiler tries to do – the compiler examines the function that does the yield

 

    public static IEnumerable Power(int number, int exponent)

    {

        int counter =0;

        int result = 1;

        while(counter++ < exponent)

        {

            result = result * number;

            yield result;

        }

    }

 

Lets just ignore the yield statement for now and look at the method as thought it contained only a loop. It would basically look like this:

 

    public static IEnumerable Power(int number, int exponent)

    {

        [initial code]

        while([loop condition])

        {

            [loop body]

        }

        [post loop code]

    }

 

This is then generated into a sequence of IL statement blocks that have the following jumps between them:

 

 

Now, what yield would require is that the method exit at each point a yield statement occurs. The next time the method is invoked, execution continues immediately past the yield statement with all variables preserving their values.

 

In the CLR, when a method returns its stack frame is torn down. So there is no way that the local variables can actually preserve state. The solution taken by the C# team is turn the method that implements the yield statement into a class.

 

Such a class would

 

·         Have all local variables of the method as members of the class

·         Have a special variable that hold the value that is being yielded.

·         Have a special variable to indicate where the method should continue from, the next time it is invoked.

 

When the caller of such a method runs and encounters the foreach loop that invokes the iterator an object of this class gets created. This object is maintained as long as the foreach lop is running. When the loop exits the object is disposed.

 

That’s how iterators are implemented in C#. :)

 

Now here are some details:

 

 

The method that implements the iterators generates not one but two classes. Both the classes are generated as nested/inner classes to the class that contains the method. The classes are named as
(method name)$(number )_IEnumerableImpl
(method name)$(number)_IEnumeratorImpl

 

I am not sure about the exact reasoning behind the generation of two classes. The earlier standard for writing enumerators in C# probably required, but from the standpoint of implementing iterators, I don’t understand the need.

 

The first of these, the IEnumerableImpl simply creates an instance of the second class and returns it to the caller.

 

The second class IEnumeratorImpl is the interesting one. This class has data members for all the local variables as well as our two special data members.

 

Compare the data members (the cyan colored diamond shapes) to the original  local variables of the method.

 

    public static IEnumerable Power(int number, int exponent)

    {

        int counter =0;

        int result = 1;

        while(counter++ < exponent)

        {

            result = result * number;

            yield result;

        }

    }

 

The parameters number and exponent are there as such and the local variables counter and result are there with some name mangling (I would expect this is to avoid clashes with duplicate names in nested scopes, though that is not allowed in C# (duh?)).

 

The two new members on the class are

·         $PC

·         $_current

 

$_current is the member that holds the yielded value. In the case of the above method, $_current holds the value of ‘result’. It is an ‘object’ type for there will be a nice boxing and gc overhead when moving around an int type – I don’t know why something was not done for special casing value types.

 

$PC is the interesting variable. Remember our little diagram above that showed execution through IL. In the case of the iterators, the method does not simply execute in a loop like shown there, but executes one iteration of the loop on each call. The $PC is the variable that keeps track of where the code should jump to, the next time the method is called. Understandably $PC is someone idea of program counter ;)

 

The code method called MoveNext() in the class actually does the work that the method power() originally did. This is what is look like in IL code.

 

 

Sorry I am not very good with diagrams, but if you look at it you will see that the code is simply built for repeated invocation. Each time according to $PC the code braches to a new location and executes. It then sets the value of $PC to a new location of entry before the function exits.

 

In C# the yielded value is assigned to the $_current member variable and the MoveNext() itself exits by returning a true or false. A true indicates that the method returned through a yield and the false indicates that the method has completed execution. Subsequent calls to the method, after it has returned false will simply cause the method to return false and the $_current will not be updated.

 

So how does the caller of an iterative method behave? In this case its the main. The  caller simply does the following –

 

Invoke Power$00000000__IEnumerableImpl. GetEnumerator() to get an instance of Power$00000000__IEnumeratorImpl

 

Invoke Power$00000000__IEnumeratorImpl.MoveNext()

 

If result is true, use invoke Power$00000000__IEnumeratorImpl.get_Current() which will return the $_current. The foreach loop will cause the MoveNext() to be invoked again after the reurned value is consumed.

 

If result is false, break out of foreach loop.

 

After the loop breaks out the instance of Power$00000000__IEnumeratorImpl is dispose and is available for garbage collection. 

 

I am looking forward to the beta preview to see f things have changed. There is a lot of rather redundant code generated by the compiler here that I have not mentioned. When you are reading IL you might want to skip over those parts.

 

Probably in the future the CLR will contain constructs that enable true iterators and closures. Present day processors don’t natively support such constructs and so implementation will have to be hacks on the C stack or using some kind of class-object mechanism like shown here.

 

As a foot note I would like to mention that the Python also implements iterators in a manner similar to C#. There the function that yields is also converted into a class that maintains state. I believe the MoveNext() equivalent in Python is simply next(). Python however raises an exception to signal end of iteration. C# uses a Boolean return value to indicate this.

 

If this topic holds your interest then I recommend reading:

 

Coroutines in C
by Simon Tatham

 

C# 2.0 Create Elegant Code with Anonymous Methods, Iterators, and Partial Classes
by Juval Lowy (MSDN Mag)

 

Charming Python: Iterators and simple generators - New constructs in Python 2.2
by David Mertz (developerWorks)

Sunday, April 25, 2004 6:16:33 AM (Eastern Standard Time, UTC-05:00)  #    Comments [9]  | 
 Thursday, April 22, 2004

I downloaded and tried the new programming language Groovy today. In short groovy is like having Ruby on JVM. Maybe only better, because, it now has the power of the whole JVM to leverage. This is the homepage:

http://groovy.codehaus.org

 

 

The language is a stunner.

 

There is a lot of neat language design going on here.

http://wiki.codehaus.org/groovy/BlocksAndClosures

Imagine something like Ruby actually being available to code JSP, beans and what not in the Java world.

 

Being from the .Net background, I wish this was being done for the CLR. Imagine the power to the multi language support of the CLR brought into something like Ruby. For now I am content with gaping at features like this:

 

def counter(a)

{

      c = a;

      x = {c +=1; c};

      x

}

 

a_counter = counter(0)

b_counter = counter(20)

 

println(a_counter())

println(b_counter())

println(a_counter())

println(a_counter())

println(b_counter())

 

This actually works. Real closures!
If you are a lost C or VB soul, what is happening is that the function/method called counter() creates and returns a closure called x. A closure is a block of code that maintains state and scope based access to its variables. So closure x has the maintains state and has access to the variables of the method counter().

a_counter and b_counter are instance of the closure in the counter() method, that live after the invocations to the counter() method has exited. You can see that state is maintained between calls as the value of ‘c’ is incremented in each successive call.  

 

This is way ahead of languages like C# which are just grappling with their implementation of yield. This is of course not to blame the C# team, because admittedly the concept of programming with closures is yet to hit ‘the masses’

 

Groovy seems to do a whole pile of exciting things that Ruby can do

·         Closures

·         Iterators and Blocks

·         Regular expressions

·         Flexible collection types

·         Dynamic Method Invocations and types

I haven’t seen any mention of continuations, extendible classes, mixins and the like yet.

 

Of course, being on the JVM is slow and implementing a lot of features like the ones above, accounts for expensive constructs, which make the language even slower. However for most scripting language speeds, it should be acceptable.

 

What I think is more important is that languages of Ruby stature are being implemented on popular OO virtual machines. This is a sign for a possible trend in the future – a good one. It will be interesting times ahead when we have dynamic languages and functional languages move onto popular VMs.

 

I really like C and I think that simplicity is a feature (EricGu), however there is a real wealth of possibilities to be gleaned if constructs that have long been available only to students and researchers actually hit popular programming.

 

I am excited about the possibilities of a Ruby like implementation under .Net. Python is already getting there with Jim Hugunin and his IronPython.

 

Here are the folk behind Groovy:

http://groovy.codehaus.org/team-list.html

 

If you enjoy programming in Ruby or in a language that supports lists, iterators, closures etc, you might enjoy Groovy. It is still under development, so there might be things that are missing. You will also have to get the JVM.

 

Thursday, April 22, 2004 3:09:35 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Wednesday, April 21, 2004

This is a Wish List for Ruby. Ruby is an excellent language, however here are some small things that I would like to see added to Ruby:

 

  • Threading
    I wish ruby had real threads. The threading support currently provided is really sad. If Rite could actually have OS threads as Ruby threads, like in the .Net framework it would be awesome, instead of doing them as interpreter threads. Write now doing any sort of meaningful multithreaded application in ruby is meaningless.

  • C/C++ style operators
    I wish ruby had ++, -- operators. They really do not contribute to unmanageable code and on the whole are nice things to have.
  • Use of Curly Braces { }
    I wish that Ruby would let the usage of curly braces to define blocks of code other than just parameter blocks that receive yield results. I would like to use {} to enclose methods, classes, if statements, loops etc.

    Write now code that is written like:

    def func(a)
       [1,2,3].each {|n|
          if(n % 2 == 0)
             print “This is even”
           else
             print “Odd”
             print “Multiple of 3” if (n%3==0)
           end
       }
    end


    being very C-ish in my ways I would really like it if I could avoid all those clumsy ends.

    def func(a) {
      [1,2,3].each {|n|
        if(n%2 == 0)
          print “This is even”
         else {
             print “Odd”
             print “Multiple of 3” if (n%3==0)
         }
      }
    }

     
    These days since the Python bug has bitten a bit, I am warming up to the idea of scope by indentation.

    def func(a)
      [1,2,3].each |n|
        if(n%2 == 0)
          print “This is even”
         else
             print “Odd”
             print “Multiple of 3” if (n%3==0)

    This actually looks quiet nice, but it may not be a good think to have because such code often tends to get messed up real bad when you copy paste it around and spoils the indentation.


  • Better Win32Ole libraries
    This is something that I must have. I use scripting to be able to talk to WMI (Windows Management Instrumentation).

    The libraries that Ruby ship for this is really sad. Very unstable. At the time of this writing the current Ruby distribution has removed the win32ole libraries from Ruby. I hope they will come back, stabler.

    The reason why Win32Ole is important to me is that it is the mechanism used to talk to WMI and WMI can let you some really awesome stuff.

    WMI Primer on MSDN

  • Auto Initialization of variables
    When I write code like this

    sum = 0
    10.times{|n| sum = sum + n }


    I wish I need not have to initialize ‘sum’. I wish there was some unambiguous way of saying that ‘I know sum hasn’t been defined before, so please use its initial value as ’. I would just like to be able to say 10.times {|n| sum = sum + n } and things should just work, assuming that sum gets initialized as 0. I wish there was some shorthand hand initializing a variable for its first appearance in an expression.

    Like I could probably replace:

    sum  = 0
    prod = 1
    10.times {|n| sum = sum + n; prod = prod * n }

    with

    10.times {|n| sum = sum<0> + n; prod = prod<1> + n; }

    or better if I had support for C++ style operators, I could write

    10.times{|n| sum<0> += n; prod<1> *= n; }


  •  Run on .Net
    I wish ruby could run on .Net. There are python variants that run on Java and now Python is coming up for .Net (
    IronPython). Imagine the power of having the flexibility of Ruby with the power and expanse of the .Net framework.

    Maybe more work needs to be done before this is possible.

  •  Currying of Methods and Partial Evaluations
    I wish I could have currying/partial evaluation possible for ruby methods.
    In many functional languages, functions are defined like this:

    - fn add x y = x + y
    > int -> int -> int

    Consider the ML like code above. The first line I have defines a function called ‘add’ that takes x and y and does x+y. The second line is what the interpreter echoes back to me about the function.

    It is simply is trying to say that the method consumes two integers and produces an integer. The two integers how ever are not used up at one go, rather, they are used up sequentially. First the integer x is taken and bound to the function and then the value y.

    By being able to do that, we can define other function instances of add that have one of the variables bound.

    - fn add10 = add 10
    - fn add5 = add 5
    - add10 2
    > 12
    - add5 2
    > 7

    This shows off some very powerful features of what currying can do. Here add10 and add5 are created as new functions, but with the value of x substituted as 10 and 5 respectively. Now we can treat add10 and add5 as proper functions that take only one parameter. 


    What these languages let us do is that we can apply a subset of the parameters of a function and created a curried or partially evaluated function instance. Such an instance can, if the runtime is optimizing enough, already do all the processes possible in the code upfront. Whenever the remaining parameters are supplied, it could just go on to complete the operations.  

Imagine that the method we were calling is this

fn mult x y = 10 * x * y

and then we wish to do


mult 10 2

mult 10 3

mult 10 4

 

These calls will now cause it to do 10 * 10 * 2, 10 * 10 * 3 and 10 * 10 * 4

However if we could partially evaluate a function we could say

 

fn mult10 = mult 10
mult10 2

mult10 3

mult10 4

 

When mult10 is created it is already evaluated to being “100 * y”. So, subsequent calls would cause it to do only 100 * 2, 100 * 3 and 100 * 4.

 

To add this sort of support to Ruby will have to bring large changes to the language. A simpler implementation would be to create a method object (yes that’s possible in Ruby) and also a hash of the partial list of parameters. The call itself could be formally executed only when all formal parameters are satisfied by the parameter hash table collection.

 

If you are still reading this might interest you:

http://www.svendtofte.com/code/curried_javascript/

 

Whew!

Well, that’s about it for now. But as you can see most of what I am asking for here are simple things and superficial changes. I would however really like to see the win32ole, threads and ++ operators in Ruby, even if none of the others work out.

 

Matz, (Yukihiro Matsumoto), the creator of Ruby is planning to introduce some significant changes to the language and more importantly going to get it running off a formal virtual machine that he is writing for Ruby called Rite.

Here are some of the plans for Rite and Ruby:

http://www.rubygarden.org/ruby?Rite

 

I found this on one of the websites, this is about how Matz wanted to work on Rite:

 

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/76588
|* will Rite be developed publicly.. Or will you keep it souce secret?

From my experience and observation, an open source software needs to

have running code before the ball rolling to success.  I think I need to work alone until the first running version.

 

|* still use Ruby license scheme?

It will be open source software for sure.  License terms may be

changed.

 

|* do you need help?  Say what we should do and we will do it :-)

This is very important.  Listen carefully.

 

From the reason I stated above, I feel like I will work alone.

But if someone shows his talent, and comes up with his own _good_

implementation of new Ruby earlier than me, and if he is willing to

contribute his code, and if he allows me to hack and chop his code to

make it "Rite", I will name it "Rite".  And he will be honored for ever.

Wednesday, April 21, 2004 4:21:08 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  | 
 Monday, April 19, 2004

Last night we did it again.

We went for this movie (50 First Dates) and came home feeling a little giddish. I was feeling a little giddish before the movie after nearly having my head ripped off sitting on a Torra Torra, in a fair in Bangalore.

 

So after the movie and the drive back home, what do we decide to do, like the nice normal people we are? We decide that we need to drink coffee at 12am and discuss programming. So we head off to Leela Palace where there is a late night Barista.

 

Something about the way coffee affects my head, when drunk late at night, especially after a movie needs some investigation. Sidharth was my comrade is arms, or rather comrade in coffee. So what do we do? we go there and sit down and drink coffee and I start off on SICP (Structure and Interpretation of Computer Programs) which I have been postponing for several years now.

 

I think part of why I was so adamant about starting out on SICP in the middle of the night is that I feel life (like usual) isn’t going anywhere. It turns out that a lot of smart people at various Universities decided that I was wasn’t smart enough to warrant a formal higher education in Computer Science and the place I want to be the most, doesn’t seem to want me around because of some technicality (for the fifth time). So since life wasn’t going anywhere, I figured I’d just have teach myself the things I want to know, my own way.

 

A little fast-forward in time and what finally ends up happening is that Sidharth and I end up talking about a certain MSDN article.

Implementing Coroutines for .NET by Wrapping the Unmanaged Fiber API

http://msdn.microsoft.com/msdnmag/issues/03/09/CoroutinesinNET/default.aspx

We ended up in a rather (heated) philosophic discussion about how iterators could be implemented, till 4am, which is what this blog entry is about.

 

If you have been reading about iterators in my previous blog entries

Iterators in Ruby (Part - 1)

Warming up to using Iterators (Part 2)

Then the idea is probably growing on you already. What Sidharth and I did is put in some thinking about how iterators could be implemented. This entry is going to break the logical flow of these two articles, but I am letting it be. I will probably have a part 3 post that will bridge the gap between Parts 1 and 2 and what I am going to say here about iterators.

Also, like a lot of things on this blog, I am not an authority on the subject so I am just guessing at how these things actually work.

 

 

Iterators

The thing about iterators is that there are two functions involved that have to maintain execution state at the same time. So example when a function calls another function, the caller is frozen and the callee executes – so the caller maintains execution state during the run time of the callee.

 

def callee

      yield 1

      yield 2

      yield 3

end

 

def caller

      callee { |n|

#parameter block to the iterator

puts n
}

end

 

When the callee is an iterator, the control actual leaves the callee and returns to the caller, when the execution is in the parameter block of the iterator. However we don’t see this sort of behavior in a normal C stack. Why? because when a function on the C stack returns to the caller, the function’s activation record on the stack is destroyed.

 

How do we do this?

The approach in the MSDN article uses an API called the fiber API.

 

Fiber Approach

The fibers can the thought of as threads that don’t have the scheduler attached to them.  So unless a fiber is explicitly passed control it will not be executed, unlike a thread which is invoked by scheduler for a time slice.

 

What Ajai Shankar (the author of the MSDN article) does is use fibers to represent iterators. So in the above snippet, the function callee() would actually execute on a different fiber from  caller. So when control needs to shift to the parameter block, which is to be executed in the caller() function, a fiber is a switch occurs.

 

When the parameter has finished execution a context switch occurs again.

 

What further happens is that the author has wrapped up all this dirty jumping around into a managed C++ class that invokes the OS api. He then goes onto write C# code (really!) that uses yield, almost the same way Ruby would use it.

 

(pasted)

class CorIter {

    public void Next() {

        object[] array = new object[] {1, 2, 3, 4};

        for(int ndx = 0; true; ++ndx)

            Yield(arr[ndx]);

    }

}

 

If you get the general idea, then lets move on.

 

The problems with using the fiber API, among other problems, are

·         Every fiber is like a thread, which means that the more the iterators the more the number of fiber specific stack frames and such that get created – which means  more the code bloat for code like this.

·         Using the fiber api actually makes this a very OS specific solution – other OSes that the CLR may wish to target may not have provisions for building up such an API.

·         Exceptions: exceptions in the windows world are strung to the TLS (Thread Local Storage) of the thread of execution – this may behave rather odd when fibers are mixed into the picture.

 

Let ignore everything and just examine the first problem, the issue of creating separate stack frames per fiber and thus bloating the system – if we could solve this one, then I think (and I might be wrong), would bring more credit to this approach.

 

Wrapping State in a Caller Object

One other approach to supporting iterators is to ensure that one of the two functions (the caller or the callee) maintain state using some mechanism other than the C stack.

 

Lets take a look at the caller:

 

def caller

      callee { |n|

            puts n

      }

end

 

or maybe a C# equivalent.

 

void caller()
{

      foreach(int n in callee())

      {

            Console.WriteLine(n);

      }

}

 

This method can actually be though off as consisting of three parts

 

void caller()
{

     

      foreach(int n in callee())

      {

           

            Console.WriteLine(n);

      }

     

}

 

We could create an object to hold the state of the function that would hold these three parts. Something like this:

 

class caller_object

{

      //declare all local variable so the class as member variables here

      void do_part1()

      {

}

 

void do_codeblock() //part 2

{
}

 

void do_part3()

{

}

}

 

The idea is that we create an object that has member variables that represent the local variable of the caller.  So we execute the caller as three parts

 

void caller()

{

      caller_object co = new caller_object()

      co.do_part1();

      callee(co);

      co.do_part3();

}

 

The caller method now is simply a wrapper around the class that represents the caller function as an object. When the method do_part1() is called on the class, the object will have the same state as the original caller() function when it has just run till the point where the iterator is invoked.

 

Then the callee() is invoked and the object that represents the caller’s state is passed to the callee. The callee then goes on to invoke the object’s do_codeblock() every time a yield is required.

 

Since the callee never returns till it has completed execution it maintains state on the runtime stack, like a normal function. The do_codeblock() has the same code that the code block of the for each loop had and it can also maintain any state changes into the object. Finally when the callee() exits the object’s do_part3() is invoked.

 

This is similar to what the iterators accomplish. Here the state is stored in an object and not on the stack. However, here a full managed type that represents that caller has to be created. I didn’t like that too much.

 

Wrapping State in a Callee Object

This is similar to the above approach, except that roles are reversed. We create an object that can represent the callee. The callee then returns to the caller at every yield statement.

 

The callee state is maintained in the object representing it. There is an excellent write up you can read about a similar approach here:

Coroutines in C

http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html

 

The idea there is that the state of the function is retained in a state variable. The state variable is used to jump back to the point where the function had previously yielded from. Code would look a little like this:

 

(pasted)

int function(void) {

    static int i, state = 0;

    switch (state) {

        case 0: /* start of function */

        for (i = 0; i < 10; i++) {

            state = 1; /* so we will come back to "case 1" */

            return i;

            case 1: /* resume control straight after the return */

        }

    }

}

 

Now this example uses static variables but it is easy to imagine this being extended such that each variable is the member of some object.

 

(pasted)

It's a little bit ugly, because suddenly you have to use ctx->i as a loop counter where you would previously just have used i; virtually all your serious variables become elements of the coroutine context structure. But it removes the problems with re-entrancy, and still hasn't impacted the structure of the routine.

 

(Kudos to Pooja, for coming up with this idea at one sitting).

 

 

 

When C# announced the coming of iterators in the language and a new yield keyword, I was excited. In the mood of the MSN co-routines article, I had expected a CLR level support for iterators.

 

It turns out that the C# teams approach is similar to that of the saving the callee state in an object. (I am not very sure about whether its the caller or the callee, in case I am wrong in assuming that it’s the callee, which seems to be the more logical choice, I will blog about it).

 

In the Co-routines in C article, the author talks of writing macros that wraps up the behavior.  Since the compiler does the temporary object creation and hides all the mess from you, in the case of C#, it seems like a reasonable alternative.

 

 

A modified form of the Fiber API idea

The reason I don’t really like the way C# does iterators right now is because it is a hack. They did not want to change the CLR for a feature that may not catch on. So I guess, they used a less expensive approach. If I am wrong, I would like to be corrected. I would expect that more serious CLR level support will come up for iterators if the idea’s introduced in Whidbey C# become popular.

 

The other reason I don’t really like the approach, the real reason, is that the .Net type system is a fairly comprehensive type system designed to propagate an idea of types as a level playing field for language agnostic components to interact. Introducing a type into the system just to retain a function’s state does not seem consistent with this philosophy.

 

Fiber API on the other hand more naturally lend themselves to the way I would choose to think of iterators – as functions that can be frozen during execution and be continued.

 

Now this might seem like a weak argument, but it seems to better to use the processors abilities to do a context switch to actually freeze execution of a block of code, that write the code as code that manages members of an object (only for the purpose that the object can be used to retain the state of the code).

 

The Fiber API like approach seemed to do this more naturally. I would expect that the CLR in future would internally provide some API similar to that of the OS provided fibers so that it can do iterators and closures and probably even continuations.

 

Some basic requirements would be that implementing such features don’t slow down execution of code that don’t require any of these features. Such features should be reasonably efficient with respect time as well as space.

 

Let me try and discuss the space issues here. In fiber API there would be need for creating totally new independent stack frames for each fiber. This is wasteful.

 

Would it be possible so that we have a modified API, which will behave like fibers, share stack space with the common C stack and can use the processor context switching abilities to freeze function execution, rather than save state as a managed object.

 

A little bit of brainstorming last night and we had this:

 

In the .Net world, we have the luxury of being able to predict the stack usage of a function under execution with IL directives like “.maxstack”. Which is to say - we know how much space the function will use on the managed stack.

 

The stack frame for regular method calls would look like this:

  

 

This is obvious for anyone who understands how methods are laid out on the stack. The only advantage that we have here is that in the .Net world. We know exactly how much stack space a given method will use.

 

Now if the method calls an iterators that has a yield, we create a Fiber, but a special sort that would use the main stack itself as its stack frame. So the newly created method instance (the iterator itself) will reside on the call stack, above the caller.

 

 

Now the usual semantics of stack usage are allowed on this fiber. The fiber behaves like any other thread would behave, owning the stack. To allow methods to keep track of their callee’s we add a reference to the activation record of the callee.

 

  

 

The interesting part, when the iterator needs to yield a value. When it does control is switched back to the original fiber. The activation record of the iterator is still maintained on the stack. Further method calls would however place their activation records above the iterator’s activation and behave as though it was normal C stack.

 

 

Thus I think it is possible to have fiber API like constructs to implement iterators, share stack space have reasonably efficient implementations too. The only real over head introduced here is a level of indirection when activation records are torn down from the stack frame.

 

I feel that this is a more co-routine like approach that the one that involves creating hidden managed objects.

 

I would like to wish that this idea can be extended to implement proper continuations also, that is not very easy. Here the stack management is very easy because as any point a sleeping fiber will contain only one activation record on the stack. A continuation will require that activation objects live and die on the manage stack as though they were proper objects and some sort of garbage collection routine will be required on the stack.

 

I am extremely open to opinions about this entry, because I am treading on many areas that I am not very well versed with. I am hoping that the idea of freezing execution state via fiber like constructs is more efficient that the approach that involves creating full managed objects.

 

Monday, April 19, 2004 7:48:40 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 
 Friday, April 16, 2004

In the past article Iterators in Ruby (Part - 1) I talked about the concept of iterators and how iterators are available in Ruby. In this part I will dwell on how iterators are used, so that the concept grows on you.

 

For someone used to the C/C++ world, the constructs provided by those languages suffice to express any idea of their choosing. While that is true, programming in a C-like language causes us to close our minds to other styles of programming and other constructs that might exist. Programming in C after a point is about writing the next big program optimized with lots of data-structure usage and trying to tie a new algorithm down into C. Sometimes the joy of programming, where the language lets you do your job - express ideas as code, is lost. Sometimes we spend our time servicing our language syntax and spoon-feeding our compilers. The fact that languages might actually evolve so that you can get on with your job, was alien for a long time to me.

 

If you have read the first part you might be wondering how iterators are used in Ruby. Admittedly, the idea would seem a little complex and maybe contrived to the uninitiated.

 

In Ruby, iterators are used pervasively. Its there all over the place and once you get started on Ruby, you will probably end up using an iterator without realizing that you are using one. The Ruby libraries are rich with iterators of various sorts.

 

Simple Loops

When you start of on Ruby code, you might see loops of the sort:

 

10.times {

      print “hello world”

}

 

This, as you might expect, prints ‘hello world’ 10 times.

 

How does this work? Ruby is a pure object oriented language. The number 10 is an integer, and the integer class exposes a method called ‘times’. The times method is an iterators that yields values from 0 to its value -1.

 

Since it yields values, can we catch them ? Yes.

 

10.times {|n|

      print n

}

 

And this prints all the values from 0 to n-1.
'times' is an iterator.

 

File Handling

Let’s look at some file handling in Ruby. The following code will open a file and read each line of the file and print the line among with its line number.

 

file = File.new(“filename.txt”)

c = 0
file.each_line {|line|

      c = c + 1

      print “#{c}: #{line}”

}

 

The code is simple. I open a file and create a file object. I ask the object to yield each line to me. As I get each line I print it out along with the line number. This is as logically expressive as I have seen in any language that I have used. All the mess stays out of your way and you get to focus on the job at hand.

 

The each_line is a method of the File class and it yields each line in the file. The variable ‘line’ will hold the value of each line. Slick?

 

(I you are wondering what “#{c}: #{line}” means – in a string #{ } is a substitution. You can write any expression into the curly braces. Here the values of c and line get substituted into the string)

 

Arrays / Collections

Similarly collection types expose an “each” method which yields every member of the collection. So if I had to iterate over an array I would write:

 

array = [1,2,3,4]

array.each {|m| puts m }

 

The above code creates an array of 4 elements and accesses each element using the iterator “each”.

 

In similar fashion, a lot of the Ruby library exposes functionality as iterators. So much so, that I rarely write for loops in Ruby.

 

Recursive Directory Enumeration

Now let us try and write code of our own. Something you may all have written is code that will find all the text files in a folder and is sub folders. The usual approach is to write a recursive function.

 

The function will try and remember a list of text files, in the current directory and the list of sub directories it has. It will then recursively call each of the subdirectories, each of which will do the same task. The problem is that if every time a text file is to be found, some processing is to be done, things get very complicated. The usual approach is to find all the text files and create a big list of filenames, which is then processed later.

 

Here is an approach with iterators. Try and implement this in your favorite language that does not have iterators and see how it looks.

 

def textfiles(dir)

        Dir.chdir(dir)

        Dir["*"].each do |entry|

                yield dir+"\\"+entry if /^.*\.txt$/ =~ entry

                if FileTest.directory?(entry)

                        textfiles(entry){|file| yield dir+"\\"+file}

                end

        end

        Dir.chdir("..")

end

 

textfiles(“c:\\”){|file|

        puts file

}

 

What the above code does is simple. I have defined a method called textfiles() that takes a directory name as a parameter.

 

The code looks exactly like you would explain it algorithmically.

  1. Go to the folder (chdir)
  2. Take a look at the contents (Dir[“*”])
  3. See is an entry is a text file, if so yield it (yield dir+"\\"+entry if /^.*\.txt$/ =~ entry)
  4. See is an entry is a directory, if so, recurse into it
    (
    if FileTest.directory?(entry)
       textfiles(entry){|file| yield dir+"\\"+file}
    end)

 

Simple?  Notice that the beauty of code is that the yield actually sends the value of a filename down a recursive hierarchy.

 

As a disclaimer, if you are using Ruby, then you might a well finish off in one line by saying:


Dir[“**/*.txt”].each{|file| puts file }

 

 

Friday, April 16, 2004 3:28:18 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1]  | 
 Thursday, April 15, 2004

I finally got copies of my first article published about the DDL. The article was published in the .Net Developer Journal.
http://www.sys-con.com/dotnet/

 

The DDL was a language that my team developed during our final year college project. At that time, we believed that it was a one of a kind language. Of late we have come across similar work done by Professor Godmar Back of Stanford University.

 

The DDL language basically lets one specify binary data formats and the language interpreter provides services to interact with data of that format. Read more about the DDL at the project homepage:

http://ddl.sscli.net/

 

Professor Godmar Back’s DataScript language is described here:

http://datascript.sourceforge.net/

Apr 14 2004 Wednesday 01-24PM

Thursday, April 15, 2004 1:35:38 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0]  | 

One of the things that’s rather high on my mind’s sort order these days is Ruby programming. I have been thinking about what makes ruby so neat a language to use, simply by virtue of what the language lets me do.

 

One of the early things that got me hooked to Ruby, was its support for iterators. If you have been spoiled by many years of C programming, like me, then its time to wake up and take a look at a few things that C can’t pull off, at least not very easily.

 

What is an iterator?

Let’s take a look at code like this, where there is a piece of code that produces value and a piece of code that consumes values.

 

void produce()
{

for (int i=0;i<100;i++)
            if( i%5 == 0)
                  consumer(i);

}

 

void consumer(int v)
{

printf(“%d”,v);
}

 

All things considered this code is fine, except that the producer invokes the consumer. And simply because of that the consumer cannot maintain state. The only way the consumer can maintain state, ie remember something between two calls is to save variables into either static variables, or globals or into some object.

 

The would be the argument if the consumer function tried invoking the producer, where the producer will have to have a very contrived piece of code to remember variable values between calls.

 

From a perspective, an iterator solves exactly this problem. This is a ruby code:

 

def producer

      for i in 0..99

            if (i%5 == 0)

                  yield i

            end  

      end

end

 

def consumer

      producer() do |v|

            print v

      end

end

 

The ‘def’ keyword starts a function/method declaration. The code above for the producer should be rather easy to understand, except for the yield statement.

 

What does the yield do? The yield causes the function producer() to exit with the return value of the function as the parameter of the yield, in this case ‘i’.

 

The difference between yielding a value and actually doing a return is that the function can continue execution from the point of the yield statement.

 

The consumer function then simply invokes the producer() function and catches each of the yielded values. That is why these is a ‘do’ statement and a corresponding ‘end’ statement in the consumer code. The parameter for the do-end block is the ‘v’ that is enclosed in ||. Every time the producer yields a value, the value is available in ‘v’ and the do-end block is executed. When the block finishes the producer continues after the point of the yield.

 

So if you want to, say calculate the sum of all the values that the producer yields, then you can

 

def consumer

      sum = 0

      producer() do |v|

            sum = sum + v

      end

      print sum

end

 

 

Now that you have been introduced to the idea of iterators, I suggest you do some thinking about, especially if you have done a fair bit of C programming. Imagine how these functions would have to maintain state, what their call stacks will look like and such.

 

Now let me clean up on a few things. In ruby all functions are called methods, formally. So let’s start calling them methods. Secondly a lot of the Ruby libraries are built to support iterators so you will see the idea being used a lot. Thirdly, the do-end block can also be written as { } curly braces.

 

The methods that I have written have been written in a drawn out C-like style, so that the ideas are clear despite the slight difference in syntax. So lets just rewrite the two methods slightly more ruby-ishly and close this blog entry.

 

def producer

      100.times{|i| yield i if i%5 == 0}

end

 

def consumer

      sum = 0

      producer {|v| sum = sum + v}

      print sum

end

 

You can get Ruby from here, for your windows box:

http://rubyinstaller.sourceforge.net

Apr 13 2004 Tuesday 11-05AM

Thursday, April 15, 2004 1:31:50 AM (Eastern Standard Time, UTC-05:00)  #    Comments [3]  |