[ prog / sol / mona ]

prog


Scheme has no currying

1 2020-10-31 05:51

https://docs.racket-lang.org/srfi/srfi-std/srfi-26.html
Does currying provide anything useful at all?

2 2020-10-31 08:03 *

currying happens to be very good with rice. lamb and chicken, too.

3 2020-10-31 08:36

Curring's necessarily a part of languages where every function takes a single argument. Like Haskell (Curry). The SRFI-26 style currying is different. To get real currying, you need a define or lambda form that adds extra lambdas for every argument in your formals list. I used SRFI-26 cut/cute when it was new and it helped me in one way, namely that it (mentally) lowered the bar to writing code with filter, map, folds, etc. That might be a disaster for performance sometimes, but let's write code that way and put pressure on compilers to get better at optimizing it instead! Rise up against the imperative tyranny, demand your sufficiently clever compiler! But really, SRFI-26 does not let you do anything you could not do before.

In summary, it's kind of meh. Chicken curry is good though (recommended).

4 2020-10-31 09:04

>>1 does the language have to do it for you for it to be currying? I thought currying was just storing a partial call and you can do that by returning a closure.

5 2020-10-31 11:37

>>4
Currying actually refers to the transformation, where a function that takes multiple arguments is transformed into a series of functions that take only one argument and return the next function. It's pretty easy to do it by hand and if you have some way to figure out the arguments a procedure takes (SRFI 102, maybe?), you can do it automatically.

Here's a pretty ugly currying implementation for Guile that only works on functions that take at least one required argument and ignores optional arguments (including rest, I honestly have no idea how these could be handled):

(define (curry f)
  (let ((nargs (length (assoc-ref (procedure-arguments f) 'required))))
    ((let loop ((n nargs))
       (cond
        ((zero? n)
         (lambda (args)
           (apply f args)))
        (else
         (lambda (args)
           (lambda (v)
             ((loop (- n 1)) (append args (list v))))))))
     '())))

If you want to do it compile time, it's even easier (and actually portable!):

(define-syntax lambda-curry
  (syntax-rules ()
    ((_ () body body* ...)
     (begin body body* ...))
    ((_ (param params ...) body ...)
     (lambda (param) (lambda-curry (params ...) body ...)))))

;; Example: curried definition of map
(define curry-map
  (lambda-curry (f l)
    (cond
     ((null? l) l)
     (else (cons (f (car l)) ((curry-map f) (cdr l)))))))
6


VIP:

do not edit these