Macros in Scheme

Andy Balaam

Contents

The problem




(define num 3)

(cond
    ((zero? num)     (display "Z"))
    ((positive? num) (display "P"))
    (else            (display "N")))

Hiding complexity

Hiding complexity (2)

Hiding complexity (3)

First attempt

(define (3-state
        value
        positive-body
        zero-body
        negative-body)
    (cond
        ((zero? value)     zero-body)
        ((positive? value) positive-body)
        (else              negative-body)))

> (3-state
    100 (display "P") (display "Z") (display "N"))
PZN

A solution


(define-syntax
    3-state
    (syntax-rules ()
        ((3-state
            value positive-body zero-body negative-body)
        (cond
            ((zero? value)     zero-body)
            ((positive? value) positive-body)
            (else              negative-body)))))

A solution (2)

> (3-state
    100 (display "P") (display "Z") (display "N"))
P
> (3-state
    0 (display "P") (display "Z") (display "N"))
Z
> (3-state
    -100 (display "P") (display "Z") (display "N"))
N

How else could we do this?

/* MACROS */

#define THREESTATE(VALUE,PBODY,ZBODY,NBODY) \
    { \
        int v = (VALUE); \
        if( v == 0 )     { (ZBODY); } \
        else if( v > 0 ) { (PBODY); } \
        else             { (NBODY); } \
    }

int main()
{
    THREESTATE( 3, printf("P\n"), printf("Z\n"), printf("N\n") )
    return 0;
}

How else could we do this?


// Quoting

function threeState( value, pbody, zbody, nbody )
{
    if( value === 0 )     { eval( zbody ); }
    else if ( value > 0 ) { eval( pbody ); }
    else                  { eval( nbody ); }
}

threeState(
    3, "print('P')", "print('Z')", "print('N')" );

How else could we do this?

# Function pointers

def three_state( 
        value, p_body_fn, z_body_fn, n_body_fn ):
    if value == 0:  z_body_fn()
    elif value > 0: p_body_fn()
    else:           n_body_fn()

def pr( x ):
    def ret():
        print x
    return ret

three_state(  3, pr("P"), pr("N"), pr("Z") )

How else could we do this?

class TestJava {

    interface IThreeStateBodies {
        void positiveBody();
        void zeroBody();
        void negativeBody();
    }

    static void threeState(
            int value, IThreeStateBodies bodies ) {
        if ( value == 0 )     bodies.zeroBody();
        else if ( value > 0 ) bodies.positiveBody();
        else                  bodies.negativeBody();
    }
    ...

How else could we do this?

...
    public static void main( String[] args ) {
        threeState( 3,
            new IThreeStateBodies() {
                public void positiveBody() {
                    System.out.println( "P" );
                }
                public void zeroBody() {
                    System.out.println( "Z" );
                }
                public void negativeBody() {
                    System.out.println( "N" );
                }
            }
        );
    }

Discussion