From bdfe96018e07ab795a620f8aec40252c29c5fc75 Mon Sep 17 00:00:00 2001 From: Eric Hanchrow Date: Sat, 28 Sep 2013 11:42:41 -0400 Subject: [PATCH] Add a margin note --- Transform_.html | 2 +- all.html | 6 ++++-- index.html | 2 +- index.rkt | 11 +++++++---- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Transform_.html b/Transform_.html index 48cb66e..77f0627 100644 --- a/Transform_.html +++ b/Transform_.html @@ -36,7 +36,7 @@ and so on recursively—which is what

When we want to transform syntax, we’ll generally take the pieces we were given, maybe rearrange their order, perhaps change some of the pieces, and often introduce brand-new pieces.

3.3 Actually transforming the input

Let’s write a transformer function that reverses the syntax it was -given:

> (define-syntax (reverse-me stx)
    (datum->syntax stx (reverse (cdr (syntax->datum stx)))))
> (reverse-me "backwards" "am" "i" values)

"i"

"am"

"backwards"

Understand Yoda, can we. Great, but how does this work?

First we take the input syntax, and give it to +given:

the values at the end allows the result to evaluate nicely. Try (reverse-me "backwards" "am" "i") to see why it’s handy.

> (define-syntax (reverse-me stx)
    (datum->syntax stx (reverse (cdr (syntax->datum stx)))))
> (reverse-me "backwards" "am" "i" values)

"i"

"am"

"backwards"

Understand Yoda, can we. Great, but how does this work?

First we take the input syntax, and give it to syntax->datum. This converts the syntax into a plain old list:

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

'(reverse-me "backwards" "am" "i" values)

Using cdr slices off the first item of the list, reverse-me, leaving the remainder: diff --git a/all.html b/all.html index 7bf69aa..2477d86 100644 --- a/all.html +++ b/all.html @@ -1,6 +1,6 @@ Fear of Macros

Fear of Macros

-
Copyright (c) 2012-2013 by Greg Hendershott. All rights reserved.
Last updated 2013-08-15T14:15:12
Feedback and corrections are welcome here.

Contents:

    1 Preface

    2 Our plan of attack

    3 Transform!

      3.1 What is a syntax transformer?

      3.2 What’s the input?

      3.3 Actually transforming the input

      3.4 Compile time vs. run time

      3.5 begin-for-syntax

    4 Pattern matching: syntax-case and syntax-rules

      4.1 Pattern variable vs. template—fight!

        4.1.1 with-syntax

        4.1.2 with-syntax*

        4.1.3 format-id

        4.1.4 Another example

      4.2 Making our own struct

      4.3 Using dot notation for nested hash lookups

    5 Syntax parameters

    6 What’s the point of splicing-let?

    7 Robust macros: syntax-parse

      7.1 Error-handling strategies for functions

      7.2 Error-handling strategies for macros

      7.3 Using syntax/parse

    8 References and Acknowledgments

    9 Epilogue

1 Preface

I learned Racket after 25 years of mostly using C and C++.

Some psychic whiplash resulted.

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

Copyright (c) 2012-2013 by Greg Hendershott. All rights reserved.
Last updated 2013-09-28T11:41:22
Feedback and corrections are welcome here.

Contents:

    1 Preface

    2 Our plan of attack

    3 Transform!

      3.1 What is a syntax transformer?

      3.2 What’s the input?

      3.3 Actually transforming the input

      3.4 Compile time vs. run time

      3.5 begin-for-syntax

    4 Pattern matching: syntax-case and syntax-rules

      4.1 Pattern variable vs. template—fight!

        4.1.1 with-syntax

        4.1.2 with-syntax*

        4.1.3 format-id

        4.1.4 Another example

      4.2 Making our own struct

      4.3 Using dot notation for nested hash lookups

    5 Syntax parameters

    6 What’s the point of splicing-let?

    7 Robust macros: syntax-parse

      7.1 Error-handling strategies for functions

      7.2 Error-handling strategies for macros

      7.3 Using syntax/parse

    8 References and Acknowledgments

    9 Epilogue

1 Preface

I learned Racket after 25 years of mostly using C and C++.

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 @@ -79,7 +79,9 @@ and so on recursively—which is what

When we want to transform syntax, we’ll generally take the pieces we were given, maybe rearrange their order, perhaps change some of the pieces, and often introduce brand-new pieces.

3.3 Actually transforming the input

Let’s write a transformer function that reverses the syntax it was -given:

> (define-syntax (reverse-me stx)
    (datum->syntax stx (reverse (cdr (syntax->datum stx)))))
> (reverse-me "backwards" "am" "i" values)

"i"

"am"

"backwards"

Understand Yoda, can we. Great, but how does this work?

First we take the input syntax, and give it to +given:

the values at the end allows the result to +evaluate nicely. Try (reverse-me "backwards" "am" "i") to +see why it’s handy.

> (define-syntax (reverse-me stx)
    (datum->syntax stx (reverse (cdr (syntax->datum stx)))))
> (reverse-me "backwards" "am" "i" values)

"i"

"am"

"backwards"

Understand Yoda, can we. Great, but how does this work?

First we take the input syntax, and give it to syntax->datum. This converts the syntax into a plain old list:

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

'(reverse-me "backwards" "am" "i" values)

Using cdr slices off the first item of the list, reverse-me, leaving the remainder: diff --git a/index.html b/index.html index a4da1b7..aebe792 100644 --- a/index.html +++ b/index.html @@ -1,3 +1,3 @@ Fear of Macros

Fear of Macros

-
Copyright (c) 2012-2013 by Greg Hendershott. All rights reserved.
Last updated 2013-08-15T14:15:07
Feedback and corrections are welcome here.

Contents:

    1 Preface

    2 Our plan of attack

    3 Transform!

      3.1 What is a syntax transformer?

      3.2 What’s the input?

      3.3 Actually transforming the input

      3.4 Compile time vs. run time

      3.5 begin-for-syntax

    4 Pattern matching: syntax-case and syntax-rules

      4.1 Pattern variable vs. template—fight!

        4.1.1 with-syntax

        4.1.2 with-syntax*

        4.1.3 format-id

        4.1.4 Another example

      4.2 Making our own struct

      4.3 Using dot notation for nested hash lookups

    5 Syntax parameters

    6 What’s the point of splicing-let?

    7 Robust macros: syntax-parse

      7.1 Error-handling strategies for functions

      7.2 Error-handling strategies for macros

      7.3 Using syntax/parse

    8 References and Acknowledgments

    9 Epilogue

 
\ No newline at end of file +
Copyright (c) 2012-2013 by Greg Hendershott. All rights reserved.
Last updated 2013-09-28T11:41:16
Feedback and corrections are welcome here.

Contents:

    1 Preface

    2 Our plan of attack

    3 Transform!

      3.1 What is a syntax transformer?

      3.2 What’s the input?

      3.3 Actually transforming the input

      3.4 Compile time vs. run time

      3.5 begin-for-syntax

    4 Pattern matching: syntax-case and syntax-rules

      4.1 Pattern variable vs. template—fight!

        4.1.1 with-syntax

        4.1.2 with-syntax*

        4.1.3 format-id

        4.1.4 Another example

      4.2 Making our own struct

      4.3 Using dot notation for nested hash lookups

    5 Syntax parameters

    6 What’s the point of splicing-let?

    7 Robust macros: syntax-parse

      7.1 Error-handling strategies for functions

      7.2 Error-handling strategies for macros

      7.3 Using syntax/parse

    8 References and Acknowledgments

    9 Epilogue

 
\ No newline at end of file diff --git a/index.rkt b/index.rkt index 904c82e..1694c67 100644 --- a/index.rkt +++ b/index.rkt @@ -318,6 +318,9 @@ pieces, and often introduce brand-new pieces. Let's write a transformer function that reverses the syntax it was given: +@margin-note{The @racket[values] at the end of the example allows the +result to evaluate nicely. Try +@racket[(reverse-me "backwards" "am" "i")] to see why it's handy.} @i[ (define-syntax (reverse-me stx) (datum->syntax stx (reverse (cdr (syntax->datum stx))))) @@ -855,7 +858,7 @@ if we need to define more than one pattern variable. (syntax-case stx () [(_ a b (args ...) body0 body ...) (with-syntax ([name (datum->syntax stx - (string->symbol (format "~a-~a" + (string->symbol (format "~a-~a" (syntax->datum #'a) (syntax->datum #'b))))]) #'(define (name args ...) @@ -1180,7 +1183,7 @@ like JavaScript? [(_ chain default) (let ([xs (map (lambda (x) (datum->syntax stx (string->symbol x))) - (regexp-split #rx"\\." + (regexp-split #rx"\\." (symbol->string (syntax->datum #'chain))))]) (with-syntax ([h (car xs)] [ks (cdr xs)]) @@ -1216,7 +1219,7 @@ messages when used in error. Let's try to do that here. stx #'chain)) (let ([xs (map (lambda (x) (datum->syntax stx (string->symbol x))) - (regexp-split #rx"\\." + (regexp-split #rx"\\." (symbol->string (syntax->datum #'chain))))]) ;; Check that we have at least hash.key (unless (and (>= (length xs) 2) @@ -1286,7 +1289,7 @@ certain kind of mistake in our macros. The mistake is if our new syntax introduces a variable that accidentally conflicts with one in the code surrounding our macro. -The Racket @italic{Reference} section, +The Racket @italic{Reference} section, @hyperlink["http://docs.racket-lang.org/reference/syntax-model.html#(part._transformer-model)" "Transformer Bindings"], has a good explanation and example. Basically, syntax has "marks" to preserve lexical scope. This makes your macro behave