[racket] Some struct questions

From: Ryan Culpepper (ryan at cs.utah.edu)
Date: Mon Jul 16 14:14:18 EDT 2012

On 07/16/2012 12:39 PM, Harry Spier wrote:
> I should have been a little clearer with my question.  I understand
> that its not a good idea to expose the setters and getters of a struct
> unnecessarily.  What I meant was:
> (provide struct-id)  exposes the struct constructor
> (provide (struct-out struct-id)) exposes the constructor and the field
> getters and setters
> I'm not clear the use of the first form.  I.e. of what use is having
> access to the constructor without access to the field getters and
> setters.  So thats why I asked if there are any cases where (provide
> struct-id) would be of use.  If the answer is no, then why not just
> have (provide struct-id) expose the constructor and the field getters
> and setters.

(provide id) always just provides 'id'. We've chosen to use other 
subforms, like struct-out, for other behavior. Making struct-name 
identifiers work specially in provide forms would be more complicated 
and (IMO) less readable.


> Another question about provide provide-specs, since almost all
> provide-specs allow multiple provide-specs as arguments where would
> the form (provide (combine-all x x x x)) be useful.
> Thanks,
> Harry Spier
>> About question 2, in general you don't want to expose the details of
>> your structures. For example, when defining a queue like:
>> (struct queue ([front #:mutable] [rear #:mutable]))
>> you don't want users to set/get the fields directly; instead you
>> probably want them to use the `enqueue'/`dequeue' functions, which
>> maintain the abstraction invariants, assuring the queue is consistent
>> no matter what the users do. In general, I believe it is better not to
>> provide the setters (unless it really makes sense, of course).
>> PS: Sorry for the duplicate Harry, I forgot to put
>> users at racket-lang.org in CC in my original response.
>> 2012/7/15 Harry Spier<vasishtha.spier at gmail.com>:
>>> 1) In section 8 of the Racket reference there is this example:
>>> -------------------------------------------
>>> Examples:
>>> (define-struct tree (val left right))
>>>> (match (make-tree 0 (make-tree 1 #f #f) #f)
>>>      [(tree a (tree b  _ _) _) (list a b)])
>>> '(0 1)
>>> ----------------------------------
>>> but I wasn't able to find any reference in the documentation to a
>>> constructor form make-struct-id .  I'm assuming that in the above example
>>> (match (make-tree 0 (make-tree 1 #f #f) #f)
>>>   is equivalent to
>>> (match (tree 0 (tree 1 #f #f) #f)
>>> Is that correct? Is make-struct-id  a deprecated form of the constructor
>>> procedure struct-id?
>>> 2) In a module which contains a structure, lets call it  "structure-a" I can
>>> have the statement:
>>> (provide (struct-out structure-a))
>>> which provides the constructor procedure and the getters and setters to
>>> structure-a
>>> but I can also have the statement
>>> (provide structure-a)
>>> which only provides the constructor function.
>>> Are there any cases where you would want to have (provide structure-a)
>>> rather than (provide (struct-out structure-a)) ?
>>> Thanks,
>>> Harry Spier
>>> ____________________
>>>    Racket Users list:
>>>    http://lists.racket-lang.org/users
> ____________________
>    Racket Users list:
>    http://lists.racket-lang.org/users

Posted on the users mailing list.