unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
From: Cor Legemaat <cor@cor.za.net>
To: guile-user@gnu.org
Subject: Extending primitive to generic functions problem
Date: Fri, 09 Oct 2020 20:30:29 +0200	[thread overview]
Message-ID: <88f424cfefbce959534eb647b581b9c9a9552114.camel@cor.za.net> (raw)

[-- Attachment #1: Type: text/plain, Size: 2611 bytes --]

Hi All:

I am trying to extend some of the primitive functions with generic
methods in a module to use them with custom classes. From 8.6.5 Generic
Function and Method Examples in the manual I came up with the following
module:

(define-module (test ep)
  #:use-module (oop goops)
  #:use-module ((rnrs base)
                #:select (+ - * / map max min sqrt expt abs log)
                #:prefix rnrs:))


(define-macro (make-primitive-generic source destination arguments)
  (let ((tmp-symbol (string->symbol (string-append (symbol->string
destination)
                                                   "-new"))))
    `(begin (define-generic ,tmp-symbol)
            ,(if (not (defined? destination))
                 `(define ,destination ,source))
            (let ((,destination ,source))
              ,(cond
                ((eq? arguments 1)
                 `(define-method (,tmp-symbol (n <real>)) (,source n)))
                ((eq? arguments 2)
                 `(define-method (,tmp-symbol (a <real>) (b <real>))
                                 (,source a b)))
                (else
                 `(begin
                    (define-method (,tmp-symbol (a <real>) (b <real>))
                                   (,source a b))
                    (define-method (,tmp-symbol (a <number>)) a)
                    (define-method (,tmp-symbol) 0)
                    (define-method (,tmp-symbol . args)
                      (,tmp-symbol (car args)
                                   (apply ,tmp-symbol (cdr args))))))))
            (set! ,destination ,tmp-symbol)
            (export ,destination))))
(export make-primitive-generic)

(make-primitive-generic rnrs:+ sum 0)
(make-primitive-generic rnrs:max max 0)
(make-primitive-generic rnrs:min min 0)
(make-primitive-generic rnrs:* product 0)
(make-primitive-generic rnrs:/ divide 0)
(make-primitive-generic rnrs:- difference 0)
(make-primitive-generic rnrs:sqrt sqrt 1)
(make-primitive-generic rnrs:expt expt 2)
(make-primitive-generic rnrs:abs abs 1)
(make-primitive-generic rnrs:log log 1)

Now 2 problems:
If I don't hack the primitive with the prefix there is an 'Unbound
variable:' error on those where the source and destination is the same.
This works but only if compiled, the second time guile uses 100% cpu
and never finish loading. Did play with eval-when but it's either not
defining the methods or not loading after it's compiled.

Where is it going wrong, is this possible or do I mis understand
something about how guile works?

Thanks in advance

Regards:
Cor

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

                 reply	other threads:[~2020-10-09 18:30 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=88f424cfefbce959534eb647b581b9c9a9552114.camel@cor.za.net \
    --to=cor@cor.za.net \
    --cc=guile-user@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).