I often have a class that is composed of a list of another class. For example, I'll have a vector-list class made up of vectors. To avoid writing long statements, I write a method to access the embedded class. However, this method only acts as a getter; I cannot use it to set the slot value. Is there a way to use a method to set a class slot value?
Below is a minimal example:
(defclass vector ()
((name :accessor vector-name
:initarg :name)))
(defclass vector-list ()
((vectors :accessor vector-list-vectors
:initarg :vectors)))
(defun make-vector-list ()
(make-instance 'vector-list
:vectors (list
(make-instance 'vector :name 'v1)
(make-instance 'vector :name 'v2))))
(defmethod access-vector-name ((vt vector-list) vector-idx)
(vector-name (nth vector-idx (vector-list-vectors vt))))
;; returns V1
(print (access-vector-name (make-vector-list) 0))
;; Now, trying to set the same slot returns an error
;; How can I set the slot?
(setf (access-vector-name (make-vector-list) 0) 'new); --> error
The simplest would be to write:
(setf (aref (access-vector-name ...) index) value)`
But if you don't want to expose the fact that you have arrays/vectors, you can define a custom setf expander.
First, only define access-vector-name as a :reader in your class.
Then:
(defun (setf access-vector-name) (newval obj index)
(setf (aref (access-vector-name obj) index) newval))
If the intent is to hide the underlying implementation, maybe access-vector-name is a bad name.
You just need to define a setter method to do this. However your code is not legal as it stands: VECTOR is a defined symbol in the CL package (and in fact names both a function and a type) so defining a class called VECTOR is horribly illegal (and a decent implementation would barf at this). Here is a version of your code with the basic class renamed to VEC, and with a setter method.
(defclass vec ()
;; Don't call it VECTOR since it's a function in CL
((name :accessor vec-name
:initarg :name)))
(defclass vec-list ()
((vecs :accessor vec-list-vecs
:initarg :vecs)))
(defun make-vec-list ()
(make-instance 'vec-list
:vecs (list
(make-instance 'vec :name 'v1)
(make-instance 'vec :name 'v2))))
(defmethod access-vec-name ((vt vec-list) vec-idx)
(vec-name (nth vec-idx (vec-list-vecs vt))))
(defmethod (setf access-vec-name) (new (vt vec-list) vec-idx)
(setf (vec-name (nth vec-idx (vec-list-vecs vt))) new))
CLOS doesn't have a predefined macro to define accessor methods like this, outside class definitions: I'm not sure why but perhaps because cases where it's really a 'pure' accessor like this are relatively uncommon.
Related
Regexes are actually Methods:
say rx/foo/.^mro # ((Regex) (Method) (Routine) (Block) (Code) (Any) (Mu))
In that case, it means that they can act on self and are part of a class. What would that class be? My hunch is that it's the Match class and that they are actually acting on $/ (which they actually are). Any other way of formulating this?
Ultimately, all regexes expect to receive an invocant of type Match or some subclass of Match. In Perl 6, an invocant is simply the first argument, and is not special in any other way.
Those regexes declared with rule, token or regex within a package will be installed as methods on that package. Most typically, they are declared in a grammar, which is nothing more than a class whose default parent is Grammar rather than Any. Grammar is a sub-type of Match.
grammar G {}.^mro.say # ((G) (Grammar) (Match) (Capture) (Cool) (Any) (Mu))
It's thus quite natural to see these as just methods, but with a body written in a different language. In fact, that's precisely what they are.
It's a little harder to see how the anonymous regexes are methods, in so far as they don't get installed in the method table of any type. However, if we were to write:
class C {
method foo() { 42 }
}
my $m = anon method () { self.foo }
say C.$m()
Then we see that we can resolve symbols on the invocant through self, even though this method is not actually installed on the class C. It's the same with anonymous regexes. The reason this matters is that assertions like <ident>, <.ws>, <?before foo> and friends are actually compiled into method calls.
Thus, anonymous regexes being methods, and thus treating their first argument as an invocant, is what allows the various builtin rules, which are declared on Match, to be resolved.
A method does not have to correspond with any class:
my method bar () { say self, '!' }
bar 'Hello World'; # Hello World!
my regex baz { :ignorecase 'hello world' }
'Hello World' ~~ /<baz>/;
'Hello World' ~~ &baz;
&baz.ACCEPTS('Hello World'); # same as previous line
# baz 'Hello World';
By default methods, and by extension regexes have a has relationship with whatever class they are declared inside of.
class Foo {
method bar () { say self, '!' }
# has method bar () { say self, '!' }
regex baz { :ignorecase 'hello world' }
# has regex baz () { :ignorecase 'hello world' }
}
A regex does need some requirements fulfilled by whatever it's invocant is.
By just running it as a subroutine, it tells you the first one:
my regex baz { :ignorecase 'hello world' }
baz 'Hello World';
No such method '!cursor_start' for invocant of type 'Str'
in regex baz at <unknown file> line 1
in block <unit> at <unknown file> line 1
Usually a regex is declared inside of a class declared with grammar.
grammar Foo {
}
say Foo.^mro;
# ((Foo) (Grammar) (Match) (Capture) (Cool) (Any) (Mu))
So the requirements are likely fulfilled by Grammar, Match, or Capture in this case.
It could also be from a role that gets composed with it.
say Foo.^roles.map(*.^name);
# (NQPMatchRole)
There is even more reason to believe that it is Match or Capture
my regex baz {
^
{ say 'baz was called on: ', self.^name }
}
&baz.ACCEPTS(''); # baz was called on: Match
my regex baz ( $s ) {
:ignorecase
"$s"
}
baz Match.new(orig => 'Hello World'), 'hello';
# 「Hello」
I see no reason someone couldn't do that themselves in a normal class though.
Note that $/ is just a variable. So saying it is passed to a regex is a misunderstanding of the situation.
my regex baz ( $/ ) {
:ignorecase
"$/"
}
'Hello World' ~~ /<baz('hello')>/;
# 「Hello」
# baz => 「Hello」
It would be more accurate to say that when calling a regex from inside of another one, the current $/ is used as the invocant to the method/regex.
(I'm not entirely sure this is actually what happens.)
So the previous example would then be sort-of like this:
'Hello World' ~~ /{ $/.&baz('hello') }/;
This explanation combines what I think Brad++ and Jonathan++ just taught me, with what I thought I already knew, with what I discovered as I dug further.
(My original goal was to directly explain Brad's mysterious No such method '!cursor_start' message. I've failed for now, and have instead just filed a bug report, but here's what else I ended up with.)
Methods
Methods are designed to work naturally in classes. Indeed a method declaration without a scope declarator assumes has -- and a has declaration belongs inside a class:
method bar {} # Useless declaration of a has-scoped method in mainline
But in fact methods also work fine as either:
subs (i.e. not behaving as an object oriented method at all); or
methods for prototype-based programming (i.e. object orientation, but without classes).
What really makes methods methods is that they are routines with an "invocant". An invocant is a special status first parameter that:
Is implicitly inserted into the method's signature if not explicitly declared. If a method is declared inside a class, then the type constraint is that class, otherwise it's Mu:
class foo { my method bar {} .signature .say } # (foo: *%_)
my method bar {} .signature .say # (Mu: *%_)
Is a required positional. Thus:
my method bar {}
bar # Too few positionals passed; expected 1 argument but got 0
Is always aliased to self. Thus:
my method bar { say self }
bar 42 # 42
Is occasionally explicitly declared by specifying it as the first parameter in a signature and following it with a colon (:). Thus:
my method bar (Int \baz:) { say baz }
say &bar.signature; # (Int \baz: *%_)
bar 42; # 42
bar 'string'; # Type check failed in binding to parameter 'baz'
Regexes
Focusing just on the invocant perspective, regexes are methods that take/expect a match object as their invocant.
A regex is typically called in three somewhat different scenarios:
By direct use. For example my regex foo { . }; say 'a' ~~ &foo; # 「a」 (or just say 'a' ~~ / . /; # 「a」, but I'll only cover the essentially identical named example to simplify my explanation). This translates to say &foo.ACCEPTS: 'a'. This in turn is implemented by this code in Rakudo. As you can see, this calls the regex foo with the invocant Match.'!cursor_init'(...) -- which runs this code without :build. The upshot is that foo gets a new Match object as its invocant.
By way of the Grammar class's .parse method. The .parse method creates a new instance of the grammar and then calls the top "rule" (rule/token/regex/method) on that new grammar object. Note that a Grammar is a sub-class of Match; so, just as with the first scenario, the rule/regex is being passed an as-yet-empty match object. If the top rule matches, the new grammar/match object will be returned by the call to .parse. (Otherwise it'll return Nil.)
By way of one of the above. The top rule in a grammar will typically contain calls to lower level rules/tokens/regexes/methods. Likewise, a free standing rule/regex may contain calls to other rules/regexes. Each such call will involve creating another new grammar/match object that becomes the invocant for the nested call. If the nested call matches, and it's a capturing call, then the new grammar/match object is added to the higher level grammar/match object.
In Python, I would do like this:
class foo:
def __init__(self):
self.x = self
Otherwise, now the object is a parameter of itself. How can I do it in common lisp?
(defclass mn ()
((pai :accessor mn-pai
:initarg :pai
:initform self)))
In a DEFCLASS slot description one can't reference the object itself. But one can write methods for instance initialization. This would be similar to your Python example.
Our class:
? (defclass foo ()
((bar :accessor foo-bar :initarg :foo)))
#<STANDARD-CLASS FOO>
We create an :after method for initialize-instance. This generic function is provided by CLOS and its purpose is to initialize a new instance. The first argument is the instance to initialize. The method will be called by the Lisp system when we create an instance of the class foo.
Using the accessor foo-bar:
? (defmethod initialize-instance :after ((object foo) &key)
(setf (foo-bar object) object))
#<STANDARD-METHOD INITIALIZE-INSTANCE :AFTER (FOO)>
or setting the slot via (setf slot-value).
? (defmethod initialize-instance :after ((object foo) &key)
(setf (slot-value object 'bar) object))
#<STANDARD-METHOD INITIALIZE-INSTANCE :AFTER (FOO)>
Note that we can name the instance parameter with any name: object or even self. But the name has no semantics. Since in CLOS we have multi-dispatch (dispatch can work about more than one argument and there is no default dispatched argument), there is no self semantics.
Now we make and then describe an instance of class foo:
? (describe (make-instance 'foo))
#<FOO #x302000D20C0D>
Class: #<STANDARD-CLASS FOO>
Wrapper: #<CCL::CLASS-WRAPPER FOO #x302000D2B43D>
Instance slots
BAR: #<FOO #x302000D20C0D>
As you can see, the slot bar of that instance has been set to the instance itself.
Note that the initform is evaluated in the lexical context of defclass, but the dynamic context of make-instance. This allows you to define a special variable named *this* (you could use this, but that could be confusing) and use it when you initialize objects.
(defvar *this*)
Define a mixin for classes that may reference *this*:
(defclass knows-this () ())
(defmethod shared-initialize :around ((object knows-this) slot-names &rest args)
(declare (ignore args))
(let ((*this* object))
(call-next-method)))
For example:
(defclass foo (knows-this)
((myself :initform *this*)))
(describe (make-instance 'foo))
#<FOO {100AC6EF13}>
[standard-object]
Slots with :INSTANCE allocation:
MYSELF = #<FOO {100AC6EF13}>
CLOS doesn't have the concept of "this" or "self" because through the use of generic functions, whatever instance is being acted upon is passed as an argument.
So, given your example with the accessor mn-pai:
(setf instance (make-instance 'mn))
(mn-pai instance 1)
Here, instance is passed as an argument to the accessor.
If you created a method:
(defmethod inc-pai (an-mn amount)
(incf (mn-pai an-mn) amount))
Again, you see the instance is passed in as the first argument. So, there's always an explicit argument that you use.
Now consider:
(defmethod inc-both (an-mn another-mn amount)
(incf (mn-pai an-mn) amount)
(incf (mn-pai another-mn) amount))
So, in a normal class based system, where would you put this method? In a Utility class? Is this a "mn" class method? It sort of defies ready categorization.
Now consider:
(defclass mn2 ()
((pai :accessor mn2-pai)))
if we were to do this:
(setf an-mn (make-instance 'mn))
(setf an-mn2 (make-instance 'mn2))
(inc-both an-mn an-mn2)
The second line would fail, as mn2 does not have a mn-pai accessor.
However, this would work:
(defmethod inc-both2 (an-mn another-mn amount)
(incf (slot-value 'pai an-mn) amount)
(incf (slot-value 'pai another-mn) amount))
Because the slot-value is the primitive accessor for CLOS, and both classes have a slot named pai. But, then you don't get to call the accessor function. Rather you're setting the slot directly. Probably not what you want. And, of course, the names are coincidence. There's no relationship between the classes save their similar names and a shared slot name.
But you can then do this:
(defmethod inc-both ((mn an-mn) (mn2 another-mn) amount)
(incf (mn-pai an-mn) amount)
(incf (mn-pai2 another-mn) amount))
This works because the runtime will dispatch based on the types of the parameters. We "know" another-mn is an instance of mn2 because we told the system that it must be when we qualified the argument.
But, again, you can see how in a class based system, there's no "place" for this kind of method. We typically just create a Utility class of some kind and stick these in there, or a regular function in the global namespace.
While CLOS has classes, it's not really a class based system.
This also comes up in multi-inheritance scenarios (which CLOS supports). Who is "self" then?
Which Clojure methods can I use to create multiple instances on an object and store then in an Java ArrayList?
I know how to do this in Java but I'm not sure how to proceed in Clojure, any help/pointers will be much appreciated
Look at http://clojure.org/java_interop
(doto (new java.util.ArrayList)
(.add (new Object))
(.add (new Object)))
returns #<ArrayList [java.lang.Object#5ae7fa2, java.lang.Object#33d6798]>
There are 2 forms for creating new objects in clojure.
(Classname. args*)
(new Classname args*)
So here is the straightforward example how to create the java object in clojure. Firstly how it looks in Java:
Thread thread = new Thread("Hi there");
Clojure
; return instance of java.lang.Thread class
(new Thread "Hi there")
or another way
(Thread. "Hi there")
why not store in vector?
user=> (def lst (atom []))
user=> (swap! lst conj "String")
user=> (swap! lst conj 123)
user=> #lst
["String" 123]
Consider the following S4 class:
setClass('Foo', representation(model='data.frame'))
setMethod('initialize', 'Foo',
function(.Object, a, b) {
.Object#model <- data.frame(a, b)
.Object
})
It can be instantiated with:
new('Foo', a=1:4, b=4:7)
So far so good. However, when I try to subclass Foo I get an error.
setClass('Bar', contains='Foo')
>>> Error in data.frame(a, b) : argument "a" is missing, with no default
Personally, I would prefer to instantiate class Foo with explicit arguments because the code is more... well, explicit. However, this does not seem possible, does it? It looks like the signature of initialize must match the slots that the class has, otherwise it's a problem waiting to happen. Am I wrong?
The requirement is that new called with no arguments, new("Foo"), must work. Also, it's probably better practice for your initialize method to take ..., to callNextMethod, and to have arguments after the ... (because initialize is documented to use unnamed arguments for initializing contained classes). So
setMethod(initialize, "Foo", function(.Object, ..., a=integer(), b=integer()) {
callNextMethod(.Object, ..., model=data.frame(a, b))
})
Normally one wants to insulate the user from calling new, and will instead use a constructor Foo. Typically the constructor does whatever coercion you might have instead put in the initialize method, so the initialize method is just not specified.
Foo <- function(a=integer(), b=integer(), ...) {
model <- data.frame(a, b)
new("Foo", model=model, ...)
}
To be honest, I don't know much about OCaml's object system. The following snippet illustrates my problem:
class foo =
object (o)
method foo1 y =
print_endline "foo1";
o#foo2 (y - 1)
method foo2 y =
print_endline "foo2";
if y > 0 then o#foo2 y else print_endline "end"
end
class bar =
object (o : 'self_type)
inherit foo as super
method foo2 y =
print_endline "bar2";
if y > 0 then super#foo1 y else print_endline "endbar"
end
let _ = (new bar)#foo2 3
When executed, the snippet produces the following output:
bar2
foo1
bar2
foo1
bar2
endbar
, showing that the superclass method foo1 (called via super#foo1) executes the overriden method foo2 from the subclass. I would instead have expected it to call the method foo2 from the superclass, as it is called via super.
Is it possible to achieve this behaviour, i.e. have a superclass method call only other superclass methods even if they are overriden in a subclass?
No it's not. This is "late binding", a basic idea of OO, not specific to OCaml.
I don't know what you're trying to do, but object-oriented programming is perhaps not the right tools, or at least not used that way. If you want to learn OCaml, you should probably concentrate on the non-OO parts, which is interesting enough for a start.
I'm not 100% sure on this, but I'm pretty sure you can't. In OCaml inheritance and subtyping are two different concepts. A class can be a subtype of another type without inheritance. All inheritance does is pull in the methods from the inherited class.
Polymorphism is achieved via structural typing, so your call to foo2 calls the method in bar because bar has implemented foo2 and NOT because bar inherits from foo (as apposed to say, C++, where bar#foo2 is called due to a virtual function table look up).
That said, OCaml does provide you with a way to distinguish between overridden methods and inherited methods using the inherit...as... syntax. In bar from your example, o#foo1 and super#foo1 are the same method (since bar doesn't implement foo1) whereas o#foo2 and super#foo2 are different methods. Despite this, I don't think there is anyway for the inherited class to know that it has been inherited and distinguish between it's methods and the overridden methods. There might be some syntax for that but I highly doubt it due to the fact that inheritance and polymorphism are independent concepts.
As gasche points out, this is the intended and standard behavior for OO languages.
The super#foo1 call, since bar does not override foo1, is exactly equivalent to o#foo1. The super construct only exists to be able to call the foo2 method of foo from methods in bar (otherwise there is no way to reference that method). In foo1 as called from bar#foo2, o is actually a bar, not a foo, so invoking the foo2 method invokes the bar foo2 method.
I'd say that if you want to hardcode that behavior, you'd better not use object-oriented programming. Simply implement it as functions calling other functions.
("that behavior" as understood by me: if calling foo2 from inside the code that has been called as super#foo1, then exactly the foo2 from the implementation of the superclass should be called, not from the more "specific" implementations from subclasses)
It's the simplest and cleanest and clearest way to proceed: program functions that do what you want.
Or you should explain to yourself and to us: Why do you need OOP? The reason for it is not given in the question text. Why make foo1 and foo2 methods rather than independent functions? (Aside from foo1 and foo2, you may have some objects and classes and methods in your program, where appropriate).
Wondering whether this question comes from comparison to other lnaguages
If you know another OO language, that's strange that you want "that behavior" from OOP: it's not the behavior expected in, say, Java or C++, because they employ the concept of a table of virtual methods that is associated with each object at run-time, so when calling a method in your program, it gets dispatched at run-time to the implementation of that method actually associated with the object. So, in short: whenever you use a method-calling expression in your program, you commit yourself to this principle of finding the implementation of the method ("late binding"), as pointed out by gasche. Although still cf. the differences between OCaml and languages implemented with a virtual methods table pointed out by Niki Yoshiuchi.
Formalizing all the discussion of the available and wanted behaviors
Although what you want might not be the expected and available behavior in many popular OO languages, it is imaginable and could be implementable in some specific OOP systems, if one has access to the OOP implementation internals.
Say, if in some implementation, super is a structure holding the methods table of the superclass (to fallback to when resolving a method call for the current object), and the methods are functions which must receive the object (the methods table) as the 1st arg, then to perform what you want, one would write super.foo1(super, y).
(I actually wonder whether there are OOP implementations whose internals are exposed to the programmer and that allow doing such a call.)
Whereas the usual OOP behavior would be expressed in this system by this.foo1(this, y) (where this is the methods table for the current object.)
Your OCaml call super#foo1 y or a Java super.foo1(y); translates into this "my" system as super.foo1(this, y). (Although still cf. the differences pointed out by Niki Yoshiuchi between OCaml and languages like Java implemented with a virtual methods table.)
You see the differences between the 3 cases.
Appendix. Looking for languages that would work that way
Hmm, PHP could be a language where that behavior would be possible, but:
only on "class-level" programming (static methods), not object-level;
only when you hardcode some strange "late static binding" at the function calls:
#!/usr/bin/php
<?php
class Foo {
public static function foo1($y) {
echo "foo1\n";
static::foo2($y-1);
}
public static function foo2($y) {
echo "foo2\n";
if ($y > 0)
static::foo2($y);
else
echo "end\n";
}
}
class Bar extends Foo {
public static function foo2($y) {
echo "bar2\n";
if ($y > 0)
Foo::foo1($y);
else
echo "endbar\n";
}
}
class Model extends Foo {
public static function foo2($y) {
echo "model2\n";
if ($y > 0)
static::foo1($y);
else
echo "endmodel\n";
}
}
Model::foo2(3);
Bar::foo2(3);
?>
The Model behaves in a sense like standard OO objects with virtual methods, and Bar as you wanted:
$ ./test-force-super-binding.php | head -20
model2
foo1
model2
foo1
model2
foo1
model2
endmodel
bar2
foo1
foo2
foo2
foo2
foo2
foo2
foo2
foo2
foo2
foo2
foo2
$
(BTW, using parent:: instead of Foo:: wouldn't get us at your wanted behavior.)
I don't understand the prupose of the insane PHP's binding specifications like static::, which are of some effect only for static methods (i.e., class-level programming).
An analoguous C++ example doesn't give an OO object-level behavior by default:
#include<iostream>
class Foo {
protected:
static void foo1(int y) {
std::cout << "foo1" << std::endl;
foo2(y-1);
}
public:
static void foo2(int y) {
std::cout << "foo2" << std::endl;
if (y > 0)
foo2(y);
else
std::cout << "end" << std::endl;
}
};
class Bar: public Foo {
public:
static void foo2(int y) {
std::cout << "bar2" << std::endl;
if (y > 0)
foo1(y);
else
std::cout << "endbar" << std::endl;
}
};
int main() {
Bar::foo2(3);
return 0;
}
-- it gives your wanted behavior:
$ ./a.out | head -10
bar2
foo1
foo2
foo2
foo2
foo2
foo2
foo2
foo2
foo2
$
even without any special qualifier at the function call in the code for Bar::foo2(), so not interesting for us.
What about Java's static methods?.. (Do they differ from C++ and give us a virtual-method-like resolution of the function-calls by default?)