<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div>For some sort of type-match statement, it wouldn’t work.</div><div>If you have a function, say f, where you would want to do something like this:</div><div>(: f : (case-> [(Promise Number) -> ’got-a-number]</div><div>               [(Promise String) -> ‘got-a-string]))</div><div>(define (f x)</div><div>  (type-match x ; x has type (U (Promise Number) (Promise String))</div><div>    [(Promise Number) ‘got-a-number]</div><div>    [(Promise String) ‘got-a-string]))</div><div><br></div><div>And then you have some uses of f:</div><div>(f (delay 5))</div><div>(f (delay “string”))</div><div>(f (delay 42))</div><div><br></div><div>Then it knows that f can take either a promise of a number or a promise of a string, so when f is type-checked, x would be of the type (U (Promise Number) (Promise String)), so when f is type-checked, it doesn’t know at type-check-time whether x will be a promise of a number or a promise of string, because x could be either one.  And at run-time, it would have to force the promise to find out, so that wouldn’t work for you.  </div><div><br></div><div>There is a bit of discussion about this here:</div><div><a href="http://lists.racket-lang.org/users/archive/2014-June/062969.html">http://lists.racket-lang.org/users/archive/2014-June/062969.html</a></div><div><br></div><div>I began thinking as you did, but <span style="background-color: rgb(255, 255, 255); white-space: pre-wrap;">Sam Tobin-Hochstadt</span> explained it to me.</div><div>In there I asked if the type-checker could put the type-information in the value so that the run-time function could look at that to tell whether it was a promise of number or a promise of string, but, as Sam said, this in general (as it would have to be for a :has-type? or a type-match form) would require fundamental changes to racket, to put the type in the run-time value.  However, for your own data and functions, you can put that type information there in the run-time value yourself, and that’s exactly what wrapping them in structs does.  </div><div><div><br></div><div>#lang typed/racket</div><div>(struct num-promise ([promise : (Promise Number)]) #:transparent)</div><div>(struct str-promise ([promise : (Promise String)]) #:transparent)</div><div>(: f : (case-> [num-promise -> 'got-a-number]</div><div>               [str-promise -> 'got-a-string]))</div><div>(define (f x)</div><div>  (cond [(num-promise? x) 'got-a-number]</div><div>        [(str-promise? x) 'got-a-string]))</div><div>(f (num-promise (delay 5)))</div><div>(f (str-promise (delay "string")))</div><div>(f (num-promise (delay (begin (displayln "this doesn't get run") 42))))</div></div><br><div><div>On Jan 24, 2015, at 7:35 PM, Luke Whittlesey <<a href="mailto:luke.whittlesey@gmail.com">luke.whittlesey@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">I'm not seeing it, but maybe my brain is all twisted up.<br>It seems to me that in:<br><br>(letrec ((a (Not b))<br>         (b (...)))<br>  b)<br>any runtime code evaluating b within (Not ..) will always see <undefined> because the second line in the letrec hasn't been evaluated yet, so there is no way to perform any kind of occurrence typing (because of the run-time requirement), and hence no way for the type checker to typecheck before handing the program off to the run-time Racket. If TR had some sort of `type-match` statement that could at compile time select an expression to pass to Racket I could see how I could get this to work, but when mixing compile time TR and run-time Racket I don't see how I could get around the <undefined> issue above. <br>And then again maybe I've just been staring at this too long..<br></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 24, 2015 at 6:20 PM, Alexander D. Knauth <span dir="ltr"><<a href="mailto:alexander@knauth.org" target="_blank">alexander@knauth.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Could you make a promise that held a struct that held a promise?</div><div>That way you can force the outer promise and then look at the struct to see whether it’s a wire or a wire-vec, without forcing the inner promise?</div><div><div class="h5"><br><div><div>On Jan 24, 2015, at 5:59 PM, Luke Whittlesey <<a href="mailto:luke.whittlesey@gmail.com" target="_blank">luke.whittlesey@gmail.com</a>> wrote:</div><br><blockquote type="cite"><div dir="ltr"><div><div>That's a nice idea, I like it, but now I can't figure out how to perform the `delay` end without some form of compile time type dispatch for `delay`.<br><br></div>For example I run into trouble with the second letrec form below:<br><br></div>;;; this works<br><div>(letrec ((a (Not (delay b)))<br>         (b 'my-wire))<br>  b)<br></div><div>;; but this won't work<br></div><div>(letrec ((a (Not (delay b)))<br>         (b (wire-vec (list 'a 'b 'c))))<br>  b)<br><br></div><div>The way forward (at least as far as I can tell) would need a type specific `delay`, delay-wire vs delay-wirevec macro, but I run into trouble with mixed delayed/eager evaluation. In the example above, a single `delay-dispatch` macro would need to expand to run-time code that would eagerily evaluate b in order to wrap it with the proper delay struct, but b is undefined at that point. Of course I could just manually provide the proper delay macro, but my macros that generate these letrec forms don't know how to do that... At some point I need to recheck my premise that my approach is sound.<br><br></div><div>I also tried using Neil's suggestion of changing types; I wrapped all promises within their own structs, but I ran into the same sort of trouble.<br><br></div><div>I just don't see a way to do this, so I might alter my approach. Maybe use Racket to generate a netlist/graph from the same letrec forms, but without a type checker in the way, and then figure out a way to type check the graph as a second step.<br><br></div><div>Thanks for your help.<br><br></div><div>-Luke<br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Sat, Jan 24, 2015 at 12:50 AM, Alexander D. Knauth <span dir="ltr"><<a href="mailto:alexander@knauth.org" target="_blank">alexander@knauth.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>Would it help to wrap one of them (in this case WireVec) in a structure like this:</div><div><span><div>#lang typed/racket</div><div>(define-type Wire (U (Promise Wire) Symbol))</div></span><div>(define-type Wire-List (U (Promise Wire-List) (Listof Wire)))</div><div>(struct wire-vec ([wires : Wire-List]) #:transparent)</div><div>(define-type WireVec wire-vec)</div><span><div><br></div><div>;; dispatch based on type</div><div>(: Not (case-> (Wire -> Wire)</div><div>               (WireVec -> WireVec)))</div><div>(define (Not wire*)</div></span><div>  (if (wire-vec? wire*)</div><div>      (Not-wirevec wire*)</div><div>      (Not-wire wire*)))</div><span><div><br></div><div>(: Not-wire (Wire -> Wire))</div><div>(define (Not-wire w)</div><div>  (displayln "received wire")</div><div>  w)</div><div><br></div><div>(: Not-wirevec (WireVec -> WireVec))</div><div>(define (Not-wirevec w)</div><div>  (displayln "received wirevec")</div><div>  w)</div><div><br></div><div>;; test</div><div>(Not 'my-wire)</div></span><div>(Not (wire-vec (list 'a 'b 'c)))</div><span><div><br></div><div>;;; printed results are</div><div>;received wire</div><div>;'my-wire</div><div>;received wirevec</div></span><div>;(wire-vec '(a b c))</div></div><div><br></div><br><div><div><div>On Jan 23, 2015, at 11:41 AM, Luke Whittlesey <<a href="mailto:luke.whittlesey@gmail.com" target="_blank">luke.whittlesey@gmail.com</a>> wrote:</div><br></div><blockquote type="cite"><div><div dir="ltr"><br><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span></span>
That's only a guess at what `Not` is supposed to do, though. If you need to make a decision without first forcing the promise, you'll need to use different types.<span><font color="#888888"></font></span></blockquote><div><br></div><div>I'm playing around with describing circuits using Racket and using TR to type check my ports. Unfortunately I do have to make a decision before forcing the promise, just because in my current design I use nested letrec forms and can't guarantee that the promise is ready. `Not` is just a simple example of something that has a different behavior depending if the input is a single wire or a bundle of wires, but the input could also be a promise that forces to either a wire or a bundle.<br></div><div>Ususally when I get myself into a corner and there's not an easy way out, I need to rethink my approach (or goals). <br></div><div>Thanks for your suggestions.<br><br></div><div>-Luke<br></div></div></div></div></div><span>
____________________<br>  Racket Users list:<br>  <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br></span></blockquote></div><br></div></blockquote></div><br></div>
</blockquote></div><br></div></div></div></blockquote></div><br></div>
</blockquote></div><br></body></html>