You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
typesetting/quad/qtest/mds/binding.md

86 lines
3.0 KiB
Markdown

This file contains invisible Unicode characters!

This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# Identifiers and Binding
The context of an expression determines the meaning of identifiers that
appear in the expression. In particular, starting a module with the
language `racket`, as in
`#lang` `racket`
means that, within the module, the identifiers described in this guide
start with the meaning described here: `cons` refers to the function
that creates a pair, `car` refers to the function that extracts the
first element of a pair, and so on.
> +\[missing\] introduces the syntax of identifiers.
Forms like `define`, `lambda`, and `let` associate a meaning with one or
more identifiers; that is, they _bind_ identifiers. The part of the
program for which the binding applies is the _scope_ of the binding. The
set of bindings in effect for a given expression is the expressions
_environment_.
For example, in
```racket
#lang racket
(define f
(lambda (x)
(let ([y 5])
(+ x y))))
(f 10)
```
the `define` is a binding of `f`, the `lambda` has a binding for `x`,
and the `let` has a binding for `y`. The scope of the binding for `f` is
the entire module; the scope of the `x` binding is `(let ([y 5]) (+ x
y))`; and the scope of the `y` binding is just `(+ x y)`. The
environment of `(+ x y)` includes bindings for `y`, `x`, and `f`, as
well as everything in `racket`.
A module-level `define` can bind only identifiers that are not already
defined or `require`d into the module. A local `define` or other binding
forms, however, can give a new local binding for an identifier that
already has a binding; such a binding _shadows_ the existing binding.
Examples:
```racket
(define f
(lambda (append)
(define cons (append "ugly" "confusing"))
(let ([append 'this-was])
(list append cons))))
> (f list)
'(this-was ("ugly" "confusing"))
```
Similarly, a module-level `define` can shadow a binding from the
modules language. For example, `(define cons 1)` in a `racket` module
shadows the `cons` that is provided by `racket`. Intentionally shadowing
a language binding is rarely a good idea—especially for widely used
bindings like `cons`—but shadowing relieves a programmer from having to
avoid every obscure binding that is provided by a language.
Even identifiers like `define` and `lambda` get their meanings from
bindings, though they have _transformer_ bindings \(which means that
they indicate syntactic forms\) instead of value bindings. Since
`define` has a transformer binding, the identifier `define` cannot be
used by itself to get a value. However, the normal binding for `define`
can be shadowed.
Examples:
```racket
> define
eval:1:0: define: bad syntax
in: define
> (let ([define 5]) define)
5
```
Again, shadowing standard bindings in this way is rarely a good idea,
but the possibility is an inherent part of Rackets flexibility.