diff --git a/index.html b/index.html index 75cab9f..c833dfc 100644 --- a/index.html +++ b/index.html @@ -2,7 +2,7 @@ Fear of Macros
1 Introduction
2 The plan of attack
3 Transformers
3.1 What is a syntax transformer?
3.2 What is the input?
3.3 Actually transforming the input
3.4 Compile time vs. run time
4 Pattern matching: syntax-case and syntax-rules
4.1 Patterns and templates
4.1.1 "A pattern variable can’t be used outside of a template"
5 Syntax parameters
6 Robust macros: syntax-parse
7 Other questions
7.1 What’s the point of with-syntax?
7.2 What’s the point of begin-for-syntax?
7.3 What’s the point of racket/ splicing?
8 References/ Acknowledgments
9 Epilogue

Fear of Macros

Copyright (c) 2012 by Greg Hendershott. All rights reserved. -
Last updated 2012-10-25 18:15:21

1 Introduction

I learned Racket after 25 years of doing C/C++ imperative programming.

Some psychic whiplash resulted.

"All the parentheses" was actually not a big deal. Instead, the first +

Last updated 2012-10-25 18:54:58

    1 Introduction

    2 The plan of attack

    3 Transformers

      3.1 What is a syntax transformer?

      3.2 What is the input?

      3.3 Actually transforming the input

      3.4 Compile time vs. run time

    4 Pattern matching: syntax-case and syntax-rules

      4.1 Patterns and templates

        4.1.1 "A pattern variable can’t be used outside of a template"

    5 Syntax parameters

    6 Robust macros: syntax-parse

    7 Other questions

      7.1 What’s the point of with-syntax?

      7.2 What’s the point of begin-for-syntax?

      7.3 What’s the point of racket/splicing?

    8 References/Acknowledgments

    9 Epilogue

1 Introduction

I learned Racket after 25 years of doing C/C++ imperative programming.

Some psychic whiplash resulted.

"All the parentheses" was actually not a big deal. Instead, the first mind warp was functional programming. Before long I wrapped my brain around it, and went on to become comfortable and effective with many other aspects and features of Racket.

But two final frontiers remained: Macros and continuations.

I found that simple macros were easy and understandable, plus there @@ -78,7 +78,7 @@ given:

("backwards" "am" "i" values). Passing that to reverse changes it to (values "i" "am" "backwards"):

> (reverse (cdr '("backwards" "am" "i" values)))

'(values "i" "am")

Finally we use syntax->datum to convert this back to syntax:

> (datum->syntax #f '(values "i" "am" "backwards"))

#<syntax (values "i" "am" "backwards")>

That’s what our transformer function gives back to the Racket -compiler, and that syntax is evaluated:

> (values "i" "am" "backwards")

"i"

"am"

"backwards"

3.4 Compile time vs. run time

Normal Racket code runs at ... run time. Duh.

Instead of "compile time vs. run time", you may hear it +compiler, and that syntax is evaluated:

> (values "i" "am" "backwards")

"i"

"am"

"backwards"

3.4 Compile time vs. run time

          (define-syntax (foo stx)
            (make-pipe)) ;This is not run time.

Normal Racket code runs at ... run time. Duh.

Instead of "compile time vs. run time", you may hear it described as "syntax phase vs. runtime phase". Same difference.

But a syntax transformer is run by the Racket compiler, as part of the process of parsing, expanding and understanding your code. In other words, your syntax transformer function is evaluated at compile time.

This aspect of macros lets you do things that simply aren’t possible diff --git a/main.rkt b/main.rkt index 8268f3e..1a4c24b 100644 --- a/main.rkt +++ b/main.rkt @@ -287,6 +287,11 @@ compiler, and @italic{that} syntax is evaluated: @subsection{Compile time vs. run time} +@codeblock[#:indent 10]{ +(define-syntax (foo stx) + (make-pipe)) ;This is not run time. +} + Normal Racket code runs at ... run time. Duh. @margin-note{Instead of "compile time vs. run time", you may hear it