# I'm confused by the documentation for Classes and Objects

**URL:** <https://racket.discourse.group/t/im-confused-by-the-documentation-for-classes-and-objects/4103>\
**Category:** Questions & Answers\
**Tags:** question, class\
**Created:** [February 6, 2026, 12:24am UTC](https://racket.discourse.group/t/im-confused-by-the-documentation-for-classes-and-objects/4103 "2026-02-06T00:24:16Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![MickeyKnox](https://avatars.discourse-cdn.com/v4/letter/m/a4c791/32.png) [@MickeyKnox](https://racket.discourse.group/u/MickeyKnox)\
**Post date:** [February 6, 2026, 12:24am UTC](https://racket.discourse.group/t/im-confused-by-the-documentation-for-classes-and-objects/4103/1 "2026-02-06T00:24:16Z")

</div>

The documentation in the [guide](https://docs.racket-lang.org/guide/classes.html) looks relatively straight forward: methods are defined with `define/public`, for example.

However, when I started to read the documentation in the [reference](https://docs.racket-lang.org/reference/createclass.html), things started falling apart for me. It's almost as if two different things are documented here. For example, there is no `define/public` class-clause in class. There is however a `public` clause.

But when I try to define a method only with `public`, I get an error:

```
class: -public element is not an identifier or pair of identifiers

```

Thus `define/public` and `public` is not the same. There is virtually no explanation of what `public` actually does. Just a code example that I didn't understand. Why exactly does the method call for jump return 'hop?

It seems that the public clause somehow introduces the method jump. But how exactly?

And why is `define/public` not among the class-clauses?

---

<div class="post-metadata">

**Author:** ![ryanc](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/ryanc/32/71_2.png) [@ryanc](https://racket.discourse.group/u/ryanc)\
**Post date:** [February 6, 2026, 2:26am UTC](https://racket.discourse.group/t/im-confused-by-the-documentation-for-classes-and-objects/4103/2 "2026-02-06T02:26:44Z")

</div>

The `define/public` form is a macro that expands into both `public` declaration and a definition. The `public` form is the "primitive" that tells the `class` macro which definitions to interpret as methods vs private fields. So when you write

```
(define counter%
  (class object%
    (super-new)
    (define n 0)
    (define/public (click)
      (set! n (add1 n))
      n)))

```

the `class` macro first shallowly expands the class body (using `local-expand`) to the following (roughly):

```
(define counter%
  (class object%
    (super-new)
    (define-values (n) 0)
    (public click)
    (define-values (click)
      (lambda ()
        (set! n (add1 n))
        n))))

```

Now it fits the grammar from the Reference. The `(public click)` declaration says to interpret the definition of the identifier `click` as a method definition. The class macro checks that its right-hand side satisfies the restrictions on methods, rearranges the method code to add the implicit `this` argument, and arranges for the method to be part of the class (the "vtable") rather than taking up space in each object. Since there isn't any `public` (or `private`, etc) declaration for `n`, its definition is treated as a private field.

The advantage of designing the `class` form this way is that you can use other Racket macros to define fields and methods, since private field definitions are just ordinary Racket definitions and method definitions are just ordinary Racket definitions plus a declaration. Here's a little toy example about a Point class that uses `racket/match` definition forms:

```
(define point%
  (class object%
    ;; Init args:
    ;; - xy : (list Real Real)
    ;; Fields:
    ;; - x, y : Real
    ;; Methods:
    ;; - move! : (list Real Real) -> (list Real Real)
    (super-new)
    (init xy)
    (match-define (list x y) xy)
    (public move!)
    (define/match (move! dxy)
      [[(list dx dy)]
       (set! x (+ x dx))
       (set! y (+ y dy))
       (list x y)])))

(define p (new point% (xy (list 1 2))))
(send p move! (list 5 6))
;; => '(6 8)

```
