[racket] Traits and private data

From: Markku Rontu (markku.rontu at iki.fi)
Date: Wed Dec 29 12:23:24 EST 2010

Hello everybody,

I have a question about Racket traits. I was going to implement a trait
that supplies some methods but also contains data. Looks like I'm out of
luck if I don't want the data exposed as a field, but want it to be
private to the trait, and only accessible through the exposed methods.
Let's say a I have a simple trait like this:

---

#lang racket

(require racket/trait)

(define counted-trait
  (trait
   (field (counter 0))
   
   (define/public (add!)
     (set! counter (add1 counter)))
   
   (define/public (current-count)
     counter)))

(define counted-mixin
  (trait->mixin counted-trait))

(define my-class%
  (counted-mixin
   (class object%
     (super-new))))

(define m (new my-class%))

(send m add!)
(send m add!)
(send m add!)

; returns 3 as expected
(send m current-count)

; leaks potentially private information
(get-field counter m)

---

Now what would be closer to my wishes is something like this where the
counter is protected and not exposed.

---

(define protected-counted-trait
  (trait
   (define counter 0)
   
   (define/public (add!)
     (set! counter (add1 counter)))
   
   (define/public (current-count)
     counter)))

---

This however is not possible as far as I know. There is a hint to some
solution in the Racket Reference 5.6 Traits:

"External identifiers in trait, trait-exclude, trait-exclude-field,
trait-alias, trait-rename, and trait-rename-field forms are subject to
binding via define-member-name and define-local-member-name. Although
private methods or fields are not allowed in a trait form, they can be
simulated by using a public or field declaration and a name whose scope
is limited to the trait form."

It is unclear to me still what this exactly means. I would have thought
there must be a convenient mechanism to have some "private-field" or
other solution. Or have I missed it?

Thanks,
-Markku



Posted on the users mailing list.