#!/usr/bin/env racket #lang racket (require compatibility/defmacro)
napište makro slambda, které se bude chovat identicky jako speciální forma lambda v jazyku Scheme, ale navíc umožní ve svém těle získat kód sebe sama prostřednictvím vazby symbolu self.
((slambda () 10)) ;=> 10 ((slambda (x) (+ x 1)) 10) ;=> 11 ((slambda () self)) ;=> (slambda () self) ((slambda (x) (list (+ x 1) self)) 10) ;=> ??? ((slambda () (slambda () self) self)) ;=> (slambda () (slambda () self) self)
(define-macro slambda1 (lambda (args body) `(letrec ((self (lambda ,args ,body))) self ))) ((slambda1 () 10)) ((slambda1 (x) (+ x 1)) 10) ((slambda1 () self)) ;=> (slambda () self) resp #<procedure:self> ((slambda1 (x) (list (+ x 1) self)) 10) ;=> '(1 #<procedure:self> ???
vyssi rad?
;((slambda1 () (slambda1 () self) self)) ;=> (slambda () (slambda () self) self)
http://stackoverflow.com/questions/23167464/scheme-self-reference-lambda-macro, uživatel poody je student UPOL
rec definujeme si sami, mohli bychom (require srfi/31)
(define-syntax rec (syntax-rules () ((_ (id . params) body ...) (rec id (lambda params body ...))) ((_ id value) (letrec ((id value)) id)))) (require racket/stxparam) (define-syntax-parameter self (lambda (stx) (raise-syntax-error 'self "Can only be used inside slambda"))) (define-syntax slambda (syntax-rules () ((_ params body ...) (rec (ohai . params) (syntax-parameterize ((self (make-rename-transformer #'ohai))) body ...))))) ((slambda () 10)) ((slambda (x) (+ x 1)) 10) ((slambda () self)) ;=> (slambda () self) resp #<procedure:ohai ? ((slambda (x) (list (+ x 1) self)) 10) ;=> '(1 #<procedure:ohai ???
vyssi rad?
((slambda () (slambda () self) self)) ;=> (slambda () (slambda () self) self)
Hmm, “kod sebe sama” ??? nebo odkazovat na sebe?
(define-macro selambda (lambda (args body) `(letrec ((self (list 'selambda ',args ',body))) ;"kod sebe sama" (lambda ,args ,body) ))) ((selambda () 10)) ((selambda (x) (+ x 1)) 10) ((selambda () self)) ;=> (selambda () self) nebo #<procedure:xxx> ??? ((selambda (x) (list (+ x 1) self)) 10) ;=> jaky ma byt vysledek???
nasl je podivne:
;((selambda () (selambda () self) self)) ;=> (slambda () (slambda () self) self) ;^^^^^__ spravne zadani?
další? linky/zdroje:
vim: syntax=racket