slambda.scm

#!/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)
  • Hmm, k čemu se self dá využít? jako rec?
  • Hmm, kod sebe sama ??? nebo odkazovat na sebe?

define-macro a letrec

(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

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)

kod sebe sama

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

PAPR2/slambda.scm.txt · Last modified: 2014/04/24 01:53 (external edit)
CC Attribution-Noncommercial-Share Alike 4.0 International
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0