<div dir="ltr"><div>Okay, thank you Vincent.<br></div>Typed Racket itself is a good Code Guide for untyped programs.<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Feb 24, 2014 at 10:24 PM, Vincent St-Amour <span dir="ltr"><<a href="mailto:stamourv@ccs.neu.edu" target="_blank">stamourv@ccs.neu.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">At Mon, 24 Feb 2014 13:51:30 +0800,<br>
<div class="">WarGrey Gyoudmon Ju wrote:<br>
> Does RVM know the type information at runtime? Is typed racket just a<br>
> front-end parser (target to contracts)? In theory is it possible to<br>
> manually optimize untyped racket to make it as fast as the typed one in<br>
> most cases?<br>
<br>
</div>Typed Racket operates entirely at macro-expansion time. By the time the<br>
Racket compiler sees a Typed Racket program, the types are all gone.<br>
<br>
Typed Racket's optimizer simply rewrites operations to use unsafe<br>
type-specific operations provided by Racket (see racket/unsafe/ops),<br>
something you could do by hand if you wanted. TR also does some other<br>
optimizations (scalar replacement, dead code elimination, etc.) which<br>
you could also do by hand.<br>
<br>
There are some advantages at having TR do it for you, though. First,<br>
modulo bugs in TR, these "unsafe" operations are actually guaranteed to<br>
actually be safe by the typechecker. If you manually add unsafe<br>
operations, you may accidentally introduce segfaults. Second, TR<br>
typechecks (and optimizes) code after macros are expanded, and so it can<br>
optimize inside the expansion of macros, which you can't do at the<br>
source level.<br>
<div class=""><br>
> To ignore the developing features, do we lose any expressivenesses?<br>
><br>
> (lambda ([μ 0.0] [σ 1.0] #:multiple [p 1])<br>
> (define samples (flnormal-sample μ σ p))<br>
> (apply values (flvector->list samples))<br>
><br>
> This example returns non-fix-length multiple values, it seems impossible<br>
> to annotate its type.<br>
<br>
</div>That does indeed look like something TR does not support.<br>
<br>
However, functions that return a variable number of values are often<br>
(IMO) questionable design. I would recommend rewriting your code to<br>
return a collection instead (and would recommend that even if TR was not<br>
involved).<br>
<div class=""><br>
> It took me hours and hours to enumerate all possible ways but still<br>
> unsolved.<br>
><br>
> (define: random-gaussian : (case-> [[#:mean Flonum] [#:stddev Flonum]<br>
> [#:multiple False] -> Flonum]<br>
> [[#:mean Flonum] [#:stddev Flonum]<br>
> [#:multiple Index] -> (Listof Flonum)])<br>
> {lambda {#:mean [μ 0.0] #:stddev [σ 1.0] #:multiple [p #false]}<br>
> (define: samples : FlVector (flnormal-sample μ σ (if (false? p) 1 p)))<br>
> (cond [(false? p) (flvector-ref samples 0)]<br>
> [else (flvector->list samples)])})<br>
><br>
> Actually, DrRacket complains about (Values Flonum)<br>
> So 'multiple values' is evil!<br>
><br>
> Keyword argument is also the optional one, it's good for stopping (case->)<br>
> becoming too complexity. But why not (false? p) tells Typed Racket to<br>
> choose the first function types?<br>
<br>
</div>That's odd. I'll look into it.<br>
<span class="HOEnZb"><font color="#888888"><br>
Vincent<br>
</font></span></blockquote></div><br></div>