Macros

Boilerplate Busting in Functional Languages

6 May 2024

This is the story of how I solved a problem (ugly, cumbersome boilerplate code) that I ran into while writing a program in a functional language (Elixir). Functional programming languages often pride themselves on expressiveness and elegance; but occasionally they are not amenable to the most obvious solutions to the problems we wish to solve. In this case, the simplest solution to my problem would have been to have a global mutable variable. But no one likes those.

...

Towards Fearless Macros

13 Nov 2023

Macros are tricky beasts. Most languages—if they have macros at all—usually include a huge “here there be dragons” warning to warn curious would-be macro programmers of the dangers that lurk ahead.

What is it about macros that makes them so dangerous and unwieldy? That’s difficult to answer in general: there are many different macro systems with varying degrees of ease-of-use. Moreover, making macros easy to use safely is an open area of research—most languages that have macros don’t have features necessary to implement macros safely. Hence, most people steer clear of macros.

...

Implementing Type Systems as Macros

14 Aug 2023

There’s a neat paper Type Systems as Macros by Chang, Knauth, and Greenman [1] that describes how to implement a typed language using an untyped host language and macro expansion. The paper is neat, but I found the code hard to follow—the paper uses a compact notation that’s convenient for print, but not so much for reproducing on one’s own. This post is my attempt to implement and explain in more accessible terms what’s presented in the paper.

...

Writing Racket Macros: define-syntax and phases

19 May 2023

There are a bunch of different ways of writing a macro in Racket. There are also some tricky things around phases to keep in mind. This is to help me keep them all straight.

3+1 ways to make a macro #

This form:

(define-syntax-rule (foo args ...) (use args ...))

is equivalent to:

(define-syntax foo
  (syntax-rules ()
    ([foo args ...] (use args ...))))

Which, is in turn equivalent to:

(define-syntax foo
  (λ (stx)
    (syntax-case stx ()
      [(gensymed-foo args ...) #'(use args ...)])))  ; gensymed-foo is like foo but doesn't match in the template

because syntax-rules expands to syntax-case with some fancy wrapping around it.

...

Mastodon