[racket] prop:procedure and arity

From: Alexander D. Knauth (alexander at knauth.org)
Date: Mon Feb 9 20:07:10 EST 2015

On Feb 9, 2015, at 7:46 PM, Matthew Flatt <mflatt at cs.utah.edu> wrote:

> At Mon, 9 Feb 2015 19:36:56 -0500, "Alexander D. Knauth" wrote:
>> Say I want a struct that will act as a procedure.
>> For a given instance of that struct, I want the procedure to have a given 
>> arity, but I don’t want the procedure to be a field in the struct.
>> Is there a way to do this without making the procedure a field?
> 
> I think there's no way to do that, assuming that you want a single
> constructor that answers #t to `struct-constructor-procedure?`.
> 
> If you get to substitute a function for the constructor, then you could
> make that function use `procedure-reduce-arity` on each raw instance,


> or you could generate a structure subtype for each arity and
> instantiate a subtype based on field values.

Ok sorry I missed this the first time I read this.
This works fine, thanks!
#lang racket
(require rackunit)
(struct my-f (lst) #:transparent)
(define (make-my-f lst #:name [name 'my-f])
  (struct my-f2 my-f () #:transparent
    #:property prop:procedure
    (procedure-reduce-arity
     (procedure-rename
      (lambda (this . args)
        (apply-my-f this args))
      name)
     (add1 (length lst))))
  (my-f2 lst))
(define (apply-my-f my-f args)
  (define lst (my-f-lst my-f))
  (unless (= (length args) (length lst))
    (error 'my-f "wrong number of arguments, expected ~v, recieved ~v" (length lst) args))
  (for/sum ([x (in-list args)]
            [a (in-list lst)])
    (* a x)))
(define f (make-my-f '(1 2 3)))
(check-pred my-f? f)
(check-equal? (procedure-arity f) 3)
(check-equal? (f 3 2 1) 10)



Posted on the users mailing list.