Formatting predefined functions

master
Florian Mari 2021-05-06 12:49:54 +02:00
parent 48a07bfa6c
commit a150c649c7
1 changed files with 170 additions and 12 deletions

View File

@ -334,7 +334,8 @@ y
**Internal Definitions.** When a *BODY* begins with a sequence of `define` constructs, they are known as "internal definitions" and are interpreted a little differently from top-level definitions. Specifically, they work like [letrec](https://wizardforcel.gitbooks.io/sicp-in-python/content/21.html#letrec) does.
\> *First, bindings are created for all the names defined by the `define` statements, initially bound to undefined values. >* Then the values are filled in by the defines.
* First, bindings are created for all the names defined by the `define` statements, initially bound to undefined values.
* Then the values are filled in by the defines.
As a result, a sequence of internal function definitions can be mutually recursive, just as `def` statements in Python that are nested inside a function can be:
@ -355,17 +356,174 @@ As a result, a sequence of internal function definitions can be mutually recursi
**Predefined Functions.** There is a large collection of predefined functions, all bound to names in the global environment, and we'll simply illustrate a few here; the rest are catalogued in the [Revised(4) Scheme](http://people.csail.mit.edu/jaffer/r4rs_toc.html) Report. Function calls are not "special" in that they all use the same completely uniform evaluation rule: recursively evaluate all items (including the operator), and then apply the operator's value (which must be a function) to the operands' values.
\> ***Arithmetic:** Scheme provides the standard arithmetic operators, many with familiar denotations, although the operators uniformly appear before the operands: >
\>
\>
\> ``` > >>> ; Semicolons introduce one-line comments. > >>> ; Compute (3+7+10)*(1000-8) // 992 - 17 > >>> (- (quotient ( *(+ 3 7 10) (- 1000 8))) 17) > 3 > >>> (remainder 27 4) > 3 > >>> (- 17) > -17 >
\> `> > > > Similarly, there are the usual numeric comparison operators, extended to allow more than two operands: > > > > >` > > >>> (< 0 5) > > #t > > >>> (>= 100 10 10 0) > > #t > > >>> (= 21 (* 7 3) (+ 19 2)) > > #t > > >>> (not (= 15 14)) > > #t > > >>> (zero? (- 7 7)) > > #t > > > > `> > > > `not`, by the way, is a function, not a special form like `and` or `or`, because its operand must always be evaluated, and so needs no special treatment. > > > * **Lists and Pairs:** A large number of operations deal with pairs and lists (which again are built of pairs and empty lists): > > > >` > >>> (cons 'a 'b) > (a . b) > >>> (list 'a 'b) > (a b) > >>> (cons 'a (cons 'b '())) > (a b) > >>> (car (cons 'a 'b)) > a > >>> (cdr (cons 'a 'b)) > b > >>> (cdr (list a b)) > (b) > >>> (cadr '(a b)) ; An abbreviation for (car (cdr '(a b))) > b > >>> (cddr '(a b)) ; Similarly, an abbreviation for (cdr (cdr '(a b))) > () > >>> (list-tail '(a b c) 0) > (a b c) > >>> (list-tail '(a b c) 1) > (b c) > >>> (list-ref '(a b c) 0) > a > >>> (list-ref '(a b c) 2) > c > >>> (append '(a b) '(c d) '() '(e)) > (a b c d e) > >>> ; All but the last list is copied. The last is shared, so: > >>> (define L1 (list 'a 'b 'c)) > >>> (define L2 (list 'd)) > >>> (define L3 (append L1 L2)) > >>> (set-car! L1 1) > >>> (set-car! L2 2) > >>> L3 > (a b c 2) > >>> (null? '()) > #t > >>> (list? '()) > #t > >>> (list? '(a b)) > #t > >>> (list? '(a . b)) > #f >
\> `> > > * **Equivalence:** The `=` operation is for numbers. For general equality of values, Scheme distinguishes `eq?` (like Python's `is`), `eqv?` (similar, but is the same as `=` on numbers), and `equal?` (compares list structures and strings for content). Generally, we use `eqv?` or `equal?`, except in cases such as comparing symbols, booleans, or the null list: > > > >` > >>> (eqv? 'a 'a) > #t > >>> (eqv? 'a 'b) > #f > >>> (eqv? 100 (+ 50 50)) > #t > >>> (eqv? (list 'a 'b) (list 'a 'b)) > #f > >>> (equal? (list 'a 'b) (list 'a 'b)) > #t >
\> `> > > * **Types:** Each type of value satisfies exactly one of the basic type predicates: > > > >` > >>> (boolean? #f) > #t > >>> (integer? 3) > #t > >>> (pair? '(a b)) > #t > >>> (null? '()) > #t > >>> (symbol? 'a) > #t > >>> (procedure? +) > #t >
\> `> > > * **Input and Output:** Scheme interpreters typically run a read-eval-print loop, but one can also output things under explicit control of the program, using the same functions the interpreter does internally: > > > >` > >>> (begin (display 'a) (display 'b) (newline)) > ab >
\> `> > > > Thus, `(display x)` is somewhat akin to Python's > > > > > `print(str(x), end="")` > > > > and `(newline)` is like `print()`. > > > > For input, the `(read)` function reads a Scheme expression from the current "port". It does _not_ interpret the expression, but rather reads it as data: > > > >` > >>> (read) > >>> (a b c) > (a b c) >
\> `> > > * **Evaluation:** The `apply` function provides direct access to the function-calling operation: > > > > >` > > >>> (apply cons '(1 2)) > > (1 . 2) > > >>> ;; Apply the function f to the arguments in L after g is > > >>> ;; applied to each of them > > >>> (define (compose-list f g L) > > ... (apply f (map g L))) > > >>> (compose-list + (lambda (x) (* x x)) '(1 2 3)) > > 14 > > > > `> > > > An extension allows for some "fixed" arguments at the beginning: > > > > >` > > >>> (apply + 1 2 '(3 4 5)) > > 15 > > > > `> > > > The following function is not in [Revised(4) Scheme](http://people.csail.mit.edu/jaffer/r4rs_toc.html), but is present in our versions of the interpreter (_warning:_ a non-standard procedure that is not defined this way in later versions of Scheme): > > > >` > >>> (eval '(+ 1 2)) > 3 >
\> `> > > > That is, `eval` evaluates a piece of Scheme data that represents a correct Scheme expression. This version evaluates its expression argument in the global environment. Our interpreter also provides a way to specify a specific environment for the evaluation: > > > > >` > > >>> (define (incr n) (lambda (x) (+ n x))) > > >>> (define add5 (incr 5)) > > >>> (add5 13) > > 18 > > >>> (eval 'n (procedure-environment add5)) > > 5 > > > > ```
* **Arithmetic:** Scheme provides the standard arithmetic operators, many with familiar denotations, although the operators uniformly appear before the operands:
```
>>> ; Semicolons introduce one-line comments.
>>> ; Compute (3+7+10)*(1000-8) // 992 - 17
>>> (- (quotient (* (+ 3 7 10) (- 1000 8))) 17)
3
>>> (remainder 27 4)
3
>>> (- 17)
-17
```
&emsp; &emsp; Similarly, there are the usual numeric comparison operators, extended to allow more than two operands:
```
>>> (< 0 5)
#t
>>> (>= 100 10 10 0)
#t
>>> (= 21 (* 7 3) (+ 19 2))
#t
>>> (not (= 15 14))
#t
>>> (zero? (- 7 7))
#t
```
&emsp; &emsp; `not`, by the way, is a function, not a special form like `and` or `or`, because its operand must always be evaluated, and so needs no special treatment.
* **Lists and Pairs:** A large number of operations deal with pairs and lists (which again are built of pairs and empty lists):
```
>>> (cons 'a 'b)
(a . b)
>>> (list 'a 'b)
(a b)
>>> (cons 'a (cons 'b '()))
(a b)
>>> (car (cons 'a 'b))
a
>>> (cdr (cons 'a 'b))
b
>>> (cdr (list a b))
(b)
>>> (cadr '(a b)) ; An abbreviation for (car (cdr '(a b)))
b
>>> (cddr '(a b)) ; Similarly, an abbreviation for (cdr (cdr '(a b)))
()
>>> (list-tail '(a b c) 0)
(a b c)
>>> (list-tail '(a b c) 1)
(b c)
>>> (list-ref '(a b c) 0)
a
>>> (list-ref '(a b c) 2)
c
>>> (append '(a b) '(c d) '() '(e))
(a b c d e)
>>> ; All but the last list is copied. The last is shared, so:
>>> (define L1 (list 'a 'b 'c))
>>> (define L2 (list 'd))
>>> (define L3 (append L1 L2))
>>> (set-car! L1 1)
>>> (set-car! L2 2)
>>> L3
(a b c 2)
>>> (null? '())
#t
>>> (list? '())
#t
>>> (list? '(a b))
#t
>>> (list? '(a . b))
#f
```
* **Equivalence:** The `=` operation is for numbers. For general equality of values, Scheme distinguishes `eq?` (like Python's `is`), `eqv?` (similar, but is the same as = on numbers), and `equal?` (compares list structures and strings for content). Generally, we use `eqv?` or `equal?`, except in cases such as comparing symbols, booleans, or the null list:
```
>>> (eqv? 'a 'a)
#t
>>> (eqv? 'a 'b)
#f
>>> (eqv? 100 (+ 50 50))
#t
>>> (eqv? (list 'a 'b) (list 'a 'b))
#f
>>> (equal? (list 'a 'b) (list 'a 'b))
#t
```
* **Types:** Each type of value satisfies exactly one of the basic type predicates:
```
>>> (boolean? #f)
#t
>>> (integer? 3)
#t
>>> (pair? '(a b))
#t
>>> (null? '())
#t
>>> (symbol? 'a)
#t
>>> (procedure? +)
#t
```
* **Input and Output:** Scheme interpreters typically run a read-eval-print loop, but one can also output things under explicit control of the program, using the same functions the interpreter does internally:
```
>>> (begin (display 'a) (display 'b) (newline))
ab
```
&emsp; &emsp; Thus, `(display x)` is somewhat akin to Python's
&emsp; &emsp; ```print(str(x), end="")```
&emsp; &emsp; and `(newline)` is like `print()`.
&emsp; &emsp; For input, the `(read)` function reads a Scheme expression from the current "port". It *does not* interpret the expression, but rather reads it as data:
```
>>> (read)
>>> (a b c)
(a b c)
```
* **Evaluation:** The apply function provides direct access to the function-calling operation:
```
>>> (apply cons '(1 2))
(1 . 2)
>>> ;; Apply the function f to the arguments in L after g is
>>> ;; applied to each of them
>>> (define (compose-list f g L)
... (apply f (map g L)))
>>> (compose-list + (lambda (x) (* x x)) '(1 2 3))
14
```
&emsp; &emsp; An extension allows for some "fixed" arguments at the beginning:
```
>>> (apply + 1 2 '(3 4 5))
15
```
&emsp; &emsp; The following function is not in [Revised(4)](http://people.csail.mit.edu/jaffer/r4rs_toc.html) Scheme, but is present in our versions of the interpreter (*warning*: a non-standard procedure that is not defined this way in later versions of Scheme):
```
>>> (eval '(+ 1 2))
3
```
&emsp; &emsp; That is, eval evaluates a piece of Scheme data that represents a correct Scheme expression. This version evaluates its expression argument in the global environment. Our interpreter also provides a way to specify a specific environment for the evaluation:
```
>>> (define (incr n) (lambda (x) (+ n x)))
>>> (define add5 (incr 5))
>>> (add5 13)
18
>>> (eval 'n (procedure-environment add5))
5
```
### 3.6.2 The Logo Language