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
generativity trick:
(define-struct the-unsupplied-arg ())
(define the-unsupplied-arg (make-the-unsupplied-arg))
(provide 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:
#lang racket/base
(define the-unsupplied-arg
(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
not?
You could use a chaperone to prohibit `struct-info`:
(define the-unsupplied-arg
(chaperone-struct (make-the-unsupplied-arg)
struct:unsupplied-arg
struct-info (lambda _ (error "not allowed"))))
Ryan
--
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 [email protected].
For more options, visit https://groups.google.com/d/optout.