From mboxrd@z Thu Jan  1 00:00:00 1970
Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail
From: David Pirotte <david@altosw.be>
Newsgroups: gmane.lisp.guile.devel,gmane.lisp.guile.bugs
Subject: GOOPS - specialized make method upon user defined class 'does not
 work'
Date: Mon, 28 Oct 2024 20:27:00 -0300
Message-ID: <20241028202700.18fbbdb1@tintin>
Mime-Version: 1.0
Content-Type: multipart/signed; boundary="Sig_/9wlQMdeP+jlv5.pw1p7HeMd";
 protocol="application/pgp-signature"; micalg=pgp-sha512
Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214";
	logging-data="4699"; mail-complaints-to="usenet@ciao.gmane.io"
Cc: guile-devel <guile-devel@gnu.org>
To: <bug-guile@gnu.org>
Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Tue Oct 29 00:27:40 2024
Return-path: <guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org>
Envelope-to: guile-devel@m.gmane-mx.org
Original-Received: from lists.gnu.org ([209.51.188.17])
	by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
	(Exim 4.92)
	(envelope-from <guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org>)
	id 1t5Z9A-00017I-1P
	for guile-devel@m.gmane-mx.org; Tue, 29 Oct 2024 00:27:40 +0100
Original-Received: from localhost ([::1] helo=lists1p.gnu.org)
	by lists.gnu.org with esmtp (Exim 4.90_1)
	(envelope-from <guile-devel-bounces@gnu.org>)
	id 1t5Z8p-0005AP-4Y; Mon, 28 Oct 2024 19:27:19 -0400
Original-Received: from eggs.gnu.org ([2001:470:142:3::10])
 by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <david@altosw.be>)
 id 1t5Z8m-00059t-Kq; Mon, 28 Oct 2024 19:27:16 -0400
Original-Received: from smtp.all2all.org ([79.99.200.14] helo=moses.all2all.org)
 by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)
 (Exim 4.90_1) (envelope-from <david@altosw.be>)
 id 1t5Z8k-0004EF-PR; Mon, 28 Oct 2024 19:27:16 -0400
Original-Received: from localhost (localhost [127.0.0.1])
 by moses.all2all.org (Postfix) with ESMTP id 2558867C007A;
 Tue, 29 Oct 2024 00:27:09 +0100 (CET)
X-Virus-Scanned: Debian amavisd-new at moses.all2all.org
Original-Received: from moses.all2all.org ([127.0.0.1])
 by localhost (moses.all2all.org [127.0.0.1]) (amavisd-new, port 10024)
 with ESMTP id aMXfz-ZLqnlY; Tue, 29 Oct 2024 00:27:08 +0100 (CET)
Original-Received: from tintin (unknown [168.227.184.182])
 by moses.all2all.org (Postfix) with ESMTPSA id 8E56267C0074;
 Tue, 29 Oct 2024 00:27:07 +0100 (CET)
X-Mailer: Claws Mail 4.3.0 (GTK 3.24.43; x86_64-pc-linux-gnu)
Received-SPF: pass client-ip=79.99.200.14; envelope-from=david@altosw.be;
 helo=moses.all2all.org
X-Spam_score_int: -25
X-Spam_score: -2.6
X-Spam_bar: --
X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_LOW=-0.7,
 RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001,
 SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-BeenThere: guile-devel@gnu.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "Developers list for Guile,
 the GNU extensibility library" <guile-devel.gnu.org>
List-Unsubscribe: <https://lists.gnu.org/mailman/options/guile-devel>,
 <mailto:guile-devel-request@gnu.org?subject=unsubscribe>
List-Archive: <https://lists.gnu.org/archive/html/guile-devel>
List-Post: <mailto:guile-devel@gnu.org>
List-Help: <mailto:guile-devel-request@gnu.org?subject=help>
List-Subscribe: <https://lists.gnu.org/mailman/listinfo/guile-devel>,
 <mailto:guile-devel-request@gnu.org?subject=subscribe>
Errors-To: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org
Original-Sender: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org
Xref: news.gmane.io gmane.lisp.guile.devel:22749 gmane.lisp.guile.bugs:11091
Archived-At: <http://permalink.gmane.org/gmane.lisp.guile.devel/22749>

--Sig_/9wlQMdeP+jlv5.pw1p7HeMd
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

Hello,

	GOOPS - specialized make method upon user defined class 'does
	not work': those methods are properly defined and added to the
	make (make-instance) generic function, but not eligible as
	applicable methods ...

The bug is so easy to reproduce [1] and i did dig a bit into what i
think the problem is, though i fail to 'relly fix it'.

I would be grateful if those who know GOOPS internals would look at
this bug and help me find a proper fix.

Many thanks,
David

[1]	a reproducible example, an attempt to explain the cause, but
	i failed to find a proper fix

Consider the following short module


;; a (foo) module
(define-module (foo)
  #:use-module (oop goops)

  #:duplicates (merge-generics
		replace
		warn-override-core
		warn
		last)

  #:export (<foo>))


(define-class <foo> ())

(define-method (make (c-lass <foo>) . initargs)
  (let ((callback (get-keyword #:callback initargs #f))
        (data (get-keyword #:data initargs #f)))
    (peek 'make-foo callback data)))
;; enf of (foo)


If you drop this file into your-path, then

  guile
  (add-to-load-path your-path)
  ,use (foo)

  (make <foo> #:callback 'callback #:data 'data)
  =3D> #<<foo> 7f0ac4b2b310>


so as you can see, it didn't called the specialized method, otherwise it
would have peeked ";;; (make-foo callback data", and no instance would
have been created, since we 'bypass' the default make-instance method
(on purpose, g-golf requires such a 'bypass' in some context).

the method is well defined, and part of the make generic-function, as
expected:

  make
  =3D> #<<generic> make-instance (2)>

  (generic-function-methods make)
  =3D> (#<<method> (<foo> . <top>) 7f69f9fa0d80> #<<method> (<class> .
  <top>) 7f69=E2=80=A6>)

however, it is (unexpectedly) not part of the applicable methods for
(list <foo> #:callback 'callback #:data 'data) arguments:

  (compute-applicable-methods make (list <foo> #:callback 'callback
  #:data 'data)) =3D> (#<<method> (<class> . <top>) 7f69f9ea6440>)

afaict, this is because compute-applicable-methods, in (oop goops) lines
2007 - 2040, calls (method-applicable? m types), with types bind to (map
calls-of args), and within its core, loops over the types, checking if a
method is applicable by calling

  (memq (car specs) (class-precedence-list (car types)))
  ;; with specs bound to the method specializers

given the above defs, it fails upon the first make (method) argument,
<foo>, because, manually run the above code ourselves, as expected, we
get:

  ;; (car types)
  (class-of <foo>)
  =3D> #<<class> <class> 7f69f9e2c380>

  ;; (memq (car specs) (class-precedence-list (car types)))
  (memq <foo> (class-precedence-list <class>))
  =3D> #f

I am not sure what a proper fix would be, i naively tried this, in the
core of %compute-applicable-methods:

  ;; instead of
  ...
  (let ((n (length args))	;; by the way n is unused and could be
  removed
         (types (map class-of args)))
    ...)

  ;; this
  (let ((n (length args))
        (types (map (lambda (arg)
                      (if (is-a? arg <class>)
                          arg
                          (class-of arg)))
                 args)))
    ...)

but this fails, more precisely:

(1)  if i patch (oop goops), then

  make
  make install
  guile -q
  =3D>
  guile: uncaught exception:
  No applicable method for #<<generic> make-instance (1)> in call
  (make-instance Error while printing exception. Cannot exit gracefully
  when init is in progress; aborting. Aborted (core dumped)

(2) i leave (oop goops) 'untouched'

  fire emacs
  geiser-guile
  ,use (oop goops)

  then edit (oop goops) with the above change, C-x e
  u=E1=B9=95on both %compute-applicable-methods and compute-applicable-meth=
ods

  ,use (oop goops)
  (add-to-load-path (getcwd))
  ,use (foo)
  (make <foo> #:callback 'callback #:data 'data)
  $5 =3D #<<foo> 7ff44ed06020>

  (compute-applicable-methods make (list <foo> #:callback 'callback
  #:data 'data)) $6 =3D (#<<method> (<foo> . <top>) 7ff4583a0d80>)

it doesn't work because applicable methods are being memoized, i don't
know how/where the cache invalidation occurs, _and also_ the
compute-applicable-methods result is also 'wrong', because it should
return both the specialized method, and the default method defined by
oops, in that order -

--Sig_/9wlQMdeP+jlv5.pw1p7HeMd
Content-Type: application/pgp-signature
Content-Description: OpenPGP digital signature

-----BEGIN PGP SIGNATURE-----

iQEzBAEBCgAdFiEEhCJlRZtBM3furJHe83T9k6MFetcFAmcgHcQACgkQ83T9k6MF
etdYKggAzLad/33jLinraBbAIEJx15Pd7Q7taOdLSHD7MKsMqo47ZGHmFeSlrn1t
wa7bSun+wVrFGhcDs2BOVOLIyUUvj/PdaOlzxldin2ozyzuBaXerDdRhC6xo/d44
oWWE3QCzlUqyGVDmrL6etS9Nw/S52OmeB/MfSJqGd69Bs39wWPJs+uijqg+u15NE
ivKZKz7VQ7DfxNnm9cNGO25DGbezKinmP2GD+nthd/nqio2BQeXJVTY6vam2SKai
+WKxTph3qevXNAW6hjhKRszWwgNKZcKfUq9OwTHR4Gk1LYf6AaMOagqwUSOmU1tZ
rOSXv38ZdDNjLhMs1gcn6Wg8jYq3Ag==
=dSG5
-----END PGP SIGNATURE-----

--Sig_/9wlQMdeP+jlv5.pw1p7HeMd--