matthew arcus

valof

Advertisements

I’ve never written much BCPL, but it always seemed like a nice language. Many features ended up in C of course, but one that didn’t was VALOF, allowing the inclusion of a statement block in an expression, and using RESULTIS to return a value. Using slightly invented syntax:


LET B = VALOF $(
        FOR I = 1 TO J DO $(
                IF I*I = J THEN RESULTIS 1
        $)
        RESULTIS 0
$)

GCC defines the block-expression extension, allowing us to write:


int main(int argc, char *argv[])
{
  int j = atoi(argv[1]);
  printf("%d\n";,
         ({
           bool found = false;
           for (int i = 1; i < j; i++) {
             if (i*i == j) {
               found = true;
               goto end;
             }
           }
         end:
           found;
         }));
}

but having to use the last expression in the block as the return value can get a bit convoluted.

With C++11, we can do better with immediately applied lambda expressions, with return taking the role of RESULTIS:


int main(int argc, char *argv[])
{
  int j = atoi(argv[1]);
  printf("%d\n";,
         [=](){
           for (int i = 1; i < j; i++) {
             if (i*i == j) return true;
           }
           return false;
         }());
}

If we don’t like the smiley syntax, we can even define a VALOF macro:


#define VALOF(e) [=](){e}()
int main(int argc, char *argv[])
{
  int j = atoi(argv[1]);
  printf("%d\n";,
         VALOF(
             for (int i = 1; i < j; i++) {
               if (i*i == j) return true;
             }
             return false;
           ));
}

though we’ll have to be a little bit careful with commas not enclosed in parentheses (and we might end up needing different macros for different variable capture methods).

Curiously, this idiom seems to be popular in Javascript.

Advertisements

Advertisements