an attempt at 2d documentation
This commit is contained in:
parent
8adbd7e836
commit
bb0795c502
|
@ -2,13 +2,14 @@
|
||||||
@(require scribble/base
|
@(require scribble/base
|
||||||
scribble/manual
|
scribble/manual
|
||||||
"utils.rkt"
|
"utils.rkt"
|
||||||
|
scribble/core
|
||||||
(for-label ;unstable/2d/cond
|
(for-label ;unstable/2d/cond
|
||||||
;unstable/2d/match
|
;unstable/2d/match
|
||||||
racket/file
|
racket/file
|
||||||
racket/contract
|
racket/contract
|
||||||
racket/base))
|
racket/base))
|
||||||
|
|
||||||
@title[#:tag "2d"]{2D Cond and Match}
|
@title[#:tag "2d"]{2D Syntax}
|
||||||
|
|
||||||
@defmodulelang[unstable/2d]{The @racketmodname[unstable/2d] language installs
|
@defmodulelang[unstable/2d]{The @racketmodname[unstable/2d] language installs
|
||||||
@litchar{#2d} reader support in the readtable, and then chains to the reader of
|
@litchar{#2d} reader support in the readtable, and then chains to the reader of
|
||||||
|
@ -16,24 +17,24 @@ another language that is specified immediately after
|
||||||
@racketmodname[unstable/2d].}
|
@racketmodname[unstable/2d].}
|
||||||
|
|
||||||
The @litchar{#2d} syntax extension adds the ability use
|
The @litchar{#2d} syntax extension adds the ability use
|
||||||
two dimensional grid syntax. That is, you can drawn an ASCII-art
|
a two-dimensional grid syntax. That is, you can drawn an ASCII-art
|
||||||
grid and then treat that as a conditional expression. For example,
|
grid and then treat that as an expression. For example,
|
||||||
here is a simple equality function that operates on pairs and
|
here is a simple equality function that operates on pairs and
|
||||||
numbers:
|
numbers, written using a @litchar{#2d} conditional expression:
|
||||||
@codeblock{
|
@codeblock{
|
||||||
#lang unstable/2d racket
|
#lang unstable/2d racket
|
||||||
|
|
||||||
(define (same? a b)
|
(define (same? a b)
|
||||||
#2dcond
|
#2dcond
|
||||||
╔═════════════╦═══════════════════════╦═════════════╗
|
╔═════════════╦═══════════════════════╦═════════════╗
|
||||||
║ ║ (pair? a) ║ (number? a) ║
|
║ ║ (pair? a) ║ (number? a) ║
|
||||||
╠═════════════╬═══════════════════════╬═════════════╣
|
╠═════════════╬═══════════════════════╬═════════════╣
|
||||||
║ (pair? b) ║ (and (same? (car a) ║ #f ║
|
║ (pair? b) ║ (and (same? (car a) ║ #f ║
|
||||||
║ ║ (car b)) ║ ║
|
║ ║ (car b)) ║ ║
|
||||||
║ ║ (same? (cdr a) ║ ║
|
║ ║ (same? (cdr a) ║ ║
|
||||||
║ ║ (cdr b))) ║ ║
|
║ ║ (cdr b))) ║ ║
|
||||||
╠═════════════╬═══════════════════════╬═════════════╣
|
╠═════════════╬═══════════════════════╬═════════════╣
|
||||||
║ (number? b) ║ #f ║ (= a b) ║
|
║ (number? b) ║ #f ║ (= a b) ║
|
||||||
╚═════════════╩═══════════════════════╩═════════════╝)
|
╚═════════════╩═══════════════════════╩═════════════╝)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,16 +49,134 @@ produce a sequence whose first position is the identifier @racket[2dcond].
|
||||||
|
|
||||||
That macro will take over and then expand into ordinary conditional
|
That macro will take over and then expand into ordinary conditional
|
||||||
expressions, in this case figuring out whether or not the inputs
|
expressions, in this case figuring out whether or not the inputs
|
||||||
are pairs or numbers and selecting the appropriate cell.
|
are pairs or numbers and evaluating the code in the appropriate cell.
|
||||||
|
|
||||||
|
At the reader level, the syntax @litchar{#2d} notation checks
|
||||||
|
the number of columns in the first row and uses that as a guide
|
||||||
|
for where subsequent rows may appear. Once that first row is set,
|
||||||
|
it serves as a guide to where the columns may appear in subsequent
|
||||||
|
rows, although following columns may be merged.
|
||||||
|
|
||||||
|
This merging can simplify
|
||||||
|
some uses of @litchar{#2d} expressions. For example, consider this
|
||||||
|
expression that captures subtyping relationships between a few of the
|
||||||
|
Typed Racket numeric types, this time using a @litchar{#2d} match
|
||||||
|
expression:
|
||||||
|
@codeblock{
|
||||||
|
#lang unstable/2d racket
|
||||||
|
|
||||||
|
(define (subtype? a b)
|
||||||
|
#2dmatch
|
||||||
|
╔══════════╦══════════╦═══════╦══════════╗
|
||||||
|
║ a b ║ 'Integer ║ 'Real ║ 'Complex ║
|
||||||
|
╠══════════╬══════════╩═══════╩══════════╣
|
||||||
|
║ 'Integer ║ #t ║
|
||||||
|
╠══════════╬══════════╗ ║
|
||||||
|
║ 'Real ║ ║ ║
|
||||||
|
╠══════════╣ ╚═══════╗ ║
|
||||||
|
║ 'Complex ║ #f ║ ║
|
||||||
|
╚══════════╩══════════════════╩══════════╝)
|
||||||
|
}
|
||||||
|
|
||||||
|
There are a number of cell walls missing here, but this is still a
|
||||||
|
well-formed @litchar{#2d} expression. In this case, the @racket[2dmatch]
|
||||||
|
treats any of the situations that fall into the larger regions as
|
||||||
|
the same.
|
||||||
|
|
||||||
@section{2D Cond}
|
@section{2D Cond}
|
||||||
|
|
||||||
@defmodule[unstable/2d/cond]
|
@defmodule[unstable/2d/cond]
|
||||||
|
|
||||||
@defform[(2dcond . stuff)]{}
|
@defform/subs[(2dcond cond-content)
|
||||||
|
([cond-content (code:line question-row
|
||||||
|
body-row
|
||||||
|
⋮)]
|
||||||
|
[question-row (code:line empty-cell question-cell ⋯)]
|
||||||
|
[body-row (code:line question-cell exprs-cell ⋯)]
|
||||||
|
[question-cell (code:line ╔═════════════╗
|
||||||
|
║question-expr║
|
||||||
|
╚═════════════╝)]
|
||||||
|
|
||||||
|
[empty-cell (code:line ╔═══╗
|
||||||
|
║ ║
|
||||||
|
╚═══╝)]
|
||||||
|
|
||||||
|
[exprs-cell (code:line ╔═════════════╗
|
||||||
|
║expr expr ...║
|
||||||
|
╚═════════════╝)])]{
|
||||||
|
Evaluates the first row of question expressions until
|
||||||
|
one of them returns a true value (signaling an error if none do),
|
||||||
|
then evaluates the first column of question expressions until
|
||||||
|
one of them returns a true value (signaling an error if none do),
|
||||||
|
and then evaluates the cell in the middle where both point to,
|
||||||
|
returning the result of the last expression in that cell.
|
||||||
|
}
|
||||||
|
|
||||||
@section{2D Match}
|
@section{2D Match}
|
||||||
|
|
||||||
@defmodule[unstable/2d/match]
|
@defmodule[unstable/2d/match]
|
||||||
|
|
||||||
@defform[(2dmatch . stuff)]{}
|
@defform/subs[(2dmatch match-content)
|
||||||
|
([match-content (code:line match-first-row
|
||||||
|
match-row
|
||||||
|
⋮)]
|
||||||
|
[match-first-row (code:line two-expr-cell match-pat-cell ⋯)]
|
||||||
|
[match-row (code:line match-pat-cell exprs-cell ⋯)]
|
||||||
|
[two-expr-cell (code:line ╔═════════════════╗
|
||||||
|
║col-expr row-expr║
|
||||||
|
╚═════════════════╝)]
|
||||||
|
|
||||||
|
[match-pat-cell (code:line ╔═════╗
|
||||||
|
║ pat ║
|
||||||
|
╚═════╝)]
|
||||||
|
|
||||||
|
[exprs-cell (code:line ╔═════════════╗
|
||||||
|
║expr expr ...║
|
||||||
|
╚═════════════╝)])]{
|
||||||
|
Matches @racket[col-expr] against each of patterns
|
||||||
|
in the first column of the table and matches @racket[row-expr]
|
||||||
|
against each of the patterns in the row row, and then evaluates
|
||||||
|
the corresponding @racket[exprs-cell], returning the value of the
|
||||||
|
last expression in that cell.
|
||||||
|
}
|
||||||
|
|
||||||
|
@section{2D Tabular}
|
||||||
|
|
||||||
|
@defmodule[unstable/2d/tabular]
|
||||||
|
|
||||||
|
@defform/subs[(2dmatch tabular-content)
|
||||||
|
|
||||||
|
([tabular-content (code:line tabular-row
|
||||||
|
⋮)
|
||||||
|
(code:line tabular-row
|
||||||
|
⋮
|
||||||
|
style-cell)]
|
||||||
|
[tabular-row (code:line tabular-cell ⋯)]
|
||||||
|
[tabular-cell (code:line ╔════════════════╗
|
||||||
|
║tabular-expr ...║
|
||||||
|
╚════════════════╝)]
|
||||||
|
[style-cell (code:line ╔═════════════════╗
|
||||||
|
║style-content ...║
|
||||||
|
╚═════════════════╝)]
|
||||||
|
[style-content (code:line #:style style-expr)
|
||||||
|
(code:line #:sep sep-expr)
|
||||||
|
#:ignore-first-row])
|
||||||
|
|
||||||
|
#:contracts ([style-expr style?]
|
||||||
|
[sep-expr (or/c block? content? #f)]
|
||||||
|
[tabular-expr (or/c block? content?)])]{
|
||||||
|
Constructs a @racket[tabular] matching the given cells.
|
||||||
|
|
||||||
|
If a cell spans multiple columns, then the resulting
|
||||||
|
@racket[tabular] has @racket['cont] in the corresponding
|
||||||
|
list element. No cells may span rows.
|
||||||
|
|
||||||
|
The @racket[#:style] and @racket[#:sep] arguments are just passed
|
||||||
|
to @racket[tabular].
|
||||||
|
|
||||||
|
If the @racket[#:ignore-first-row] keyword is provided, then the first
|
||||||
|
row of the @racket[2dtabular] expression is ignored. This can be used
|
||||||
|
in case the first row of the rendered table should not have all of the
|
||||||
|
columns (as @litchar{#2d} syntax requires that the first row contain
|
||||||
|
a cell for each column that appears in the table).
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user