I have the following two classes:
(defclass person () ())
(defmethod speak ((s person) string)
(format t "-A" string))
(defmethod speak :before ((s person) string)
(print "Hello! "))
(defmethod speak :after ((s person) string)
(print "Have a nice day!"))
(defclass speaker (person) ())
(defmethod speak ((i speaker) string)
(print "Bonjour!"))
(speak (make-instance 'speaker) "Can I help yoU?")
And the ouput of this is:
"Hello! "
"Bonjour!"
"Have a nice day!"
What I'm trying to figure out is how these methods are executed in terms of "order." I cannot seem to grasp on what is happening and why. Supposedly there is a rule precedence to this but I'm not sure where to find it. For example, why doesn't "Hello!Can I help you" ever fire in this case?
When you don't have any around methods, the order of method application is: all before methods from most specific to least specific, then the most specific primary method, and then the after methods from least specific to most specific. In your case you have two primary methods (methods without :before or :after next to the name), one which specifies on person, and the other which specifies on speaker. Since speaker is more specific than person, only the speaker primary method is called. If you want to call multiple primary methods, look at call-next-method.
While I see that there's already an accepted answer, Common Lisp has some very nice documentation in the HyperSpec, and it's useful to know where to find the full description of what happens. In this case, it's 7.6.6.2 Standard Method Combination, which says (abbreviated):
The semantics of standard method combination is as follows:
If there are any around methods, the most specific around method is called. It supplies the value or values of the generic function.
Inside the body of an around method, call-next-method can be used to call the next method. When the next method returns, the around method
can execute more code, perhaps based on the returned value or values.
The generic function no-next-method is invoked if call-next-method is
used and there is no applicable method to call. The function
next-method-p may be used to determine whether a next method exists.
If an around method invokes call-next-method, the next most specific around method is called, if one is applicable. If there are no around
methods or if call-next-method is called by the least specific around
method, the other methods are called as follows:
All the before methods are called, in most-specific-first order. Their values are ignored. An error is signaled if
call-next-method is used in a before method.
The most specific primary method is called. Inside the body of a primary method, call-next-method may be used to call the next most
specific primary method. When that method returns, the previous
primary method can execute more code, perhaps based on the returned
value or values. The generic function no-next-method is invoked if
call-next-method is used and there are no more applicable primary
methods. The function next-method-p may be used to determine whether a
next method exists. If call-next-method is not used, only the most
specific primary method is called.
All the after methods are called in most-specific-last order. Their values are ignored. An error is signaled if call-next-method is
used in an after method.
If no around methods were invoked, the most specific primary method supplies the value or values returned by the generic function. The
value or values returned by the invocation of call-next-method in the
least specific around method are those returned by the most specific
primary method.
There's a particularly helpful illustration at the end of that page that describes the behavior and its motivation:
The before methods are run in most-specific-first order while the
after methods are run in least-specific-first order. The design
rationale for this difference can be illustrated with an example.
Suppose class C1 modifies the behavior of its superclass, C2, by
adding before methods and after methods. Whether the behavior of the
class C2 is defined directly by methods on C2 or is inherited from its
superclasses does not affect the relative order of invocation of
methods on instances of the class C1. Class C1's before method runs
before all of class C2's methods. Class C1's after method runs after
all of class C2's methods.
By contrast, all around methods run before any other methods run. Thus
a less specific around method runs before a more specific primary
method.
If only primary methods are used and if call-next-method is not used,
only the most specific method is invoked; that is, more specific
methods shadow more general ones.
In addition to other answers, note that you can define custom method combination with the following macro:
DEFINE-METHOD-COMBINATION. There are already ten existing method combinators so I don't think it is common to define custom ones. Of course, being able to do so can be very useful at times (see Joshua Taylor's comment).
Also, the way your methods are invoked is subject to class inheritance, which by default takes into account parent-child relationships, as well as order between superclasses. Please read "Fundamentals of CLOS". The class precedence list can be changed with the Meta-Object Protocol: see COMPUTE-CLASS-PRECEDENCE-LIST.
Related
(While this question is tagged with annotation-processing I'm actually asking questions about the type model exposed by javax.lang.model whether or not annotation processing is involved.)
In javax.lang.model, there are two fundamental constructs: Elements and TypeMirrors.
Every Element is backed by a TypeMirror. However only certain TypeMirror subtypes, namely DeclaredType and TypeVariable, have Elements associated with them via DeclaredType#asElement() and TypeVariable#asElement() respectively.
(It follows that all Elements "have" TypeMirrors, but not all TypeMirrors "have" Elements.)
Speaking loosely and intuitively, this makes sense: you declare types by chanting certain Java spells: the spells themselves are the (declared) elements; the things they bring into being are the types that back them. I've programmed in Java for decades and have a good working familiarity with oddities like Foo implements Comparable<Foo>. I'm trying to get more rigorous here.
With all that in mind, and considering the following snippet, how are the javax.lang.model types and elements manifested?
// (Defined by the JDK itself of course.)
public interface Comparable<T> ...
// (My class.)
public class Frob implements Comparable<Frob> ...
I see the following "things", working from "top" to "bottom" with less and less certainty as I go along:
a TypeParameterElement whose affiliated Name is equal to "T"
The return value of its asType() method will be a (definitionally nameless) TypeVariable whose asElement() method will return the TypeParameterElement currently being discussed.
The return value of its getGenericElement() method (and its getEnclosingElement() method) will be the Element we'll talk about next ("Comparable").
a TypeElement whose affiliated Name is equal to "Comparable"
The return value of its asType() method will be a (definitionally nameless) DeclaredType whose asElement() method will return the TypeElement currently being discussed
The DeclaredType so returned will have exactly one type argument which will be the (definitionally nameless) TypeVariable discussed above whose asElement() method will return the TypeParameterElement discussed above ("T")
The return value of its getTypeParameters() method will consist solely of the TypeParameterElement discussed earlier.
a TypeElement whose affiliated Name is equal to "Frob".
(This TypeElement is brought into being with the Java syntax public class Frob ....)
The return value of its asType() method will be a (definitionally nameless) DeclaredType whose asElement() method will return the TypeElement currently being discussed.
The return value of its getInterfaces() method will be discussed in a moment.
an Element of some variety loosely described by "Comparable<Frob>".
I say "of some variety" because as written it itself does not have, say, an explicit or implicit extends or implements clause, or other markers I would expect to see of, say, a TypeElement. Nevertheless I'm not sure that it could be any other kind of Element other than a TypeElement. Maybe it is a TypeElement equal to that denoted by "Comparable<T>", but with its various TypeMirror-returning or -referencing methods using the type denoted by Frob?
The return value of its asType() method will be a (definitionally nameless) TypeMirror of some variety (almost certainly a DeclaredType) whose asElement() method will return the Element currently being discussed (this corresponds somewhat to java.lang.reflect.ParameterizedType in the runtime/reflection model)
The TypeMirror so returned will have exactly one type argument which will be the (definitionally nameless) DeclaredType returned by the asType() method of the TypeElement whose Name is equal to "Frob" described above
The TypeMirror so returned will be the sole member of the return value of the getInterfaces() method when invoked on the TypeElement whose Name is equal to "Frob" described above
Do I have this right as far as it goes?
Your question seems well-reasoned, and I can't find anything specifically wrong with it to point out to you, but it is missing the one vital truth of where Elements and TypeMirrors differ.
Elements represent nodes in the Java type AST that reside "on disk" - the code at rest, either in .java or .class files. Any class/interface/enum/record/annotation that exists on disk in this form is in some way discoverable by this. To get a bit further, these cover the entire API of any of those types above - any members (fields/constructors/methods or nested types, then also the params of those methods/ctors) and packages too are described by elements. But the Element hierarchy only covers the types on disk - to use a concrete example from your question, Comparable<T> and its Comparable<T>.compareTo(T) member, and that method's parameter are covered in this way. And yes, lest I omit the type parameter, both the class and the method have a type param embedded in their respective element - as an element.
On the other hand, TypeMirrors represent those elements "in use" - you can't really reason about Comparable<T> in your code, but instead will either use it raw (please don't), or will parameterize it in some specific way (such as Comparable<Frob>, Comparable<?>, or possibly Comparable<T> where T is the type param of an enclosing element such as the current method or class). This means that T is not the same TypeElement as above - it isn't the value of the TypeElement that was on disk, but is something more specific.
You'll find TypeMirrors in Elements (for example "what is the return type of the method that appears in this class?"), and all Elements can be converted to some form of TypeMirror. On the other hand, not all TypeMirrors can be converted to some Element (such as a primitive), or if they can, that conversion may be "lossy" (for example converting a TypeMirror of List<String> to an Element would give you only List<T> itself).
I have a function foo which takes another function (say bar) as a parameter. Is there a way to get the function name of bar as a string inside foo?
No. See the difference between methods and functions. Methods aren't passed as parameters under the hood - they are expanded into function objects when being passed to some other method/function. These function objects are instances of anonymous, compiler-generated classes , and have no name (or, at least, being anonymous classes, have some mangled name which you could access using reflection, but probably don't need).
So, when you do:
def foo() {}
def bar(f: () => Unit) {}
bar(foo)
what actually happens in the last call is:
bar(() => foo())
Theoretically, though, you could find the name of the method that the function object you're being passed is wrapping. You could do bytecode introspection to analyze the body of the apply method of the function object f in method bar above, and conclude based on that what the name of the method is. This is both an approximation and an overkill, however.
I've had quite a dig around, and I don't think that there is. toString on the function object just says eg <function1>, and its class is a synthesised class generated by the compiler rather that something with a method object inside it that you might query.
I guess that if you really needed this there would be nothing to stop you implementing function with something that delegated but also knew the name of the thing to which it was delegating.
Racket's documentation only partially describe what augment and pubment do: augment makes a method that executes after the superclass's version of that method, while pubment makes a method that will implicitly have the augment property if it is defined in a child class.
The docs say absolutely nothing about overment and augride, and I can't guess what they would do based on their names. What are they, and what is the difference between them?
The relatively large family of inheritance functions for Racket's class system is, as you describe, a little confusing, and their somewhat cutesy names don't always help.
In order to understand this, Racket provides two separate mechanisms for method inheritance.
public methods correspond to the classical idea of public methods in other OO models. Methods declared with public may be overridden in subclasses, unless they're declared final, in which case they cannot.
pubment methods are similar, but they cannot be overridden, only augmented. Augmenting a method is similar to overriding it, but the dispatch calls the superclass's implementation instead of the subclass's.
To clarify the difference between overriding and augmentation, when an overridden method is called, the overriding implementation is executed, which may optionally call the superclass's implementation via inherit/super. In contrast, in an augmented method, the superclass's implementation receives control, and it may optionally call the subclass's implementation via inner.
Now, we're also provided public-final, override-final, and augment-final. These are pretty simple. Declaring a method with public-final means it can neither be augmented nor overridden. Using override-final overrides a superclass's public method, but it doesn't allow any further overriding. Finally, augment-final is similar, but for methods declared with pubment, not public.
So then, what about the two weird hybrids, overment and augride?
overment can be used to implement methods initially defined with public. This "converts" them to augmentable methods instead of overridable methods for all the class's subclasses.
augride goes in the opposite direction. It converts an augmentable method to one that is overridable, but the overriding implementations only replace the augmentation, not the original implementation.
To summarize:
public, pubment, and public-final all declare methods that do not exist in a superclass.
Then we have a family of forms for extending superclass methods:
override and augment extend methods declared with public and pubment, respectively, using the relevant behaviors.
override-final and augment-final do the same as their non-final counterparts, but prevent further overriding or augmentation.
overment and augride convert overridable methods to augmentable ones and vice-versa.
For another, fuller explanation, you might be interested in taking a look at the paper from which Racket's model was derived, which is quite readable and includes some helpful diagrams.
I am looking at a source code and it has a method named updateDisplayList. There are various methods in this source code with similar name. However I am interested in one particular updateDisplayList method. I want to check where this method is getting called. I have tried using CTRL+SHIFT+G in eclipse which returns me all the references of this method in that source code. However as there are many methods with same name, those references are also getting returned. How can I know where that particular updateDisplayList method is getting called?
As stated in the comments updateDisplayList() is a Flex component life cycle method. Practically every Flex component implements this method.
If you've modified this method in one class, lets call it ClassA, and you're also seeing the effects of this modification in other classes, it must mean that the other classes inherit from ClassA in some way.
To determine who's inheriting from ClassA, you can just search for that class name in your project. This will likely find the other class that you're looking for. However, there could be a series of classes that inherit from ClassA so you might have to look deeper than that (find all the classes that extend ClassA and then search for those classes). This might be a slippery slope and may not be fruitful.
Another approach is to set a breakpoint in the updateDisplayList() method in ClassA. As I mentioned, you'll hit this breakpoint frequently. In FlashBuilder/Eclipse, you can use the "expressions" window and inspect the value of this. If this is ClassA, it's not the droid(s) you're looking for, so let execution resume.
I'm sure there are a handful of other ways to get to the bottom of this. But updateDisplayList() is such a common method, there's no point in searching for that method name :)
Is it possible to create an AOP like interceptor using Scalas new Dynamic Type feature? For example: Would it be possible to create a generic stopwatch interceptor that could be mixed in with arbitrary types to profile my code? Or would I still have to use AspectJ?
I'm pretty sure Dynamic is only used when the object you're selecting on doesn't already have what you're selecting:
From the nightly scaladoc:
Instances x of this trait allow calls x.meth(args) for arbitrary method names meth and argument lists args. If a call is not natively supported by x, it is rewritten to x.invokeDynamic("meth", args)
Note that since the documentation was written, the method has been renamed applyDynamic.
No.
In order for a dynamic object to be supplied as a parameter, it'll need to have the expected type - which means inheriting from the class you want to proxy, or from the appropriate superclass / interface.
As soon as you do this, it'll have the relevant methods statically provided, so applyDynamic would never be considered.
I think your odds are bad. Scala will call applyDynamic only if there is no static match on the method call:
class Slow {
def doStuff = //slow stuff
}
var slow = new Slow with DynamicTimer
slow.doStuff
In the example above, scalac won't call applyDynamic because it statically resolved your call to doStuff. It will only fall through to applyDynamic if the method you are calling matches none of the names of methods on the type.