[racket] typed/racket, promises, and type dispatch
Could you make a promise that held a struct that held a promise?
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?
On Jan 24, 2015, at 5:59 PM, Luke Whittlesey <luke.whittlesey at gmail.com> wrote:
> 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`.
>
> For example I run into trouble with the second letrec form below:
>
> ;;; this works
> (letrec ((a (Not (delay b)))
> (b 'my-wire))
> b)
> ;; but this won't work
> (letrec ((a (Not (delay b)))
> (b (wire-vec (list 'a 'b 'c))))
> b)
>
> 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.
>
> 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.
>
> 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.
>
> Thanks for your help.
>
> -Luke
>
>
> On Sat, Jan 24, 2015 at 12:50 AM, Alexander D. Knauth <alexander at knauth.org> wrote:
> Would it help to wrap one of them (in this case WireVec) in a structure like this:
> #lang typed/racket
> (define-type Wire (U (Promise Wire) Symbol))
> (define-type Wire-List (U (Promise Wire-List) (Listof Wire)))
> (struct wire-vec ([wires : Wire-List]) #:transparent)
> (define-type WireVec wire-vec)
>
> ;; dispatch based on type
> (: Not (case-> (Wire -> Wire)
> (WireVec -> WireVec)))
> (define (Not wire*)
> (if (wire-vec? wire*)
> (Not-wirevec wire*)
> (Not-wire wire*)))
>
> (: Not-wire (Wire -> Wire))
> (define (Not-wire w)
> (displayln "received wire")
> w)
>
> (: Not-wirevec (WireVec -> WireVec))
> (define (Not-wirevec w)
> (displayln "received wirevec")
> w)
>
> ;; test
> (Not 'my-wire)
> (Not (wire-vec (list 'a 'b 'c)))
>
> ;;; printed results are
> ;received wire
> ;'my-wire
> ;received wirevec
> ;(wire-vec '(a b c))
>
>
> On Jan 23, 2015, at 11:41 AM, Luke Whittlesey <luke.whittlesey at gmail.com> wrote:
>
>>
>> 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.
>>
>> 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.
>> Ususally when I get myself into a corner and there's not an easy way out, I need to rethink my approach (or goals).
>> Thanks for your suggestions.
>>
>> -Luke
>> ____________________
>> Racket Users list:
>> http://lists.racket-lang.org/users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20150124/6f3a9012/attachment-0001.html>