[racket] naming structs that are members of other structs

From: Stephen Bloch (bloch at adelphi.edu)
Date: Wed Feb 13 13:36:21 EST 2013

On Feb 13, 2013, at 12:47 PM, Dmitry Pavlov <dpavlov at ipa.nw.ru> wrote:

> Hello,
> I just figured that there is a thing in Racket coding style
> that bothers me from time to time. That thing have never arised
> in C-style languages.

Right: in C-style languages there's a special "dot" syntax for getting at the fields of a struct object.  If C++ allowed variable names to contain periods, you could get an analogous ambiguity:

class posn { int x; int y;
		      posn(int xval, int yval) : x(xval), y(yval) {}

posn here(3,4);

int here.x = 5;

printf ("%d", here.x); // is the correct answer 3, referring to a field of the "here" object, or 5, referring to the int variable named "here.x"?

Which is why C-family languages don't allow periods to appear in a variable name.

> Say I want to have a "vehicle" struct. Also, I would like to keep
> its physical state in a separate structure. It seems natural
> to call it "vehicle-state". Also it seems natural to have a
> "state" member in the "vehicle" structure which refers to that
> separate structure. Here we go:
> (struct vehicle-state
>  (position velocity))
> (struct vehicle (state color model))
> module: duplicate definition for identifier in: vehicle-state

Yes, that's the price you pay for the convenience of having getters defined automatically.  You can drop that convenience by using :omit-define-values or make-struct-type, but then you lose the convenience for ALL your fields.  Or you could do something like

(struct vehicle-state (position velocity) #:constructor-name make-vs)
(struct vehicle (state color model))

which avoids the conflict.

Or, as you suggest, you could just name structs and their fields so that no struct's name is another struct's name, a hyphen and one of the latter's fields.

Posted on the users mailing list.