On 11/5/18 5:26 PM, Alexis King wrote:
To my knowledge, there are two main techniques for creating unique values in
Racket: `gensym` and structure type generativity. The former seems to be
bulletproof — a value created with `gensym` will never be `equal?` to anything
except itself – but the latter isn’t. Using reflective operations, it’s
possible to circumvent the encapsulation afforded by the module system.
To provide an example, `racket/contract` exports a value called
`the-unsupplied-arg`, which is created using the usual structure type
(define-struct the-unsupplied-arg ())
(define the-unsupplied-arg (make-the-unsupplied-arg))
The constructor is not exported, and this value is intended to be unique.
However, if we can arrange for the contract library to be loaded on our terms,
we can thwart this encapsulation by supplying it with a weaker inspector:
(parameterize ([current-inspector (make-inspector)])
(dynamic-require 'racket/contract 'the-unsupplied-arg)))
(define-values [info skipped?] (struct-info the-unsupplied-arg))
(define another-unsupplied-arg ((struct-type-make-constructor info)))
(equal? the-unsupplied-arg another-unsupplied-arg) ; => #t
(eq? the-unsupplied-arg another-unsupplied-arg) ; => #f
Perhaps this isn’t the end of the world, as after all, we can’t do anything
especially nefarious with this value, and we wouldn’t be able to do it in the
first place if we didn’t have complete control of the inspector hierarchy.
Still, it seems a little unsatisfying.
So, my question: is there any way to create a structure type for which there
can truly ever only be one instance? If not, is there a fundamental reason why
You could use a chaperone to prohibit `struct-info`:
struct-info (lambda _ (error "not allowed"))))
You received this message because you are subscribed to the Google Groups "Racket
To unsubscribe from this group and stop receiving emails from it, send an email
For more options, visit https://groups.google.com/d/optout.