{"size": 3295, "ext": "scrbl", "max_stars_repo_path": "pkgs/racket-doc/compatibility/scribblings/defmacro.scrbl", "max_stars_repo_name": "lkh01/racket", "max_stars_repo_stars_event_min_datetime": "2018-07-29T04:13:52.000Z", "max_stars_repo_stars_event_max_datetime": "2022-02-14T16:11:17.000Z", "max_issues_repo_path": "pkgs/racket-doc/compatibility/scribblings/defmacro.scrbl", "max_issues_repo_name": "lkh01/racket", "max_issues_repo_issues_event_min_datetime": "2017-08-25T20:26:37.000Z", "max_issues_repo_issues_event_max_datetime": "2022-02-26T17:48:40.000Z", "max_forks_repo_path": "pkgs/racket-doc/compatibility/scribblings/defmacro.scrbl", "max_forks_repo_name": "lkh01/racket", "max_forks_repo_forks_event_min_datetime": "2016-04-25T11:47:57.000Z", "max_forks_repo_forks_event_max_datetime": "2017-05-09T14:52:48.000Z"}
{"max_stars_count": 10, "max_issues_count": 15, "max_forks_count": 3, "avg_line_length": 41.7088607595, "max_line_length": 76, "alphanum_fraction": 0.7593323217}
#lang scribble/doc
@(require scribblings/reference/mz
          (for-label compatibility/defmacro
                     syntax/parse syntax/parse/define))

@title[#:tag "defmacro"]{Legacy macro support}

@defmodule[compatibility/defmacro]

This @racketmodname[compatibility/defmacro] library provides support for
writing legacy macros. Support for @racket[defmacro] is provided
primarily for porting code from other languages (e.g., some
implementations of Scheme or Common Lisp) that use symbol-based
macro systems.

Use of @racket[defmacro] for modern Racket code is @bold{@italic{strongly}}
discouraged. Instead, consider using @racket[syntax-parse] or
@racket[define-simple-macro].

@deftogether[(
@defform*[[(define-macro id expr)
           (define-macro (id . formals) body ...+)]]
@defform/subs[(defmacro id formals body ...+)
              ([formals (id ...)
                        id
                        (id ...+ . id)])]
)]{

Defines a (non-hygienic) macro @racket[id] through a procedure that
manipulates S-expressions, as opposed to
@tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{syntax objects}.

In the first form, @racket[expr] must produce a procedure. In the
second form, @racket[formals] determines the formal arguments of the
procedure, as in @racket[lambda], and the @racket[expr]s are the
procedure body. The last form, with @racket[defmacro], is like the
second form, but with slightly different parentheses.

In all cases, the procedure is generated in the
@tech[#:doc '(lib "scribblings/reference/reference.scrbl")]{
transformer environment}, not the normal environment.

In a use of the macro,

@racketblock[
(id datum ...)
]

@racket[syntax->datum] is applied to the expression, and the
transformer procedure is applied to the @racket[cdr] of the resulting
list. If the number of @racket[datum]s does not match the procedure's
arity, or if @racket[id] is used in a context that does not match the
above pattern, then a syntax error is reported.

After the macro procedure returns, the result is compared to the
procedure's arguments. For each value that appears exactly once within
the arguments (or, more precisely, within the S-expression derived
from the original source syntax), if the same value appears in the
result, it is replaced with a syntax object from the original
expression. This heuristic substitution preserves source location
information in many cases, despite the macro procedure's operation on
raw S-expressions.

After substituting syntax objects for preserved values, the entire
macro result is converted to syntax with @racket[datum->syntax]. The
original expression supplies the lexical context and source location
for converted elements.

@bold{Important:} Although @racket[define-macro] is non-hygienic, it
is still restricted by Racket's phase separation rules.  This
means that a macro cannot access run-time bindings, because it is
executed in the syntax-expansion phase.  Translating code that
involves @racket[define-macro] or @racket[defmacro] from an
implementation without this restriction usually implies separating
macro related functionality into a @racket[begin-for-syntax] or a
module (that will be imported with @racket[for-syntax]) and
properly distinguishing syntactic information from run-time
information.}
