Eino Gourdin
Eino Gourdin

Reputation: 4507

Overloading a struct constructor

Is there a way to overload the constructor for a struct in Racket, so I can make the inherited parameters optional ?

In my case, I want to define some custom exceptions for my app. For example :

(struct exn:my-app exn ())
(struct exn:my-app:illegal-access exn:my-app ())

However, to instantiate an illegal-access exception, I have to call the constructor with the 2 arguments inherited from exn (message and continuation-marks), which is quite cumbersome.

Is it possible to define (for exn:my-app and all its descendants) a constructor, which could make both parameters optional ? So I could call either :

(raise (exn:my-app:illegal-access))
(raise (exn:my-app:illegal-access "Message")) ?

Thanks,

Upvotes: 2

Views: 606

Answers (1)

Asumu Takikawa
Asumu Takikawa

Reputation: 8523

Here's one way to do it:

(struct exn:my-app exn ()
        ;; change the name of the constructor
        #:constructor-name make-exn:my-app)

;; custom constructor
(define (exn:my-app [msg "default msg"]
                    [marks (current-continuation-marks)])
  (make-exn:my-app msg marks))

(exn:my-app) ; this works now

Since you need to do this for each structure type, you may want to define a macro that abstracts over this. I bet someone has already shared such a macro on the Racket mailing list, but I don't recall one off the top of my head so I'll update this answer if I find a reference.

Upvotes: 4

Related Questions