loading...

Anaphoric macros - writing concise code

adasomg profile image Adaś ・2 min read

Today I released an early version of my clojure anaphoric macro library. To celebrate we'll discuss what anaphoric macros are, why they're interesting, why some dislike them, and their future. Don't worry there will be no clojure or lisp code. We'll use javascript to discuss.

The term "Anaphoric macro" first appeared in Paul Graham's On Lisp, a reference to the concept of anaphoras in linguistics.

We use anaphoras in everyday speech all the time. Whenever we use a word implicitly refering to something we said previously based on context, that is an anaphora. The word "that" in the previous sentence is an anaphora.

Unfortunately in programming languages we usually have to explicitly assign something to a variable before we can refer to it.

Consider this simple javascript function:

function hasNumberGreaterThan5 (arr) {
  let numGt5 = arr.find(x=>x>5);
  if(numGt5) {
    console.log("The array contains a number greater than 5: ", numGt5);
    return true;
  } else {
    console.log("The array contains no number greater than 5")
    return false;
  }  
}

Do you like the variable name numGt5? What's a better name? If javascript had an anaphoric macro for if - aif we could write this:

function hasNumberGreaterThan5 (arr) {
  aif(arr.find(x=>x>5)) {
    console.log("The array contains a number greater than 5: ", that);
    return true;
  } else {
    console.log("The array contains no number greater than 5")
    return false;
  }  
}

Isn't that much cleaner? We entirely bypassed the problem of coming up with a variable name and saved some space. that simply refers to that expression in the if statement. Sadly js doesn't have macros, but I'm sure you could write a babel plugin if you really want them.

In lisps writing a macro is as simple as writing a function. Hence you can introduce such language features without resorting to transpilers like babel.

However even in the lisp world they're somewhat controversial. One of the main problems is nesting. What if you have two aif statements? In human languages we can have two thats referring to different things and people will figure this out. But a compiler or interpreter won't. This is one of the issues that my library solves. It introduces a simple convention where you can say tthat to refer to the previous that and so forth.

They are still likely to remain controversial but I hope my contributions make them more practical.

If you want to go deeper and see actual examples or try them out check it out on github:

GitHub logo adasomg / ana

Clojure[Script] productivity macros like you've never seen before

adas.ana - Clojure[Script] productivity macros like you've never seen before

Clojars

adas.ana is a collection of general purpose macros with a focus on writing succint code They are divided into 2 broad categories "anaphoric", and "quick".

While the anaphoras are inspired by the traditional lisp kind, popularized by Paul Graham's "On Lisp", they go much further Most importantly the problem of nesting is solved by "letter doubling" and using context appropriate symbols instead of following the it tradition as you'll see in examples.

The "quick" macros are simply other general purpose macros which aren't anaphoric.

All the macros expand to code very similar (or identitcal) to that which you'd write by hand This ensures you can use them without guilt or hesitation.

The library is VERY MUCH WORK IN PROGRESS, things will break and change. Note that as of right now the symbols are replaced by

Discussion

markdown guide