From: refun on
In article <7fdbf132-5422-42ed-9367-7e896e6cfa5f(a)v34g2000prm.googlegroups.com>,
hughaguilar96(a)yahoo.com says...
>
> On Mar 22, 2:53 pm, Nicolas Neuss <lastn...(a)kit.edu> wrote:
> > Fortunately, in CLOS you do not have to know what the VMT is. (It is
> > there in a more general form, but) Things simply work as you expect.
>
> If I don't know what is going on under the hood, how do I know what to
> expect?
>

CLOS is defined in the CL standard as an interface. The actual internals may
differ from implementation to implementation, however for almost all serious CL
implementations, they try to follow the Meta-Object Protocol (MOP) defined in
the AMOP book, which will show you both how CLOS could be implemented, as well
as a portable interface which you can use to access CLOS internals (look inside
instances, classes, methods, generic functions, ... as well as extend them to
define things way beyond what standard CLOS can do). If looking at Closette is
not enough for you (its implementation is less efficient than let's say PCL
(Portable Common Loops), which is used by implementations such as SBCL,
Closette also does not implement the full CLOS as defined in the ANSI standard,
so a few features are missing), you can just look at PCL's source code, just
load up your Lisp implementation and inspect it as it runs, if your
implementation permits that.

> I'm really a low-level type of guy. If I don't know what is going on
> at the level of assembly language, then I don't claim to know what is
> going on at all. I tend to get very annoyed when people use undefined
> terminology and then tell me that it is "intuitive" and that "Things
> simply work as you expect."

Using basic CLOS features is rather intuitive, but if you want all the details,
read AMOP and inspect a live CL system which comes with source code, that way
you'll understand both what it's supposed to do, and how it does it, but keep
in mind that implementations are given a certain degree of freedom on how
things are implemented, so you can't expect things which are not documented(in
the ANSI CL standard and the MOP) to stay the same in each implementation.
From: refun on
In article <7fdbf132-5422-42ed-9367-7e896e6cfa5f(a)v34g2000prm.googlegroups.com>,
hughaguilar96(a)yahoo.com says...
>
> On Mar 22, 2:53 pm, Nicolas Neuss <lastn...(a)kit.edu> wrote:
> > Fortunately, in CLOS you do not have to know what the VMT is. (It is
> > there in a more general form, but) Things simply work as you expect.
>
> If I don't know what is going on under the hood, how do I know what to
> expect?
>

CLOS is defined in the CL standard as an interface. The actual internals may
differ from implementation to implementation, however for almost all serious CL
implementations, they try to follow the Meta-Object Protocol (MOP) defined in
the AMOP book, which will show you both how CLOS could be implemented, as well
as a portable interface which you can use to access CLOS internals (look inside
instances, classes, methods, generic functions, ... as well as extend them to
define things way beyond what standard CLOS can do). If looking at Closette is
not enough for you (its implementation is less efficient than let's say PCL
(Portable Common Loops), which is used by implementations such as SBCL,
Closette also does not implement the full CLOS as defined in the ANSI standard,
so a few features are missing), you can just look at PCL's source code, just
load up your Lisp implementation and inspect it as it runs, if your
implementation permits that.

> I'm really a low-level type of guy. If I don't know what is going on
> at the level of assembly language, then I don't claim to know what is
> going on at all. I tend to get very annoyed when people use undefined
> terminology and then tell me that it is "intuitive" and that "Things
> simply work as you expect."

Using basic CLOS features is rather intuitive, but if you want all the details,
read AMOP and inspect a live CL system which comes with source code, that way
you'll understand both what it's supposed to do, and how it does it, but keep
in mind that implementations are given a certain degree of freedom on how
things are implemented, so you can't expect things which are not documented(in
the ANSI CL standard and the MOP) to stay the same in each implementation.
From: Tim Bradshaw on
On 2010-03-22 22:07:14 +0000, Hugh Aguilar said:

> If I don't know what is going on under the hood, how do I know what to
> expect?

I think that the beauty of CLOS, or other Lisp OO systems, is that you
can build them up.

At the low level, it's fairly easy to understand, say, how conses,
symbols and numbers might be implemented in terms of memory, and hence
how lists an so on might be implemented. Then you can think about how
you might implement a program which would evaluate expressions
represented as these things, and suddenly you have a Lisp. And because
you already have a system which does the boring stuff like reading and
printing representations of things, you can actually write one and have
it working in a very short time.

At a higher level you can wonder how a lisp system without an object
system might implement one, how do you compute the appropriate
method(s) to call, and so on. And you can write one of these as well
or, better yet, several.

At a yet higher level you then have to start worrying about how you
make what you did in the previous step efficient - for instance you
probably want to avoid computing the appropriate methods each time, but
stash the result of that somewhere, and so on.

Finally, you can step back a bit, and wonder if you could implement
such an object system *as a program written in such an object system*,
and wonder how you might make that work. Because, of course, that is
how most CLOS implementations are written, it turns out.

The first three paragraphs above are probably well-covered by "On Lisp"
while the last is dealt with by the AMOP book. There may be more recent
books on both which are better - I have not kept up (though both of
those should be required reading I think).

From: Eli Barzilay on
Nicolas Neuss <lastname(a)kit.edu> writes:

> Eli Barzilay <eli(a)barzilay.org> writes:
>
>> Nicolas Neuss <lastname(a)kit.edu> writes:
>>
>>> Yes, but IMO all these are really desirable features, and for every
>>> single feature there are already reference implementations. So I
>>> think we can be quite sure that they also will be contained in the
>>> feature list of "Limit Lisp".
>>
>> Some of your points are far off because of deeper problems. For
>> example, yes there are theorem provers that can prove code correct,
>> but they're usually not things that the average programmer can deal
>> with and they're not useful for average project sizes and they still
>> require a proper language specification. Another example is your
>> mention of "(optional)" for types -- sound type systems are *very*
>> different from those that allow optional type declarations (mostly for
>> optimizations), and in addition it's unclear whether this can be dealt
>> with when you have something as dynamic as CLOS. Given such problems,
>> the meaning of your "Limit Lisp" is questionable.
>
> You are probably right - it is not as simple as I have put it above.
> OTOH, this is also a boon - it means that there is research to be
> done for finding e.g. a "continuous" passage between dynamic and
> static typing.

Yes, that's been a very active area for probably more than the past
decade.


> And as I understand it, one of the strengths of PLT is its academic
> background with a lot of funding because of such basic research.

(It does have a strong academic background -- but "a lot of funding"
in academic terms is usually an order of magnitude less than an
average commercial company.)


> Concerning the dynamicity of CLOS, I have sketched some time ago
> that I would be quite satisfied with a solution that would warn at
> compilation time if the class hierarchy would not fit its use (but
> otherwise let it pass, because the hierarchy might be changed at
> runtime).

The reason I pointed at CLOS as being a potential problem is related
to types, but goes beyond that: it is the fact that generic functions
are being extended via side-effects which complicates both having it
live in peace with a typechecker as well as other components. To get
a feeling of the general problem, consider the fact that if you have
this

(defmethod foo ((x string)) 'x)

in one file, and this

(defmethod foo ((x string)) 'y)

in another, then the order in which you load the two files becomes
important. IMO, this is the single biggest wart that I didn't address
in Swindle. (And I don't know of a way to address it.)

--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://barzilay.org/ Maze is Life!
From: Paul Donnelly on
Hugh Aguilar <hughaguilar96(a)yahoo.com> writes:

> Another funky word is "curry." This seems to refer to nothing more
> than providing default values for input parameters, which has always
> been available in C++.

Providing them after the function has been written, however, and
reducing its arity. If you want to map a function over a list and add 4
to each item, you can produce an adder by currying the + function,
without changing its definition or typing out the whole deal. You can
curry the curried function too, if you've got nested iterations. It's
particularly handy in functional programming, since mapping and
higher-order functions are the main tools. In Factor as well, since
quotations and combinators are used instead of loops structures that
update variables and have bodies.

(defun curry (function &rest args)
(lambda (&rest more-args)
(apply function (append args more-args))))

(mapcar (curry #'+ 4) (list 1 2 3 4)) => (5 6 7 8)

Strictly speaking, this use of the term is odd, and partial application
is more appropriate. Currying, as I understand it, is a transformation
like this:

(lambda (x y z) (+ x y z))

(lambda (z)
(lambda (y)
(lambda (x)
(+ x y z))))

Or maybe with the nesting reversed; I don't know. But the term is
generally used to mean what the curry function above does.