Re: [racket-users] Structured Concurrency in Racket

2019-10-08 Thread Luke Whittlesey
I think the ceu language has a nice model of what I would consider
"structured". http://ceu-lang.org/ It has automatic cancellation and
finalization. Racket can easily support this model. Await statements
are captured through delimited continuations and processes are managed
in a tree. If a parent process exits the children are canceled and
finalized.

On Mon, Oct 7, 2019 at 4:08 PM George Neuner  wrote:
>
>
> On 10/7/2019 1:46 PM, jab wrote:
> > Coming across 
> > https://trio.discourse.group/t/structured-concurrency-and-delimited-continuations/
> >  just provoked me to search for discussion of structured concurrency in 
> > Racket. I didn’t immediately find much.* I hope that doesn’t mean that the 
> > interesting work that’s being discussed over in 
> > https://trio.discourse.group/c/structured-concurrency etc. has been largely 
> > unknown by the Racket community. Trio is having a profound impact on the 
> > future of concurrency, not just in Python but in many other languages. 
> > There’s even a post on Wikipedia now: 
> > https://en.wikipedia.org/wiki/Structured_concurrency
> >
> > (For anyone new to the term, 
> > https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/
> >  might be the best starting point. One persuasive example shows Nathaniel 
> > live coding a correct implementation of RFC 655 “Happy Eyeballs” in 40 
> > lines of Python: 
> > https://github.com/python-trio/trio-talks/tree/master/njsmith-async-concurrency-for-mere-mortals
> >   (For comparison, Twisted’s implementation took hundreds of lines and 
> > still had a logic bug after years of work.) There is also some related 
> > reading in https://github.com/python-trio/trio/wiki/Reading-list.)
> >
> > I hope this post provokes discussion of structured concurrency in Racket. 
> > It’d be fascinating to read more of your thoughts!
> >
> > Thanks,
> > Josh
> >
> > * For example, Googling “structured concurrency racket” turned up mostly 
> > just a brief mention of Racket’s custodians in the bottom-most comment on 
> > this post: http://250bpm.com/blog:71
>
> "Structured concurrency" as defined by those articles really applies
> only to programs that operate in distinct phases -  which is a pretty
> good description of many science programs  - but such programs represent
> a (important, but) small subset of all parallel programs.
>
> Racket's APIs are designed to support general parallelism, not just
> phased parallelism.
>
> I suppose an argument could be made for syntax explicitly aimed at
> phased parallelism ... but using macros, such syntax could be built on
> top of the existing parallel (future, thread, place) APIs - so there is
> nothing stopping you, or anyone else, from creating a "structured
> concurrency" package that everyone can use.
>
>
> One problem I foresee is defining a reasonable syntax and semantics.
> Most of the languages that promote "structured" concurrency have C-like
> syntax.  Moreover they vary considerably in semantics - in some of them
> the spawning thread stops immediately and can't continue until its
> children exit, but other allow the spawning thread to continue until it
> executes an explicit join / wait for its children.
>
> The Lisp/Scheme based idioms of S-expr Racket are very different from
> those of C-like languages, and whether or not some "Racket2"
> materializes having a more C-like syntax, many people like Racket just
> the way it is.  I can envision heated debates about what should be the
> proper "structuring" semantics and what syntax best represents them.
>
> YMMV,
> George
>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/racket-users/8b83ff75-7b57-f3f1-0514-46170c9c3141%40comcast.net.

-- 
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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CA%2Bce6i39GYb8fVnb%2B91iGEdyTCnegaZLx%3DSHfuZ5zY1wqn%3D2-w%40mail.gmail.com.


[racket-users] DrRacket back button

2019-07-15 Thread Luke Whittlesey
In DrRacket I like being able to right click on an identifier and `Jump to
Binding Occurance". Is there a way to "jump back" to where you jumped from?

-- 
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 racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CA%2Bce6i007%3D-jkv%2BwUfkoJg-5YaJsXGgHn6jDUp%2BfPKHL3iK_Ww%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] catch and bind an unbound id in a macro

2019-04-19 Thread Luke Whittlesey
`identifier-binding` might be useful if a binding can be defined outside of
set/define

https://docs.racket-lang.org/reference/stxcmp.html?q=identifier-binding#%28def._%28%28quote._~23~25kernel%29._identifier-binding%29%29

On Fri, Apr 19, 2019 at 4:55 PM Matthias Felleisen 
wrote:

>
> I had the impression that you want to create the hashtable when it’s not
> there and use it when it is:
>
> #lang racket
>
> (define-syntax (set/define stx)
>   (syntax-case stx ()
> [(_ id key val)
>  (syntax-local-value #'id (lambda () #f))
>  (with-syntax ([h (car (syntax-local-value #'id (lambda () #f)))])
>#`(begin
>(hash-set! h 'key val)
>h))]
> [(_ id key val)
>  #'(begin
>  (define-syntax id (cons #'h 0))
>  (define h (make-hash))
>  (set/define id key val))]))
>
> (set/define h a 1)
> (set/define h a 2)
>
>
> To make sure you can see the hashtable, I also return it after every
> set/define.
>
>
>
> On Apr 19, 2019, at 4:17 PM, zeRusski  wrote:
>
> Here's what I've been trying and failing to do in Racket. The smallest
> example I
> could think of is a macro that sets a key in a hash-table, so basically
> this
> transformation:
>
>   (set/define ht 'key 42)
>   ;; =>
>   (hash-set! ht 'key 42)
>
>
> but if ht there is an unbound identifier it must bind it to a fresh hash
> table. So
> basically introduce a (define ht (make-hash)) before setting the key.
> Assume we
> run in a context where define is allowed.
>
> Please, don't ask why I want something like this, I just do. So far tricks
> I could
> use in other lisps failed in Racket. Here's one silly idea: catch unbound
> identifier exn. You can do it as per below or in the handler itself but it
> doesn't
> matter cause that define is local (I think) and doesn't happen in the
> macro use
> context.
>
>   (require (only-in syntax/macro-testing convert-compile-time-error))
>
>   (define (unbound-id-error? err)
> (and (exn:fail:syntax? err)
>  (regexp-match #rx"unbound identifier" (exn-message err
>
>   (define-syntax-rule (set/define id key val)
> (unless (let/ec k
>   (with-handlers ((unbound-id-error? (λ (_) (k #f
> (convert-compile-time-error
>  (hash-set! id key val
>   (displayln "escaped")
>   (define id (make-hash))
>   (hash-set! id key val)))
>
>   (set/define ht 'key 42)
>   ;; =>
>   ;; runs but appears that the (define ht ..) doesn't happen at top-level
>
> This is already all sorts of ugly and it doesn't even work.
>
> Another idea is to replace #%top for the extent of that transformer,
> perform
> local-expand (or some equivalent) so that #%top expansion does the job.
> I've no
> idea how to do that, but I'm sure Racket could be persuaded. Incidentally,
> I'm
> curious how to create such local transformers e.g. something like
> (let-transformer((#%top ...)) body).
>
> Even if I knew how to do the above (local-expand #'(set/define ht 'key
> 42) '())
> run at compile time doesn't seem to wrap unbound ht in #%top. I thought it
> should?
>
> So then, two questions:
>
> 1. What's the Racket way of getting what I want?
>
> 2. Is there a way to torture the above code into submission? Put
> differently is
>there a way to ensure (define id (make-hash)) runs in appropriate
> context?
>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>
>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] Re: syntax rewriting bindings

2019-02-01 Thread Luke Whittlesey
I think I figured it out in case others are interested. See
https://gist.github.com/wluker/329f85ec193b386d89f618bd02796611


On Thu, Jan 31, 2019 at 4:50 PM Luke Whittlesey 
wrote:

> I see that there is the local-expand/capture-lifts and
> syntax-local-lift-expression for expressions, but is there a way to lift
> bindings as well? ... something akin to local-expand/capture-lift-defines
> maybe ...
>
> Basically I want to rewrite a syntax so any (MyDefine ...) is lifted into
> a definition context. Something like..
> (let ()
>   (list (begin (MyDefine a 0) 1) a))
> .. into ..
> (let ()
>   (define a 0)
>   (list 1 a))
>
> I have a fuzzy idea a solution might involve
> syntax-local-make-definition-context, but all my attempts have failed thus
> far. Could anybody give me some hints as to how something like this might
> be accomplished?
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] syntax rewriting bindings

2019-01-31 Thread Luke Whittlesey
I see that there is the local-expand/capture-lifts and
syntax-local-lift-expression for expressions, but is there a way to lift
bindings as well? ... something akin to local-expand/capture-lift-defines
maybe ...

Basically I want to rewrite a syntax so any (MyDefine ...) is lifted into a
definition context. Something like..
(let ()
  (list (begin (MyDefine a 0) 1) a))
.. into ..
(let ()
  (define a 0)
  (list 1 a))

I have a fuzzy idea a solution might involve
syntax-local-make-definition-context, but all my attempts have failed thus
far. Could anybody give me some hints as to how something like this might
be accomplished?

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] updated Racket-on-Chez status

2019-01-30 Thread Luke Whittlesey
This is really impressive work!

On Tue, Jan 29, 2019 at 9:49 AM Matthew Flatt  wrote:

> Here's a new status report on Racket CS:
>
>  http://blog.racket-lang.org/2019/01/racket-on-chez-status.html
>
> Short version: Racket CS is done in a useful sense, but we'll wait
> until it gets better before making it the default Racket
> implementation.
>
>
> Matthew
>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Web server hits "Sorry, this page has expired. Please go back."

2018-10-17 Thread Luke Whittlesey
Interesting conversation.. I want to add that #lang web-server does have
file-boxes (
https://docs.racket-lang.org/web-server/stateless.html?q=web-server#%28part._lang%2Ffile-box%29)
for when one might want to preserve data like you would in the store. To
run across multiple machines I would imagine one could also write a
file-box-ish approach to a database, but I haven't gotten there yet.
I think one of the exciting aspects for me regarding stateless
continuations is the idea of running on multiple servers with the only
shared state being cookies and file-boxes. I imagine being able to easily
scale with something like Amazon Lambda. Although I haven't tried that yet
either, so maybe there are roadblocks there.

On Sun, Oct 14, 2018 at 7:55 PM George Neuner  wrote:

> Hi Philip,
>
> Sorry for the delay in responding ... busy day.
>
>
> On 10/14/2018 7:09 AM, Philip McGrath wrote:
>
> On Sun, Oct 14, 2018 at 5:30 AM George Neuner 
> wrote:
>
>> You are absolutely correct that in typical usage globals are not closed
>> over ... normally they are considered mutable shared "communication"
>> state.
>>
>> However, I was speaking more generally:  to be persisted long duration,
>> and be made portable across separate runtime instances, the continuation
>> must close over AND deep copy ANY VALUE the current call chain references.
>> You don't (necessarily) want to restart the continuation a week later, on a
>> different machine, with different values than when it started.
>>
>
> I am definitely not an expert on continuations or PL generally, so I could
> be very wrong. My understanding, though, has been that continuations not
> closing over non-local variables is a property of continuations in general:
> not only in a web context, and not only of the serializable continuations
> from `#lang web-server`. (I used those in my example just because it is
> easy to see what values they do in fact close over.)
>
>
> In the most basic form, the continuation is just "what to do next" - e.g.,
> a pointer to the next code to be executed.  That is [more or less] all that
> is required for a local (within a function) escape continuation because
> [barring stack corruption] all of the EC's stack context is guaranteed to
> exist if/when the continuation is invoked, and that state is needed anyway
> because the program will continue on regardless of how it leaves the scope
> of the EC.
>
> For a non-local EC, you need to return to the stack frame that was current
> when the continuation was created [the rest of the stack can be
> discarded].  In any case, an EC can very compact - just a couple of
> pointers.
>
> [Aside: a Lisp-style exception requires that the entire call stack be kept
> until you know where execution will continue.  You need to return to the
> EC's call frame (to find the exception handler), but Lisp allows exceptions
> to introspect/modify the environment and then to return control to the
> point of the exception (where the intrinsic EC was invoked).  Scheme
> doesn't have this capability.]
>
>
> General continuations - such as can implement coroutines - need to capture
> much more state.  The entire stack state of the current function call chain
> at the point where the continuation is created must be preserved in order
> to reenter the continuation.
> [this is where stateful and stateless part company - more below]
>
>
> Winding continuations are an extension of general continuations to the
> requirements of dynamic-wind.  In addition to whatever is required for a
> general continuation, a winding continuation has preamble code that must be
> executed whenever a continuation enters the winding scope, and postamble
> code to be executed whenever (and how ever) execution leaves the winding
> scope.
>
>
> The long winded point here is that continuations have no canon
> implementation - if you want more functionality from them, you need to
> capture/preserve more state.
>
>
>
> The web-server is multi-threaded, and the stack state of each thread is
> unique - so for each thread in which a continuation is created in the
> stateful server, the thread's call stack must be preserved.
>
> The stateless server is a different case.  CPS code doesn't use a call
> stack ... or rather its "stack" only ever contains one useful frame - the
> current one.  So there's only one call frame per thread that needs to be
> preserved rather than a (maybe large) stack of them.  This is why stateless
> server continuations - in general - use much less memory than stateful
> server continuations.
>
> [The above is a bit simplistic because Scheme supports nested functions
> with non-local variable access.  [Scheme also supports 1st class closures
> based on nested functions, but that is not what this is about.]   To
> support non-local access without a stack, CPS code needs to construct
> shared environments on the fly as the program executes to communicate
> values from producers to consumers, and these environments (where
> applicable)

Re: [racket-users] question on quasisyntax/loc

2018-05-08 Thread Luke Whittlesey
Very nice explanation. Thank you!

On Tue, May 8, 2018 at 11:08 AM, Alexis King  wrote:

> This behavior is intentional, though it could perhaps be more clearly
> documented. The behavior is hinted at in the documentation for
> syntax/loc:
>
> > Like syntax, except that the immediate resulting syntax object takes
> > its source-location information from the result of stx-expr (which
> > must produce a syntax object), unless the template is just a pattern
> > variable, or both the source and position of stx-expr are #f.
>
> Note the “unless the template is just a pattern variable” condition. The
> idea is that syntax/loc and quasisyntax/loc only ever adjust the source
> location information on fresh syntax introduced in the template, never
> on syntax from external pattern variables or syntax objects inserted
> with unsyntax. For this reason, (quasisyntax/loc stx #,x) is always
> equivalent to x.
>
> If you do actually want to modify the source location information on a
> syntax object, you can do it with syntax-e and datum->syntax:
>
>   (define (replace-outer-srcloc src-stx stx)
> (datum->syntax stx (syntax-e stx) src-stx stx))
>
> Then you could write (replace-outer-srcloc here y) to get the behavior
> you want.
>
> Alexis
>
> > On May 8, 2018, at 09:56, Luke Whittlesey 
> > wrote:
> >
> > I'm having trouble understanding quasisyntax/loc in some cases.
> >
> > If I have the following example code:
> >
> > 
> > #lang racket
> >
> > (define here #'here)
> > (define stx0 (syntax/loc here #'Y))
> > (define y #'Y)
> > (define stx1 (quasisyntax/loc here #,y))
> >
> > (displayln (format "here : line ~a" (syntax-line here)))
> > (displayln (format "stx0 : line ~a" (syntax-line stx0)))
> > (displayln (format "stx1 : line ~a" (syntax-line stx1)))
> > 
> >
> > It prints :
> > 
> > here : line 3
> > stx0 : line 3
> > stx1 : line 5
> > 
> >
> > I expect stx1 to also be at line 3 where `here` is defined. Is this
> > example an incorrect use of quasisyntax/loc? What am I missing?
> >
> > Thanks,
> > Luke
>
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] question on quasisyntax/loc

2018-05-08 Thread Luke Whittlesey
I'm having trouble understanding quasisyntax/loc in some cases.

If I have the following example code:


#lang racket

(define here #'here)
(define stx0 (syntax/loc here #'Y))
(define y #'Y)
(define stx1 (quasisyntax/loc here #,y))

(displayln (format "here : line ~a" (syntax-line here)))
(displayln (format "stx0 : line ~a" (syntax-line stx0)))
(displayln (format "stx1 : line ~a" (syntax-line stx1)))


It prints :

here : line 3
stx0 : line 3
stx1 : line 5


I expect stx1 to also be at line 3 where `here` is defined. Is this example
an incorrect use of quasisyntax/loc? What am I missing?

Thanks,
Luke

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Simple Interdependent Units?

2015-05-25 Thread Luke Whittlesey
Would lazy-require work here?

http://docs.racket-lang.org/reference/lazy-require.html

On Mon, May 25, 2015 at 3:56 PM, Matthias Felleisen 
wrote:

>
> On May 25, 2015, at 3:19 PM, Michael Tiedtke 
> wrote:
>
> > See, you're doing away with the class definitions and substitute them
> with unit definitions.
> > This is what I meant when I wrote you recreated encapsulation and
> inheritance. (Because
> > linking somehow resembles multiple inheritance.)
>
>
> #lang racket/gui
>
> (define-signature model^ (setter get))
> (define-signature view^ (error))
>
> ;; decoupled model-view
> (define model@
>   (unit (import view^)
> (export model^)
>
> (define model%
>   (class object%
> (super-new)
> (define the-number 12)
> (define/public (setter v)
>   (when (or (< v 0) (> 0 100))
> (error "can't do that"))
>   (displayln `(setting to ,v))
>   (set! the-number v))
> (define/public (get)
>   the-number)))
>
> (define model (new model%))
>
> (define (setter v) (send model setter v))
> (define (get) (send model get
>
> (define view@
>   (unit (import model^)
> (export view^)
>
> (define view%
>   (class object%
> (super-new)
> (define frame (new frame% [width 100][height 200][label "VW"]))
> (define vpane (new vertical-pane% [parent frame]))
> (define value0 (get))
> (define slide
>   (new slider%
>[parent vpane] [label "%"]
>[min-value 0] [init-value value0] [max-value 100]
>[style '(vertical)]
>[callback (lambda (self _e) (setter (send self
> get-value)))]))
> (define/public (error msg)
>   (displayln msg))
> (send frame show #t)))
>
> (define (error msg) (send view error msg))
> (define view (new view%
>
> (define completly-linked-program@
>   (compound-unit
> (import)
> (export)
> (link
>  [((model : model^)) model@ view]
>  (((view : view^)) view@ model
>
> (define (run)
>   (invoke-unit completly-linked-program@))
>
>
>
> > Include works best after a cut&paste operation on an over-grown file.
> > My favourite "module system" for now!
>
>
> Please see previous email.
>
> > Yes, I was thinking about things like these in my other message. But
> > this alreaddy depends on the evaluation order which can be "reversed".
> > Right in this example one would like to mix in lazy evaluation.
> >
> > (define the-view
> >   {with-lazy-evaluation (new view% #model: (new model% #view: the-view))
> })
>
> There is a difference between lazy evaluation and cyclic references.
> And it's huge.
>
>
> > One might even think about an interpreter that automatically tries ...
>
> See shared. That's NOT laziness. Repeat, it's NOT laziness.
>
>
> Here is what it takes (in principle) to extend it to objects:
>
> (define-syntax (object-shared stx)
>   (syntax-case stx (new)
> [(_ [(x x-field (new x% [x-field_ x0]))
>  (y y-field (new y% [y-field_ y0]))]
> body)
>  #'(letrec ([x (new x% [x-field '*undefined-x*])]
>  [y (new y% [y-field y0])])
>  (set-field! x-field x x0)
>  #;
>  (set-field! y-field y y0)
>  body)]))
>
> (define the-view
>   (object-shared [(the-model view (new model% [view the-view]))
>   (the-view model (new view% [model the-model]))]
>  the-view))
>
>
> Git pull request for complete extension welcome.
>
>
>
>
>
>
>
>
>
> --
> 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 racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket] typed/racket, promises, and type dispatch

2015-01-24 Thread Luke Whittlesey
I'm not seeing it, but maybe my brain is all twisted up.
It seems to me that in:

(letrec ((a (Not b))
 (b (...)))
  b)
any runtime code evaluating b within (Not ..) will always see 
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
 issue above.
And then again maybe I've just been staring at this too long..

On Sat, Jan 24, 2015 at 6:20 PM, Alexander D. Knauth 
wrote:

> 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 
> 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 <
> alexan...@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 
>> 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
>>
>>
>>
>
>

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] typed/racket, promises, and type dispatch

2015-01-24 Thread Luke Whittlesey
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 
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 
> 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
>
>
>

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] typed/racket, promises, and type dispatch

2015-01-23 Thread Luke Whittlesey
> 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


Re: [racket] typed/racket, promises, and type dispatch

2015-01-23 Thread Luke Whittlesey
I had thought TR would use types to prune unreachable paths. So something
like:

(: test-fn (Symbol -> Symbol))
(define (test-fn y)
  (: only-symbol (case-> (Symbol -> Symbol)
 (String -> String)))
  (define (only-symbol x)
(if (symbol? x)
x
(error "can't ever get here!")))
  (only-symbol y))

(test-fn 'a)

would get pruned/rewritten before being handed off to the middle end of
Racket. Now that I'm writing this I realize that type checking, rewriting,
and inlining would have to occur, so I'm not sure why I thought that was
the case. Thanks for setting me straight.

-Luke



On Thu, Jan 22, 2015 at 8:26 PM, Matthias Felleisen 
wrote:

>
>
> TR is a library-language of R with types and type checking hooked in after
> macro-expansion is done (the part of the compiler that is relevant). When
> type checking is done, types disappear so that the middle end of Racket can
> kick in as before. The macro system of Racket is unaware of types so it
> cannot dispatch in response to Racket. -- Matthias
>
>
>
> On Jan 22, 2015, at 11:39 AM, Luke Whittlesey wrote:
>
> > Hello,
> >
> > I've been learning TR, but I seem to have gotten myself into a corner
> that I haven't been able to find a workaround for. I'm looking for some
> help on how to get TR to perform occurrence typing with promises. Basically
> I'm trying to dispatch based on type, which works without promises, but
> fails with promises.
> >
> > For background, this code works::
> >  begin working code 
> >
> > #lang typed/racket
> >
> > (define-type Wire Symbol)
> > (define Wire? (make-predicate Wire))
> > (define-type WireVec (Listof Wire))
> > (define WireVec? (make-predicate WireVec))
> >
> > ;; dispatch based on type
> > (: Not (case-> (Wire -> Wire)
> >(WireVec -> WireVec)))
> > (define (Not wire*)
> >   (if (Wire? wire*)
> >   (Not-wire wire*)
> >   (Not-wirevec 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 (list 'a 'b 'c))
> >
> > ;;; printed results are
> > ;received wire
> > ;'my-wire
> > ;received wirevec
> > ;'(a b c)
> >
> >  end working code 
> >
> > When I use the same code as above, but add promises to the basic types,
> I can no longer create a predicate, so I also can't do occurrence typing.
> Is there a workaround to be able to perform compile time dispatch based on
> promise types?
> >
> > ;; define types with promises as well
> > (define-type Wire (U (Promise Wire) Symbol))
> > (define Wire? (make-predicate Wire))   ; <-- error
> > (define-type WireVec (U (Promise WireVec) (Listof Wire)))
> > (define WireVec? (make-predicate WireVec)) ; <-- error
> >
> > I understand that a contract can't be generated for something like
> (Promise Wire), because at runtime a promise can't identify it's payload
> without forcing it, but it seems like the (Promise Wire) type is available
> at compile time, so there might be a way to make a compile time dispatch.
> >
> > Thanks,
> > Luke
> >
> > 
> >  Racket Users list:
> >  http://lists.racket-lang.org/users
>
>

  Racket Users list:
  http://lists.racket-lang.org/users


[racket] typed/racket, promises, and type dispatch

2015-01-22 Thread Luke Whittlesey
Hello,

I've been learning TR, but I seem to have gotten myself into a corner that
I haven't been able to find a workaround for. I'm looking for some help on
how to get TR to perform occurrence typing with promises. Basically I'm
trying to dispatch based on type, which works without promises, but fails
with promises.

For background, this code works::
 begin working code 

#lang typed/racket

(define-type Wire Symbol)
(define Wire? (make-predicate Wire))
(define-type WireVec (Listof Wire))
(define WireVec? (make-predicate WireVec))

;; dispatch based on type
(: Not (case-> (Wire -> Wire)
   (WireVec -> WireVec)))
(define (Not wire*)
  (if (Wire? wire*)
  (Not-wire wire*)
  (Not-wirevec 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 (list 'a 'b 'c))

;;; printed results are
;received wire
;'my-wire
;received wirevec
;'(a b c)

 end working code 

When I use the same code as above, but add promises to the basic types, I
can no longer create a predicate, so I also can't do occurrence typing. Is
there a workaround to be able to perform compile time dispatch based on
promise types?

;; define types with promises as well
(define-type Wire (U (Promise Wire) Symbol))
(define Wire? (make-predicate Wire))   ; <-- error
(define-type WireVec (U (Promise WireVec) (Listof Wire)))
(define WireVec? (make-predicate WireVec)) ; <-- error

I understand that a contract can't be generated for something like (Promise
Wire), because at runtime a promise can't identify it's payload without
forcing it, but it seems like the (Promise Wire) type is available at
compile time, so there might be a way to make a compile time dispatch.

Thanks,
Luke

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] errortrace breaks local-require on submodules

2015-01-14 Thread Luke Whittlesey
My racketfoo is not strong enough to provide a suggestion for a solution,
but I can see the utility in what you are trying to do (at least in the way
I understood your message); use a macro to wrap untyped code within a typed
context.

TR provides a `with-type` to write typed code within an untyped context, so
maybe there should be a feature request for something like a `with-untyped`
to define an untyped region that adds type contracts at the boundary and
can be used in a typed context.

On Sun, Jan 11, 2015 at 3:55 PM, Alexis King  wrote:

> I wrote a typed racket macro that creates an untyped submodule, then uses
> require/typed to add type annotations to the bindings. This would work
> great, except that it just errors out and dies. I submitted a bug report
> before realizing that a bug report already existed
> .
> There, someone suggested that it would work fine with (submod "." foo)
> instead of simply using 'foo. This works!
>
> Except that it doesn’t work when errortrace is enabled. This behavior is
> observable here:
> https://gist.github.com/lexi-lambda/d0da64235e1bca59810f
>
> Note that it works fine using plain old require, and it also works fine
> without errortrace. What is errortrace doing that breaks this specific
> instance? How can I fix it? I’d really like to be able to solve this
> because my macro sort of depends on it.
>
> 
>   Racket Users list:
>   http://lists.racket-lang.org/users
>
>

  Racket Users list:
  http://lists.racket-lang.org/users


Re: [racket] lazy letrec-values

2014-07-11 Thread Luke Whittlesey
I just sent a pull request : https://github.com/plt/racket/pull/727

I added a few simple test cases, but the interesting thing is that running
`./racket/bin/raco test pkgs/lazy` seems to pass even when I add a failing
test case such as  `(! (eq? 1 2)) => #t`.
That same test will fail as expected if I run it within drracket.

Thank you all for your time and help. (And thank you for creating such a
nice community and toolset!)

-Luke






On Fri, Jul 11, 2014 at 12:02 AM, Spencer Florence <
flore...@northwestern.edu> wrote:

> It looks like he has taken those down. But I'm sure he would email a copy
> if asked (the think is http://pl.barzilay.org/resources.html#classnotes
> btw)
>
>
> On Thu, Jul 10, 2014 at 8:42 PM, Matthias Felleisen 
> wrote:
>
>>
>> There are also Eli's class notes. I don't have a URL handy but I am sure
>> if you google "Eli Barzilay" and "course" you'll find his notes on the
>> various levels of lazy (plus homework assignments :-) -- Matthias
>>
>>
>>
>>
>>
>>
>> On Jul 10, 2014, at 6:41 PM, Stephen Chang wrote:
>>
>> > Actually, this is a bug, because the expression in a single-argument
>> > values call is forced prematurely.
>> >
>> > eg, This should not error:
>> >
>> > -> (let-values ([(x) (values (error "a"))]) 1)
>> > ; a [,bt for context]
>> >
>> > Just like this does not error.
>> >
>> > -> (let-values ([(x y) (values (error "a") (error "b"))]) 1)
>> > 1
>> >
>> > Lazy Racket is trying to preserve the (values x) == x from Racket, but
>> > since LR's force is recursive, this is actually impossible without
>> > breaking the semantics like it's doing now.
>> >
>> > Luke, thanks for finding this. If you want to submit a pull request, I
>> > will merge. (Just drop the first clause in the case-lambda entirely.)
>> > Maybe some extra tests would be nice as well :) Otherwise if you dont
>> > have time, let me know and I'll do it.
>> >
>> >> Beyond the library documentation, does anyone know if there are any
>> discussions or tutorials that go into the do's and don'ts of using #lang
>> lazy ?
>> >
>> > There isnt any. You can check out the Barzilay-Clements paper [1] to
>> > learn about the motivation behind LR, but otherwise LR should have
>> > "standard" lazy semantics.
>> >
>> > [1]:
>> http://digitalcommons.calpoly.edu/cgi/viewcontent.cgi?article=1047&context=csse_fac
>> >
>> > On Thu, Jul 10, 2014 at 1:15 PM, Luke Whittlesey
>> >  wrote:
>> >> Thank you for the in-depth analysis. Very interesting.
>> >>
>> >> Following your reasoning, if I edit lazy.rkt and force `values` to use
>> >> `multiple-values` for the single entry case, the example that was
>> previously
>> >> broken now works. (I just have no idea if this breaks something else
>> in the
>> >> process.)
>> >>
>> >> at lazy.rkt line:223
>> >> replace:
>> >>  (define* ~values
>> >>(case-lambda [(x) x] [xs (multiple-values xs)]))
>> >>
>> >> with:
>> >>  (define* ~values
>> >>(case-lambda [(x) (multiple-values (list x))] [xs (multiple-values
>> >> xs)]))
>> >>
>> >>
>> >> I had assumed that a reference to an identifier was delayed, so thanks
>> for
>> >> showing that this is currently not the case.
>> >>
>> >> Beyond the library documentation, does anyone know if there are any
>> >> discussions or tutorials that go into the do's and don'ts of using
>> #lang
>> >> lazy ?
>> >>
>> >> Thanks,
>> >> Luke
>> >>
>> >>
>> >> On Thu, Jul 10, 2014 at 6:24 AM, Matthew Flatt 
>> wrote:
>> >>>
>> >>> I'm not sure whether to call it a bug or a limitation of `lazy`.
>> >>>
>> >>> The `lazy` language doesn't delay a reference to an identifier. As a
>> >>> result,
>> >>>
>> >>> (define x y)
>> >>> (define y (list 1))
>> >>> (car x)
>> >>>
>> >>> fails. The case could be made that the right-hand side of the
>> definition
>> >>> of `x` should have been a lazy reference to `y`, but that's not what
>> >>> `

Re: [racket] lazy letrec-values

2014-07-10 Thread Luke Whittlesey
Thank you for the in-depth analysis. Very interesting.

Following your reasoning, if I edit lazy.rkt and force `values` to use
`multiple-values` for the single entry case, the example that was
previously broken now works. (I just have no idea if this breaks something
else in the process.)

at lazy.rkt line:223
replace:
  (define* ~values
(case-lambda [(x) x] [xs (multiple-values xs)]))

with:
  (define* ~values
(case-lambda [(x) (multiple-values (list x))] [xs (multiple-values
xs)]))


I had assumed that a reference to an identifier was delayed, so thanks for
showing that this is currently not the case.

Beyond the library documentation, does anyone know if there are any
discussions or tutorials that go into the do's and don'ts of using #lang
lazy ?

Thanks,
Luke


On Thu, Jul 10, 2014 at 6:24 AM, Matthew Flatt  wrote:

> I'm not sure whether to call it a bug or a limitation of `lazy`.
>
> The `lazy` language doesn't delay a reference to an identifier. As a
> result,
>
>  (define x y)
>  (define y (list 1))
>  (car x)
>
> fails. The case could be made that the right-hand side of the definition
> of `x` should have been a lazy reference to `y`, but that's not what
> `lazy` currently does.
>
> A problem with the current choice is that it interacts badly with `!`,
> especially as used by `letrec-values`. The implementation of
> `letrec-values` forces the right-hand side of a binding using `!` to
> determine how many values it produces. That works ok when the
> right-hand side is produced by `values` on more than one argument,
> because `values` produces a special multiple-values result that leaves
> its values unforced after `!`. When `values` get one argument, then it
> just returns the argument and that's still ok for something like
> `(values (list 1 (/ 0)))`, because the `(/ 0)` expression is lazy.
>
> In your example, the implicit use of `!` for the right-hand side of the
> A` binding produces `(! (list a B))`. That `B` is not itself treated as
> a lazy expression, so forcing the list to be constructed causes `B` to
> be evaluated early.
>
> You can make the variable reference lazy by wrapping it with `~`:
>
>   (letrec-values ([(A) (values (list 'a (~ B)))]
>   [(B) (values (list 'b A))])
> B)
>
> Again, I don't know that you should have to do that, but it's how
> `lazy` is defined at the moment.
>
> At Mon, 7 Jul 2014 15:06:26 -0400, Luke Whittlesey wrote:
> > Hello all,
> > I've been playing around with creating circular lists (and learning
> racket
> > which has been quite fun), but I'm stumped on why the lazy version of
> > letrec-values is not producing a promise like the lazy version of letrec
> > does. With the lazy letrec I can create circular lists, but with the lazy
> > letrec-values I get #. See the example below.
> >
> > ; example code ;
> > #lang lazy
> >
> > ;; create a circular list using letrec (this works)
> > (define example-working
> >   (letrec ([A (list 'a B)]
> >[B (list 'b A)])
> > B))
> > (displayln "Working Example:")
> > (displayln example-working)
> > (displayln (!! example-working))
> >
> > ; Prints...
> > ;Working Example:
> > ;(b #)
> > ;#0=(b (a #0#))
> >
> > ;; create a circular list using letrec-values (this is broken)
> > (define example-broken
> >   (letrec-values ([(A) (values (list 'a B))]
> >   [(B) (values (list 'b A))])
> > B))
> > (displayln "Broken Example:")
> > (displayln example-broken)
> > (displayln (!! example-broken))
> >
> > ; Prints
> > ;Broken Example:
> > ;(b (a #))
> > ;(b (a #))
> > ; end code ;
> >
> > I realize that there are many different ways to generate circular lists,
> > but why doesn't this work? Am I misunderstanding something or is this a
> bug?
> >
> > Thanks,
> > Luke
> > 
> >   Racket Users list:
> >   http://lists.racket-lang.org/users
>

  Racket Users list:
  http://lists.racket-lang.org/users


[racket] lazy letrec-values

2014-07-07 Thread Luke Whittlesey
Hello all,
I've been playing around with creating circular lists (and learning racket
which has been quite fun), but I'm stumped on why the lazy version of
letrec-values is not producing a promise like the lazy version of letrec
does. With the lazy letrec I can create circular lists, but with the lazy
letrec-values I get #. See the example below.

; example code ;
#lang lazy

;; create a circular list using letrec (this works)
(define example-working
  (letrec ([A (list 'a B)]
   [B (list 'b A)])
B))
(displayln "Working Example:")
(displayln example-working)
(displayln (!! example-working))

; Prints...
;Working Example:
;(b #)
;#0=(b (a #0#))

;; create a circular list using letrec-values (this is broken)
(define example-broken
  (letrec-values ([(A) (values (list 'a B))]
  [(B) (values (list 'b A))])
B))
(displayln "Broken Example:")
(displayln example-broken)
(displayln (!! example-broken))

; Prints
;Broken Example:
;(b (a #))
;(b (a #))
; end code ;

I realize that there are many different ways to generate circular lists,
but why doesn't this work? Am I misunderstanding something or is this a bug?

Thanks,
Luke

  Racket Users list:
  http://lists.racket-lang.org/users