diff --git a/Robust_macros__syntax-parse.html b/Robust_macros__syntax-parse.html index 66f41f8..2478566 100644 --- a/Robust_macros__syntax-parse.html +++ b/Robust_macros__syntax-parse.html @@ -6,8 +6,7 @@ message from
> (define (misuse s)
    (unless (string? s)
      (error 'misuse "expected a string, but got ~a" s))
    (string-append s " snazzy suffix"))
; User of the function:
> (misuse 0)

misuse: expected a string, but got 0

; I goofed, and understand why! It's a shame the writer of the
; function had to work so hard to tell me.

Unfortunately the error code tends to overwhelm and/or obscure our function definition. Also, the error message is good but not great. Improving it would require even more error code.

3. Use a contract.

> (define/contract (misuse s)
    (string? . -> . string?)
    (string-append s " snazzy suffix"))
; User of the function:
> (misuse 0)

misuse: contract violation

  expected: string?

  given: 0

  in: the 1st argument of

      (-> string? string?)

  contract from: (function misuse)

  blaming: program

  at: eval:131.0

; I goofed, and understand why! I'm happier, and I hear the writer of
; the function is happier, too.

This is the best of both worlds.

The contract is a simple and concise. Even better, it’s -declarative. We say what we want, without needing to spell out what to -do.

On the other hand the user of our function gets a very detailed error +declarative. We say what we want to happen, not how.

On the other hand the user of our function gets a very detailed error message. Plus, the message is in a standard, familiar format.

4. Use Typed Racket.

> (: misuse (String -> String))
> (define (misuse s)
    (string-append s " snazzy suffix"))
> (misuse 0)

eval:3:0: Type Checker: Expected String, but got Zero

  in: 0

Even better, Typed Racket can catch usage mistakes up-front at compile time.

7.2 Error-handling strategies for macros

For macros, we have similar choices.

1. Ignore the possibility of misuse. This choice is even worse for macros. The default error messages are even less likely to make sense, @@ -27,8 +26,8 @@ confused.

Examples section illustrating many real-world scenarios.

Furthermore, everything I’d learned up to this point prepared me to -appreciate what syntax-parse does, and why. That leaves -the "how" of using it, which seems pretty straightforward, so far.

This might well be a temporary state of me "not knowing what I don’t +appreciate what syntax-parse does, and why. The details of +how to use it seem pretty straightforward, so far.

This might well be a temporary state of me "not knowing what I don’t know". As I dig in and use it more, maybe I’ll discover something confusing or tricky. If/when I do, I’ll come back here and update this.

But for now I’ll focus on improving the previous parts.

 
\ No newline at end of file diff --git a/all.html b/all.html index a700ca5..ec58f7a 100644 --- a/all.html +++ b/all.html @@ -1,6 +1,6 @@ Fear of Macros
Fear of Macros

Fear of Macros

-
Copyright (c) 2012-2013 by Greg Hendershott. All rights reserved.
Last updated 2014-03-25T08:32:00
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-2014 by Greg Hendershott. All rights reserved.
Last updated 2014-03-25T08:52:41
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 @@ -302,8 +302,7 @@ message from
> (define (misuse s)
    (unless (string? s)
      (error 'misuse "expected a string, but got ~a" s))
    (string-append s " snazzy suffix"))
; User of the function:
> (misuse 0)

misuse: expected a string, but got 0

; I goofed, and understand why! It's a shame the writer of the
; function had to work so hard to tell me.

Unfortunately the error code tends to overwhelm and/or obscure our function definition. Also, the error message is good but not great. Improving it would require even more error code.

3. Use a contract.

> (define/contract (misuse s)
    (string? . -> . string?)
    (string-append s " snazzy suffix"))
; User of the function:
> (misuse 0)

misuse: contract violation

  expected: string?

  given: 0

  in: the 1st argument of

      (-> string? string?)

  contract from: (function misuse)

  blaming: program

  at: eval:131.0

; I goofed, and understand why! I'm happier, and I hear the writer of
; the function is happier, too.

This is the best of both worlds.

The contract is a simple and concise. Even better, it’s -declarative. We say what we want, without needing to spell out what to -do.

On the other hand the user of our function gets a very detailed error +declarative. We say what we want to happen, not how.

On the other hand the user of our function gets a very detailed error message. Plus, the message is in a standard, familiar format.

4. Use Typed Racket.

#lang typed/racket
> (: misuse (String -> String))
> (define (misuse s)
    (string-append s " snazzy suffix"))
> (misuse 0)

eval:3:0: Type Checker: Expected String, but got Zero

  in: 0

Even better, Typed Racket can catch usage mistakes up-front at compile time.

7.2 Error-handling strategies for macros

For macros, we have similar choices.

1. Ignore the possibility of misuse. This choice is even worse for macros. The default error messages are even less likely to make sense, @@ -323,8 +322,8 @@ confused.

Examples section illustrating many real-world scenarios.

Furthermore, everything I’d learned up to this point prepared me to -appreciate what syntax-parse does, and why. That leaves -the "how" of using it, which seems pretty straightforward, so far.

This might well be a temporary state of me "not knowing what I don’t +appreciate what syntax-parse does, and why. The details of +how to use it seem pretty straightforward, so far.

This might well be a temporary state of me "not knowing what I don’t know". As I dig in and use it more, maybe I’ll discover something confusing or tricky. If/when I do, I’ll come back here and update this.

But for now I’ll focus on improving the previous parts.

8 References and Acknowledgments

Eli Barzliay’s blog post, diff --git a/index.html b/index.html index 90714d5..6582f28 100644 --- a/index.html +++ b/index.html @@ -1,3 +1,3 @@ Fear of Macros

Fear of Macros
On this page:
Fear of Macros

Fear of Macros

-
Copyright (c) 2012-2013 by Greg Hendershott. All rights reserved.
Last updated 2014-03-25T08:31:51
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-2014 by Greg Hendershott. All rights reserved.
Last updated 2014-03-25T08:52:33
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