5
54
Fork
You've already forked blue
4

Alpha canonicalization for lambda#. #4

Open
opened 2025年04月30日 04:27:57 +02:00 by old · 0 comments
Owner
Copy link

lambda# could be improved by doing alpha canonicalization on the formals and body. This would make identical procedures have the same hash even if their formals have different names.

Here is a minimal implementation (not supporting lambda*, let* and letrec):

(define-syntax alpha-canonicalization
 (lambda (stx)
 (define (make-environment bindings parent)
 (append bindings parent))
 (define (lookup-environment name environment)
 (assq-ref environment name))
 (define (make-identifier-counter)
 (let ((counter 0))
 (lambda _
 (let ((value counter))
 (set! counter (1+ value))
 (datum->syntax #f (string->symbol (format #f "blue-~a" value)))))))
 (syntax-case stx ()
 ((_ form)
 (let ((formal-generator (make-identifier-counter)))
 (let loop ((expression #'form)
 (environment '()))
 (syntax-case expression (lambda lambda* let let*)
 ((lambda (formals ...) body body* ...)
 (with-syntax (((new-formals ...) (map formal-generator #'(formals ...))))
 (let ((new-environment
 (make-environment (map (lambda (old-formal new-formal)
 (cons (syntax->datum old-formal)
 new-formal))
 #'(formals ...)
 #'(new-formals ...))
 environment)))
 #`(lambda (new-formals ...)
 #,@(map (lambda (expr)
 (loop expr new-environment))
 #'(body body* ...))))))
 ((let ((bindings values) ...) body body* ...)
 (with-syntax (((new-bindings ...) (map (lambda (bindin value)
 (list (formal-generator) value))
 #'(bindings ...)
 #'(values ...))))
 (let ((new-environment
 (make-environment (map (lambda (old-binding new-binding)
 (cons (syntax->datum old-binding)
 new-binding))
 #'(bindings ...)
 #'(new-bindings ...))
 environment)))
 #`(let (new-bindings ...)
 #,@(map (lambda (expr)
 (loop expr new-environment))
 #'(body body* ...))))))
 ((head rest ...)
 (map (lambda (expr)
 (loop expr environment))
 (cons #'head #'(rest ...))))
 (identifier
 (or (lookup-environment (syntax->datum #'identifier) environment)
 #'identifier)))))))))
`lambda#` could be improved by doing alpha canonicalization on the formals and body. This would make identical procedures have the same hash even if their formals have different names. Here is a minimal implementation (not supporting `lambda*`, `let*` and `letrec`): ```scheme (define-syntax alpha-canonicalization (lambda (stx) (define (make-environment bindings parent) (append bindings parent)) (define (lookup-environment name environment) (assq-ref environment name)) (define (make-identifier-counter) (let ((counter 0)) (lambda _ (let ((value counter)) (set! counter (1+ value)) (datum->syntax #f (string->symbol (format #f "blue-~a" value))))))) (syntax-case stx () ((_ form) (let ((formal-generator (make-identifier-counter))) (let loop ((expression #'form) (environment '())) (syntax-case expression (lambda lambda* let let*) ((lambda (formals ...) body body* ...) (with-syntax (((new-formals ...) (map formal-generator #'(formals ...)))) (let ((new-environment (make-environment (map (lambda (old-formal new-formal) (cons (syntax->datum old-formal) new-formal)) #'(formals ...) #'(new-formals ...)) environment))) #`(lambda (new-formals ...) #,@(map (lambda (expr) (loop expr new-environment)) #'(body body* ...)))))) ((let ((bindings values) ...) body body* ...) (with-syntax (((new-bindings ...) (map (lambda (bindin value) (list (formal-generator) value)) #'(bindings ...) #'(values ...)))) (let ((new-environment (make-environment (map (lambda (old-binding new-binding) (cons (syntax->datum old-binding) new-binding)) #'(bindings ...) #'(new-bindings ...)) environment))) #`(let (new-bindings ...) #,@(map (lambda (expr) (loop expr new-environment)) #'(body body* ...)))))) ((head rest ...) (map (lambda (expr) (loop expr environment)) (cons #'head #'(rest ...)))) (identifier (or (lookup-environment (syntax->datum #'identifier) environment) #'identifier))))))))) ```
old added this to the Backlog project 2025年05月31日 14:45:48 +02:00
Sign in to join this conversation.
No Branch/Tag specified
main
pipeline-operators
documentation
shadow-fields
instance-walker
blue-shell
promote-serializers-to-metacommands
pre-alpha
Labels
Clear labels
bug
Something is not working
contribution welcome
Contributions are very welcome, get started here
discussion
duplicate
This issue or pull request already exists
enhancement
New feature
good first issue
Interested in contributing? Get started here.
help wanted
Need some help
invalid
Something is wrong
optimization
question
More information is needed
upstream
Related to an upstream repository, already reported there
bug
Something is not working
contribution welcome
Contributions are very welcome, get started here
duplicate
This issue or pull request already exists
enhancement
New feature
good first issue
Interested in contributing? Get started here.
help wanted
Need some help
invalid
Something is wrong
question
More information is needed
upstream
Related to an upstream repository, already reported there
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lapislazuli/blue#4
Reference in a new issue
lapislazuli/blue
No description provided.
Delete branch "%!s()"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?