Home > D Programming Language, programming, ruby > Loop Abstractions in D

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!

  1. January 18th, 2008 at 03:39 | #1

    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…

    • January 18th, 2008 at 15:43 | #2

      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.

  2. January 22nd, 2008 at 09:35 | #3

    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).

    • January 24th, 2008 at 22:09 | #4

      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.

  3. January 23rd, 2008 at 09:58 | #5

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

  4. January 23rd, 2008 at 09:59 | #6

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

  5. January 23rd, 2008 at 11:19 | #7

    @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 -

  6. January 23rd, 2008 at 11:24 | #8

    @Dominik – again

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

  1. January 23rd, 2008 at 06:55 | #1
  2. January 31st, 2008 at 15:31 | #2
  3. February 13th, 2008 at 15:24 | #3