Loop Abstractions in D

One of the great things with Ruby is the natural way in which you can hide looping constructs behind descriptive names. Like the retryable example that Cheah Chu Yeow gives on his blog.

retryable(:tries => 5, :on => OpenURI::HTTPError) do
  open('http://example.com/flaky_api')
end

Notice how elegantly the loop logic is abstracted; There’s no need to look at the implementation of retryable to figure out what it does. The question is, can we do something similar with D as well? It turns out that with features like delegates and function literals we can actually get pretty close.

bool retryable(int tries, void delegate() dg)
{
  for(int i = tries; i > 0; i--)
  {
    try
    {
      dg();
      return true;
    }
    catch
    {
      // Retry
    }
  }
  return false;
}

Which can be used like this:

retryable(5, {
  open("http://example.com/flaky_api");
}) ;

Not as nice as with Ruby, but almost.

The custom exception of the Ruby version is a tricky one to implement in D. Templates to our rescue.

bool retryable(E)(int tries, void delegate() dg)
{
  for(int i = tries; i > 0; i--)
  {
    try
    {
      dg();
      return true;
    }
    catch (E)
    {
      // Retry
    }
  }
  return false;
}

With the (little bit odd) template syntax, we can then make retryable retry only when, for example, StdioExceptions are thrown.

retryable!(StdioException)(5, {
  open("http://example.com/flaky_api");
}) ;

To clean it up a bit, we can add some defaults (which requires us to switch places between the parameters).

bool retryable(E = Exception)(void delegate() dg, int tries = 5)
{
  for(int i = tries; i > 0; i--)
  {
    try
    {
      dg();
      return true;
    }
    catch (E)
    {
      // Retry
    }
  }
  return false;
}

That gives us a little more freedom when utilizing retryable.

retryable({
  // Retry up to 5 times
});

retryable({
  // Retry up to 10 times
}, 10);

retryable!(StdioException)({
  // Retry up to three times
  // on StdioException failures
}, 3);

I totally agree with Cheah Chu that Ruby is nice, but I think D is pretty cool too.

Cheers!

 If you liked this post, concider subscribing to my weblog

Related posts:

RSS feed | Trackback URI

11 Comments »

Comment by Michael Silver Subscribed to comments via email
2008-01-18 03:39:04

As usual, an interesting article.

As someone who is just learning D, your posts are very enlightening.

I wouldn’t mind D allowing a more similar syntax to Ruby’s blocks, but so far I am very impressed with D.

It reminds me of a mix of Delphi, C#, C and I suppose C++.

…Michael…

Comment by Hans-Eric
2008-01-18 15:43:20

Thanks Michael!

It reminds me of a mix of Delphi, C#, C and I suppose C++.

Right on, and if I read the Internet vibes correctly we’ll soon see features in D that better support the functional programming paradigm. That’ll be interesting.

 
 
Comment by David Wilson Subscribed to comments via email
2008-01-22 09:35:09

A for() loop would have been clearer; the marginal gains saved in keystrokes are lost in future readability (everyone reading that code from thereon in now has another badly named template to go grepping for).

Comment by Hans-Eric
2008-01-24 22:09:24

I agree to some extent, but I do like the possibility to give complex loop logic descriptive names.

In Ruby it feels more natural though. I mean, one has to love code like this:


10.times do
# code goes here
end

A for loop can never communicate intention better than that.

 
 
2008-01-23 06:55:49

[...] Grönlund has a blog post up detailing how to abstract D’s loops in a Rubyesque fashion. Elsewhere, Unknown Brackets has posted an overview D from a user [...]

 
Comment by Dominik Susmel Subscribed to comments via email
2008-01-23 09:58:52

Excellent!
Btw, you have an error in the cleanedup version, should be i– instead of i-

 
Comment by Dominik Susmel Subscribed to comments via email
2008-01-23 09:59:44

hm can’t seem to add two minuses in a row with comment system, but you know what I mean iminusminus

 
Comment by Hans-Eric
2008-01-23 11:19:03

@Dominik

Ah, you’re right. Thanks for pointing it out. It’s Wordpress that doesn’t handle code formatting very well. I fixed the problem temporarily (by switching minuses for -

 
Comment by Hans-Eric
2008-01-23 11:24:46

@Dominik - again

Argh! The entity code translated into a -, but you know what I meant. I really need to find a solution to this…

 
2008-01-31 15:31:28

[...] my previous post on Loop Abstractions in D I showed you how we could make loop constructs abstract, in a similar way which is common in Ruby. [...]

 
2008-02-13 15:24:29

[...] could we do this in D? Well, as I’ve written before, D’s delegates in combination with function literals can be used to mimic the code blocks of [...]

 
Name (required)
E-mail (required - never shown publicly)
URI
Subscribe to comments via email
Your Comment (smaller size | larger size)
You may use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> in your comment.