> 1) At least one of the fields must be set at creation

What does it mean for one of the fields not to be set at creation? Is there
implicitly some not-initialized value like #f that is also valid for the
constructor? Do you want your accessor functions to raise an error if
someone tries to access a non-initialized field?

> 3) Both fields will return string? when accessed, as that makes it
> easier to insert into the DB when the time comes.

As you may know, the reference
<http://docs.racket-lang.org/reference/pathutils.html>warns that "some
paths may not be representable as strings" and that "decoding and
re-encoding the path’s byte string [to a string] may lose information". You
may be able to ignore this in your particular circumstances, but you might
consider using the byte-string representation of paths (which doesn't have
this problem), or this might be an argument in favor of multiple accessor
functions/methods which convert to different formats.

More broadly, what is the meaning of mutating one of the fields of your
struct? Is there a compelling reason not to use an immutable struct and
functional update?

> (let ([old-mut set-db-chunk-scratchdir-path!])
>   (set! set-db-chunk-scratchdir-path!
>       (lambda (chnk val)
>         (old-mut chnk (if (path? val) (path->string val) val))))))

Regardless of anything else, I would definitely not do this. To me, this
would "work against the idea of functional programming" far more than using
a class. (Also, I have the impression that mutating a module-level variable
can have performance implications.)

If I wanted to use a mutable struct with the sorts of wrappers you
describe, I would write a module with the struct definition and the wrapper
functions and export only the interface with guards, perhaps using
rename-out (or the rename option with contract-out) to give the wrappers
nice external names. I will sometimes even use a submodule for the purpose
of packaging up an abstraction and giving only a high-level interface to
surrounding code.

Alternatively, using a class could be a valid choice, but I would probably
only consider that if you have other code that uses racket/class: it seems
like a fairly large set of concepts to add just for this. I have come to
appreciate racket/class in the right circumstances, especially for
representing stateful objects or lots of variants with slight variations in
method behavior. I don't think there's anything inherently un-functional
about classes (and I'd say an immutable object is more functional than a
mutable struct).

You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to