3

私は計画で持っていたアイデアをめぐって数日間苦労してきました。私はよく次のスタイルでコードを書いています

(define fib_h (lambda (n a b) <body ...>))
(define fib (lambda (n) (fib_h n 0 1)))

そして、マクロを紹介するのにいい方法だと思いました。残念ながら、これをマクロ化する方法については、私を少し超えているようです。ある時点で近づいたと思います

(define-syntax dvf
  (syntax-rules ()
    ((_ f (args ...) (name value) ... body)
      <stuff that didn't work>)))

これは、「args...」または「args... name ...」のいずれかをとる関数「f」を定義し、「args ...」だけをとる場合は、「value...」を適用します。 「名前...」引数に。私はそれを行うための2つの良い方法を考えることができます。最初のものはYコンビネータを必要とします、そして私は本当にそれらと一緒に働きたくありません。他の方法では、「name...」と「args...」の変数の数を取得する必要があります。誰かがこれを手伝ってくれるなら、私はそれをいただければ幸いです。

4

2 に答える 2

1

私は要点を見逃しているかもしれませんが、これはSchemeの組み込みのデフォルト引数が機能するのとまったく同じではありません。

(define f1
  (lambda (n (a 0) (b 1))
    (printf "n:~a  b:~a  b:~a\n" n a b)))

(f1 10)
(f1 10 0 1)
(f1 10 8 3)

収量

n:10  b:0  b:1
n:10  b:0  b:1
n:10  b:8  b:3
于 2012-11-19T18:16:46.430 に答える
1

SRFI-16case-lambdaで説明されている構文を探している可能性があります。そこに与えられた実装は次のとおりです。

(define-syntax case-lambda
  (syntax-rules ()
    ((case-lambda)
     (lambda args
       (error "CASE-LAMBDA without any clauses.")))
    ((case-lambda 
      (?a1 ?e1 ...) 
      ?clause1 ...)
     (lambda args
       (let ((l (length args)))
         (case-lambda "CLAUSE" args l 
           (?a1 ?e1 ...)
           ?clause1 ...))))
    ((case-lambda "CLAUSE" ?args ?l 
      ((?a1 ...) ?e1 ...) 
      ?clause1 ...)
     (if (= ?l (length '(?a1 ...)))
         (apply (lambda (?a1 ...) ?e1 ...) ?args)
         (case-lambda "CLAUSE" ?args ?l 
           ?clause1 ...)))
    ((case-lambda "CLAUSE" ?args ?l
      ((?a1 . ?ar) ?e1 ...) 
      ?clause1 ...)
     (case-lambda "IMPROPER" ?args ?l 1 (?a1 . ?ar) (?ar ?e1 ...) 
       ?clause1 ...))
    ((case-lambda "CLAUSE" ?args ?l 
      (?a1 ?e1 ...)
      ?clause1 ...)
     (let ((?a1 ?args))
       ?e1 ...))
    ((case-lambda "CLAUSE" ?args ?l)
     (error "Wrong number of arguments to CASE-LAMBDA."))
    ((case-lambda "IMPROPER" ?args ?l ?k ?al ((?a1 . ?ar) ?e1 ...)
      ?clause1 ...)
     (case-lambda "IMPROPER" ?args ?l (+ ?k 1) ?al (?ar ?e1 ...) 
      ?clause1 ...))
    ((case-lambda "IMPROPER" ?args ?l ?k ?al (?ar ?e1 ...) 
      ?clause1 ...)
     (if (>= ?l ?k)
         (apply (lambda ?al ?e1 ...) ?args)
         (case-lambda "CLAUSE" ?args ?l 
           ?clause1 ...)))))
于 2012-11-19T21:53:33.063 に答える