Lycurgus has quit [Quit: Exeunt: personae.ai-integration.biz]
<splittist>
phoe: wow (:
<Bike>
that is an unexpected use of call-method.
<phoe>
Bike: I know, right? I kind of realized this when I started to hack this together - CALL-METHOD can be thunked and this thunk can be called from elsewhere
<phoe>
twelve lines of LOOP plus ten lines of an obscure lisp operator - and bam, we can hack our way to dispatching on &REST
tyson2 has joined #commonlisp
<phoe>
this is very likely incorrect because it does not respect class precedence (since it finds the first method that matches) but it shows the general idea I guess
<Bike>
the "right" way to do this would be to specialize compute-discriminating-function so that method combination and discrimination are still separated, but whatevs
<Bike>
and that would be difficult with getting it to work with defmethod and all
<phoe>
we'd obviously need a custom GF class for that
<phoe>
doable, though
<phoe>
is CL:DEFMETHOD guaranteed to expand into any sort of MOP-defined generic function?
<jackdaniel>
since mop is not part of the standard...
<Bike>
it calls add-method and make-method-lambda and bla bla bla, but some of the parsing does not have mop hooks
<Bike>
e.g. as far as i know there is no way to define new specializer syntax, though sbcl has some kind of extension for that
<pjb>
phoe: nice goops!
<phoe>
I think ADD-METHOD would be enough
jolby has joined #commonlisp
<phoe>
if we had a custom GF class with a custom method class, then on (add-method goops-gf standard-method) we could create a goops-method based on the standard-method and subsequently call (add-method goops-gf goops-method) which would perform the actual adding
<phoe>
and that would be necessary to remove all required parameters, since I think that a (&REST ...) or similar lambda list would be required to satisfy conformance constraints in that case
<phoe>
since we can have a maximum of 0 required parameters if we were to imitate GOOPS in this case
<phoe>
like, move required arguments to optional or &REST in the lambda list, turn the specializers into qualifiers, hack our way around the rest
<phoe>
such as compute-discriminating-function
dra has joined #commonlisp
pdietz has joined #commonlisp
overclucker has joined #commonlisp
overclucker_ has quit [Ping timeout: 256 seconds]
aartaka has quit [Ping timeout: 272 seconds]
aartaka has joined #commonlisp
selfish has quit [Ping timeout: 260 seconds]
tevo has joined #commonlisp
<phoe>
Bike: you mentioned that you'd need to separate method combination and discrimination, but I see no way to achieve the latter without the former
<phoe>
namely, you cannot pass specializers without required arguments if you use standard DEFMETHOD syntax
random-nick has joined #commonlisp
ec has joined #commonlisp
<phoe>
unless we, ourselves, create freakish method objects where the number of specializers is more than the number of required arguments
<phoe>
which is likely to break *something* along the way
ec_ has quit [Ping timeout: 255 seconds]
frgo has quit [Read error: Connection reset by peer]
frgo_ has joined #commonlisp
<phoe>
yes, this cannot be done because 7.6.2 states, "there must be a parameter specializer for each required parameter".
<phoe>
...wait, okay, this is crazy, but this only seems to rule out the situation where there are *less* specializers than required parameters
<phoe>
not *more*
<phoe>
yes, it seems that most implementations break in various creative places then this is done
<phoe>
yes, I think this cannot be done portably without using qualifiers, because 7.6.3 leaves us only with wiggle room in the qualifier section
<phoe>
which also means that we need a custom method combination on all of these GFs, sigh
<phoe>
even if this combination turns out to be method-combination-utilities:lax
<phoe>
(defclass foo-gf (c2mop:standard-generic-function) () (:default-initargs :method-combination 'method-combination-utilities:lax) (:metaclass c2mop:funcallable-standard-class)) fails because the symbol is not enough, a method combination metaobject is required - but c2mop:find-method-combination requires a GF object
<phoe>
what do I pass it?
prokhor has joined #commonlisp
akoana has joined #commonlisp
gxt has quit [Ping timeout: 255 seconds]
gxt has joined #commonlisp
<phoe>
seems like any standard generic function will do
<phoe>
and I think that, within the compute-discriminating-function, c-a-m-u-s can always return (VALUES NIL NIL) beacuse there are no required arguments, which means that c-a-m will be called which seems like the right thing to do
<phoe>
at which point caching will need to be done by c-a-m too, because the MOP page of c-d-f mentions caching only done if c-a-m-u-s returns a true secondary value
<phoe>
and it seems that there are no MOP hooks into the caching mechanism whatsoever, since that is mostly implementation-defined
tyson2 has quit [Remote host closed the connection]
Inline has joined #commonlisp
dnc has quit [Ping timeout: 264 seconds]
gxt has quit [Remote host closed the connection]
gxt has joined #commonlisp
<phoe>
sigh, doing it properly is tougher than I expected, because it effectively requires a custom mop:c-a-m, which means that it will be slow because this won't be cached, unless I find some clever way to reuse the system c-d-f which seems unfeasible since the system c-d-f won't cache anything for me
<phoe>
and writing a custom c-d-f seems scary
igemnace has quit [Remote host closed the connection]
aartaka has quit [Ping timeout: 260 seconds]
aartaka has joined #commonlisp
<phoe>
I think the craziest but most portable and fastest way would be to have a series of "internal" standard-generic-functions with 0, 1, ..., N required arguments, have these use system caching, and dispatch between their c-d-fs based on the length of arglist for each call - also forward all sorts of i-i/r-i/add-method/remove-method calls to them as well
johnjaye has joined #commonlisp
azimut has quit [Ping timeout: 255 seconds]
tyson2 has joined #commonlisp
terrorjack has quit [Ping timeout: 252 seconds]
aartaka has quit [Ping timeout: 272 seconds]
aartaka has joined #commonlisp
Inline has quit [Quit: Leaving]
perrierjouet has joined #commonlisp
terrorjack has joined #commonlisp
epony has quit [Ping timeout: 268 seconds]
morganw has joined #commonlisp
varjag has joined #commonlisp
cage has quit [Quit: rcirc on GNU Emacs 28.2]
aartaka has quit [Ping timeout: 252 seconds]
aartaka has joined #commonlisp
<phoe>
Bike: I have no idea how MOP- and spec-conforming this is, but https://plaster.tymoon.eu/view/3604#3604 is a hacky implementation of the above tomfoolery
scymtym__ has quit [Ping timeout: 252 seconds]
<Bike>
i don't understand what "you cannot pass specializers without required arguments" means
<phoe>
how do you pass NUMBER and INTEGER without BAR and BAZ
<Bike>
what is "pass" here
<Bike>
what is being passed to what?
<phoe>
by "pass" I mean "somehow make the specializers available for later MOP wizardry after evaluating a DEFMETHOD form"
<Bike>
but... they are available? from that defmethod? I don't understand
<Bike>
the defmethod form will create a method with specializers #<class number> and so on, and later mop stuff can interrogate that
<phoe>
that defmethod has required arguments though and you cannot evaluate it if FOO has a lambda list like (&rest args)
<Bike>
okay, so what you're saying is that with normal defmethod syntax, you can't have a lambda list of (&rest args) while there's more than zero specializers, for example
<phoe>
yes
<phoe>
and if I manually MAKE-INSTANCE 'STANDARD-METHOD and then ADD-METHOD, implementations simply break
<phoe>
because they make implicit internal assumptions that the length of specializers is equal to the length of required parameters
<phoe>
that is e.g. if the lambda list is () and specializer list is e.g. #.(loop repeat 3 collect (find-class 't))
<Bike>
right. i figured you'd just have a lambda list of (n1 n2 &rest args) or something, i guess
<phoe>
yes, but then I can't call that gf with zero args or define a zero-arg method, which is what goops explicitly allows
<phoe>
and that is a hard incompatibility, like, the spec says that it's an error wrt the number of required arguments
<phoe>
IIUC the most standard required arguments such a GF can have is zero, which means that 7.6.3 leaves only qualifiers for method disagreement
<Bike>
i figured you'd use the proxy thing for that
<phoe>
for what exactly?
<Bike>
like add the method to the proxy gf (which has a fixed number of required args that matches the number of specializers)
<phoe>
if I understand correctly, then you mean what I actually did in code
<Bike>
looks like it.
<phoe>
OK, which means that I have one hacky implementation of that clos thing that people have been complaining about
<phoe>
maybe worth polishing and testing and performance measurement
<phoe>
thanks for rubberducking a little bit
<Bike>
it is unfortunate that the number of specializers has to match the lambda list. i don't really see any reason that needs to be the case, for nonstandard methods
<phoe>
this is correct, but I guess that would need to be an extension that would then need to be implemented and tested in each implementation
<phoe>
and that's the really rough part
<phoe>
the spec only seems to mandate that there must be at least as many specializers as there are required args, it says nothing about more specializers - but that's where the implicit part of the spec comes into play
<phoe>
and it takes a person bonkers enough to check what happens when they supply more specializers than required args, and I assume there are not many of them