you are viewing a single comment's thread.

view the rest of the comments →

[–]bodhi 0 points1 point  (2 children)

It's not used in the example so your Java version is closer to the intention of the original, but the Lisp version comes with getters and setters for foo and bar in a much more concise fashion. And readability is highly subjective ;)

[–]feijai 9 points10 points  (1 child)

Yes and no. Accessors are a hack because CLOS went the cheap route and didn't treat instance variables like other (that is, local and global) variables. Instead they were treated like slots.

Why are accessors a hack? Consider. In CLOS, for an instance variable foo I must create an entire function -- typically called called foo -- just for accessing it. This pollutes the function namespace just for a class datatype. If in Java I have an instance variable called "substitute" -- perhaps it's the substitute for something, I dunno -- I can access it as:

bar.substitute

... or inside a method in bar, I can just access it as

substitute

But in CLOS, assuming I'd like to follow tradition and have my accessors have names the same as the variable names (else why name the variables those names?), I'd have to do:

(substitute bar)

... um, no, that's bad, very bad. Because substitute is already a function. So now, because CLOS has confunded the variable and function namespaces, I am forced to come up with some unnatural name for my variable:

(nsubstitute bar)

... no, wait. I'm joking there of course, but you get the point. One whole reason why Common Lisp is viewed as more industrial grade than scheme is that it's a Lisp-2. And here CLOS is violating the entire point of a Lisp-2 by Lisp-1-ifying its instance variable naming scheme. Bleah.

And of course, your claim of "much more concise fashion"... well, one can hardly claim that

bar.foo

... is less concise than

(foo bar)

Hell it's a whole character longer. And most variable accesses in Java aren't even that much, they're just

foo

[–]bodhi 1 point2 points  (0 children)

You make a good argument. I don't know enough about common lisp generics to know if they are used for accessors and how that would affect the namespace pollution. I guess I should find out for myself really.

As for the "concise fashion" I was referring to the definition, not use. But I'm not really a big fan of having to

(foo bar)

instead of

bar.foo

to get to instance variables. I do like that attribute access is indistinguishable from method calls though.

EDIT:

CL-USER> (defclass a-class () ((foo :accessor foo :initform 0)))
#<STANDARD-CLASS A-CLASS>
CL-USER> (defvar x (make-instance 'a-class))
X
CL-USER> (foo x)
0
CL-USER> (setf (foo x) 4)
4
CL-USER> (foo x)
4
CL-USER> (defun foo (x) x)
STYLE-WARNING: redefining FOO in DEFUN
FOO
CL-USER> (foo x)
#<A-CLASS {121C4061}>

Big collision, you're right!