## Programming Shorthands

We propose programming language mechanisms to reduce redundancy in program source code. These abbreviation mechanisms, shorthands, make programs shorter and easier to write and read. In addition, we provide a framework for describing language abbreviation mechanisms.

### Right, but we don't outlaw

Right, but we don't outlaw pronouns, or even discourage their use in formal writing.
Anything can be abused.

### Call for backup?

So what are the tools that help bail somebody out who has been thrown overboard by somebody else's refactoring?

(I think saying "just because it can be abused doesn't mean we shouldn't have it" is sorta irresponsible. You have to figure out just how abusable it is and what the consequences of the abuse would be. Then if you are ethical I think you have to figure out how to shore-up against those situations.)

### plug

“I can't recall seeing any other papers on this topic, so pointers are welcome.”
Taking the occasion to plug myself here, almost 10 years back I wrote an article on a very similar topic.

### anaphora

I haven't had time to read the article, but this makes me think of anaphora, a context-sensitive reference to another expression (caveat: IANA linguist). One example of anaphora in programming languages is anaphoric if, which implicitly (unhygienically) binds the name it to the result of the test expression so it can be referred to within the consequent:

(aif (foobar) (+ it 42) (error 'nothing))

Ken Shan's dissertation draws another interesting relationship between anaphora and programming languages.

### Smalltalk

In Smalltalk you can do some of these things using cascades which is very useful:

foo diffusionArray
at: i put: xi;
at: j put: xj;
at: k put: xk

planet1 spatialDist point x
velocity: v1;
mass: m1;
accel: a1


### Maybe your PL is just too "static"!

Redundancy in source code is often a sign that something in our language isn't first-class when it might be. In this case, we might:

• make aspects of syntax first-class (macrology and metaprogramming), and
• make aspects of program structure first-class (reflection).

This choice, made seriously, leads to the kind of metaprogramming that makes Ruby (and Python, to a lesser degree) so popular. The authors argue against ugly macrology, but to my eyes, there's nothing terribly ugly about:

path = 'spatial_dist.pt.x'
eval <<-"end;"
planet1.#{path}.velocity = v1
planet2.#{path}.velocity = v2
planet1.#{path}.mass = m1
planet2.#{path}.mass = m2
end;


(Well, at least it's not visually ugly...) The ability to do this kind of thing is really the much more important notion of "dynamic" that fans of these languages get excited about. Of course it's not totally unrelated to dynamic typing, but we know by now that constructs like this are useful, and we know it's worth fighting to analyze them when possible.

### Not visually ugly?

There actually is a visually ugly part of that: editor support. How is your text editor supposed to know that the contents of that big string are code? When you're editing that code, you don't have the advantage of automatic indentation or syntax highlighting beyond "make it all string-colored". Now, it wouldn't be too hard to work around that for the specific "eval <<-..." case, but in general it would be nice if the language provided an idiomatic and well-supported way of writing code at runtime to evaluate. Example (in no particular programming language):

path = 'spatial_dist.pt.x'
planet1.#{path}.velocity = v1
planet2.#{path}.velocity = v2
planet1.#{path}.mass = m1
planet2.#{path}.mass = m2


Or, fancier (and more contrived):

def return_setter_code(planet, v, m):
return runtime:
path = 'spatial_dist.pt.x'
planet.#{path}.velocity = ##{v}
planet.#{path}.mass = ##{m}
end
end

eval return_setter_code(planet1, m1, v1)
eval return_setter_code(planet2, m2, v2)


This introduces new syntax: there's the "runtime: ... end" block which is shorthand for making a string with source code in it and which can contain #{expr} to insert the evaluation of expr in the enclosing scope and ##{expr} for another level of enclosing scope, and so on. There's also the ability to use the #{expr} syntax without an enclosing "runtime: ... end" block, which just adds an implicit runtime block (and an eval, if it's being used outside a runtime block).

This is suspiciously similar to Lisp's macro facilities, with the (backtick ,and ,,@quasiquote) stuff. In fact, I think it's almost exactly the same; eventually this proposed metaprogramming scheme would need gensym() and once_only() and all the other fun, fun aspects of Lispy metaprogramming.

I would use it.

### yes, but... dependent syntax?

This is suspiciously similar to Lisp's macro facilities, with the (backtick ,and ,,@quasiquote) stuff. In fact, I think it's almost exactly the same; eventually this proposed metaprogramming scheme would need gensym() and once_only() and all the other fun, fun aspects of Lispy metaprogramming.

This is more or less the approach taken by MetaML and MacroML, and by Dylan's macros (if I understand them correctly). One difficulty of this approach as opposed to a pure string-based approach is that it's often difficult to produce certain program fragments whose intermediate forms don't consist of well-formed syntax. For example, in our running example, it's not clear what "spatial_dist.pt.x" is, as context-less syntax. As a string, it could even be reasonably spliced into multiple different syntactic contexts (as part of a string constant, as an object traversal expression, the final "x" might be the beginning of a longer identifier, etc). This is very powerful, but of course since it's so undisciplined it's very hard to say anything about it statically.

By analogy with types, I suggest that we might call this kind of macrology "dependent syntax", in which even syntactic well-formedness of a program depends on the semantics of the program. I suspect it may be possible to say a lot more about dependently parsed programs than has been said so far... (And, witness the perennial popularity of string-based metaprogramming, I suspect it would be worth saying.)

### Metaprogramming in Q

Another way to go about this are user-defined special forms as Q (a dynamically typed functional programming language based on term rewriting) provides them. This kills two birds with one stone: It gives you both lazy data structures and dynamic (runtime) macros. The latter makes for a fairly powerful metaprogramming facility. E.g., in Q the lambda construct is just another special form (which could actually be defined by the programmer, but is provided as a builtin for efficiency), and you can define list comprehensions on top of this with the following little Q snippet (in fact I copied that definition straight from Q's standard library):

listof A Cs		= (listofx A Cs);

listofx A ()		= '[A];
listofx A (X in Xs|Cs)	= '(cat (map (\X.(listofx A Cs)) Xs))
if isvar X; // will always match
= '(cat (map (\X.(listofx A Cs))
(filter (matchp X) Xs)));
listofx A (X in Xs)	= '(cat (map (\X.[A]) Xs)) if isvar X;
= '(cat (map (\X.[A]) (filter (matchp X) Xs)));
listofx A (P|Cs)	= '(ifelse P (listofx A Cs) []);
listofx A P		= '(ifelse P [A] []);


The listofx function constructs the actual "code" (an expression of nested lambdas, cat, map, filter and if-then-else applications) which is returned as a quoted expression and then implicitly evaluated when it gets unquoted with the backquote operator (first line, definition of listof`). The backquote operator can also be used to evaluate and splice a subexpression into a quoted expression (as can be seen in the 3rd and 4th equation).

Expressions are first class citizens in Q which you can manipulate to your heart's content before actually evaluating them. That makes Q's special forms much more powerful than, say, good ol' Algol's call by name or Alice's lazy futures. They are like Lisp macros, only fully dynamic.