{"size": 2143, "ext": "scrbl", "max_stars_repo_path": "first-class-or/first-class-or.scrbl", "max_stars_repo_name": "maueroats/syntax-parse-example", "max_stars_repo_stars_event_min_datetime": "2017-05-18T22:15:56.000Z", "max_stars_repo_stars_event_max_datetime": "2021-09-17T13:13:05.000Z", "max_issues_repo_path": "first-class-or/first-class-or.scrbl", "max_issues_repo_name": "maueroats/syntax-parse-example", "max_issues_repo_issues_event_min_datetime": "2017-05-18T22:54:53.000Z", "max_issues_repo_issues_event_max_datetime": "2021-10-19T02:58:50.000Z", "max_forks_repo_path": "first-class-or/first-class-or.scrbl", "max_forks_repo_name": "maueroats/syntax-parse-example", "max_forks_repo_forks_event_min_datetime": "2017-05-19T14:27:57.000Z", "max_forks_repo_forks_event_max_datetime": "2022-03-30T09:36:54.000Z"}
{"max_stars_count": 22, "max_issues_count": 20, "max_forks_count": 6, "avg_line_length": 30.1830985915, "max_line_length": 124, "alphanum_fraction": 0.6448903406}
#lang syntax-parse-example
@require[
  (for-label
    racket/base
    syntax/parse
    syntax-parse-example/first-class-or/first-class-or)]

@(define first-class-or-eval
   (make-base-eval
     '(require syntax-parse-example/first-class-or/first-class-or)))

@title{@tt{first-class-or}}

@; =============================================================================

@defmodule[syntax-parse-example/first-class-or/first-class-or]{}

@defform[(first-class-or expr ...)]{
  Racket's @racket[or] is a macro, not a function.
  It cannot be used like a normal value (i.e., evaluated as an identifier).
  @margin-note{See also @secref["and+or" #:doc '(lib "scribblings/guide/guide.scrbl")]}

  @examples[#:eval (make-base-eval)
    (or #false #true)
    (eval:error (apply or '(#false #true 0)))
  ]

  @tech/guide{Identifier macros} can be evaluated as identifiers.

  So we can write a @racket[first-class-or] macro to:
  @itemlist[
  @item{
    expand like Racket's @racket[or] when called like a function, and
  }
  @item{
    expand to a function definition when used like an identifier.
  }
  ]
  In the latter case, the function that @racket[first-class-or] evaluates to
   is similar to @racket[or], but evaluates all its arguments.

  @examples[#:eval first-class-or-eval
    (first-class-or #false #true)
    (apply first-class-or '(#false #true 0))
    (first-class-or (+ 2 3) (let loop () (loop)))
    (map first-class-or '(9 #false 3) '(8 #false #false))
  ]

  The macro:

  @racketfile{first-class-or.rkt}

  Some comments:
  @itemlist[
  @item{
    The first two @racket[syntax/parse] clauses define what happens when @racket[or]
     is called like a function.
  }
  @item{
    The pattern @litchar{_:id} matches any @tech/reference{identifier}.
  }
  @item{
    The dot notation in @racket[(_ _?a . _?b)] could be
     @racket[(_ _?a _?b ...)] instead.
    See @secref["Pairs__Lists__and_Racket_Syntax" #:doc '(lib "scribblings/guide/guide.scrbl")]
     for intuition about what the dot means, and @secref["stxparse-patterns" #:doc '(lib "syntax/scribblings/syntax.scrbl")]
     for what it means in a syntax pattern.
  }
  ]
}
