From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Mikael Djurfeldt Newsgroups: gmane.lisp.guile.devel,gmane.lisp.guile.user Subject: Re: Keywords in GOOPS methods Date: Sun, 24 Nov 2024 12:56:55 +0100 Message-ID: References: <87iksg2qnm.fsf@gnu.org> <20241123163143.gFXi2D00541pia201FXiCK@xavier.telenet-ops.be> <20241123164914.gFpC2D00841pia206FpC0X@albert.telenet-ops.be> Reply-To: mikael@djurfeldt.com Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="000000000000ac83a20627a75026" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="3725"; mail-complaints-to="usenet@ciao.gmane.io" Cc: "janneke@gnu.org" , guile-devel , =?UTF-8?Q?Ludovic_Court=C3=A8s?= , guile-user , Andy Wingo To: Maxime Devos Original-X-From: guile-devel-bounces+guile-devel=m.gmane-mx.org@gnu.org Sun Nov 24 12:57:51 2024 Return-path: 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 ) id 1tFBFP-0000s4-6m for guile-devel@m.gmane-mx.org; Sun, 24 Nov 2024 12:57:51 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFBEo-0001J3-9o; Sun, 24 Nov 2024 06:57:14 -0500 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 ) id 1tFBEm-0001Il-RO; Sun, 24 Nov 2024 06:57:12 -0500 Original-Received: from mail-vs1-f41.google.com ([209.85.217.41]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFBEk-00024f-Lk; Sun, 24 Nov 2024 06:57:12 -0500 Original-Received: by mail-vs1-f41.google.com with SMTP id ada2fe7eead31-4aefdbf8134so402143137.2; Sun, 24 Nov 2024 03:57:07 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732449427; x=1733054227; h=cc:to:subject:message-id:date:from:reply-to:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=cKuRPNorBS8MiHhPgFt3XV+e509TwLX99fXPJwyqjOw=; b=Wcgk+ye+LCmEW4V2lUOIG+AaUZ7TItdHnUd3XwbLOYMmM8r2SOGBFJcOnIUSo3Y844 pWXm8IgwtzLx/sLfo8xDNzMqQOslk/QTdo3rbrN3Cd0RsEtCWksxAM9sCHfzwFHmlgIo fJy24K2yJXRf4/9Ztpt4efMxHskU5ZHHxYsVnsh/vhz74jo8z9YkF1ax3bH1Z+KoVS2T CkC6Z1w6fesLa5d1o7ZCtxuXy88+qGI8UyEJYsf5q46t2HUoYH6ZxW5WHqik7v1N2DQ/ 4AEQVZBGbGvHvp9TJysTMnY0r9bf7e4nolV42C+kQaYIgb2ijQ+E7VBzuQDf8NxiW4uh J6UA== X-Forwarded-Encrypted: i=1; AJvYcCWKsVsi5DaXjNH08udYHMPnGC2rXmtggkkCumpdYZCmyefgs4juzKOa5V4glbsLp6VqXzRIDUGAJ8byRw==@gnu.org, AJvYcCWSsYqvEt91YtlJp1oOZ/MUeZfh0PjgC37ErjM1GDgR1EeHwXAR8wzddTrSfrv9tu0EP4PFcA==@gnu.org, AJvYcCXpxDx661gZg4a4O8UbYSZlQl5QQyDDM6QTPYE6+aqQ5X2fv7agenUphSg4zTAwmCn+Lfxtw7wb9feDbQ==@gnu.org X-Gm-Message-State: AOJu0YxQTOKVh4j/+Cd/+mbd4xozb1PTe8wELLW/RBLsLt6g/m02DRrq lKCclpXjBxIShzDtiF/+Majae/gDKy4XMihGTz54TQkuweTNornH25/eKKqSQt0TI6tRSIRdpJZ 3gUPWdnzUDC6/hdrJn659/pLz3DO51H86 X-Gm-Gg: ASbGncsrjlx7LM9Oy3xQtbUtGRl/mChDizhaFEjPLyK7PwT2jLhbxIv30zBX+M2JqOR loi1HQeJqWlufe00KLVu5hkVNRshrKiQf X-Google-Smtp-Source: AGHT+IF7CysiBoeatxo0D6YoDJkjzNXw4G4tbNtXkFZgFyYl+0gASZJVMTIKNalDGaskZy4nIJDjMGiFHxeM1L2fQ7s= X-Received: by 2002:a67:cb1a:0:b0:4ad:dd96:3c80 with SMTP id ada2fe7eead31-4addd96547amr6952092137.0.1732449426766; Sun, 24 Nov 2024 03:57:06 -0800 (PST) In-Reply-To: <20241123164914.gFpC2D00841pia206FpC0X@albert.telenet-ops.be> Received-SPF: pass client-ip=209.85.217.41; envelope-from=mdjurfeldt@gmail.com; helo=mail-vs1-f41.google.com X-Spam_score_int: -15 X-Spam_score: -1.6 X-Spam_bar: - X-Spam_report: (-1.6 / 5.0 requ) BAYES_00=-1.9, FREEMAIL_FORGED_FROMDOMAIN=0.001, FREEMAIL_FROM=0.001, HEADER_FROM_DIFFERENT_DOMAINS=0.25, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no 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" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-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:22793 gmane.lisp.guile.user:19919 Archived-At: --000000000000ac83a20627a75026 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable (It's (define-method (f #:key foo) ...).) This is a valid point. Certainly there should be unambiguous rules so that we know which method should be selected. (I planned to examine this aspect before applying my patch to Guile. I was just eager to share what I had done in order to collect opinions before putting too much effort into it.) In this case, I would say that positional *should* win since it is most specific with regards to the specifiers. The patch I posted actually doesn't result in this, but it could be easily fixed with a change based on the following consideration: The motivation for having what you call the "major limitation" of not doing type dispatch on keyword arguments in GOOPS or CLOS is to strike a reasonable balance with regards to the complexity of implementation (and cognitive load for the user, I guess :). In the future, if we come up with a conceptually simple picture of how to regard method precedence in the light of typed keyword arguments and also see that this doesn't make the implementation overly complicated, we can consider extending the functionality in this direction. CLOS has a fixed number of required arguments per generic function. So, in CLOS it isn't possible to come up with two allowed methods where the order of dispatch is unclear. We loosed that up in GOOPS and allow varying number of arguments (which is a Good Thing). So, you are right that we need to come up with rules that make the order of dispatch clear. I propose that the simplest rule which corresponds to restricting type dispatch to non-keyword arguments is to define the specializer list of every method with keyword formals like this: Method formals: (( ) ... ...) results in Specializer list: ( ... . ) So (method ((x ) . y) ...) will have the same specializers as (method* ((x ) #:key z) ...) With this definition, positional above will win. In my patch, this corresponds to changing #''() to #' in the computation of specializers for keyword methods. Meanwhile, I've found a further bug in my patch: We need to consider keyword arguments in re-definition in methods. Fixed now in my still private code. Also, I should add that I now lean towards supplying the keyword functionality in additional syntax method* and define-method*, and keep the semantics for method and define-method as is. Best regards, Mikael On Sat, Nov 23, 2024 at 4:49=E2=80=AFPM Maxime Devos wrote: > >Well, these particular examples aren't valid since GOOPS doesn't allow > type specifiers for keyword arguments. (It's the same in CLOS.) Type > dispatch is done *only* on the required arguments. > > > > That=E2=80=99s a shame, it should support them IMO, it=E2=80=99s a major = limitation if it > doesn=E2=80=99t. > > > > A variant with untyped keyword arguments: > > > > (define-method (f (a ) (b )) > > (pk 'positional)) > > > > (define-method (f (#:key foo)) > > (pk 'optional-keyword foo)) > > > > (f #:foo 'bar) > > > > Who should win? Both are a quite specific match. > > > > Best regards, > > Maxime Devos > --000000000000ac83a20627a75026 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
(It's (define-method (f #:key foo) ...).)

This is a valid point. Certainly there should be unambigu= ous rules so that we know which method should be selected. (I planned to ex= amine this aspect before applying my patch to Guile. I was just eager to sh= are what I had done in order to collect opinions before putting too much ef= fort into it.)

In this case, I would say that = positional *should* win since it is most specific with regards to the speci= fiers.

The patch I posted actually doesn't res= ult in this, but it could be easily fixed with a change based on the follow= ing consideration:

The motivation for having what = you call the "major limitation" of not doing type dispatch on key= word arguments in GOOPS or CLOS is to strike a reasonable balance with rega= rds to the complexity of implementation (and cognitive load for the user, I= guess :). In the future, if we come up with a conceptually simple picture = of how to regard method precedence in the light of typed keyword arguments = and also see that this doesn't make the implementation overly complicat= ed, we can consider extending the functionality in this direction.

CLOS has a fixed number of required arguments per gene= ric function.=C2=A0 So, in CLOS it isn't possible to come up with two a= llowed methods where the order of dispatch is unclear.

We loosed that up in GOOPS and allow varying number of arguments (= which is a Good Thing). So, you are right that we need to come up with rule= s that make the order of dispatch clear.

I pro= pose that the simplest rule which corresponds to restricting type dispatch = to non-keyword arguments is to define the specializer list of every method = with keyword formals like this:

Method formals: ((= <F1> <TYPE1>) ... <KEYWORD> ...)

results in

Specializer list: (<TYPE1> ... .= <top>)

So

=C2=A0 (= method ((x <integer>) . y) ...)

will have th= e same specializers as

=C2=A0 (method* ((x <int= eger>) #:key z) ...)

With this definition, posi= tional above will win. In my patch, this corresponds to changing #''= ;() to #'<top> in the computation of specializers for keyword met= hods.

Meanwhile, I've found a further bug in m= y patch: We need to consider keyword arguments in re-definition in methods.= Fixed now in my still private code.

Also, I shoul= d add that I now lean towards supplying the keyword functionality in additi= onal syntax method* and define-method*, and keep the semantics for method a= nd define-method as is.

Best regards,
Mikael

On Sat, Nov 23, 2024 at 4:49=E2=80=AFPM Maxime Devos <= maximedevos@telenet.be> wr= ote:

>Well, these particular examples= aren't valid since GOOPS doesn't allow type specifiers for keyword= arguments. (It's the same in CLOS.) Type dispatch is done *only* on th= e required arguments.

=C2=A0

That=E2=80=99s a shame, it should support them IM= O, it=E2=80=99s a major limitation if it doesn=E2=80=99t.

=C2=A0

A variant with untyped k= eyword arguments:

=C2=A0

(define-method (f (a <keyword>) (b <symbol>))=

=C2=A0 (pk &#= 39;positional))

=C2=A0

(define-method (f (#:key foo))

=C2=A0 (pk 'optional-keyword foo))<= u>

= =C2=A0

(f #:fo= o 'bar)

=C2=A0

Who should win? Both are a quite specific match.<= /p>

=C2=A0<= /p>

Best regards,<= /u>

Maxime Devos

--000000000000ac83a20627a75026--