Re: [racket-users] Sharing scope in setup/cleanup for dynamic-wind?

2021-05-19 Thread George Neuner

Coming late to this ...

On 5/19/2021 11:31 AM, David Storrs wrote:
On Tue, May 18, 2021 at 4:09 PM Philip McGrath 
mailto:phi...@philipmcgrath.com>> wrote:


On Tue, May 18, 2021 at 3:52 PM Sam Tobin-Hochstadt
mailto:sa...@cs.indiana.edu>> wrote:

I think the key question is what you want to happen if you
would need
to re-run the "pre" thunk, because you re-enter the code via a
continuation.

In many cases, you don't want to support that at all …


Then you can use `call-with-continuation-barrier`, right?

(let* ([conn (connect-to-server)])
  (dynamic-wind
   void
   (λ ()
     (call-with-continuation-barrier
      (λ ()
        (send-message conn "hi"
   (λ ()
     (finalize-connection conn

I think I don't understand cwcb well enough to get this, but the 
connect call is not in the pre thunk so it's not guaranteed to 
happen...right?


The connect will occur once before the dynamic-wind is entered. However, 
because it is outside dynamic-wind rather than in the pre thunk - 
connect will /not/ be executed again if the value thunk is reentered.


call-with-continuation-barrier, in effect, puts a sandbox around the 
contained thunk which prevents continuations captured within the thunk 
from being invoked outside of it.  IOW, you can jump around /inside/ the 
thunk, and you can jump out of the thunk ... but if you jump out, you 
/can't/ jump back in.


As used in the example, the barrier around the value thunk turns 
dynamic-wind into the moral equivalent of Lisp's unwind-protect: modulo 
exceptions, pre and value will be executed at most once, and post is 
guaranteed to be executed regardless of whether pre or value finish.


Hope this helps,
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/ccf271c7-420e-ded7-ec39-c29bb4f2663d%40comcast.net.


Re: [racket-users] Sharing scope in setup/cleanup for dynamic-wind?

2021-05-19 Thread David Storrs
On Tue, May 18, 2021 at 4:09 PM Philip McGrath 
wrote:

> On Tue, May 18, 2021 at 3:52 PM Sam Tobin-Hochstadt 
> wrote:
>
>> I think the key question is what you want to happen if you would need
>> to re-run the "pre" thunk, because you re-enter the code via a
>> continuation.
>>
>> In many cases, you don't want to support that at all …
>>
>
> Then you can use `call-with-continuation-barrier`, right?
>
> (let* ([conn (connect-to-server)])
>   (dynamic-wind
>void
>(λ ()
>  (call-with-continuation-barrier
>   (λ ()
> (send-message conn "hi"
>(λ ()
>  (finalize-connection conn
>
> I think I don't understand cwcb well enough to get this, but the connect
call is not in the pre thunk so it's not guaranteed to happen...right?

-- 
> 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/0100017981191578-b5eaa465-de2a-4f1f-a4f1-d2976db88de0-00%40email.amazonses.com
> 
> .
>

-- 
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/CAE8gKodVmpqrNQMhEiX2QOi-CTQkO_s96%3Dgdoks4wt93%2Bmxy6g%40mail.gmail.com.


Re: [racket-users] Sharing scope in setup/cleanup for dynamic-wind?

2021-05-18 Thread Philip McGrath
On Tue, May 18, 2021 at 3:52 PM Sam Tobin-Hochstadt 
wrote:

> I think the key question is what you want to happen if you would need
> to re-run the "pre" thunk, because you re-enter the code via a
> continuation.
>
> In many cases, you don't want to support that at all …
>

Then you can use `call-with-continuation-barrier`, right?

(let* ([conn (connect-to-server)])
  (dynamic-wind
   void
   (λ ()
 (call-with-continuation-barrier
  (λ ()
(send-message conn "hi"
   (λ ()
 (finalize-connection conn

-- 
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/0100017981191578-b5eaa465-de2a-4f1f-a4f1-d2976db88de0-00%40email.amazonses.com.


Re: [racket-users] Sharing scope in setup/cleanup for dynamic-wind?

2021-05-18 Thread Sam Tobin-Hochstadt
I think the key question is what you want to happen if you would need
to re-run the "pre" thunk, because you re-enter the code via a
continuation.

In many cases, you don't want to support that at all, and then it's
pretty easy (although you still need mutation):

(let* ([conn (connect-to-server)]
[started? #f])
 (dynamic-wind
 (lambda () (when started? (error 'fail)) (set! started? #t))
 (lambda () (send-message conn "hi"))
 (lambda () (finalize-connection conn

You could just not do the check in the pre thunk, in which case you'd
get worse error messages but probably nothing else wrong.

Sam


On Tue, May 18, 2021 at 3:42 PM David Storrs  wrote:
>
> Thank you.  Is there a way to do it without the mutation?  I was hoping to 
> use this for macro generation that simplifies combining with-handlers and 
> dynamic-wind with setup/teardown code.
>
> (try [pre
>   (define db (connect-to-db))
>   (define conn (connect-to-server))]
>  [(send-message conn (query-value db "invalid SQL"))]
>  [catch ([exn:fail:contract? (lambda (e) (displayln "contract"))]
>  [exn:fail:network?  (lambda (e) (displayln "network"))]
>  [(and/c exn:fail? (compose1 (curry regexp-match #rx"query") 
> exn-message))
>   (lambda (e) (displayln "database"))])]  ; this should run
>  [finally
>   (finalize-db-connection db)
>   (finalize-server-connection conn)])
>
> The goal is to guarantee that the connections are created/released every time 
> we go in and out of the code (usually via an exception) and also to put the 
> happy path first so that it's easier to see what the code should do before 
> getting into the weeds of error handling.
>
> (I probably should have put these details in the original message but I was 
> trying to keep it simple so as not to make people burn brain cycles.)
>
> On Tue, May 18, 2021 at 2:34 PM Sam Tobin-Hochstadt  
> wrote:
>>
>> It's not quite as convenient, but here's a version of your program
>> that should work:
>>
>> (let ([conn #f])
>>   (dynamic-wind
>> (lambda () (set! conn (connect-to-server))
>> (lambda () (send-message conn "foo"))
>> (lambda () (finalize-connection conn
>>
>> Sam
>>
>> On Tue, May 18, 2021 at 2:08 PM David Storrs  wrote:
>> >
>> > dynamic-wind is nice because it guarantees that the pre- and 
>> > postconditions for a chunk of code will be run regardless of continuation 
>> > jumps, exceptions, etc.  The only issue I have is that the three thunks do 
>> > not share scope, making it difficult to do setup/teardown workflows.  I 
>> > feel like I should be able to make this work with nested dynamic-wind or 
>> > with-handlers but haven't been able to get there without losing the 
>> > guarantee of running.  Is there a way?
>> >
>> > Example of what I'd like to do:
>> >
>> > (my-dynamic-wind
>> >   (thunk (define conn (connect-to-server)))
>> >   (thunk (send-message conn "foo"))
>> >   (thunk (finalize-connection conn)))
>> >
>> > --
>> > 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/CAE8gKodTcogsfeiYKu5iyFbL4H%2Ba3dzuL7rLTfYERD%2BauFD9xQ%40mail.gmail.com.
>
> --
> 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/CAE8gKofbcigfJDFgU8AXVqomQYqmgGT_OEXwAx7m8BQyyoCHqQ%40mail.gmail.com.

-- 
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/CAK%3DHD%2Bb0j3Y4DDHJSBcA8LjjXm3bvRvRNwLrfrNq%3DOs9Z4HpKg%40mail.gmail.com.


Re: [racket-users] Sharing scope in setup/cleanup for dynamic-wind?

2021-05-18 Thread David Storrs
Thank you.  Is there a way to do it without the mutation?  I was hoping to
use this for macro generation that simplifies combining with-handlers and
dynamic-wind with setup/teardown code.

(try [pre
  (define db (connect-to-db))
  (define conn (connect-to-server))]
 [(send-message conn (query-value db "invalid SQL"))]
 [catch ([exn:fail:contract? (lambda (e) (displayln "contract"))]
 [exn:fail:network?  (lambda (e) (displayln "network"))]
 [(and/c exn:fail? (compose1 (curry regexp-match #rx"query")
exn-message))
  (lambda (e) (displayln "database"))])]  ; this should run
 [finally
  (finalize-db-connection db)
  (finalize-server-connection conn)])

The goal is to guarantee that the connections are created/released every
time we go in and out of the code (usually via an exception) and also to
put the happy path first so that it's easier to see what the code should do
before getting into the weeds of error handling.

(I probably should have put these details in the original message but I was
trying to keep it simple so as not to make people burn brain cycles.)

On Tue, May 18, 2021 at 2:34 PM Sam Tobin-Hochstadt 
wrote:

> It's not quite as convenient, but here's a version of your program
> that should work:
>
> (let ([conn #f])
>   (dynamic-wind
> (lambda () (set! conn (connect-to-server))
> (lambda () (send-message conn "foo"))
> (lambda () (finalize-connection conn
>
> Sam
>
> On Tue, May 18, 2021 at 2:08 PM David Storrs 
> wrote:
> >
> > dynamic-wind is nice because it guarantees that the pre- and
> postconditions for a chunk of code will be run regardless of continuation
> jumps, exceptions, etc.  The only issue I have is that the three thunks do
> not share scope, making it difficult to do setup/teardown workflows.  I
> feel like I should be able to make this work with nested dynamic-wind or
> with-handlers but haven't been able to get there without losing the
> guarantee of running.  Is there a way?
> >
> > Example of what I'd like to do:
> >
> > (my-dynamic-wind
> >   (thunk (define conn (connect-to-server)))
> >   (thunk (send-message conn "foo"))
> >   (thunk (finalize-connection conn)))
> >
> > --
> > 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/CAE8gKodTcogsfeiYKu5iyFbL4H%2Ba3dzuL7rLTfYERD%2BauFD9xQ%40mail.gmail.com
> .
>

-- 
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/CAE8gKofbcigfJDFgU8AXVqomQYqmgGT_OEXwAx7m8BQyyoCHqQ%40mail.gmail.com.


Re: [racket-users] Sharing scope in setup/cleanup for dynamic-wind?

2021-05-18 Thread Sam Tobin-Hochstadt
It's not quite as convenient, but here's a version of your program
that should work:

(let ([conn #f])
  (dynamic-wind
(lambda () (set! conn (connect-to-server))
(lambda () (send-message conn "foo"))
(lambda () (finalize-connection conn

Sam

On Tue, May 18, 2021 at 2:08 PM David Storrs  wrote:
>
> dynamic-wind is nice because it guarantees that the pre- and postconditions 
> for a chunk of code will be run regardless of continuation jumps, exceptions, 
> etc.  The only issue I have is that the three thunks do not share scope, 
> making it difficult to do setup/teardown workflows.  I feel like I should be 
> able to make this work with nested dynamic-wind or with-handlers but haven't 
> been able to get there without losing the guarantee of running.  Is there a 
> way?
>
> Example of what I'd like to do:
>
> (my-dynamic-wind
>   (thunk (define conn (connect-to-server)))
>   (thunk (send-message conn "foo"))
>   (thunk (finalize-connection conn)))
>
> --
> 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/CAE8gKodTcogsfeiYKu5iyFbL4H%2Ba3dzuL7rLTfYERD%2BauFD9xQ%40mail.gmail.com.

-- 
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/CAK%3DHD%2BYaP0GV4JppQs%2BpmoOomFskEY%3D7cJ82Ujero7QrzPst1w%40mail.gmail.com.


[racket-users] Sharing scope in setup/cleanup for dynamic-wind?

2021-05-18 Thread David Storrs
dynamic-wind is nice because it guarantees that the pre- and postconditions
for a chunk of code will be run regardless of continuation jumps,
exceptions, etc.  The only issue I have is that the three thunks do not
share scope, making it difficult to do setup/teardown workflows.  I feel
like I should be able to make this work with nested dynamic-wind or
with-handlers but haven't been able to get there without losing the
guarantee of running.  Is there a way?

Example of what I'd like to do:

(my-dynamic-wind
  (thunk (define conn (connect-to-server)))
  (thunk (send-message conn "foo"))
  (thunk (finalize-connection conn)))

-- 
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/CAE8gKodTcogsfeiYKu5iyFbL4H%2Ba3dzuL7rLTfYERD%2BauFD9xQ%40mail.gmail.com.