Anonymous methods and Clipper

One of the new features of C# in the upcoming Whidbey release are anonymous methods. What they are and how they work is clearly explained in the gotdotnet page Vijay pointed to in his blog. And Don Box uses them reguarly in his blog. Take this snippet taken from the page pointed at :

public MyForm()
{
      listBox = new ListBox(…);
      textBox = new TextBox(…);
      button = new Button(…);
     
button.Click += new EventHandler(sender, e)
      {
      listBox.Items.Add(textBox.Text);
      };
  
}
}

A new eventhandler is created, the implementation of this eventhandler immediately follows this creation. I am not among the happy few who already have a copy of Whidbey running, but I think you can code like this as well :

public MyForm()
{
      listBox = new ListBox(…);
      textBox = new TextBox(…);
      button = new Button(…);

      otherButton = new Button(…);
      EventHandler myAnonymousHandler =
new EventHandler(sender, e)
      {
      listBox.Items.Add(textBox.Text);
      };
      button.Click += myAnonymousHandler;
      otherButton.Click += myAnonymousHandler;
  
}
}

I think that’s pretty cool. When describing anonymous methods they are compared to lambda functions found in Lisp and Eiffel. But I have seen something very similar years ago in Clipper, a very more down to earth language.

Clipper started as a compiler for dBase III applications. Quite some interesting things were added to the dBase language, making it, at the time, quite a nice tool to build applications for DOS. In Clipper 5 you had code blocks which were, according to the documentation, unnamed assignable functions. This is a snippet of Clipper code with a code block

MyCodeblock:= { | a, b| c:= a+b, c}

Function UsingBlock(theBlock, param1, param2)
  @1,1 SAY EVAL(theBlock, param1, param2)
Return .T.

On the screen will appear the sum of the parameters passed. So a codeblock is a piece of code which can be passed around, just like the EventHandler in C#. Only the Eval function (and two derived ones) could execute it. You could even compile a code block at runtime, like

MyCodeBlock:= &ThisStringContainsCode

That can be done in C# as well but thank goodness, it is a little more organized there.

I don’t want to compare C# and Clipper. Actually Clipper is a crude language, all variables are variants and OOP was still being re-invented at the time. Database support is a disaster compared to today’s SQL based tools. And a Clipper app behaves horrific in a Windows (NT) environment. For instance, one running Clipper app can literally cripple a terminal server.

But I considered it worth mentioning. Stay tuned.

This entry was posted in Uncategorized. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Slobodan Filipovic

    (See link Blocks and Iterators)

    You have same staff in Ruby:

    "Blocks and Iterators

    This section briefly describes one of Ruby’s particular strengths. We’re about to look at code blocks: chunks of code that you can associate with method invocations, almost as if they were parameters. This is an incredibly powerful feature. You can use code blocks to implement callbacks (but they’re simpler than Java’s anonymous inner classes), to pass around chunks of code (but they’re more flexible than C’s function pointers), and to implement iterators.

    Code blocks are just chunks of code between braces or do…end.

    { puts "Hello" } # this is a block

    do #

    club.enroll(person) # and so is this

    person.socialize #

    end #

    Once you’ve created a block, you can associate it with a call to a method. That method can then invoke the block one or more times using the Ruby yield statement. The following example shows this in action. We define a method that calls yield twice. We then call it, putting a block on the same line, after the call (and after any arguments to the method).[Some people like to think of the association of a block with a method as a kind of parameter passing. This works on one level, but it isn’t really the whole story. You might be better off thinking of the block and the method as coroutines, which transfer control back and forth between themselves.]

    def callBlock

    yield

    yield

    end

    callBlock { puts "In the block" }

    produces: In the block

    In the block

    See how the code in the block (puts "In the block") is executed twice, once for each call to yield.

    You can provide parameters to the call to yield: these will be passed to the block. Within the block, you list the names of the arguments to receive these parameters between vertical bars (“|”).

    def callBlock

    yield ,

    end

    callBlock { |, | … }

    Code blocks are used throughout the Ruby library to implement iterators: methods that return successive elements from some kind of collection, such as an array.

    a = %w( ant bee cat dog elk ) # create an array

    a.each { |animal| puts animal } # iterate over the contents

    produces: ant

    bee

    cat

    dog

    elk

    Let’s look at how we might implement the Array class’s each iterator that we used in the previous example. The each iterator loops through every element in the array, calling yield for each one. In pseudo code, this might look like:

    # within class Array…

    def each

    for each element

    yield(element)

    end

    end

    You could then iterate over an array’s elements by calling its each method and supplying a block. This block would be called for each element in turn.

    [ ‘cat’, ‘dog’, ‘horse’ ].each do |animal|

    print animal, " — "

    end

    produces: cat — dog — horse —

    Similarly, many looping constructs that are built into languages such as C and Java are simply method calls in Ruby, with the methods invoking the associated block zero or more times.

    5.times { print "*" }

    3.upto(6) {|i| print i }

    (‘a’..’e’).each {|char| print char }

    produces: *****3456abcde

    Here we ask the number 5 to call a block five times, then ask the number 3 to call a block, passing in successive values until it reaches 6. Finally, the range of characters from “a” to “e” invokes a block using the method each. "