[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Implementing it as a procedure

This page is part of the web mail archives of SRFI 26 from before July 7th, 2015. The new archives for SRFI 26 contain all messages, not just those from before July 7th, 2015.



Hello list,

I just realised that, with a small modification,
curry-which-isnt-curry can be written as an ordinary
procedure instead of a macro. The only problem is that
ordinary procedures cannot handle improper lists.

This could be fixed by introducing a special marker for
"the rest", e.g. <...>.

Then we get the following code:

  (define <> (list "Marker 1"))
  (define <...> (list "Marker 2"))

  (define (curry-which-isnt-curry proc . params)
    (define (substitute-params params args)
      (cond
	((null? params)
	 (if (null? args)
	     '()
	     (error "Trailing arguments" args)))
	((eq? (car params) <...>)
	  (if (null? (cdr params))
	      args
	      (error "Parameters after <...>" (cdr params))))
	((eq? (car params) <>)
	 (if (null? args)
	     (error "Too few arguments")
	     (cons (car args)
		   (substitute-params (cdr params) (cdr args)))))
	(else
	 (cons
	  (car params)
	  (substitute-params (cdr params) args)))))
    (lambda args
      (apply proc (substitute-params params args))))
      
  (define example1 (curry-which-isnt-curry list 1 <> 2 3))
  (define example2 (curry-which-isnt-curry vector <> 'b <...>)) 

This gives then:

(example1 'foo) ==> (1 foo 2 3)
(example2 'foo 'bar 'baz) ==> #(foo b bar baz)

So the advantage of using <...> (or something else) as a marker
is that then this form can be implemented as a procedure.
Don't know if that is considered important, but I think
I should just note it.

Stephan