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 <david.sto...@gmail.com> 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 <sa...@cs.indiana.edu> 
> 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 <david.sto...@gmail.com> 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.

Reply via email to