kinghajj wrote:Basically, when you "call" a function without supplying it every argument, it returns a curried function that expects the takes the next arguments.
You have underspecified the wanted behavior: if you call a function
with supplying it every argument, do you want just to call it, or to return a null-ary function with can be called later? If second, than it can be easy done for any function:
Code: Select all
(define (make-curry2 f)
(letex (F f)
(lambda ()
(letex (A (args))
(lambda ()
(apply F (append 'A (args))))))))
> (setq add-nums2 (make-curry2 +))
> ((add-nums2 10 20) 30 40)
100
If first, then you must define what the the words "
every argument" mean. Remember that function may be called with fewer or more arguments, and, say, there are no "right" number of arguments for built-in function "+". If we limit ourself with user-defined (not built-in) functions, and declare that "right" number of arguments is number of arguments explicitly written in its definition, then the following works:
Code: Select all
(define (make-curry1 f)
(letex (F f)
(lambda ()
(if (< (length (args)) (length ((0 F) 0)))
(letex (A (args))
(lambda ()
(apply F (append 'A (args)))))
(apply F (args))))))
> (define (add-nums a b) (+ a b))
> (setq add-nums1 (make-curry1 add-nums))
> ((add-nums1 10) 20)
30
> (add-nums1 10 20)
30
Note: edited 9:10 am Moscow time. Has contained nasty bug before: wrong
(0 F) instead of right
((0 F) 0). Sorry if you have read this before fix.
Note that this
not work with "+" instead of "add-nums". And then think, why authors of Ocaml took so long time to introduce the concept of "default value of an argument" in their language (this feature appears in Ocaml 3.0 only). The task of joining default values
and default curring in a single language is not an easy one. Whichever you implement first, the second will be a difficult quest. Most languages (including newlisp) have had default values first, Ocaml have had curring first.