Re: [racket-users] Equivalent of dynamic-wind post-thunk for with-handlers

2018-01-24 Thread Alexander McLin

On Wednesday, January 24, 2018 at 5:54:44 PM UTC-5, Alexis King wrote:
>
> Based on your question, why not just use dynamic-wind in combination 
> with with-handlers? Just keep in mind that the post-thunk could be 
> called multiple times if there is a continuation jump into value-thunk, 
> so you should also wrap the whole thing with 
> call-with-continuation-barrier if it’s important that the post-thunk 
> only be executed once. 
>
> Alexis 
>

I was thinking about using `dynamic-wind` but indeed was worried about 
post-thunk being called multiple times. Wrapping with 
`call-with-continuation-barrier` sounds like the right thing to do.

Additionally, the note from Matthias lead me to realize that 
`call-with-exception-handler` is supposed to receive an actual thunk as its 
second argument and `with-handlers` most definitely isn't one. Moving it 
into a thunk resolved the problem so that means in my erroneous code 
`with-handlers` was being evaluated before `call-with-exception-handler` 
even has a chance to install the handler and see the raised exceptions.

Now I just have to think some more about which avenue I want to use.

Thank you for your suggestion!

-- 
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] Equivalent of dynamic-wind post-thunk for with-handlers

2018-01-24 Thread Alexis King
Based on your question, why not just use dynamic-wind in combination
with with-handlers? Just keep in mind that the post-thunk could be
called multiple times if there is a continuation jump into value-thunk,
so you should also wrap the whole thing with
call-with-continuation-barrier if it’s important that the post-thunk
only be executed once.

Alexis

> On Jan 24, 2018, at 1:32 PM, Alexander McLin 
> wrote:
> 
> I have a with-handlers expression which handles several exceptions
> appropriately and raises user-error exceptions, I have some additional
> code I'd like to be executed after the exception have been handled,
> analogous to dyanmic-wind's post-thunk argument or like the finally
> clause of a conventional try{}catch{}finally{} structure found in
> other languages.
> 
> Documentation has shown that with-handlers and its cousins don't seem
> to have anything like that so I thought I'd wrap my with-handlers
> expression in a call-with-exception-handler to intercept the raised
> user-error exceptions, do additional processing and returns the
> exception to continue its propagation. It's not working and the
> installed exception handler doesn't seem to be called at all.
> 
> Here's simplified code.
> 
> (call-with-exception-handler 
>(lambda (e) 
>  ...do more work 
>  e) 
> (with-handlers ([exn:a? (lambda (e) (raise-user-error "exception exn:a 
> caught"))] 
>   [exn:b? (lambda (e) (raise-user-error "exception 
> exn:b caught"))]) 
>   ...code that may throw either exn:a or exn:b ))
> 
> My expectation was that the lambda installed by the
> call-with-exception-handler would run after each user-error is raised.
> I do see the user-error exceptions' messages being printed in the
> terminal so they're being propagated all the way to the uncaught
> exception handler but no work is being done by my own lambda handler.
> What am I doing wrong? More to the point, is there a better way to do
> post with-handlers exception handling processing?
> 
> My thinking is that I have a flawed understanding of the meaning of
> dynamic extent of with-handlers and call-with-exception-handler forms.

-- 
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] Equivalent of dynamic-wind post-thunk for with-handlers

2018-01-24 Thread Alexander McLin
I have a with-handlers expression which handles several exceptions 
appropriately and raises user-error exceptions, I have some additional code 
I'd like to be executed after the exception have been handled, analogous to 
dyanmic-wind's post-thunk argument or like the finally clause of a 
conventional try{}catch{}finally{} structure found in other languages.

Documentation has shown that with-handlers and its cousins don't seem to 
have anything like that so I thought I'd wrap my with-handlers expression 
in a call-with-exception-handler to intercept the raised user-error 
exceptions, do additional processing and returns the exception to continue 
its propagation. It's not working and the installed exception handler 
doesn't seem to be called at all.

Here's simplified code.

(call-with-exception-handler 
   (lambda (e) 
 ...do more work 
 e) 
(with-handlers ([exn:a? (lambda (e) (raise-user-error "exception exn:a 
caught"))] 
  [exn:b? (lambda (e) (raise-user-error "exception 
exn:b caught"))]) 
  ...code that may throw either exn:a or exn:b ))

My expectation was that the lambda installed by the 
call-with-exception-handler would run after each user-error is raised. I do 
see the user-error exceptions' messages being printed in the terminal so 
they're being propagated all the way to the uncaught exception handler but 
no work is being done by my own lambda handler. What am I doing wrong? More 
to the point, is there a better way to do post with-handlers exception 
handling processing?

My thinking is that I have a flawed understanding of the meaning of dynamic 
extent of with-handlers and call-with-exception-handler forms.

-- 
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] Using ffi/unsafe/alloc

2018-01-24 Thread Matthew Flatt
I think I haven't run into this because `r` and `foo` are usually
combined into one value that's more Rackety. Maybe `allocator` should
have a `get-result` optional argument similar to `deallocator`.

Meanwhile:

 ;; Not exported:
 (define-fooapi make_foo
   (_fun (foo : (_ptr o _foo))
 -> (r : _int)
 -> (values r foo)))

 ;; Not exported:
 (define made-foo ((allocator destroy-foo) (lambda (foo) foo)))

 ;; Exported:
 (define (make-foo)
   (start-atomic)
   (let-values ([(r foo) (make_foo)])
 (made-foo foo)
 (end-atomic)
 (values r foo)))

With Dmitry's solution as written, you don't get atomicity of the
foreign function producing a result and registering it, if that
matters. But you could use `#:wrap` to add a `call-as-atomic` wrapper.
(That doesn't let you call the destructor more eagerly, though.)

At Wed, 24 Jan 2018 22:53:41 +0300, Dmitry Pavlov wrote:
> Konrad,
> 
> I would create a wrapper like this:
> 
> (define-fooapi make-foo
>   (_fun (foo : (_ptr o _foo)
>      -> (r : _int)
>      -> (if r (begin (register-finalizer-and-custodian-shutdown foo 
> destroy-foo) foo)
>      (error "can not make foo")))
> 
> 
> Regards,
> 
> Dmitry
> 
> On 01/24/2018 10:47 PM, Konrad Hinsen wrote:
> > Hi everyone,
> >
> > I am working on an FFI which overall progresses well - the Racket FFI 
> library is really a very nice tool to have.
> >
> > The one problem I couldn't solve yet is handling resource allocation. My 
> > use 
> case is very similar to what allocator/deallocator are meant for, except that 
> the allocated object is not the return value of any function, and therefore I 
> cannot use allocator.
> >
> > I have an API like
> >
> >    int make_foo(foo** new_foo);
> >    int destroy_foo(foo* a_foo);
> >
> > so my FFI definitions look like
> >
> >   (define _foo (_cpointer 'foo))
> >
> >   (define-fooapi make-foo
> >  (_fun (foo : (_ptr o _foo)
> >     -> (r : _int)
> >     -> (values r foo))
> >
> >   (define-fooapi destroy-foo
> >  (_fun _foo -> _void))
> >
> > Given that make-foo returns two values, I cannot use #:wrap to make it an 
> allocator.
> >
> > Since the C API I am wrapping is pretty standard, I suspect others have had 
> this problem before. Any suggestions?
> >
> > Thanks in advance,
> >   Konrad.
> >
> 
> -- 
> 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] unsubscr...@googlegroups.com

2018-01-24 Thread Hans Schueren
unsubscr...@googlegroups.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.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] Using ffi/unsafe/alloc

2018-01-24 Thread Dmitry Pavlov

Konrad,

I would create a wrapper like this:

(define-fooapi make-foo
 (_fun (foo : (_ptr o _foo)
    -> (r : _int)
    -> (if r (begin (register-finalizer-and-custodian-shutdown foo 
destroy-foo) foo)
    (error "can not make foo")))


Regards,

Dmitry

On 01/24/2018 10:47 PM, Konrad Hinsen wrote:

Hi everyone,

I am working on an FFI which overall progresses well - the Racket FFI library 
is really a very nice tool to have.

The one problem I couldn't solve yet is handling resource allocation. My use 
case is very similar to what allocator/deallocator are meant for, except that 
the allocated object is not the return value of any function, and therefore I 
cannot use allocator.

I have an API like

   int make_foo(foo** new_foo);
   int destroy_foo(foo* a_foo);

so my FFI definitions look like

  (define _foo (_cpointer 'foo))

  (define-fooapi make-foo
 (_fun (foo : (_ptr o _foo)
    -> (r : _int)
    -> (values r foo))

  (define-fooapi destroy-foo
 (_fun _foo -> _void))

Given that make-foo returns two values, I cannot use #:wrap to make it an 
allocator.

Since the C API I am wrapping is pretty standard, I suspect others have had 
this problem before. Any suggestions?

Thanks in advance,
  Konrad.



--
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] Using ffi/unsafe/alloc

2018-01-24 Thread Konrad Hinsen

Hi everyone,

I am working on an FFI which overall progresses well - the Racket FFI 
library is really a very nice tool to have.


The one problem I couldn't solve yet is handling resource allocation. My 
use case is very similar to what allocator/deallocator are meant for, 
except that the allocated object is not the return value of any 
function, and therefore I cannot use allocator.


I have an API like

   int make_foo(foo** new_foo);
   int destroy_foo(foo* a_foo);

so my FFI definitions look like

  (define _foo (_cpointer 'foo))

  (define-fooapi make-foo
 (_fun (foo : (_ptr o _foo)
-> (r : _int)
-> (values r foo))

  (define-fooapi destroy-foo
 (_fun _foo -> _void))

Given that make-foo returns two values, I cannot use #:wrap to make it 
an allocator.


Since the C API I am wrapping is pretty standard, I suspect others have 
had this problem before. Any suggestions?


Thanks in advance,
  Konrad.

--
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] whither `splicing-parameterize`? or am I doing it wrong?

2018-01-24 Thread Ryan Culpepper
It might make sense to `(set! new-parameterization #f)` at the end so 
that the parameterization (and the values it holds) can be GC'd sooner 
when splicing-parameterize is used at top level or module level.


Ryan


On 1/24/18 6:00 AM, Alexis King wrote:

Here is an implementation of a version of splicing-parameterize that
uses local-expand, a la other forms in racket/splicing:

#lang racket

(require (for-syntax syntax/kerncase)
 (for-meta 2 racket/base)
 syntax/parse/define)

(begin-for-syntax
  (define-syntax (syntax/loc/props stx)
(syntax-case stx ()
  [(_ src-expr template)
   #`(let ([src src-expr])
   (datum->syntax (quote-syntax #,stx)
  (syntax-e (syntax template))
  src
  src))])))

(define-syntax-parser splicing-parameterize
  [(_ ([{~var param (expr/c #'parameter?)} value:expr] ...)
  body ...)
   (if (eq? (syntax-local-context) 'expression)
   #'(parameterize ([param.c value] ...)
   body ...)
   #'(begin
   (define new-parameterization
 (parameterize ([param.c value] ...)
   (current-parameterization)))
   (do-splicing-parameterize new-parameterization body)
   ...))])

(define-syntax-parser do-splicing-parameterize
  [(_ parameterization:expr body:expr)
   (syntax-parse (local-expand #'body (syntax-local-context)
   (kernel-form-identifier-list))
 #:literal-sets [kernel-literals]
 [(begin new-body ...)
  (syntax/loc/props this-syntax
(begin
  (do-splicing-parameterize parameterization new-body)
  ...))]
 [(define-values ids rhs)
  (syntax/loc/props this-syntax
(define-values ids
  (call-with-parameterization parameterization
  (thunk rhs]
 [({~or begin-for-syntax define-syntaxes module module*
#%require #%provide #%declare}
   . _)
  this-syntax]
 [expr
  (syntax/loc/props this-syntax
(call-with-parameterization parameterization
(thunk expr)))])])

I have not extensively tested it, but it seems to work okay for simple
programs. For example, given the following program:

(define my-param (make-parameter #f))

(splicing-parameterize ([my-param #t])
  (my-param)
  (define x (my-param))
  (define (f) (my-param)))

x
(f)

...the output is:

#t
#t
#f

...which I believe makes sense, since the dynamic adjustment of my-param
does not affect its use within the internal definition of a procedure.

Additionally, mutating a parameter does the right thing, so this
program:

(splicing-parameterize ([my-param #t])
  (my-param 42)
  (my-param))

(my-param)

...produces:

42
#f

This seems like something that would make sense in racket/splicing,
though it’s different from the other forms, since they are all lexical
binding forms (even splicing-syntax-parameterize), whereas parameterize
is not.

Alexis



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