|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T l
Length: 14420 (0x3854) Types: TextFile Names: »lambda.scm.44«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/gnu-31mar87/scheme/scm/lambda.scm.44«
;;; -*-Scheme-*- ;;; ;;; Copyright (c) 1984 Massachusetts Institute of Technology ;;; ;;; This material was developed by the Scheme project at the ;;; Massachusetts Institute of Technology, Department of ;;; Electrical Engineering and Computer Science. Permission to ;;; copy this software, to redistribute it, and to use it for any ;;; purpose is granted, subject to the following restrictions and ;;; understandings. ;;; ;;; 1. Any copy made of this software must include this copyright ;;; notice in full. ;;; ;;; 2. Users of this software agree to make their best efforts (a) ;;; to return to the MIT Scheme project any improvements or ;;; extensions that they make, so that these may be included in ;;; future releases; and (b) to inform MIT of noteworthy uses of ;;; this software. ;;; ;;; 3. All materials developed as a consequence of the use of ;;; this software shall duly acknowledge such use, in accordance ;;; with the usual standards of acknowledging credit in academic ;;; research. ;;; ;;; 4. MIT has made no warrantee or representation that the ;;; operation of this software will be error-free, and MIT is ;;; under no obligation to provide any services, by way of ;;; maintenance, update, or otherwise. ;;; ;;; 5. In conjunction with products arising from the use of this ;;; material, there shall be no use of the name of the ;;; Massachusetts Institute of Technology nor of any adaptation ;;; thereof in any advertising, promotional, or sales literature ;;; without prior written consent from MIT in each case. ;;; ;;;; Lambda Abstraction (declare (usual-integrations)) (define lambda?) (define make-lambda) (define lambda-components) (define lambda-body) (define set-lambda-body!) (define lambda-bound) (define lambda-package (make-package lambda-package ((slambda-type (microcode-type 'LAMBDA)) (slexpr-type (microcode-type 'LEXPR)) (xlambda-type (microcode-type 'EXTENDED-LAMBDA)) (internal-lambda-tag (make-named-tag "INTERNAL-LAMBDA")) (internal-lexpr-tag (make-named-tag "INTERNAL-LEXPR")) (lambda-optional-tag (make-interned-symbol "#!OPTIONAL"))) (define internal-lambda-tags (list internal-lambda-tag internal-lexpr-tag)) \f ;;;; Hairy Advice Wrappers ;;; The body of a LAMBDA object can be modified by transformation. ;;; This has the advantage that the body can be transformed many times, ;;; but the original state will always remain. ;;; **** Note: this stuff was implemented for the advice package. ;;; Please don't use it for anything else since it will just ;;; confuse things. (define lambda-body-procedures (let ((wrapper-tag '(LAMBDA-WRAPPER)) (wrapper-body comment-expression) (set-wrapper-body! set-comment-expression!)) (define (make-wrapper original-body new-body state) (make-comment (vector wrapper-tag original-body state) new-body)) (define (wrapper? object) (conjunction (comment? object) (let ((text (comment-text object))) (conjunction (vector? text) (not (zero? (vector-size text))) (eq? (vector-ref text 0) wrapper-tag))))) (define (wrapper-state wrapper) (vector-ref (comment-text wrapper) 2)) (define (set-wrapper-state! wrapper new-state) (vector-set! (comment-text wrapper) 2 new-state)) (define (wrapper-original-body wrapper) (vector-ref (comment-text wrapper) 1)) (define (set-wrapper-original-body! wrapper new-body) (vector-set! (comment-text wrapper) 1 new-body)) \f (named-lambda (lambda-body-procedures physical-body set-physical-body! receiver) (receiver (named-lambda (wrap-body! lambda transform) (let ((physical-body (physical-body lambda))) (if (wrapper? physical-body) (transform (wrapper-body physical-body) (wrapper-state physical-body) (lambda (new-body new-state) (set-wrapper-body! physical-body new-body) (set-wrapper-state! physical-body new-state))) (transform physical-body '() (lambda (new-body new-state) (set-physical-body! lambda (make-wrapper physical-body new-body new-state))))))) (named-lambda (wrapper-components lambda receiver) (let ((physical-body (physical-body lambda))) (if (wrapper? physical-body) (receiver (wrapper-original-body physical-body) (wrapper-state physical-body)) (receiver physical-body '())))) (named-lambda (unwrap-body! lambda) (let ((physical-body (physical-body lambda))) (if (wrapper? physical-body) (set-physical-body! lambda (wrapper-original-body physical-body))))) (named-lambda (unwrapped-body lambda) (let ((physical-body (physical-body lambda))) (if (wrapper? physical-body) (wrapper-original-body physical-body) physical-body))) (named-lambda (set-unwrapped-body! lambda new-body) (if (wrapper? (physical-body lambda)) (set-wrapper-original-body! (physical-body lambda) new-body) (set-physical-body! lambda new-body))) )) )) \f ;;;; Compound Lambda (define (make-clambda name required auxiliary body) (make-slambda name required (if (null? auxiliary) body (make-combination (make-slambda internal-lambda-tag auxiliary body) (mapcar (lambda (auxiliary) (make-unassigned-object)) auxiliary))))) (define (clambda-components clambda receiver) (slambda-components clambda (lambda (name required body) (let ((unwrapped-body (clambda-unwrapped-body clambda))) (if (combination? body) (let ((operator (combination-operator body))) (if (is-internal-lambda? operator) (slambda-components operator (lambda (tag auxiliary body) (receiver name required '() '() auxiliary unwrapped-body))) (receiver name required '() '() '() unwrapped-body))) (receiver name required '() '() '() unwrapped-body)))))) (define (clambda-bound clambda) (slambda-components clambda (lambda (name required body) (cons name (if (combination? body) (let ((operator (combination-operator body))) (if (is-internal-lambda? operator) (slambda-components operator (lambda (tag auxiliary body) (append required auxiliary))) required)) required))))) (define (clambda-has-internal-lambda? clambda) (let ((body (slambda-body clambda))) (conjunction (combination? body) (let ((operator (combination-operator body))) (conjunction (is-internal-lambda? operator) operator))))) (define clambda-wrap-body!) (define clambda-wrapper-components) (define clambda-unwrap-body!) (define clambda-unwrapped-body) (define set-clambda-unwrapped-body!) (lambda-body-procedures (lambda (clambda) (slambda-body (disjunction (clambda-has-internal-lambda? clambda) clambda))) (lambda (clambda new-body) (set-slambda-body! (disjunction (clambda-has-internal-lambda? clambda) clambda) new-body)) (lambda (wrap-body! wrapper-components unwrap-body! unwrapped-body set-unwrapped-body!) (set! clambda-wrap-body! wrap-body!) (set! clambda-wrapper-components wrapper-components) (set! clambda-unwrap-body! unwrap-body!) (set! clambda-unwrapped-body unwrapped-body) (set! set-clambda-unwrapped-body! set-unwrapped-body!))) \f ;;;; Compound Lexpr (define (make-clexpr name required rest auxiliary body) (make-slexpr name required (make-combination (make-slambda internal-lexpr-tag (cons rest auxiliary) body) (cons (let ((e (make-the-environment))) (make-combination system-subvector-to-list (list e (+ (length required) 3) (make-combination system-vector-size (list e))))) (mapcar (lambda (auxiliary) (make-unassigned-object)) auxiliary))))) (define (clexpr-components clexpr receiver) (slexpr-components clexpr (lambda (name required body) (slambda-components (combination-operator body) (lambda (tag auxiliary body) (receiver name required '() (car auxiliary) (cdr auxiliary) (clexpr-unwrapped-body clexpr))))))) (define (clexpr-bound clexpr) (slexpr-components clexpr (lambda (name required body) (slambda-components (combination-operator body) (lambda (tag auxiliary body) (cons name (append required auxiliary))))))) (define (clexpr-has-internal-lambda? clexpr) (combination-operator (slexpr-body clexpr))) (define clexpr-wrap-body!) (define clexpr-wrapper-components) (define clexpr-unwrap-body!) (define clexpr-unwrapped-body) (define set-clexpr-unwrapped-body!) (lambda-body-procedures (lambda (clexpr) (slambda-body (clexpr-has-internal-lambda? clexpr))) (lambda (clexpr new-body) (set-slambda-body! (clexpr-has-internal-lambda? clexpr) new-body)) (lambda (wrap-body! wrapper-components unwrap-body! unwrapped-body set-unwrapped-body!) (set! clexpr-wrap-body! wrap-body!) (set! clexpr-wrapper-components wrapper-components) (set! clexpr-unwrap-body! unwrap-body!) (set! clexpr-unwrapped-body unwrapped-body) (set! set-clexpr-unwrapped-body! set-unwrapped-body!))) \f ;;;; Extended Lambda (define (make-xlambda name required optional rest auxiliary body) (&typed-triple-cons xlambda-type body (list->vector `(,name ,@required ,@optional ,@(if (null? rest) auxiliary (cons rest auxiliary)))) (make-non-pointer-object (+ (length optional) (* 256 (+ (length required) (if (null? rest) 0 256))))))) (define (xlambda-components xlambda receiver) (let ((qr1 (integer-divide (primitive-datum (&triple-third xlambda)) 256))) (let ((qr2 (integer-divide (car qr1) 256))) (let ((ostart (1+ (cdr qr2)))) (let ((rstart (+ ostart (cdr qr1)))) (let ((astart (+ rstart (car qr2))) (bound (&triple-second xlambda))) (receiver (vector-ref bound 0) (subvector->list bound 1 ostart) (subvector->list bound ostart rstart) (if (zero? (car qr2)) '() (vector-ref bound rstart)) (subvector->list bound astart (vector-size bound)) (xlambda-unwrapped-body xlambda)))))))) (define (xlambda-bound xlambda) (vector->list (&triple-second xlambda))) (define (xlambda-has-internal-lambda? xlambda) #!FALSE) (define xlambda-wrap-body!) (define xlambda-wrapper-components) (define xlambda-unwrap-body!) (define xlambda-unwrapped-body) (define set-xlambda-unwrapped-body!) (lambda-body-procedures &triple-first &triple-set-first! (lambda (wrap-body! wrapper-components unwrap-body! unwrapped-body set-unwrapped-body!) (set! xlambda-wrap-body! wrap-body!) (set! xlambda-wrapper-components wrapper-components) (set! xlambda-unwrap-body! unwrap-body!) (set! xlambda-unwrapped-body unwrapped-body) (set! set-xlambda-unwrapped-body! set-unwrapped-body!))) \f (set! lambda? (named-lambda (lambda? object) (disjunction (primitive-type? slambda-type object) (primitive-type? slexpr-type object) (primitive-type? xlambda-type object)))) (define (is-internal-lambda? lambda) (conjunction (primitive-type? slambda-type lambda) (memq (slambda-name lambda) internal-lambda-tags))) (set! make-lambda (named-lambda (make-lambda name required optional rest auxiliary body) (cond ((conjunction (< (length required) 256) (< (length optional) 256) (disjunction (not (null? optional)) (not (null? rest)) (not (null? auxiliary)))) (make-xlambda name required optional rest auxiliary body)) ((not (null? optional)) (error "Optionals not implemented" 'MAKE-LAMBDA)) ((null? rest) (make-clambda name required auxiliary body)) (else (make-clexpr name required rest auxiliary body))))) \f (define ((dispatch-0 op-name clambda-op clexpr-op xlambda-op) lambda) ((cond ((primitive-type? slambda-type lambda) clambda-op) ((primitive-type? slexpr-type lambda) clexpr-op) ((primitive-type? xlambda-type lambda) xlambda-op) (else (error "Not a lambda" op-name lambda))) lambda)) (define ((dispatch-1 op-name clambda-op clexpr-op xlambda-op) lambda arg) ((cond ((primitive-type? slambda-type lambda) clambda-op) ((primitive-type? slexpr-type lambda) clexpr-op) ((primitive-type? xlambda-type lambda) xlambda-op) (else (error "Not a lambda" op-name lambda))) lambda arg)) (set! lambda-components (dispatch-1 'LAMBDA-COMPONENTS clambda-components clexpr-components xlambda-components)) (define has-internal-lambda? (dispatch-0 'HAS-INTERNAL-LAMBDA? clambda-has-internal-lambda? clexpr-has-internal-lambda? xlambda-has-internal-lambda?)) (define lambda-wrap-body! (dispatch-1 'LAMBDA-WRAP-BODY! clambda-wrap-body! clexpr-wrap-body! xlambda-wrap-body!)) (define lambda-wrapper-components (dispatch-1 'LAMBDA-WRAPPER-COMPONENTS clambda-wrapper-components clexpr-wrapper-components xlambda-wrapper-components)) (define lambda-unwrap-body! (dispatch-0 'LAMBDA-UNWRAP-BODY! clambda-unwrap-body! clexpr-unwrap-body! xlambda-unwrap-body!)) (set! lambda-body (dispatch-0 'LAMBDA-BODY clambda-unwrapped-body clexpr-unwrapped-body xlambda-unwrapped-body)) (set! set-lambda-body! (dispatch-1 'SET-LAMBDA-BODY! set-clambda-unwrapped-body! set-clexpr-unwrapped-body! set-xlambda-unwrapped-body!)) (set! lambda-bound (dispatch-0 'LAMBDA-BOUND clambda-bound clexpr-bound xlambda-bound)) \f ;;;; Simple Lambda/Lexpr (define (make-slambda name required body) (&typed-pair-cons slambda-type body (list->vector (cons name required)))) (define (slambda-components slambda receiver) (let ((bound (&pair-cdr slambda))) (receiver (vector-ref bound 0) (subvector->list bound 1 (vector-size bound)) (&pair-car slambda)))) (define (slambda-name slambda) (vector-ref (&pair-cdr slambda) 0)) (define slambda-body &pair-car) (define set-slambda-body! &pair-set-car!) (define (make-slexpr name required body) (&typed-pair-cons slexpr-type body (list->vector (cons name required)))) (define slexpr-components slambda-components) (define slexpr-body slambda-body) ;;; end LAMBDA-PACKAGE. ))