From: Barry Margolin on 16 Jun 2010 00:40 In article <xbaibpbb3ip9.fsf(a)cam.ac.uk>, Leo <sdl.web(a)gmail.com> wrote: > On 2010-06-15 20:32 +0100, Captain Obvious wrote: > > L> But using change-class is a bad idea, because methods for the > > L> superclasses stopping working on the new SOLVER class. > > > > I think the bad idea was inheriting from both. > > > > (defclass solver (multi-dimensional-root-solver-f > > multi-dimensional-root-solver-fdf)() > > > > Do you really mean that solver IS BOTH solver-f AND solver-fdf? > > > > As far as I understand from your code solver might be EITHER solver-f > > OR solver-fdf. > > It is not expressed via inheritance relationship. > > > > I don't really understand why you need your own solver class at all. > > Just use one of stock ones. > > You are right. I was looking for a way to solve this dilemma: > > The routine (defined as fsolve-1 in the example code below) to find the > solution is essentially the same for both classes and I want to avoid > doing: > > (defmethod fsolve > ((solver multi-dimensional-root-solver-f) > &key (absolute-error 1d-7) (max-iteration 500) print-steps) > (fsolve-1 solver absolute-error max-iteration print-steps)) > > (defmethod fsolve > ((solver multi-dimensional-root-solver-fdf) > &key (absolute-error 1d-7) (max-iteration 500) print-steps) > (fsolve-1 solver absolute-error max-iteration print-steps)) > > -fdf and -f's have a common superclass that is also the superclass of > many other classes. > > Leo Define a class fsolve-1-er, and make this a superclass of both multi-dimensional-root-solver-f and multi-dimensional-root-solver-fdf. Then define the method: (defmethod fsolve ((solver fsolve-1-er) &key ...) (fsolve-1 solver absolute-error max-iteration print-steps)) -- Barry Margolin, barmar(a)alum.mit.edu Arlington, MA *** PLEASE post questions in newsgroups, not directly to me *** *** PLEASE don't copy me on replies, I'll read them in the group ***
From: Leo on 16 Jun 2010 02:50 On 2010-06-16 05:40 +0100, Barry Margolin wrote: > Define a class fsolve-1-er, and make this a superclass of both > multi-dimensional-root-solver-f and multi-dimensional-root-solver-fdf. > Then define the method: > > (defmethod fsolve ((solver fsolve-1-er) > &key ...) > (fsolve-1 solver absolute-error max-iteration print-steps)) The two classes are from a common lisp package named GSLL. I am trying to do things in my own package instead of modifying GSLL. Is that possible? Thanks. Leo
From: Tamas K Papp on 16 Jun 2010 04:01 On Wed, 16 Jun 2010 07:50:34 +0100, Leo wrote: > On 2010-06-16 05:40 +0100, Barry Margolin wrote: >> Define a class fsolve-1-er, and make this a superclass of both >> multi-dimensional-root-solver-f and multi-dimensional-root-solver-fdf. >> Then define the method: >> >> (defmethod fsolve ((solver fsolve-1-er) >> &key ...) >> (fsolve-1 solver absolute-error max-iteration print-steps)) > > The two classes are from a common lisp package named GSLL. I am trying > to do things in my own package instead of modifying GSLL. Is that > possible? Thanks. Maybe you could ask on the GSLL mailing list. Initially, I liked the idea of GSLL because it provided access to a relatively nice library. But when I tried using it, I got the impression that GSL can't interface with Lisp in a particularly natural way, and thus GSLL has to jump through hoops to provide a reasonable interface. In particular, callbacks are quite opaque. I plan to implement one of the a robust solver/optimizer algorithms one of these days, using LLA, but I haven't got around to it yet. Tamas
From: Captain Obvious on 16 Jun 2010 04:05 L> You are right. I was looking for a way to solve this dilemma: L> The routine (defined as fsolve-1 in the example code below) to find the L> solution is essentially the same for both classes and I want to avoid L> doing: I don't think it is "routine". From this short example it looks more like a convenience wrapper function which does nothing on its own. I guess it is better to implement it in some other way, but from this short example I don't know what is best. 1. To begin with, you don't need a generic function here if both methods are 100% same. Simple DEFUN would do it. 2. If it has non-trivial implementations for other classes, you can make a default method: (defmethod fsolve (solver &key (absolute-error 1d-7) (max-iteration 500) print-steps) (fsolve-1 solver absolute-error max-iteration print-steps)) and add methods only for those non-trivial methods. 3. You can decouple convenience wrapper from function which does actual dispatch and work itself. E.g. fsolve only provides default parameters and then calls fsolve-1 which does actual job. Then you don't need dispatch in fsolve. 4. If you have lots of different cases, you can write a macro to simplify that. L> I am beginning programming in CLOS. Then I guess you do not realize that CLOS is much more flexible than object systems in other languages. Unlike C++ and Java where methods need to be attached to classes, in CLOS methods and classes are almost independent from each other. Classes are for grouping data together and for creating type hierarchy which can be dispatched on. Generic functions and their methods are for dispatching. But generic function is just one of ways how you can implement dispatching. Sometimes you do not need to dispatch at all -- then you can make a simple DEFUN or a GF with single catch-all method. Sometimes you need to dispatch in a special, different way which generic functions cannot implement. Then you should resort to a plain DEFUN and implement whatever you want directly. And do not forget closures/lambdas -- they might be thought as a kind of dispatch too, but dispatch very different to what GFs provide. So I think the best strategy is to do best thing possible and refactor it later. Sometimes "let's use defmethod for everything" is the simpliest, no-brainer way to do CLOS-style stuff, but if it clearly does not fit into your code then you're free to try something else.
From: Peder O. Klingenberg on 16 Jun 2010 07:33 Leo <sdl.web(a)gmail.com> writes: > On 2010-06-16 05:40 +0100, Barry Margolin wrote: >> Define a class fsolve-1-er, and make this a superclass of both >> multi-dimensional-root-solver-f and multi-dimensional-root-solver-fdf. >> Then define the method: >> >> (defmethod fsolve ((solver fsolve-1-er) >> &key ...) >> (fsolve-1 solver absolute-error max-iteration print-steps)) > > The two classes are from a common lisp package named GSLL. I am trying > to do things in my own package instead of modifying GSLL. Is that > possible? Thanks. You could always do it by hand: (defun fsolve (solver &key ...) (if (member (type-of solver) '(multi-dimensional-root-solver-f multi-dimensional-root-solver-fdf)) (fsolve-1 solver absolute-error max-iteration print-steps) (error 'type-error ...)))) If this is more than a once-off, you could define a macro defmethod* that accepts a list of types and expands into something like the above. ....Peder... -- Sl�v uten dop.
First
|
Prev
|
Next
|
Last
Pages: 1 2 3 4 5 Prev: Is Scheme/LISP faster than C/C++ Next: Emacs language (was: line-move-visual) |