unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* access slot of a class
@ 2023-11-20 21:32 Damien Mattei
  2023-11-20 23:27 ` Mikael Djurfeldt
       [not found] ` <CABESxg=NP7LJepcAG-z21f13tVup0NL0iG=4ae+dCADNf+Xpsg@mail.gmail.com>
  0 siblings, 2 replies; 7+ messages in thread
From: Damien Mattei @ 2023-11-20 21:32 UTC (permalink / raw)
  To: guile-user

hi,
is there a way to access a slot of a class like other variable with set! ,
Racket,Kawa allow that, but it does not seem to be the case in Guile.

regards,
damien


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: access slot of a class
  2023-11-20 21:32 access slot of a class Damien Mattei
@ 2023-11-20 23:27 ` Mikael Djurfeldt
       [not found] ` <CABESxg=NP7LJepcAG-z21f13tVup0NL0iG=4ae+dCADNf+Xpsg@mail.gmail.com>
  1 sibling, 0 replies; 7+ messages in thread
From: Mikael Djurfeldt @ 2023-11-20 23:27 UTC (permalink / raw)
  To: Damien Mattei; +Cc: guile-user, Mikael Djurfeldt

Well, if you want to set a slot explicitly using the set! form, and this is
a good way to access a slot, you can use an accessor (which internally is a
pair of a getter and a setter):

(define-class a () (x #:accessor x))

(define o (make a))

(set! (x o) 1)
(x o) -> 1

I guess you already know that you can *also* reference this slot using:

(slot-set! o 'x 2)
(slot-ref o 'x) -> 2

I should add that the accessor way fits well with GOOPS' (and CLOS')
basically rather simple concept of having objects and then generic
functions operating on them (an accessor is a generic function). Generic
functions, in turn, fit with how some Scheme procedures accept different
types of arguments and can dispatch to different actions on them.

Best regards,
Mikael

On Mon, Nov 20, 2023 at 10:33 PM Damien Mattei <damien.mattei@gmail.com>
wrote:

> hi,
> is there a way to access a slot of a class like other variable with set! ,
> Racket,Kawa allow that, but it does not seem to be the case in Guile.
>
> regards,
> damien
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: access slot of a class
       [not found] ` <CABESxg=NP7LJepcAG-z21f13tVup0NL0iG=4ae+dCADNf+Xpsg@mail.gmail.com>
@ 2023-11-21  8:19   ` Damien Mattei
  2023-11-21  8:21     ` Damien Mattei
  2023-11-21 10:31     ` Mikael Djurfeldt
  0 siblings, 2 replies; 7+ messages in thread
From: Damien Mattei @ 2023-11-21  8:19 UTC (permalink / raw)
  To: Nate Rosenbloom, guile-user, mikael

that is interesting answer about guile's features i did not know ,
it is related with code i'm writing that instead of fetching the value
modify it using the fetch syntax in Scheme+ but my question was just
about how to have a class method in a class that can set! the value of
a slot. This does nt seem to be available in Guile because "A method
is not formally associated with any single class (as it is in many
other object oriented languages)" [0].

i will explain the problem more in my answer to Mikael and you, i just
wanted to be able to create a class method that can access the slot
directly , more than in the example [2] :

(define-class <my-complex> (<number>)
   (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
   (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))

(set! (real-part c) new-value)

in othe Scheme i can do simply:

(set! r new-value)

for example in Kawa:

(define-simple-class ReseauRetroPropagation ()

  (nbiter init-value: 3)
  (activation_function_hidden_layer)
  (activation_function_output_layer)
  (activation_function_hidden_layer_derivative)
  (activation_function_output_layer_derivative)

  (ηₛ 1.0)

  (z)
  (z̃)

  (M)

  (ᐁ)

  (error 0)

  ((*init* nc nbiter0 ηₛ0 activation_function_hidden_layer0
                     activation_function_output_layer0
              activation_function_hidden_layer_derivative0
              activation_function_output_layer_derivative0)

   (display "*init* : nc=") (display nc) (newline)
   {nbiter <- nbiter0}
   {ηₛ <- ηₛ0}

...

or in Racket :

(define ReseauRetroPropagation

  (class object%

     (super-new)

     ; this is the initialisation parameters
     (init-field (nc #(2 3 1)) ;; on crée le tableau des couches du réseau
                    (nbiter 10000)
                    (ηₛ 1.0)
             (activation_function_hidden_layer tanh)
             (activation_function_output_layer tanh)
             (activation_function_hidden_layer_derivative der_tanh)
             (activation_function_output_layer_derivative der_tanh))

     {lnc <+ (vector-length nc)}

     ; les entrées concrètes seront fournies avec la méthode accepte
     ;; (field (z (vector-ec (: i (vector-length nc)) (make-vector {nc[i]} 0))))
     ;;(field (z (vector-ec (:vector lg nc)
    ;;              (make-vector lg 0))))
     (field (z (vector-map (lambda (lg) (make-vector lg 0))
                   nc)))

     ;; (field (z (for/vector ([lg nc])
     ;;                (make-vector lg 0))))

     (display "z=") (display z) (newline)


     ; z̃[0] is not used as z[0] is x, the initial data
     ;;(field (z̃ (vector-ec (:vector lg nc)
        ;;          (make-vector lg 0))))
     (field (z̃ (vector-map (lambda (lg) (make-vector lg 0))
                   nc)))


     (display "z̃=") (display z̃) (newline)


     {M <+ (vector-ec (: n {lnc - 1}) ; vectors by eager comprehension (SRFI 42)
              create-matrix-vect-by-function(uniform-dummy nc[n + 1]
{nc[n] + 1}))} ;; Matrix-vect

     ;(field (M (vector-ec (: n {lnc - 1}) ; vectors by eager
comprehension (SRFI 42)
     ;          (create-matrix-vect-by-function uniform-dummy {nc[n +
1]} {nc[n] + 1})))) ;; Matrix-vect


     (display "M=") (display M) (newline)

     (field (ᐁ (for/vector ([lg nc])
                   (make-vector lg 0))))


     (display "ᐁ=") (display ᐁ) (newline)

     (display "nbiter=") (display nbiter) (newline)

     (field (error 0))


     ; forward propagation

         ; z_* sans le coef. 1 constant pour le bias
     (define (accepte_et_propage x) ; on entre des entrées et on les propage

        (when {vector-length(x) ≠ vector-length(z[0])}
          (display "Mauvais nombre d'entrées !") (newline)
          (exit #f))

        {z[0] <- x} ; on ne touche pas au biais

in those 2 example z is a slot (or field in Racket) of the class
ReseauRetroPropagation that can directly be accessed from a class
method without using the accessors (getter and setter)

Regards,
Damien




[0] 8.6 Methods and Generic Functions
https://www.gnu.org/software/guile/manual/html_node/Methods-and-Generic-Functions.html

[2] 8.5  Illustrating Slot Description:
https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html

On Mon, Nov 20, 2023 at 11:43 PM Nate Rosenbloom
<nate.rosenbloom@gmail.com> wrote:
>>
>> is there a way to access a slot of a class like other variable with set! ,
>> Racket,Kawa allow that, but it does not seem to be the case in Guile.
>
>
> Hello Damien:
> Does 'generalized set'[0] do what you want?
> You can create accessor procedures that have an attached setter -
>
> Or were you speaking specifically about class slots? In which case it looks like the accessor can be used in in set!: [2]
> Thanks,
> Nate
> [0] 7.5.14 sfri 17 Generalized set!: https://www.gnu.org/software/guile/manual/html_node/SRFI_002d17.html
> [1] 6.7.8 Procedures with Setters: https://www.gnu.org/software/guile/manual/html_node/Procedures-with-Setters.html
> [2] 8.5  Illustrating Slot Description: https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html
>



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: access slot of a class
  2023-11-21  8:19   ` Damien Mattei
@ 2023-11-21  8:21     ` Damien Mattei
  2023-11-21 10:31     ` Mikael Djurfeldt
  1 sibling, 0 replies; 7+ messages in thread
From: Damien Mattei @ 2023-11-21  8:21 UTC (permalink / raw)
  To: Nate Rosenbloom, guile-user, mikael

just forget to say that in my previous examples, <- is a macro that
contain a set! case that is used with single variable.(does not use
setter, just set!)

On Tue, Nov 21, 2023 at 9:19 AM Damien Mattei <damien.mattei@gmail.com> wrote:
>
> that is interesting answer about guile's features i did not know ,
> it is related with code i'm writing that instead of fetching the value
> modify it using the fetch syntax in Scheme+ but my question was just
> about how to have a class method in a class that can set! the value of
> a slot. This does nt seem to be available in Guile because "A method
> is not formally associated with any single class (as it is in many
> other object oriented languages)" [0].
>
> i will explain the problem more in my answer to Mikael and you, i just
> wanted to be able to create a class method that can access the slot
> directly , more than in the example [2] :
>
> (define-class <my-complex> (<number>)
>    (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
>    (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
>
> (set! (real-part c) new-value)
>
> in othe Scheme i can do simply:
>
> (set! r new-value)
>
> for example in Kawa:
>
> (define-simple-class ReseauRetroPropagation ()
>
>   (nbiter init-value: 3)
>   (activation_function_hidden_layer)
>   (activation_function_output_layer)
>   (activation_function_hidden_layer_derivative)
>   (activation_function_output_layer_derivative)
>
>   (ηₛ 1.0)
>
>   (z)
>   (z̃)
>
>   (M)
>
>   (ᐁ)
>
>   (error 0)
>
>   ((*init* nc nbiter0 ηₛ0 activation_function_hidden_layer0
>                      activation_function_output_layer0
>               activation_function_hidden_layer_derivative0
>               activation_function_output_layer_derivative0)
>
>    (display "*init* : nc=") (display nc) (newline)
>    {nbiter <- nbiter0}
>    {ηₛ <- ηₛ0}
>
> ...
>
> or in Racket :
>
> (define ReseauRetroPropagation
>
>   (class object%
>
>      (super-new)
>
>      ; this is the initialisation parameters
>      (init-field (nc #(2 3 1)) ;; on crée le tableau des couches du réseau
>                     (nbiter 10000)
>                     (ηₛ 1.0)
>              (activation_function_hidden_layer tanh)
>              (activation_function_output_layer tanh)
>              (activation_function_hidden_layer_derivative der_tanh)
>              (activation_function_output_layer_derivative der_tanh))
>
>      {lnc <+ (vector-length nc)}
>
>      ; les entrées concrètes seront fournies avec la méthode accepte
>      ;; (field (z (vector-ec (: i (vector-length nc)) (make-vector {nc[i]} 0))))
>      ;;(field (z (vector-ec (:vector lg nc)
>     ;;              (make-vector lg 0))))
>      (field (z (vector-map (lambda (lg) (make-vector lg 0))
>                    nc)))
>
>      ;; (field (z (for/vector ([lg nc])
>      ;;                (make-vector lg 0))))
>
>      (display "z=") (display z) (newline)
>
>
>      ; z̃[0] is not used as z[0] is x, the initial data
>      ;;(field (z̃ (vector-ec (:vector lg nc)
>         ;;          (make-vector lg 0))))
>      (field (z̃ (vector-map (lambda (lg) (make-vector lg 0))
>                    nc)))
>
>
>      (display "z̃=") (display z̃) (newline)
>
>
>      {M <+ (vector-ec (: n {lnc - 1}) ; vectors by eager comprehension (SRFI 42)
>               create-matrix-vect-by-function(uniform-dummy nc[n + 1]
> {nc[n] + 1}))} ;; Matrix-vect
>
>      ;(field (M (vector-ec (: n {lnc - 1}) ; vectors by eager
> comprehension (SRFI 42)
>      ;          (create-matrix-vect-by-function uniform-dummy {nc[n +
> 1]} {nc[n] + 1})))) ;; Matrix-vect
>
>
>      (display "M=") (display M) (newline)
>
>      (field (ᐁ (for/vector ([lg nc])
>                    (make-vector lg 0))))
>
>
>      (display "ᐁ=") (display ᐁ) (newline)
>
>      (display "nbiter=") (display nbiter) (newline)
>
>      (field (error 0))
>
>
>      ; forward propagation
>
>          ; z_* sans le coef. 1 constant pour le bias
>      (define (accepte_et_propage x) ; on entre des entrées et on les propage
>
>         (when {vector-length(x) ≠ vector-length(z[0])}
>           (display "Mauvais nombre d'entrées !") (newline)
>           (exit #f))
>
>         {z[0] <- x} ; on ne touche pas au biais
>
> in those 2 example z is a slot (or field in Racket) of the class
> ReseauRetroPropagation that can directly be accessed from a class
> method without using the accessors (getter and setter)
>
> Regards,
> Damien
>
>
>
>
> [0] 8.6 Methods and Generic Functions
> https://www.gnu.org/software/guile/manual/html_node/Methods-and-Generic-Functions.html
>
> [2] 8.5  Illustrating Slot Description:
> https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html
>
> On Mon, Nov 20, 2023 at 11:43 PM Nate Rosenbloom
> <nate.rosenbloom@gmail.com> wrote:
> >>
> >> is there a way to access a slot of a class like other variable with set! ,
> >> Racket,Kawa allow that, but it does not seem to be the case in Guile.
> >
> >
> > Hello Damien:
> > Does 'generalized set'[0] do what you want?
> > You can create accessor procedures that have an attached setter -
> >
> > Or were you speaking specifically about class slots? In which case it looks like the accessor can be used in in set!: [2]
> > Thanks,
> > Nate
> > [0] 7.5.14 sfri 17 Generalized set!: https://www.gnu.org/software/guile/manual/html_node/SRFI_002d17.html
> > [1] 6.7.8 Procedures with Setters: https://www.gnu.org/software/guile/manual/html_node/Procedures-with-Setters.html
> > [2] 8.5  Illustrating Slot Description: https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html
> >



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: access slot of a class
  2023-11-21  8:19   ` Damien Mattei
  2023-11-21  8:21     ` Damien Mattei
@ 2023-11-21 10:31     ` Mikael Djurfeldt
  2023-11-21 11:49       ` Mikael Djurfeldt
  2023-11-21 18:10       ` Damien Mattei
  1 sibling, 2 replies; 7+ messages in thread
From: Mikael Djurfeldt @ 2023-11-21 10:31 UTC (permalink / raw)
  To: Damien Mattei; +Cc: Nate Rosenbloom, guile-user, Mikael Djurfeldt

OK, now I see what you are asking. You want the slots to be available as
local variables in the lexical scope of the method. The answer is that that
is not possible "out of the box". I guess it *could* be made available
through some contortionist coding using a combination of GOOPS and the
syntax-case macro system, but it goes against the design of GOOPS and CLOS.
There are macro systems where the class definition provides a lexical scope
and there are macro systems based on generic functions. It's two different
takes on object orientation.

(Note though regarding the citation about a method not being formally
associated with a single class: In the case of accessor methods, which take
a single argument, they are in a sense associated with a single class.)

On Tue, Nov 21, 2023 at 9:19 AM Damien Mattei <damien.mattei@gmail.com>
wrote:

> that is interesting answer about guile's features i did not know ,
> it is related with code i'm writing that instead of fetching the value
> modify it using the fetch syntax in Scheme+ but my question was just
> about how to have a class method in a class that can set! the value of
> a slot. This does nt seem to be available in Guile because "A method
> is not formally associated with any single class (as it is in many
> other object oriented languages)" [0].
>
> i will explain the problem more in my answer to Mikael and you, i just
> wanted to be able to create a class method that can access the slot
> directly , more than in the example [2] :
>
> (define-class <my-complex> (<number>)
>    (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
>    (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
>
> (set! (real-part c) new-value)
>
> in othe Scheme i can do simply:
>
> (set! r new-value)
>
> for example in Kawa:
>
> (define-simple-class ReseauRetroPropagation ()
>
>   (nbiter init-value: 3)
>   (activation_function_hidden_layer)
>   (activation_function_output_layer)
>   (activation_function_hidden_layer_derivative)
>   (activation_function_output_layer_derivative)
>
>   (ηₛ 1.0)
>
>   (z)
>   (z̃)
>
>   (M)
>
>   (ᐁ)
>
>   (error 0)
>
>   ((*init* nc nbiter0 ηₛ0 activation_function_hidden_layer0
>                      activation_function_output_layer0
>               activation_function_hidden_layer_derivative0
>               activation_function_output_layer_derivative0)
>
>    (display "*init* : nc=") (display nc) (newline)
>    {nbiter <- nbiter0}
>    {ηₛ <- ηₛ0}
>
> ...
>
> or in Racket :
>
> (define ReseauRetroPropagation
>
>   (class object%
>
>      (super-new)
>
>      ; this is the initialisation parameters
>      (init-field (nc #(2 3 1)) ;; on crée le tableau des couches du réseau
>                     (nbiter 10000)
>                     (ηₛ 1.0)
>              (activation_function_hidden_layer tanh)
>              (activation_function_output_layer tanh)
>              (activation_function_hidden_layer_derivative der_tanh)
>              (activation_function_output_layer_derivative der_tanh))
>
>      {lnc <+ (vector-length nc)}
>
>      ; les entrées concrètes seront fournies avec la méthode accepte
>      ;; (field (z (vector-ec (: i (vector-length nc)) (make-vector {nc[i]}
> 0))))
>      ;;(field (z (vector-ec (:vector lg nc)
>     ;;              (make-vector lg 0))))
>      (field (z (vector-map (lambda (lg) (make-vector lg 0))
>                    nc)))
>
>      ;; (field (z (for/vector ([lg nc])
>      ;;                (make-vector lg 0))))
>
>      (display "z=") (display z) (newline)
>
>
>      ; z̃[0] is not used as z[0] is x, the initial data
>      ;;(field (z̃ (vector-ec (:vector lg nc)
>         ;;          (make-vector lg 0))))
>      (field (z̃ (vector-map (lambda (lg) (make-vector lg 0))
>                    nc)))
>
>
>      (display "z̃=") (display z̃) (newline)
>
>
>      {M <+ (vector-ec (: n {lnc - 1}) ; vectors by eager comprehension
> (SRFI 42)
>               create-matrix-vect-by-function(uniform-dummy nc[n + 1]
> {nc[n] + 1}))} ;; Matrix-vect
>
>      ;(field (M (vector-ec (: n {lnc - 1}) ; vectors by eager
> comprehension (SRFI 42)
>      ;          (create-matrix-vect-by-function uniform-dummy {nc[n +
> 1]} {nc[n] + 1})))) ;; Matrix-vect
>
>
>      (display "M=") (display M) (newline)
>
>      (field (ᐁ (for/vector ([lg nc])
>                    (make-vector lg 0))))
>
>
>      (display "ᐁ=") (display ᐁ) (newline)
>
>      (display "nbiter=") (display nbiter) (newline)
>
>      (field (error 0))
>
>
>      ; forward propagation
>
>          ; z_* sans le coef. 1 constant pour le bias
>      (define (accepte_et_propage x) ; on entre des entrées et on les
> propage
>
>         (when {vector-length(x) ≠ vector-length(z[0])}
>           (display "Mauvais nombre d'entrées !") (newline)
>           (exit #f))
>
>         {z[0] <- x} ; on ne touche pas au biais
>
> in those 2 example z is a slot (or field in Racket) of the class
> ReseauRetroPropagation that can directly be accessed from a class
> method without using the accessors (getter and setter)
>
> Regards,
> Damien
>
>
>
>
> [0] 8.6 Methods and Generic Functions
>
> https://www.gnu.org/software/guile/manual/html_node/Methods-and-Generic-Functions.html
>
> [2] 8.5  Illustrating Slot Description:
>
> https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html
>
> On Mon, Nov 20, 2023 at 11:43 PM Nate Rosenbloom
> <nate.rosenbloom@gmail.com> wrote:
> >>
> >> is there a way to access a slot of a class like other variable with
> set! ,
> >> Racket,Kawa allow that, but it does not seem to be the case in Guile.
> >
> >
> > Hello Damien:
> > Does 'generalized set'[0] do what you want?
> > You can create accessor procedures that have an attached setter -
> >
> > Or were you speaking specifically about class slots? In which case it
> looks like the accessor can be used in in set!: [2]
> > Thanks,
> > Nate
> > [0] 7.5.14 sfri 17 Generalized set!:
> https://www.gnu.org/software/guile/manual/html_node/SRFI_002d17.html
> > [1] 6.7.8 Procedures with Setters:
> https://www.gnu.org/software/guile/manual/html_node/Procedures-with-Setters.html
> > [2] 8.5  Illustrating Slot Description:
> https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html
> >
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: access slot of a class
  2023-11-21 10:31     ` Mikael Djurfeldt
@ 2023-11-21 11:49       ` Mikael Djurfeldt
  2023-11-21 18:10       ` Damien Mattei
  1 sibling, 0 replies; 7+ messages in thread
From: Mikael Djurfeldt @ 2023-11-21 11:49 UTC (permalink / raw)
  To: Damien Mattei; +Cc: Nate Rosenbloom, guile-user

(Sorry, when writing "macro systems", I meant "object orientation systems".)

On Tue, Nov 21, 2023 at 11:31 AM Mikael Djurfeldt <mikael@djurfeldt.com>
wrote:

> OK, now I see what you are asking. You want the slots to be available as
> local variables in the lexical scope of the method. The answer is that that
> is not possible "out of the box". I guess it *could* be made available
> through some contortionist coding using a combination of GOOPS and the
> syntax-case macro system, but it goes against the design of GOOPS and CLOS.
> There are macro systems where the class definition provides a lexical scope
> and there are macro systems based on generic functions. It's two different
> takes on object orientation.
>
> (Note though regarding the citation about a method not being formally
> associated with a single class: In the case of accessor methods, which take
> a single argument, they are in a sense associated with a single class.)
>
> On Tue, Nov 21, 2023 at 9:19 AM Damien Mattei <damien.mattei@gmail.com>
> wrote:
>
>> that is interesting answer about guile's features i did not know ,
>> it is related with code i'm writing that instead of fetching the value
>> modify it using the fetch syntax in Scheme+ but my question was just
>> about how to have a class method in a class that can set! the value of
>> a slot. This does nt seem to be available in Guile because "A method
>> is not formally associated with any single class (as it is in many
>> other object oriented languages)" [0].
>>
>> i will explain the problem more in my answer to Mikael and you, i just
>> wanted to be able to create a class method that can access the slot
>> directly , more than in the example [2] :
>>
>> (define-class <my-complex> (<number>)
>>    (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
>>    (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
>>
>> (set! (real-part c) new-value)
>>
>> in othe Scheme i can do simply:
>>
>> (set! r new-value)
>>
>> for example in Kawa:
>>
>> (define-simple-class ReseauRetroPropagation ()
>>
>>   (nbiter init-value: 3)
>>   (activation_function_hidden_layer)
>>   (activation_function_output_layer)
>>   (activation_function_hidden_layer_derivative)
>>   (activation_function_output_layer_derivative)
>>
>>   (ηₛ 1.0)
>>
>>   (z)
>>   (z̃)
>>
>>   (M)
>>
>>   (ᐁ)
>>
>>   (error 0)
>>
>>   ((*init* nc nbiter0 ηₛ0 activation_function_hidden_layer0
>>                      activation_function_output_layer0
>>               activation_function_hidden_layer_derivative0
>>               activation_function_output_layer_derivative0)
>>
>>    (display "*init* : nc=") (display nc) (newline)
>>    {nbiter <- nbiter0}
>>    {ηₛ <- ηₛ0}
>>
>> ...
>>
>> or in Racket :
>>
>> (define ReseauRetroPropagation
>>
>>   (class object%
>>
>>      (super-new)
>>
>>      ; this is the initialisation parameters
>>      (init-field (nc #(2 3 1)) ;; on crée le tableau des couches du réseau
>>                     (nbiter 10000)
>>                     (ηₛ 1.0)
>>              (activation_function_hidden_layer tanh)
>>              (activation_function_output_layer tanh)
>>              (activation_function_hidden_layer_derivative der_tanh)
>>              (activation_function_output_layer_derivative der_tanh))
>>
>>      {lnc <+ (vector-length nc)}
>>
>>      ; les entrées concrètes seront fournies avec la méthode accepte
>>      ;; (field (z (vector-ec (: i (vector-length nc)) (make-vector
>> {nc[i]} 0))))
>>      ;;(field (z (vector-ec (:vector lg nc)
>>     ;;              (make-vector lg 0))))
>>      (field (z (vector-map (lambda (lg) (make-vector lg 0))
>>                    nc)))
>>
>>      ;; (field (z (for/vector ([lg nc])
>>      ;;                (make-vector lg 0))))
>>
>>      (display "z=") (display z) (newline)
>>
>>
>>      ; z̃[0] is not used as z[0] is x, the initial data
>>      ;;(field (z̃ (vector-ec (:vector lg nc)
>>         ;;          (make-vector lg 0))))
>>      (field (z̃ (vector-map (lambda (lg) (make-vector lg 0))
>>                    nc)))
>>
>>
>>      (display "z̃=") (display z̃) (newline)
>>
>>
>>      {M <+ (vector-ec (: n {lnc - 1}) ; vectors by eager comprehension
>> (SRFI 42)
>>               create-matrix-vect-by-function(uniform-dummy nc[n + 1]
>> {nc[n] + 1}))} ;; Matrix-vect
>>
>>      ;(field (M (vector-ec (: n {lnc - 1}) ; vectors by eager
>> comprehension (SRFI 42)
>>      ;          (create-matrix-vect-by-function uniform-dummy {nc[n +
>> 1]} {nc[n] + 1})))) ;; Matrix-vect
>>
>>
>>      (display "M=") (display M) (newline)
>>
>>      (field (ᐁ (for/vector ([lg nc])
>>                    (make-vector lg 0))))
>>
>>
>>      (display "ᐁ=") (display ᐁ) (newline)
>>
>>      (display "nbiter=") (display nbiter) (newline)
>>
>>      (field (error 0))
>>
>>
>>      ; forward propagation
>>
>>          ; z_* sans le coef. 1 constant pour le bias
>>      (define (accepte_et_propage x) ; on entre des entrées et on les
>> propage
>>
>>         (when {vector-length(x) ≠ vector-length(z[0])}
>>           (display "Mauvais nombre d'entrées !") (newline)
>>           (exit #f))
>>
>>         {z[0] <- x} ; on ne touche pas au biais
>>
>> in those 2 example z is a slot (or field in Racket) of the class
>> ReseauRetroPropagation that can directly be accessed from a class
>> method without using the accessors (getter and setter)
>>
>> Regards,
>> Damien
>>
>>
>>
>>
>> [0] 8.6 Methods and Generic Functions
>>
>> https://www.gnu.org/software/guile/manual/html_node/Methods-and-Generic-Functions.html
>>
>> [2] 8.5  Illustrating Slot Description:
>>
>> https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html
>>
>> On Mon, Nov 20, 2023 at 11:43 PM Nate Rosenbloom
>> <nate.rosenbloom@gmail.com> wrote:
>> >>
>> >> is there a way to access a slot of a class like other variable with
>> set! ,
>> >> Racket,Kawa allow that, but it does not seem to be the case in Guile.
>> >
>> >
>> > Hello Damien:
>> > Does 'generalized set'[0] do what you want?
>> > You can create accessor procedures that have an attached setter -
>> >
>> > Or were you speaking specifically about class slots? In which case it
>> looks like the accessor can be used in in set!: [2]
>> > Thanks,
>> > Nate
>> > [0] 7.5.14 sfri 17 Generalized set!:
>> https://www.gnu.org/software/guile/manual/html_node/SRFI_002d17.html
>> > [1] 6.7.8 Procedures with Setters:
>> https://www.gnu.org/software/guile/manual/html_node/Procedures-with-Setters.html
>> > [2] 8.5  Illustrating Slot Description:
>> https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html
>> >
>>
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: access slot of a class
  2023-11-21 10:31     ` Mikael Djurfeldt
  2023-11-21 11:49       ` Mikael Djurfeldt
@ 2023-11-21 18:10       ` Damien Mattei
  1 sibling, 0 replies; 7+ messages in thread
From: Damien Mattei @ 2023-11-21 18:10 UTC (permalink / raw)
  To: mikael; +Cc: Nate Rosenbloom, guile-user

yes , and the solution i found is to pass the object to the method as
argument,
then assigning slot to local variables with accessors in the method and the
source code from Racket or Kawa. Original code was from Python and i had a
bit the same problem, not that slot are not accessible from method, they
are in Python, but you have to use self.v to access v and that is boring in
math expression, so i copy like that v=self.v and then i use v, after
computation, of course i have to update self.v with self.v=v. There is no
other solution in Python.

Example:
class ReseauRetroPropagation():

    def __init__(self,nc=[2,3,1], nbiter=3, ηₛ=1.0 , #ηₑ=0.0001 ,
                 activation_function_hidden_layer=tanh,
                 activation_function_output_layer=tanh,
                 activation_function_hidden_layer_derivative=der_tanh,
                 activation_function_output_layer_derivative=der_tanh):


        lnc = len(nc) # the total of all layer including input, output and
hidden layers

        self.z = [ [0] * n for n in nc ] # les entrées concrètes seront
fournies avec la méthode accepte
        self.z̃ = [ [0] * n for n in nc ] # z̃[0] is not used as z[0] is x,
the initial data


....

 def accepte_et_propage(self,x):         # on entre des entrées et on les
propage

        # note: i just reference the variables for code readness (hide all
the self keyword)
        z = self.z
        z̃ = self.z̃
        M = self.M

        if len(x) != len(z[0]):
            raise ValueError("Mauvais nombre d'entrées !")

        #z[0] = x       # on ne touche pas au biais
        self.z[0] = z[0] = x

        n = len(z)

        # hidden layers
        for i in range(n-2) :

            # create a list with 1 in front for the bias coefficient
            z_1 = [1] + z[i]

            z̃[i+1] = M[i] * z_1 # z̃ = matrix * iterable (list here) ,
return a list

            z[i+1] =
list(map(self.activation_function_hidden_layer,z̃[i+1]))

            # update the variable when necessary
            self.z[i+1] = z[i+1]
            self.z̃[i+1] = z̃[i+1]

this is consuming processor cycles of course but the coding is more easy.

finally the solution in Guile looks like that:

(define-class ReseauRetroPropagation ()

  (nbiter #:init-value 3 #:init-keyword #:nbiter)
  (activation_function_hidden_layer #:init-keyword
#:activation_function_hidden_layer)
  (activation_function_output_layer #:init-keyword
#:activation_function_output_layer)
  (activation_function_hidden_layer_derivative #:init-keyword
#:activation_function_hidden_layer_derivative)
  (activation_function_output_layer_derivative #:init-keyword
#:activation_function_output_layer_derivative)

  (ηₛ #:init-value 1.0 #:init-keyword #:ηₛ)

  (z #:getter nbp-get-z #:setter nbp-set-z!)


....


(define (*init* nc nbp)

(display "*init* : nc=") (display nc) (newline)

{lnc <+ (vector-length nc)}

(define (make-vector-zero lg) (make-vector lg 0))

{z <+ (nbp-get-z nbp)}

{z <- (vector-map make-vector-zero nc)}
    (display "z=") (display z) (newline)


(nbp-set-z! nbp z)
...

) ; end method *init*

Damien


On Tue, Nov 21, 2023 at 11:31 AM Mikael Djurfeldt <mikael@djurfeldt.com>
wrote:

> OK, now I see what you are asking. You want the slots to be available as
> local variables in the lexical scope of the method. The answer is that that
> is not possible "out of the box". I guess it *could* be made available
> through some contortionist coding using a combination of GOOPS and the
> syntax-case macro system, but it goes against the design of GOOPS and CLOS.
> There are macro systems where the class definition provides a lexical scope
> and there are macro systems based on generic functions. It's two different
> takes on object orientation.
>
> (Note though regarding the citation about a method not being formally
> associated with a single class: In the case of accessor methods, which take
> a single argument, they are in a sense associated with a single class.)
>
> On Tue, Nov 21, 2023 at 9:19 AM Damien Mattei <damien.mattei@gmail.com>
> wrote:
>
>> that is interesting answer about guile's features i did not know ,
>> it is related with code i'm writing that instead of fetching the value
>> modify it using the fetch syntax in Scheme+ but my question was just
>> about how to have a class method in a class that can set! the value of
>> a slot. This does nt seem to be available in Guile because "A method
>> is not formally associated with any single class (as it is in many
>> other object oriented languages)" [0].
>>
>> i will explain the problem more in my answer to Mikael and you, i just
>> wanted to be able to create a class method that can access the slot
>> directly , more than in the example [2] :
>>
>> (define-class <my-complex> (<number>)
>>    (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
>>    (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
>>
>> (set! (real-part c) new-value)
>>
>> in othe Scheme i can do simply:
>>
>> (set! r new-value)
>>
>> for example in Kawa:
>>
>> (define-simple-class ReseauRetroPropagation ()
>>
>>   (nbiter init-value: 3)
>>   (activation_function_hidden_layer)
>>   (activation_function_output_layer)
>>   (activation_function_hidden_layer_derivative)
>>   (activation_function_output_layer_derivative)
>>
>>   (ηₛ 1.0)
>>
>>   (z)
>>   (z̃)
>>
>>   (M)
>>
>>   (ᐁ)
>>
>>   (error 0)
>>
>>   ((*init* nc nbiter0 ηₛ0 activation_function_hidden_layer0
>>                      activation_function_output_layer0
>>               activation_function_hidden_layer_derivative0
>>               activation_function_output_layer_derivative0)
>>
>>    (display "*init* : nc=") (display nc) (newline)
>>    {nbiter <- nbiter0}
>>    {ηₛ <- ηₛ0}
>>
>> ...
>>
>> or in Racket :
>>
>> (define ReseauRetroPropagation
>>
>>   (class object%
>>
>>      (super-new)
>>
>>      ; this is the initialisation parameters
>>      (init-field (nc #(2 3 1)) ;; on crée le tableau des couches du réseau
>>                     (nbiter 10000)
>>                     (ηₛ 1.0)
>>              (activation_function_hidden_layer tanh)
>>              (activation_function_output_layer tanh)
>>              (activation_function_hidden_layer_derivative der_tanh)
>>              (activation_function_output_layer_derivative der_tanh))
>>
>>      {lnc <+ (vector-length nc)}
>>
>>      ; les entrées concrètes seront fournies avec la méthode accepte
>>      ;; (field (z (vector-ec (: i (vector-length nc)) (make-vector
>> {nc[i]} 0))))
>>      ;;(field (z (vector-ec (:vector lg nc)
>>     ;;              (make-vector lg 0))))
>>      (field (z (vector-map (lambda (lg) (make-vector lg 0))
>>                    nc)))
>>
>>      ;; (field (z (for/vector ([lg nc])
>>      ;;                (make-vector lg 0))))
>>
>>      (display "z=") (display z) (newline)
>>
>>
>>      ; z̃[0] is not used as z[0] is x, the initial data
>>      ;;(field (z̃ (vector-ec (:vector lg nc)
>>         ;;          (make-vector lg 0))))
>>      (field (z̃ (vector-map (lambda (lg) (make-vector lg 0))
>>                    nc)))
>>
>>
>>      (display "z̃=") (display z̃) (newline)
>>
>>
>>      {M <+ (vector-ec (: n {lnc - 1}) ; vectors by eager comprehension
>> (SRFI 42)
>>               create-matrix-vect-by-function(uniform-dummy nc[n + 1]
>> {nc[n] + 1}))} ;; Matrix-vect
>>
>>      ;(field (M (vector-ec (: n {lnc - 1}) ; vectors by eager
>> comprehension (SRFI 42)
>>      ;          (create-matrix-vect-by-function uniform-dummy {nc[n +
>> 1]} {nc[n] + 1})))) ;; Matrix-vect
>>
>>
>>      (display "M=") (display M) (newline)
>>
>>      (field (ᐁ (for/vector ([lg nc])
>>                    (make-vector lg 0))))
>>
>>
>>      (display "ᐁ=") (display ᐁ) (newline)
>>
>>      (display "nbiter=") (display nbiter) (newline)
>>
>>      (field (error 0))
>>
>>
>>      ; forward propagation
>>
>>          ; z_* sans le coef. 1 constant pour le bias
>>      (define (accepte_et_propage x) ; on entre des entrées et on les
>> propage
>>
>>         (when {vector-length(x) ≠ vector-length(z[0])}
>>           (display "Mauvais nombre d'entrées !") (newline)
>>           (exit #f))
>>
>>         {z[0] <- x} ; on ne touche pas au biais
>>
>> in those 2 example z is a slot (or field in Racket) of the class
>> ReseauRetroPropagation that can directly be accessed from a class
>> method without using the accessors (getter and setter)
>>
>> Regards,
>> Damien
>>
>>
>>
>>
>> [0] 8.6 Methods and Generic Functions
>>
>> https://www.gnu.org/software/guile/manual/html_node/Methods-and-Generic-Functions.html
>>
>> [2] 8.5  Illustrating Slot Description:
>>
>> https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html
>>
>> On Mon, Nov 20, 2023 at 11:43 PM Nate Rosenbloom
>> <nate.rosenbloom@gmail.com> wrote:
>> >>
>> >> is there a way to access a slot of a class like other variable with
>> set! ,
>> >> Racket,Kawa allow that, but it does not seem to be the case in Guile.
>> >
>> >
>> > Hello Damien:
>> > Does 'generalized set'[0] do what you want?
>> > You can create accessor procedures that have an attached setter -
>> >
>> > Or were you speaking specifically about class slots? In which case it
>> looks like the accessor can be used in in set!: [2]
>> > Thanks,
>> > Nate
>> > [0] 7.5.14 sfri 17 Generalized set!:
>> https://www.gnu.org/software/guile/manual/html_node/SRFI_002d17.html
>> > [1] 6.7.8 Procedures with Setters:
>> https://www.gnu.org/software/guile/manual/html_node/Procedures-with-Setters.html
>> > [2] 8.5  Illustrating Slot Description:
>> https://www.gnu.org/software/guile/manual/html_node/Slot-Description-Example.html
>> >
>>
>


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2023-11-21 18:10 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-20 21:32 access slot of a class Damien Mattei
2023-11-20 23:27 ` Mikael Djurfeldt
     [not found] ` <CABESxg=NP7LJepcAG-z21f13tVup0NL0iG=4ae+dCADNf+Xpsg@mail.gmail.com>
2023-11-21  8:19   ` Damien Mattei
2023-11-21  8:21     ` Damien Mattei
2023-11-21 10:31     ` Mikael Djurfeldt
2023-11-21 11:49       ` Mikael Djurfeldt
2023-11-21 18:10       ` Damien Mattei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).