views:

148

answers:

1

I would like code like this:

(define-struct thing (a b c))
(define th (make-thing 1 2 3))

to print something like this:

(make-thing 1 2 3)

when I type "th" into either the DrScheme or MzScheme repl. I am using the language "pretty big" in DrScheme with output style set to "constructor". This is what I get in DrScheme:

(make-thing ...)

(i literally get the three dots)

In MzScheme:

#<thing>
+2  A: 

There are several ways to do that. The most obvious one is to use:

(define-struct thing (a b c) #:transparent)

which makes the struct accessible for the kind of low-level inspection that the printout does. Another alternative is to use your own printer:

(define-struct thing (a b c)
  #:property prop:custom-write
  (lambda (thing port write?)
    (fprintf port (if write? "{~s,~s,~s}" "{~a,~a,~a}")
             (thing-a thing) (thing-b thing) (thing-c thing))))

But note that the "constructor" output style tries to write some things differently. Also note that you could combine both of these to make it have its own writer as well as being transparent. (Making it transparent is basically making it possible for any code to access the fields in a thing instance, for example, equal? can dig into it.)

Finally, for some uses a more fitting facility is to use "prefab" structs:

(define-struct thing (a b c) #:prefab)

What usually happens is that each define-struct generates a new type, even if one was already defined. But with a prefab struct it's as if there is one type that pre-exists and you're just binding some functions (the constructor, predicate, and accessors) to work with this preexisting type.

Eli Barzilay