M4 Macros

January 30, 2015

I decided to write a macro to factor integers. I first wrote this Scheme code, as a model for what I wanted to do; the algorithm is simple trial division:

> (define (fact n d)
    (if (< n (* d d))
        (list n)
        (if (zero? (modulo n d))
            (cons d (fact (/ n d) d))
            (fact n (+ d 1)))))
> (define (factors n) (fact n 2))
> (factors 32)
(2 2 2 2 2)
> (factors 35)
(5 7)
> (factors 87463)
(149 587)
> (factors 13290059)
(3119 4261)

Then I rewrote in m4; the only hard part was getting the quoting right:

$ m4
define(fact,
  `ifelse(eval($1 < $2 * $2), 1, $1,
    `ifelse(eval($1 % $2 == 0), 1,
      $2 fact(eval($1 / $2), $2),
      fact($1, incr($2)))')')dnl
define(factors, `fact($1, 2)')dnl
factors(32)
2 2 2 2 2
factors(35)
5 7
factors(87463)
149 587
factors(13290059)
3119 4261

That’s not exactly transparent, though I suppose if you write enough m4 code you’ll get accustomed to it. Most uses of m4 are simple substitution, for which it is highly suitable.

You can run the Scheme code at http://programmingpraxis.codepad.org/hAf1OFnz; no m4 processor is available.

Pages: 1 2

One Response to “M4 Macros”

  1. matthew said

    And a paper from computational dreamtime (well, 1965 anyway), describing Strachey’s GPM, the original ancestor of m4:

    Click to access 225.full.pdf

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: