How to document functions that aren't defined (yet) but will be by a user?

This image shows a problem I have in the documentation for Scribble in the overview section.

The blue links are correct, they link to the documentation entries for mouse-x, mouse-y etc.
The problem is the black non-links on-mouse-dragged, etc.

The entries for these identifiers are written and appear with working links in the in left side menu.

The problem is to link from the name "on-mouse-dragged" to the documentation entry.

Here is how the entries in the overview section looks like in Scribble:

   (CRow "Events"
         @elem{@racket[on-mouse-dragged]
               @racket[on-mouse-moved] @LB
               @racket[on-mouse-pressed]
               @racket[on-mouse-released]})

This looks fine, racket normally takes care of everything automatically.
In this case the problem is that the identifier on-mouse-dragged is not yet defined.
It will eventually be defined by a user of the #lang sketching language.

#lang sketching
(define (on-mouse-dragged) (displayln "dragged"))

The event loop run by the Sketching backend then calls the user defined function, when the mouse is dragged.

The problem is that (from the perspective of Scribble) the function on-mouse-dragged isn't defined
anywhere.

What is the intended way of documenting functions that aren't defined (yet) but will be by a user?

2 Likes

I think that's fundamentally not how to approach documenting these kinds of functions. You have an interface and you want users to define the implementation, but the interface isn't bound to anything. An alternative would be to wrap those functions in a struct or object of some kind and have an API that takes the object as an input, like this:

(struct mouse-handler (drag-handler move-handler press-handler release-handler))

(define (make-mouse-handler #:on-drag drag-handler
                            #:on-move move-handler
                            #:on-press press-handler
                            #:on-release release-handler)
  (mouse-handler drag-handler move-handler press-handler release-handler))

(define (on-mouse-dragged handler arg ..)
  ((mouse-handler-drag-handler handler) arg ...))

(define (on-mouse-moved handler arg ..)
  ((mouse-handler-move-handler handler) arg ...))

(define (on-mouse-pressed handler arg ..)
  ((mouse-handler-press-handler handler) arg ...))

(define (on-mouse-released handler arg ..)
  ((mouse-handler-release-handler handler) arg ...))

Now you can document the generic on-mouse-dragged / on-mouse-moved / etc. functions because they're bound to the API definition, while users can implement the handler functions themselves and pass them to make-mouse-handler. You could make #lang sketching get rid of some of the boilerplate for users if you wanted to as well.

4 Likes

I believe you can do something similar to the start function in the web-server documentation.

This consists of:

  1. create a fake binding in a file. E.g.
;; dummy-bindings.rkt
#lang racket/base
(provide start)
(define start #f)

  1. (require (for-label module-path-to/scribblings/dummy-bindings))
  2. @declare-exporting[#:use-sources (module-path-to/scribblings/dummy-bindings)]
  3. @defproc[(start ...) ...]
6 Likes

Hi @notjack

In principle I agree with you - and would do it your way in other projects than Sketching.

With Sketching I am following the lead of Processing - and I'd like it to be trivial
to port a Processing program in Sketching. Mainly due the large amount of tutorials
available for Processing.

1 Like

Thanks @sorawee .

After a little experimentation I got this approach to work.

If others are following this route: remember to place the call to declare-exporting in the section that documents the binding.

1 Like