From: blandest
Subject: Strange error in CLISP
Date: 
Message-ID: <8cb2f004-d1f2-407f-aa58-9fc1e920f9c4@w1g2000prm.googlegroups.com>
I'm running the following code in CLISP:

(defun test ()
   (format t "~A"))
(compile 'test) ;; this is required to reproduce the error
(test)

When running #'test without compiling it first, the error is
(obviously): There are not enough arguments left for this format
directive.
After compiling, the error is somehow lost and I get this strange
message: APPLY: too few arguments given to #<COMPILED-FUNCTION TEST-1>
Also, evaluating (test 1) breaks into the debugger with the message:
EVAL: too many arguments given to TEST: #1=(TEST 1)
So it seems impossible to call this function because any number of
parameters will be wrong.

I've run this test on Windows with and without SLIME and using SBCL
too. Only CLISP has this problem. I find this behavior annoying
because I'm losing the useful error message. Is this a bug or am I
doing something stupid ? :)

From: Zach Beane
Subject: Re: Strange error in CLISP
Date: 
Message-ID: <m3iqo6ues8.fsf@unnamed.xach.com>
blandest <··············@gmail.com> writes:

> I'm running the following code in CLISP:
>
> (defun test ()
>    (format t "~A"))
> (compile 'test) ;; this is required to reproduce the error
> (test)
>
> When running #'test without compiling it first, the error is
> (obviously): There are not enough arguments left for this format
> directive.
> After compiling, the error is somehow lost and I get this strange
> message: APPLY: too few arguments given to #<COMPILED-FUNCTION TEST-1>

It sure is an opaque error.

I believe CLISP has noticed that your format control string is constant
and produced a compiled formatter function in place of the FORMAT
call. If the format control isn't a constant, you get a different error:

  (defvar *control* "~A")
  (defun test ()
    (format t *control*))
  (funcall (compile 'test))

  *** - There are not enough arguments left for this format directive.
        Current point in control string:
          "~A"
           |


> Also, evaluating (test 1) breaks into the debugger with the message:
> EVAL: too many arguments given to TEST: #1=(TEST 1)
> So it seems impossible to call this function because any number of
> parameters will be wrong.

I don't think the #<COMPILED-FUNCTION TEST-1> object is your TEST
function, but the compiled FORMATTER function. Just a guess, though.

> I've run this test on Windows with and without SLIME and using SBCL
> too. Only CLISP has this problem. I find this behavior annoying
> because I'm losing the useful error message. Is this a bug or am I
> doing something stupid ? :)

Well, the error message could be better, but it's certainly not right to
try to call FORMAT with too few arguments. I don't think CLISP is doing
anything wrong.

Zach
From: budden
Subject: Re: Strange error in CLISP
Date: 
Message-ID: <68cff1dc-da36-468a-8c2a-494168b98628@40g2000prx.googlegroups.com>
> I don't think the #<COMPILED-FUNCTION TEST-1> object is your TEST
> function, but the compiled FORMATTER function.
Certainly, test function itself would be called #<compiled-function
test>
or #<compiled-closure test> or something like this.

It is easy to learn with
> #'test
From: Kaz Kylheku
Subject: Re: Strange error in CLISP
Date: 
Message-ID: <20090129092533.194@gmail.com>
On 2009-01-23, blandest <··············@gmail.com> wrote:
> I'm running the following code in CLISP:

What version?

> (defun test ()
>    (format t "~A"))
> (compile 'test) ;; this is required to reproduce the error
> (test)
>
> When running #'test without compiling it first, the error is
> (obviously): There are not enough arguments left for this format
> directive.
> After compiling, the error is somehow lost and I get this strange
> message: APPLY: too few arguments given to #<COMPILED-FUNCTION TEST-1>
> Also, evaluating (test 1) breaks into the debugger with the message:
> EVAL: too many arguments given to TEST: #1=(TEST 1)

Sounds like CLISP is compiling the one-directive format string into a 
local function, using the FORMATTER macro or something that
shares its implementation.

Hint: Experiment with

 (funcall (formatter "~a") *standard-output*)

 (funcall (formatter "~a") *standard-output* 42)

 (macroexpand '(formatter "~a"))

When a format string is compiled to a function, you no longer get
a diagnostic about there being not enough parameters for a format
directive. The concept of format directives is compiled away.

> So it seems impossible to call this function because any number of
> parameters will be wrong.

Well, that's true! You've defined TEST so that the only correct way to
call it is (TEST), and so that it makes an incorrect call to FORMAT.
From: blandest
Subject: Re: Strange error in CLISP
Date: 
Message-ID: <e48c4134-e311-4e30-96e7-34f8cb13e34b@p23g2000prp.googlegroups.com>
On Jan 23, 9:25 pm, Kaz Kylheku <········@gmail.com> wrote:
> On 2009-01-23, blandest <··············@gmail.com> wrote:
>
> > I'm running the following code in CLISP:
>
> What version?
>
> > (defun test ()
> >    (format t "~A"))
> > (compile 'test) ;; this is required to reproduce the error
> > (test)
>
> > When running #'test without compiling it first, the error is
> > (obviously): There are not enough arguments left for this format
> > directive.
> > After compiling, the error is somehow lost and I get this strange
> > message: APPLY: too few arguments given to #<COMPILED-FUNCTION TEST-1>
> > Also, evaluating (test 1) breaks into the debugger with the message:
> > EVAL: too many arguments given to TEST: #1=(TEST 1)
>
> Sounds like CLISP is compiling the one-directive format string into a
> local function, using the FORMATTER macro or something that
> shares its implementation.
>
> Hint: Experiment with
>
>  (funcall (formatter "~a") *standard-output*)
>
>  (funcall (formatter "~a") *standard-output* 42)
>
>  (macroexpand '(formatter "~a"))
>
> When a format string is compiled to a function, you no longer get
> a diagnostic about there being not enough parameters for a format
> directive. The concept of format directives is compiled away.
>
> > So it seems impossible to call this function because any number of
> > parameters will be wrong.
>
> Well, that's true! You've defined TEST so that the only correct way to
> call it is (TEST), and so that it makes an incorrect call to FORMAT.

Thanks, you and Pascal are right. I usually don't compile functions in
CLISP, but this time the source file was loaded into a lisp image
using mudballs. I removed the last parameter to #'format by mistake,
so the compiled function was wrong. Didn't expect the compiler to be
so permissive.
From: Thomas A. Russ
Subject: Re: Strange error in CLISP
Date: 
Message-ID: <ymi1vuta9e3.fsf@blackcat.isi.edu>
blandest <··············@gmail.com> writes:

> > On 2009-01-23, blandest <··············@gmail.com> wrote:
> >
> > > I'm running the following code in CLISP:
> > > (defun test ()
> > > �� ��(format t "~A"))
> > > (compile 'test) ;; this is required to reproduce the error
> > > (test)
...
> Thanks, you and Pascal are right. I usually don't compile functions in
> CLISP, but this time the source file was loaded into a lisp image
> using mudballs. I removed the last parameter to #'format by mistake,
> so the compiled function was wrong. Didn't expect the compiler to be
> so permissive.

Well, I suppose part of it could be an issue of being permissive.  But
perhaps more of it involves issues of how far a compiler is willing to
go in interpreting and checking format strings for correctness.  Given
the very flexible nature of format string directives, especially
conditional and forward and backward skipping directives, it could be
rather tough in the general case.

So an implementation that didn't even bother to check at all doesn't
seem all that unreasonable.

As a simple example, is this code that should be flagged?

(defun test (flag)
  (format t "~:[Works for nil! ~;~A~]" flag))

As long as you call TEST with NIL as an argument, it will work fine.  So
it isn't necessarily broken, as long as it gets reasonable input.

Now, IMO this code is broken, or at least not very robust, since it will
fail with bad and unchecked inputs, but one could imagine more
complicated forms where it might be hard to see that there is a
problem.  And perhaps there are some checks external to the format
statement to make sure that the bad input never gets there.  A general
soluton would be just too hard for a compiler.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal J. Bourguignon
Subject: Re: Strange error in CLISP
Date: 
Message-ID: <877i4lkf5v.fsf@galatea.local>
blandest <··············@gmail.com> writes:

> I'm running the following code in CLISP:
>
> (defun test ()
>    (format t "~A"))
> (compile 'test) ;; this is required to reproduce the error
> (test)
>
> When running #'test without compiling it first, the error is
> (obviously): There are not enough arguments left for this format
> directive.
> After compiling, the error is somehow lost and I get this strange
> message: APPLY: too few arguments given to #<COMPILED-FUNCTION TEST-1>
> Also, evaluating (test 1) breaks into the debugger with the message:
> EVAL: too many arguments given to TEST: #1=(TEST 1)
> So it seems impossible to call this function because any number of
> parameters will be wrong.
>
> I've run this test on Windows with and without SLIME and using SBCL
> too. Only CLISP has this problem. I find this behavior annoying
> because I'm losing the useful error message. Is this a bug or am I
> doing something stupid ? :)

Remember that Common Lisp allows implementations to open code all the
functions in CL.  Here, FORMAT is removed from the compiled code, and
the function generated by the FORMATTER macro is directly called. 

-- 
__Pascal Bourguignon__