[cl-typesetting-devel] CLISP support

Klaus Weidner kw at w-m-p.com
Sun Apr 25 17:24:24 UTC 2004


On Sun, Apr 25, 2004 at 04:01:55PM +0200, Marc Battyani wrote:
> Sure and it's contagious as I took some time to look at it too. :(
> But at least for the maximize into, the culprit is clearly CLISP. ;-)

I'm not entirely convinced of that, see below. I tend to blame the rather
imprecise standard here...

> >From 6.1.3 Value Accumulation Clauses:
> "The var argument is bound as if by the construct with.
> [...]
> The default type is implementation-dependent; but it must be a supertype of
> type real."

CLISP is correct here, "t" is a supertype of real.

> >From 6.1.2.2 Local Variable Initializations:
> The with construct initializes variables that are local to a loop.
> [...]
> For example, for the types t, number, and float, the default values are nil,
> 0, and 0.0 respectively."
> 
> So max-height should be 0.0

Why? It's not being declared as a float anywhere. The section you quote
is specifically for the "with" declaration and states that the default
value is supplied "If the optional type-spec argument is supplied".
There is no type-spec argument here.

The accumulation section for maximize specifically says "If the maximize
or minimize clause is never executed, the accumulated value is
unspecified". And that's what is happening here.

Other compilers apparently use more complex type inference to figure out
that it's a number (I can't see how they are supposed to deduce that it's
a float given the available information), but that's beyond what the
standard requires.

> You have to look at the standard for each loop construct to be sure.
> For instance "6.1.2.1.2 The for-as-in-list subclause" says:
> "The variable var is bound to the successive elements of the list in form1
> before each iteration."
> So (loop for r in '(42) finally (return r)) => 42 is ok.
> 
> In "6.1.2.1.3 The for-as-on-list subclause" you have
> The variable var is bound to the successive tails of the list in form1.
> There is no "before" here so nil is the tail but it's not a list (atom nil)
> => t so the clause terminates.
> (loop for r on '(42) finally (return r)) should return nil.
> Don't forget that nil is an atom (atom nil) => t
> (loop for r on '(42 . 43) do finally (return r)) should return 43
> 
> So here also clisp is wrong.

That I agree with, due to the "before each iteration" phrase that IN has
and ON does not.

> I was also prejudicied against loop earlier, but I took the time to learn it
> and now I rather like it. It fits well in the Common Lisp way of doing it
> (create a domain specfic language) the only bad thing is the syntax which is
> not lispy. (PG does not like loop but he likes scheme more than CL.) May be
> we should switch to iterate which is a more lispy loop? I have an iterate
> version and IIRC Andreas Fuchs has revived and packaged it also.

That may be an alternative, I have not looked at "iterate" yet. One
reason I dislike LOOP is that it doesn't play well with my editor's s-exp
manipulation commands.

But another disadvantage is that it apparently encourages long complex
functions with unobvious semantics which are painful to debug, which I'm
not sure that iterate would be better with.

> > (loop for i from 0 below 2
> >       for j from 0 below 1
> >       finally (return (list i j)))
> >
> >    all   => (1 1)
> >
> > (loop for i from 0 below 2
> >       for j from 0 below 2
> >       finally (return (list i j)))
> >
> >    sbcl  => (2 1)
> >    clisp => (2 2)
> 
> all is correct: the clauses are executed sequentially. (6.1.2.1 Iteration
> Control)

I don't agree - the standard specifies sequential *binding* as in DO vs.
DO*, but it does not mention anywhere that this has anything to do with
the semantics of the end tests. 

My understanding of loop (such as it is) would say that the FOR and AND
variants would be equivalent to DO*/DO loops like this:

	(do ((i 0 (incf i))
	     (j 0 (incf j)))
	    ((or (>= i 2) (>= j 2)) (list i j)))

	(do* ((i 0 (incf i))
	      (j 0 (incf j)))
	     ((or (>= i 2) (>= j 2)) (list i j)))

which of course behave identically, since the i and j binding/stepping
clauses are independent.

> So for the patches, it's not a problem of semantic differences but a
> problem of non conformance of clisp.  I will put your paches but with
> #+/-clisp conditionnals.  Do you send an email to the clisp mailing
> list (clisp-devel)  or do I do it ? ;-)

I'll do that at least to clarify what's going on. But except for the "on
list" example I'm not sure if the standard offers much support.

Is "iterate" specified less ambiguously? That alone would be a reason to
choose it.

-Klaus




More information about the cl-typesetting-devel mailing list