Re: use-package & name conflict: why they are not deferred?
- From: tar@xxxxxxxxxxxxx (Thomas A. Russ)
- Date: 30 Oct 2008 10:43:51 -0700
budden <budden01@xxxxxxxxxx> writes:
In "modern" OO languages such as C++ or Java, each class in fact
introduces its own namespace. When you use a slot/method of a class in
a definition of other method, you are into that namespace, so you
don't need to fully qualify slots/members of that class. It is
reasonable as class might encapsulate many or most of the data
required for method definition.
You are falling into the trap of thinking of methods in CLOS as
belonging to classes. THEY DON'T BELONG TO CLASSES. Methods belong to
generic functions, and so there isn't any class to provide a context.
This is a very different object model than what you would find in Java
or C++. It has, IMHO, many advantages over that model. One of the
great benefits is greater extensibility, since you can easily add
methods to classes that you don't own or even have the source code for.
Try doing that in some other language! (And no, subclassing doesn't
count, because it doesn't affect the original class.)
This leads to shorter, more easily
reading code. In Perl, class is distinctly bound to namespace. Pascal
has a with construct which joins namespaces from several records. SQL
implies namespace merging in its "select" statement. I think, this
approach is good. Surely my esthetic taste appeals me to get rid of
that ugly code like that:
(let ((foo (make-foo))
(print (foo-a foo) (foo-b foo)))
Um, right here you also seem to be confusing structs and classes.
Putting aside the historic development, there are certain fundamental
differences between structs and classes that drive this difference.
There is another fundamental problem with your suggestions, which is
that they seem to trade a perceived increase in simplicity for very
simple cases (where you don't really need much help), but at the expense
of creating many problems when you try to do anything larger or more
complicated. Common Lisp is designed to solve problems in writing large
systems, not be the most concise for certain toy examples.
Now to return to your example. Since from the development of the
syntax, FOO is a struct, you have to remember that the accessors for
structs are standard functions, not generic functions. [elide discussion
of reasons for that.] So that means they don't do any dispatch on their
arguments.
So what happens when you have
(defstruct foo a b)
(defstruct bar b a)
(let ((foo (make-foo))
(bar (make-bar)))
(print (a foo) (a bar)))
Oops! Suddenly we have the problem that the single function A can't be
distinguished, since it isn't generic. It is a standard function.
Now, if you were to use classes, you could have accessors that would
distinguish between the cases. But you do have to make the conscious
design decision to use classes and not structs. But the point of having
a language with a lot of tools is to allow you to choose the most
appropriate one for the situation. That is what the profession of
software engineering is about.
Frankly, I find that most of your suggestions for changing the language
are not well thought out in terms of their consequences. It seems that
everytime someone puts up a more complicated scenario, your changes fail
in often very cryptic ways. For now it would probably be good for you
to assume that the language designers had good reasons for doing things
the way they did. Once you have more experience with using the language
to do larger projects, you would be in a position to evaluate the
trade-offs that were made.
So, for now my advice to you would be to chill out and not try to make
lisp into some other existing language. It is different. Almost all
the time, those differences are there for very sound technical reasons.
You should take this as an opportunity to expand your way of thinking
about programming and how programming languages work. But you can only
achieve that expansion of your thinking if you will go with the flow of
the language, rather than trying to fight it and change it right away.
It would be, for example, quite silly for me to start to learn Russian
and then immediately seek to reduce the number of grammatical cases from
the six(?) that exist in the language, since that would be simpler. But
anyone fluent in Russian would surely find my suggestions useless, since
I wouldn't have the necessary background in the language.
You should go through Seibel's examples and Norvig's case studies on
Common Lisp before you try to change things. That will at least mean
you have some significant exposure to what the language can do. And
then try to imagine more complicated arrangements of code with many
programmers working on them.
--
Thomas A. Russ, USC/Information Sciences Institute
.
- Follow-Ups:
- Re: use-package & name conflict: why they are not deferred?
- From: Kaz Kylheku
- Re: use-package & name conflict: why they are not deferred?
- References:
- use-package & name conflict: why they are not deferred?
- From: budden
- Re: use-package & name conflict: why they are not deferred?
- From: Kaz Kylheku
- Re: use-package & name conflict: why they are not deferred?
- From: budden
- Re: use-package & name conflict: why they are not deferred?
- From: budden
- use-package & name conflict: why they are not deferred?
- Prev by Date: Re: How to Get Started?
- Next by Date: Re: How to Get Started?
- Previous by thread: Re: use-package & name conflict: why they are not deferred?
- Next by thread: Re: use-package & name conflict: why they are not deferred?
- Index(es):
Relevant Pages
|