<div dir="ltr"><div>FWIW,<br><br></div>Here is what I&#39;ve been doing in TR with regard to #:prefab struct: as a mechanism for ser/de-ser.   Notice the cast to the struct: type after deserialization from a string.  Of course the #:prefab struct: definition must be in both client and server code and the definitions in sync.<br>
<br><br>#lang typed/racket/base<br><br>(provide<br> deserialize-struct-from-string<br> serialize-struct-to-string)<br><br>;; Open question here on what is best approach for serialization of struct: lot&#39;s of APIs in R.<br>
;; For now simple.  This assumes the structure is prefab or equivalent.<br><br>(define-syntax deserialize-struct-from-string<br>  (syntax-rules ()<br>    ((_ str type)<br>     (let ((sin (open-input-string str)))<br>       (let ((s (cast (read sin) type)))<br>
     (close-input-port sin)<br>     s)))))<br><br>(define-syntax serialize-struct-to-string<br>  (syntax-rules ()<br>    ((_ struc)<br>     (let ((outp (open-output-string)))<br>       (write struc outp)<br>       (close-output-port outp)<br>
       (get-output-string outp)))))<br><br><br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, May 6, 2013 at 1:39 PM, Asumu Takikawa <span dir="ltr">&lt;<a href="mailto:asumu@ccs.neu.edu" target="_blank">asumu@ccs.neu.edu</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On 2013-05-06 08:46:04 -0700, Eric Dobson wrote:<br>
&gt; Couldn&#39;t this be solved by protecting the struct on export?<br>
<br>
</div>I&#39;m not sure this is sufficient. Consider the following code:<br>
<div class="im"><br>
  #lang racket/load<br>
<br>
  (module foo racket<br>
</div>    (struct foo ([f #:mutable]) #:prefab)<br>
    (define y (foo values))<br>
    (define (mutater) (set-foo-f! y (ė (x) (string-&gt;number x))))<br>
    (provide y mutater))<br>
<br>
  (module bar typed/racket<br>
    (struct: foo ([f : (Float -&gt; Float)]) #:mutable #:prefab)<br>
    (require/typed &#39;foo<br>
                   [y foo]<br>
                   [mutater (-&gt; Void)])<br>
    (mutater)<br>
    ((foo-f y) 5.3))<br>
<br>
The use of mutation lets you sneak values that don&#39;t match the type.<br>
Even if you require the struct instance with `struct/dc` and apply an<br>
impersonator-based contract, you can&#39;t prevent the un-impersonated<br>
access on the `foo` side.<br>
<br>
This actually looks like it&#39;s a problem even without #:prefab structs:<br>
<div class="im"><br>
  #lang racket/load<br>
<br>
  (module foo racket<br>
</div>    (struct foo ([f #:mutable]))<br>
    (define y (foo values))<br>
    (define (mutater) (set-foo-f! y (ė (x) (string-&gt;number x))))<br>
    (provide y (struct-out foo) mutater))<br>
<br>
  (module bar typed/racket<br>
    (require/typed &#39;foo<br>
                   [#:struct foo ([f : (Float -&gt; Float)])]<br>
                   [y foo]<br>
                   [mutater (-&gt; Void)])<br>
    (mutater)<br>
    ((foo-f y) 5.3))<br>
<br>
Another thing to be careful of is struct inheritance. For example:<br>
<br>
  #lang racket/load<br>
<div class="im"><br>
  (module foo typed/racket<br>
    (struct: foo ([f : (Float -&gt; Float)]) #:prefab)<br>
</div>    (struct: foo2 foo ([g : (Float -&gt; Float)]) #:prefab)<br>
    (define x (ann (foo2 (ė (x) (* x 5.3))<br>
                         (ė (x) (* x 5.3)))<br>
                   foo))<br>
    ;; Note that this is a type error<br>
    ;(foo2-g x)<br>
    (provide x))<br>
<div class="im"><br>
  (module bar racket<br>
    (require &#39;foo)<br>
    (struct foo (f) #:prefab)<br>
</div>    (struct foo2 foo (g) #:prefab)<br>
    ((foo2-g x) &quot;foo&quot;))<br>
<br>
In this case, `foo2` inherits from `foo` and so you can upcast an<br>
instance of `foo2` to `foo`. But then you forget a field, and if the<br>
type-&gt;contract translation isn&#39;t smart, then you may fail to protect all<br>
the fields (that an untyped client can now guess and misuse).<br>
<br>
Cheers,<br>
Asumu<br>
</blockquote></div><br></div>