Re: Fwd: new function

2021-09-21 Thread Damien Mattei
i have tested define-once
http://www.gnu.org/software/guile/docs/master/guile.html/Top-Level.html
(the defvar of Lisp)and idea are:
-unfortunately it is considered by scheme as a define,so there is some
context where it is not allowed in my code
-seems to work fine at toplevel (as mentioned in doc) but strange behavior
in a function, i did not understand really what happened but i got some
#unspecified value.

here are my test code:
cheme@(guile-user)> (define (foo2)
  (define-once  x 1)
  (if #t
  (let ()
(define-once x 2)
;;(set! x 2)
(display "x=")
(display x)
(newline))
  'never)
  (display x)
  (newline))
scheme@(guile-user)> x
;;; : warning: possibly unbound variable `x'
ice-9/boot-9.scm:1669:16: In procedure raise-exception:
Unbound variable: x

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]> ,q
scheme@(guile-user)> (foo2)
x=2
1
scheme@(guile-user)> (foo2)
x=2
1
scheme@(guile-user)> x
;;; : warning: possibly unbound variable `x'
ice-9/boot-9.scm:1669:16: In procedure raise-exception:
Unbound variable: x

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [1]> ,q
scheme@(guile-user)> (define x 3)
scheme@(guile-user)> (foo2)
x=#
#
scheme@(guile-user)> x
3

it does not seem to help me, perheaps if i can test the return of
# 

Damien

On Sun, Sep 19, 2021 at 4:46 PM Matt Wette  wrote:

>
>
> On 9/19/21 3:38 AM, Maxime Devos wrote:
> > Damien Mattei schreef op zo 19-09-2021 om 11:18 [+0200]:
> >> -- Forwarded message -
> >> From: Damien Mattei 
> >> Date: Sun, Sep 19, 2021 at 9:54 AM
> >> Subject: new function
> >> To: 
> >>
> >>
> >> hello,
> >> i'm developing an extension to Scheme
> >> and i need a procedure or macro that define a variable only if it is not
> >> bind and if it is just set! it.
> > Could you give an example in which the hypothetical define-or-set! is
> used?
> > I wonder where such a thing would be useful.
> >
> >> I can not do it in Guile or any Scheme,and i'm desperately searching a
> way
> >> to do that. I finally conclude that it can be done only by adding it in
> the
> >> language.
> >>
> >> Can someone include a such function in Guile next release?
> >> i know guile have a predicate defined?
> > defined? only works on global variables, not on lexicals,
> > and depends on the (current-module), which is not necessarily
> > the module defined? is used in.
> >
> >>   to test binfing of a vairable but
> >> writing a macro with it is not possible because define can be used in an
> >> expression context.
> > You can use 'syntax-local-binding'.
> >
> > (use-modules (system syntax))
> > (define-syntax define-or-set!
> >(lambda (s)
> >  (syntax-case s ()
> >((_ var value)
> > (case (syntax-local-binding #'var)
> >   ((lexical displaced-lexical) #'(set! var value))
> >   ((global) #'(define var value))
> >   (else ???))
> >
> > ,expand (define-or-set! a 0) ; $_ = (define a 0)
> > ,expand (let ((a 0)) (define-or-set! a 0) a) ; $_ = (let ((a 0)) (set! a
> 0) a)
> > (define-or-set! a 0)
> > ,expand (define-or-set! a 0) ; $_ = (define a 0) (might or might not be
> acceptable for your use case
> > ,expand (let () (define-or-set! a 0) (define-or-set! a 1) a) ; $_ = (let
> () (define a 0) (set! a 1))
> >
> > Greetings,
> > Maxime.
>
> Does this work for you?
>
> scheme@(guile-user)> (define a 1)
> scheme@(guile-user)> (define a 2)
> scheme@(guile-user)> a
> $2 = 2
> scheme@(guile-user)>
>
>
>
>
>
>
>


Re: foreign objects and the garbage collector

2021-09-21 Thread adriano
Hi Olivier,

thank you very much for your reply

Il giorno dom, 19/09/2021 alle 14.11 -0400, Olivier Dion ha scritto:
> On Sun, 19 Sep 2021, adriano  wrote:
> > 
> > 




> > It'd be so nice to have an example
> 
> (define (with-my-resource token proc)
>   (let ((resource #f))
>     (dynamic-wind
>   (lambda ()
> (set! resource (open-my-resource% token)))
> 
>   (proc resource)
> 
>   (lambda ()
> (when resource
>   (close-my-resource% resource))
> 
> (with-my-resource "some-internal-token" (lambda ()))

Oh my, thank you for this !

This should be included in the manual !

The example that's there currently is totally indequate, in my opinion

> > 
> 
> Says you have `open_my_resource()` and `close_my_resource()` in C in
> library "libfoo.so" where open_my_resource takes a C string and returns
> an integer for the resource while close_my_resource takes the integer
> of
> the resource:
> 
> (define open-my-resource%
>   (eval-when (eval load compile)
>     (let ((this-lib (load-foreign-library "libfoo")))
>   (foreign-library-function this-lib "open_my_resource"
>     #:return-type int
>     #:arg-types (list '*
> 
> (define open-my-resource%
>   (eval-when (eval load compile)
>     (let ((this-lib (load-foreign-library "libfoo")))
>   (foreign-library-function this-lib "open_my_resource"
>     #:return-type int
>     #:arg-types (list int)

Uhmm... I see 2 versions of open-my-resource%

The only slight difference I see is in the #:arg-types

The first one has 

(list '*) 

and the second one has 

(list int)


Maybe you you got confused while editing ?

This would be my version of close-my-resource%


(define close-my-resource%
   (eval-when (eval load compile)
 (let ((this-lib (load-foreign-library "libfoo")))
   (foreign-library-function this-lib "close_my_resource"
 #:return-type int
 #:arg-types (int)




>     
> Note that you probably need to do a wrapper named `open-my-resource`
> to
> do the conversion of scm_string to C raw pointer before calling
> `open-my-resource%` in this particular case.

Ok

> 
> This is just an example, but it shows you that you can call foreign C
> primitives easily without any C code, and that you have to use a
> dynamic context to manage the lifetime of the C resources.
> 

Thank you again




Re: foreign objects and the garbage collector

2021-09-21 Thread Olivier Dion via General Guile related discussions
On Tue, 21 Sep 2021, adriano  wrote:
> Hi Olivier,
>
> thank you very much for your reply
>
> Il giorno dom, 19/09/2021 alle 14.11 -0400, Olivier Dion ha scritto:
>> On Sun, 19 Sep 2021, adriano  wrote:
>> > 
>> > 
>
>
>
>
>> > It'd be so nice to have an example
>> 
>> (define (with-my-resource token proc)
>>   (let ((resource #f))
>>     (dynamic-wind
>>   (lambda ()
>> (set! resource (open-my-resource% token)))
>> 
>>   (proc resource)
>> 
>>   (lambda ()
>> (when resource
>>   (close-my-resource% resource))
>> 
>> (with-my-resource "some-internal-token" (lambda ()))
>
> Oh my, thank you for this !
>
> This should be included in the manual !
>
> The example that's there currently is totally indequate, in my opinion
>
>> > 
>> 
>> Says you have `open_my_resource()` and `close_my_resource()` in C in
>> library "libfoo.so" where open_my_resource takes a C string and returns
>> an integer for the resource while close_my_resource takes the integer
>> of
>> the resource:
>> 
>> (define open-my-resource%
>>   (eval-when (eval load compile)
>>     (let ((this-lib (load-foreign-library "libfoo")))
>>   (foreign-library-function this-lib "open_my_resource"
>>     #:return-type int
>>     #:arg-types (list '*
>> 
>> (define open-my-resource%
>>   (eval-when (eval load compile)
>>     (let ((this-lib (load-foreign-library "libfoo")))
>>   (foreign-library-function this-lib "open_my_resource"
>>     #:return-type int
>>     #:arg-types (list int)
>
> Uhmm... I see 2 versions of open-my-resource%
> The only slight difference I see is in the #:arg-types
>
> The first one has 
>
> (list '*) 
>
> and the second one has 
>
> (list int)
>
>
> Maybe you you got confused while editing ?

You're right.  I copy paste the form two times and forget to edit the second
binding name.  I meant `close-my-resource%` for the second define.

>
> Thank you again

Just make sure to read what Maxime says about escape continuation.
Dynamic wind are not bullet proof.

As the manual says:

If, any time during the execution of THUNK, the dynamic extent of
the ‘dynamic-wind’ expression is escaped non-locally, OUT_GUARD is
called.  If the dynamic extent of the dynamic-wind is re-entered,
IN_GUARD is called.  Thus IN_GUARD and OUT_GUARD may be called any
number of times.

Thus, you could also do a `(set! resource #f)` after freeing it, so that
the overall dynamic-wind is reentrant and you don't end up with double
free of resource.

-- 
Olivier Dion
Polymtl


Re: foreign objects and the garbage collector

2021-09-21 Thread adriano
Hi Maxime,

Il giorno dom, 19/09/2021 alle 20.23 +0200, Maxime Devos ha scritto:
> Olivier Dion via General Guile related discussions schreef op zo 19-
> 09-2021 om 14:11 [-0400]:
> > On Sun, 19 Sep 2021, adriano  wrote:
> > > > If you want to avoid the problem, you should explicitely bind
> > > > and
> > > > call the gps-close function and not rely on the garbage
> > > > collector to
> > > > do it for you. You can use dynamic-wind to open and close
> > > > resources as needed.
> > > 
> > > It'd be so nice to have an example
> > 
> > (define (with-my-resource token proc)
> >   (let ((resource #f))
> >     (dynamic-wind
> >   (lambda ()
> > (set! resource (open-my-resource% token)))
> > 
> >   (proc resource)
> > 
> >   (lambda ()
> > (when resource
> >   (close-my-resource% resource))
> > 
> > (with-my-resource "some-internal-token" (lambda ()))
> 
> FWIW, this doesn't work well with continuations, e.g. if you use
> guile-fibers
> for concurrency.  I'm not familiar with 'libgps', so I'm not sure if
> it would
> work for you, but another method for implementing with-my-resource
> could be to
> use the exception handling mechanism to  call 'close-my-resource' on
> both
> normal exits and abnormal exits.
> 
> Note that this alternative method does _not_ close the resource when
> calling
> an escape continuation (let/ec (with-my-resource  .. (lambda (r) (ec)
> (unreachable,
> so you might want to use something like guardians and after-gc-hook
> to eventually
> free the resource.
> 
> (Here, close-my-resource is like close-my-resource% except it doesn't
> do anything
> if the resource is already closed.)
> 
> Greetings,
> Maxime.


Well, it'd be wonderful to have an example of what you're describing
here ! 🙂️

The new exceptions system is still quite obscure 🤷️




Re: foreign objects and the garbage collector

2021-09-21 Thread adriano
Il giorno mar, 21/09/2021 alle 10.25 -0400, Olivier Dion ha scritto:
> On Tue, 21 Sep 2021, adriano  wrote:
> > Hi Olivier,
> > 
> > thank you very much for your reply
> > 
> > Il giorno dom, 19/09/2021 alle 14.11 -0400, Olivier Dion ha
> > scritto:
> > > On Sun, 19 Sep 2021, adriano  wrote:
> > > > 
> > > > 
> > 
> > 
> > 
> > 
> > > > It'd be so nice to have an example
> > > 
> > > (define (with-my-resource token proc)
> > >   (let ((resource #f))
> > >     (dynamic-wind
> > >   (lambda ()
> > > (set! resource (open-my-resource% token)))
> > > 
> > >   (proc resource)
> > > 
> > >   (lambda ()
> > > (when resource
> > >   (close-my-resource% resource))
> > > 
> > > (with-my-resource "some-internal-token" (lambda ()))
> > 
> > Oh my, thank you for this !
> > 
> > This should be included in the manual !
> > 
> > The example that's there currently is totally indequate, in my
> > opinion
> > 
> > > > 
> > > 
> > > Says you have `open_my_resource()` and `close_my_resource()` in C
> > > in
> > > library "libfoo.so" where open_my_resource takes a C string and
> > > returns
> > > an integer for the resource while close_my_resource takes the
> > > integer
> > > of
> > > the resource:
> > > 
> > > (define open-my-resource%
> > >   (eval-when (eval load compile)
> > >     (let ((this-lib (load-foreign-library "libfoo")))
> > >   (foreign-library-function this-lib "open_my_resource"
> > >     #:return-type int
> > >     #:arg-types (list '*
> > > 
> > > (define open-my-resource%
> > >   (eval-when (eval load compile)
> > >     (let ((this-lib (load-foreign-library "libfoo")))
> > >   (foreign-library-function this-lib "open_my_resource"
> > >     #:return-type int
> > >     #:arg-types (list int)
> > 
> > Uhmm... I see 2 versions of open-my-resource%
> > The only slight difference I see is in the #:arg-types
> > 
> > The first one has 
> > 
> > (list '*) 
> > 
> > and the second one has 
> > 
> > (list int)
> > 
> > 
> > Maybe you you got confused while editing ?
> 
> You're right.  I copy paste the form two times and forget to edit the
> second
> binding name.  I meant `close-my-resource%` for the second define.
> 
> > 
> > Thank you again
> 
> Just make sure to read what Maxime says about escape continuation.
> Dynamic wind are not bullet proof.
> 
> As the manual says:
> 
>     If, any time during the execution of THUNK, the dynamic
> extent of
>     the ‘dynamic-wind’ expression is escaped non-locally,
> OUT_GUARD is
>     called.  If the dynamic extent of the dynamic-wind is re-
> entered,
>     IN_GUARD is called.  Thus IN_GUARD and OUT_GUARD may be
> called any
>     number of times.
> 
> Thus, you could also do a `(set! resource #f)` after freeing it, so
> that
> the overall dynamic-wind is reentrant and you don't end up with
> double
> free of resource.
> 

After seeing your example of usage of dinamic-wind, I understand what
IN_GUARD and OUT_GUARD are supposed to be

Before that it was quite nebulous

Thanks again







Re: foreign objects and the garbage collector

2021-09-21 Thread Maxime Devos
adriano schreef op di 21-09-2021 om 16:26 [+0200]:
> 
> [...]
> Well, it'd be wonderful to have an example of what you're describing
> here ! 🙂️
> 
> The new exceptions system is still quite obscure 🤷️

Ignoring with-throw-handler, raise-continuable and pre-unwind handlers, it's
the same mechanism as in Java or Python, though with different syntax, and
unlike Java, Guile doesn't have ‘finally’:

;; Can also be implemented with the old 'catch' -- 'catch' isn't disappearing.
(guard (c (#t (close-resource-unless-closed the-resource)
  (raise-exception c)))
  (define-values return-values (do-stuff))
  (close-the-resource-unless-closed the-resource)
  (apply values return-vales))

Greetings,
Maxime


signature.asc
Description: This is a digitally signed message part


Re: Fwd: new function

2021-09-21 Thread Maxime Devos
Damien Mattei schreef op di 21-09-2021 om 15:04 [+0200]:
> i have tested define-once
> http://www.gnu.org/software/guile/docs/master/guile.html/Top-Level.html
> (the defvar of Lisp)and idea are:
> -unfortunately it is considered by scheme as a define,so there is some
> context where it is not allowed in my code
> -seems to work fine at toplevel (as mentioned in doc) but strange behavior
> in a function, i did not understand really what happened but i got some
> #unspecified value.
> 
> here are my test code:
> cheme@(guile-user)> (define (foo2)
>   (define-once  x 1)
>   (if #t
>   (let ()
> (define-once x 2)
> ;;(set! x 2)
> (display "x=")
> (display x)
> (newline))
>   'never)
>   (display x)
>   (newline))

Possibly you want (added a set? argument for demonstration):

(define (foo2 set?)
  (define x) ; define an (undefined or unbound, not sure about terminology) 
variable
  (if set?
  (let ()
(set! x 2) ; change the value of x
(display "x=")
(display x)
(newline))
  'never)
  (display x)
  (newline))

That should be portable and avoids global state.

scheme@(guile-user)> x
;;; :20:0: warning: possibly unbound variable `x'
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
Unbound variable: x
scheme@(guile-user) [1]> ,q

scheme@(guile-user) [1]> (foo2 #f)
# ; I expected an error as would result from ...

;; ... this ...
scheme@(guile-user)> (variable-ref (make-undefined-variable))
ice-9/boot-9.scm:1685:16: In procedure raise-exception:
In procedure variable-ref: Unbound variable: #>

Entering a new prompt.  Type `,bt' for a backtrace or `,q' to continue.
scheme@(guile-user) [2]> 

;; instead  of # but whatever ...

scheme@(guile-user) [1]> (foo2 #t)
x=2
2
scheme@(guile-user) [1]> (foo2 #t)
x=2
2


scheme@(guile-user) [1]> (define x 3)
scheme@(guile-user) [1]> (foo2 #t)
x=2 ; foo2 doesn't use the global variable 'x'
2

scheme@(guile-user) [1]> x
$1 = 3

Does this seem reasonable to you?


signature.asc
Description: This is a digitally signed message part