Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Function Warnings

139 views
Skip to first unread message

arnuld

unread,
Apr 13, 2012, 7:05:35 AM4/13/12
to
This program runs fine. I get style warnings. I know that you have to
"defvar" a variable and then do "setf" to assign a value but what about
function warning in my case, what to do about them ? (SBCL 1.0.55)



;;; ACL chpater 3 examples


;; compression algorithm a.k.a run-length-encoding
(defun compress (x)
(if (consp x)
(compr (car x) 1 (cdr x))
x))


(defun compr (elt n lst)
(if (null lst)
(n-elts elt n)
(let ((next (car lst)))
(if (eql next elt)
(compr elt (+ n 1) (cdr lst))
(cons (n-elts elt n)
(compr next 1 (cdr lst)))))))


(defun n-elts (elt n)
(if (> n 1)
(list n elt)
elt))


=========================== OUTPUT ==================================
* (load "acl-ch-3.lisp")

; file: /home/arnuld/programs/Common-Lisp/acl-ch-3.lisp
; in: DEFUN COMPRESS
; (COMPR (CAR X) 1 (CDR X))
;
; caught STYLE-WARNING:
; undefined function: COMPR
;
; compilation unit finished
; Undefined function:
; COMPR
; caught 1 STYLE-WARNING condition

; in: DEFUN COMPR
; (N-ELTS ELT N)
;
; caught STYLE-WARNING:
; undefined function: N-ELTS
;
; compilation unit finished
; Undefined function:
; N-ELTS
; caught 1 STYLE-WARNING condition

T

* (compress '(1 1 1 0 1 0 0 0 1))

((3 1) 0 1 (3 0) . 1)
*




--
arnuld
http://LispMachine.Wordpress.com

Pascal J. Bourguignon

unread,
Apr 13, 2012, 7:23:41 AM4/13/12
to
arnuld <sun...@invalid.address> writes:

> This program runs fine. I get style warnings. I know that you have to
> "defvar" a variable and then do "setf" to assign a value but what about
> function warning in my case, what to do about them ? (SBCL 1.0.55)

It's the same principle!

You must define the things you use BEFORE you use them!

--
__Pascal Bourguignon__ http://www.informatimago.com/
A bad day in () is better than a good day in {}.

arnuld

unread,
Apr 13, 2012, 7:43:45 AM4/13/12
to
> On Fri, 13 Apr 2012 13:23:41 +0200, Pascal J. Bourguignon wrote:

> It's the same principle!
> You must define the things you use BEFORE you use them!

I have used (declare ) (defun ) and (defvar ) but none of them works for
functions. I have even used (declare (defun name (arguments))) but that
does not work too. Can you point me to right direction ?





--
arnuld
http://LispMachine.Wordpress.com

Pascal J. Bourguignon

unread,
Apr 13, 2012, 8:18:00 AM4/13/12
to
arnuld <sun...@invalid.address> writes:

>> On Fri, 13 Apr 2012 13:23:41 +0200, Pascal J. Bourguignon wrote:
>
>> It's the same principle!
>> You must define the things you use BEFORE you use them!
>
> I have used (declare ) (defun ) and (defvar ) but none of them works for
> functions. I have even used (declare (defun name (arguments))) but that
> does not work too. Can you point me to right direction ?

The key word was "before", that's why I wrote it as "BEFORE"!

Jussi Piitulainen

unread,
Apr 13, 2012, 8:31:29 AM4/13/12
to
Pascal J. Bourguignon writes:
> arnuld writes:
>
> >> On Fri, 13 Apr 2012 13:23:41 +0200, Pascal J. Bourguignon wrote:
> >
> >> It's the same principle!
> >> You must define the things you use BEFORE you use them!
> >
> > I have used (declare ) (defun ) and (defvar ) but none of them
> > works for functions. I have even used (declare (defun name
> > (arguments))) but that does not work too. Can you point me to
> > right direction ?
>
> The key word was "before", that's why I wrote it as "BEFORE"!

Surely there is some other way. Do Common Lisp compilers become
nervous when they encounter mutual recursion?

Teemu Likonen

unread,
Apr 13, 2012, 8:42:34 AM4/13/12
to
* arnuld [2012-04-13 11:05:35 +0000] wrote:

> This program runs fine. I get style warnings. I know that you have to
> "defvar" a variable and then do "setf" to assign a value but what about
> function warning in my case, what to do about them ? (SBCL 1.0.55)

Reorder the functions in your file so that functions are defined before
their call appear in the source code. See:

> (defun n-elts (elt n)
> (if (> n 1)
> (list n elt)
> elt))

> (defun compr (elt n lst)
> (if (null lst)
> (n-elts elt n)
> (let ((next (car lst)))
> (if (eql next elt)
> (compr elt (+ n 1) (cdr lst))
> (cons (n-elts elt n)
> (compr next 1 (cdr lst)))))))

> (defun compress (x)
> (if (consp x)
> (compr (car x) 1 (cdr x))
> x))

With mutual calls you can use

(defun foo (...)
#+sbcl (declare (sb-ext:muffle-conditions style-warning)
...)

Paul Wallich

unread,
Apr 13, 2012, 8:43:36 AM4/13/12
to
On 4/13/12 8:18 AM, Pascal J. Bourguignon wrote:
> arnuld<sun...@invalid.address> writes:
>
>>> On Fri, 13 Apr 2012 13:23:41 +0200, Pascal J. Bourguignon wrote:
>>
>>> It's the same principle!
>>> You must define the things you use BEFORE you use them!
>>
>> I have used (declare ) (defun ) and (defvar ) but none of them works for
>> functions. I have even used (declare (defun name (arguments))) but that
>> does not work too. Can you point me to right direction ?
>
> The key word was "before", that's why I wrote it as "BEFORE"!

In other words, just re-order your text so that all the functions used
in the body of your code have been defined by the time they're seen by
the compiler.

(Note, however, that this warning may be purely about stylistic
preferences. I often find it easier, when I'm first sketching something
out, to write

(defun high-level-manipulation (thing1 thing2)
(low-level-manipulation thing1)
(other-low-level-manipulation thing1 thing2)
...
...)

(defun low-level-manipulation (thing)
...)

and so forth just because I don't know exactly what the low-level stuff
is going to be (or how I should name it) until I've at least made a stab
at the high-level stuff.)

paul



Pascal J. Bourguignon

unread,
Apr 13, 2012, 8:59:00 AM4/13/12
to
Jussi Piitulainen <jpii...@ling.helsinki.fi> writes:

> Pascal J. Bourguignon writes:
>> arnuld writes:
>>
>> >> On Fri, 13 Apr 2012 13:23:41 +0200, Pascal J. Bourguignon wrote:
>> >
>> >> It's the same principle!
>> >> You must define the things you use BEFORE you use them!
>> >
>> > I have used (declare ) (defun ) and (defvar ) but none of them
>> > works for functions. I have even used (declare (defun name
>> > (arguments))) but that does not work too. Can you point me to
>> > right direction ?
>>
>> The key word was "before", that's why I wrote it as "BEFORE"!
>
> Surely there is some other way.

Yes.


> Do Common Lisp compilers become
> nervous when they encounter mutual recursion?

But in this case there's no mutual recursion.

Pascal J. Bourguignon

unread,
Apr 13, 2012, 9:00:31 AM4/13/12
to
No. Just declare the functions before using them would be enough:

----------------------------------------
(declaim (ftype function g))

(defun f ()
(g))

(defun g ()
'ah)
--------------------


But it's much better to just write:

----------------------------------------
(defun g ()
'ah)

(defun f ()
(g))
----------------------------------------

Christophe Rhodes

unread,
Apr 13, 2012, 9:03:50 AM4/13/12
to
Teemu Likonen <tlik...@iki.fi> writes:

> * arnuld [2012-04-13 11:05:35 +0000] wrote:
>
>> This program runs fine. I get style warnings. I know that you have to
>> "defvar" a variable and then do "setf" to assign a value but what about
>> function warning in my case, what to do about them ? (SBCL 1.0.55)
>
> Reorder the functions in your file so that functions are defined before
> their call appear in the source code. See:

In SBCL, if you compile the file, the ordering does not matter:
style-warnings are only emitted for functions not recognized by the end
of the compilation. For loading the file as source, the reordering is
necessary because the compilation and evaluation proceeds a form at a
time.

> With mutual calls you can use
>
> (defun foo (...)
> #+sbcl (declare (sb-ext:muffle-conditions style-warning)
> ...)

With mutual calls, and aiming to remove this style warning on loading
source code, I would instead suggest the portable alternative:

(declaim (ftype function is-odd is-even))
(defun is-odd (x) (is-even (1- x)))
(defun is-even (x) (or (= x 0) (is-odd (1- x))))

Christophe

Teemu Likonen

unread,
Apr 13, 2012, 9:09:24 AM4/13/12
to
* Pascal J. Bourguignon [2012-04-13 15:00:31 +0200] wrote:

>> With mutual calls you can use
>>
>> (defun foo (...)
>> #+sbcl (declare (sb-ext:muffle-conditions style-warning)
>> ...)
>
> No. Just declare the functions before using them would be enough:

What does that "no" mean?

Teemu Likonen

unread,
Apr 13, 2012, 9:11:21 AM4/13/12
to
* Pascal J. Bourguignon [2012-04-13 15:00:31 +0200] wrote:

>> With mutual calls you can use
>>
>> (defun foo (...)
>> #+sbcl (declare (sb-ext:muffle-conditions style-warning)
>> ...)
>
> No. Just declare the functions before using them would be enough:

What does that "no" mean? What is the thing you are denying?

Jussi Piitulainen

unread,
Apr 13, 2012, 9:12:14 AM4/13/12
to
Pascal J. Bourguignon writes:
> Jussi Piitulainen writes:
> > Pascal J. Bourguignon writes:
> >> arnuld writes:
> >>
> >> >> On Fri, 13 Apr 2012 13:23:41 +0200, Pascal J. Bourguignon wrote:
> >> >
> >> >> It's the same principle!
> >> >> You must define the things you use BEFORE you use them!
> >> >
> >> > I have used (declare ) (defun ) and (defvar ) but none of them
> >> > works for functions. I have even used (declare (defun name
> >> > (arguments))) but that does not work too. Can you point me to
> >> > right direction ?
> >>
> >> The key word was "before", that's why I wrote it as "BEFORE"!
> >
> > Surely there is some other way.
>
> Yes.

Yes, a couple have now been posted. One by you. Thanks.

> > Do Common Lisp compilers become
> > nervous when they encounter mutual recursion?
>
> But in this case there's no mutual recursion.

I'd still be annoyed at such warnings when the required definition
follows in the file. arnuld's ordering of his code seemed fine to me.

Alex Mizrahi

unread,
Apr 13, 2012, 9:51:01 AM4/13/12
to
>> The key word was "before", that's why I wrote it as "BEFORE"!

> Surely there is some other way. Do Common Lisp compilers become
> nervous when they encounter mutual recursion?

No. OP wasn't using a compiler (directly, at least) -- he loaded the
file without compiling it.

Loading a file works by reading forms one by one and executing them in
this order, as if they were typed in REPL. (Which is very convenient
when your application consists of just one file -- you'd get package
errors otherwise.)

Compilers are usually more sophisticated, they might be able to defer
warnings until the end of compilation unit, see here:

http://clhs.lisp.se/Body/m_w_comp.htm#with-compilation-unit

---
If an implementation would normally defer certain kinds of warnings,
such as warnings about undefined functions, to the end of a compilation
unit (such as a file),
---

Alex Mizrahi

unread,
Apr 13, 2012, 9:52:52 AM4/13/12
to
> =========================== OUTPUT ==================================
> * (load "acl-ch-3.lisp")

Try

(load (compile-file "acl-ch-3.lisp"))

instead.

> ; compilation unit finished
> ; Undefined function:
> ; COMPR
> ; caught 1 STYLE-WARNING condition

It gives you a hint that each form is an independent compilation unit if
you load a file.

Pascal J. Bourguignon

unread,
Apr 13, 2012, 10:31:16 AM4/13/12
to
The use of an implementation specific solution.
The fact of muffling those warnings.
Everything :-)

Pascal J. Bourguignon

unread,
Apr 13, 2012, 10:33:37 AM4/13/12
to
Actually all the implementation listed below accept the caller ->
callee order in a file for compile-file and for load. He must have had
another problem.


Armed Bear Common Lisp --> "1.0.1"
International Allegro CL Free Express Edition --> "8.2 [Linux (x86)] (Sep 11, 2010 7:36)", ("lisp_build 256")
Clozure Common Lisp --> "Version 1.8-r15286M (LinuxX8664)"
CLISP --> "2.49+ (2010-07-17) (built 3542867425) (memory 3542867673)"
CMU Common Lisp --> "20b (20B Unicode)"
SBCL --> "1.0.45.gentoo-r0"

Espen Vestre

unread,
Apr 13, 2012, 10:47:50 AM4/13/12
to
"Pascal J. Bourguignon" <p...@informatimago.com> writes:

> Actually all the implementation listed below accept the caller ->
> callee order in a file for compile-file and for load. He must have had
> another problem.

Good, I was getting somewhat confused reading this thread :-)
--
(espen)

Alex Mizrahi

unread,
Apr 13, 2012, 10:48:59 AM4/13/12
to
> Actually all the implementation listed below accept the caller ->
> callee order in a file for compile-file and for load. He must have had
> another problem.

SBCL produces warning when you load source file, but not when you
compile-file or load a compiled file.


$ cat foo.lisp
(defun foo () (bar))

(defun bar () )

$ sbcl
This is SBCL 1.0.54.100-14bf777, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.

SBCL is free software, provided as is, with absolutely no warranty.
It is mostly in the public domain; some portions are provided under
BSD-style licenses. See the CREDITS and COPYING files in the
distribution for more information.
* (load "foo.lisp")


; file: /home/alex/foo.lisp
; in: DEFUN FOO
; (BAR)
;
; caught STYLE-WARNING:
; undefined function: BAR
;
; compilation unit finished
; Undefined function:
; BAR

Duane Rettig

unread,
Apr 13, 2012, 12:32:22 PM4/13/12
to
On Apr 13, 4:23 am, "Pascal J. Bourguignon" <p...@informatimago.com>
wrote:
> arnuld <sunr...@invalid.address> writes:
> > This program runs fine. I get style warnings. I know that you have to
> > "defvar" a variable and then do "setf" to assign a value but what about
> > function warning in my case, what to do about them ?  (SBCL 1.0.55)
>
> It's the same principle!

Wow. This was an interesting thread. Lots of platitudes running
around, and some misinformation. Here was the first of that
misinformation:

> You must define the things you use BEFORE you use them!

This statement implies that the OP was indeed using N-ELTS before he
had defined it. Establishing a call to a function within another
function's definition is not a use in the sense of the above statement
until the latter function is actually evaluated. So no, he wasn't
using something before he defined it.

It's nice to tell a compiler what is going to happen in order for the
compiler to do things more efficiently. But in this case, the OP
wasn't asking for compilation, and so he shouldn't be expected to
understand why there is a warning. I'm not saying that the warning is
wrong; SBCL is well within its right to issue the style warning. But
you were wrong to deride the OP for not understanding the reason for
the warning. A teaching moment would have been more helpful.

Duane


Pascal J. Bourguignon

unread,
Apr 13, 2012, 1:43:58 PM4/13/12
to
Indeed, I was wrong. I'm so used to define my functions in post order,
that I though it was expected.

Barry Margolin

unread,
Apr 13, 2012, 2:35:29 PM4/13/12
to
In article <87pqbbs...@kuiper.lan.informatimago.com>,
I thought you meant "In order to prevent the warnings, you must ...".
Although, as others have pointed out, compiling the file will also
prevent the warnings.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Kaz Kylheku

unread,
Apr 13, 2012, 3:37:42 PM4/13/12
to
On 2012-04-13, Barry Margolin <bar...@alum.mit.edu> wrote:
> I thought you meant "In order to prevent the warnings, you must ...".
> Although, as others have pointed out, compiling the file will also
> prevent the warnings.

That's ironic, though: compiling to /prevent/ diagnostics. :)

WJ

unread,
Apr 13, 2012, 9:48:19 PM4/13/12
to
Clojure (clean and functional):

(defn compress [xs]
(map
#(if (next %) (list (count %) (first %)) (first %))
(partition-by identity xs)))

(compress '(1 1 1 0 1 0 0 0 1))

==> ((3 1) 0 1 (3 0) 1)



NewLisp (dirty and destructive):

(define (compress xs elt accum (cnt 1))
(if (setq elt (pop xs))
(while xs
(let (next (pop xs))
(if (= next elt) (++ cnt))
(when (or (empty? xs) (!= next elt))
(push (if (> cnt 1) (list cnt elt) elt) accum -1))
(if (!= next elt)
(if (empty? xs)
(push next accum -1)
(setq elt next cnt 1)))))))

: (compress '(1 1 1 0 1 0 0 0 1))
((3 1) 0 1 (3 0) 1)


WJ

unread,
Apr 13, 2012, 11:13:48 PM4/13/12
to
WJ wrote:

> NewLisp (dirty and destructive):
>
> (define (compress xs elt accum (cnt 1))
> (if (setq elt (pop xs))
> (while xs
> (let (next (pop xs))
> (if (= next elt) (++ cnt))
> (when (or (empty? xs) (!= next elt))
> (push (if (> cnt 1) (list cnt elt) elt) accum -1))
> (if (!= next elt)
> (if (empty? xs)
> (push next accum -1)
> (setq elt next cnt 1)))))))

That was too buggy.

(define (compress xs elt accum (cnt 1))
(when (setq elt (pop xs))
(dolist (next xs)
(if (= next elt)
(++ cnt)
(push (n-elts cnt elt) accum -1)
(setq elt next cnt 1)))
(push (n-elts cnt elt) accum -1)))

(define (n-elts n elt)

Tim Bradshaw

unread,
Apr 15, 2012, 8:10:51 AM4/15/12
to
I may have missed it, but I am not sure if anyone has really give a concise
and correct answer to this (there have been concise and wrong ones such as
the various "define x before you define y which calls x" ones.

The answer is that you're using a compile-only implementation, and it is
treating a request to load a source file as a bunch of independent calls to
compile the definitions in the source file. For a file of the form

(defun x (...) ... (y ...) ...)
(defun y (...) ... (x ...) ...)

Then at the point where it compiles x it has not yet seen y, and is
therefore warning you.

If instead you compile *the whole file* then it will treat it as a
compilation unit, and will complain only about definitions at the end of
the unit, and since at that point it will have seen both x and y it will be
happy.

It's tempting to say that it is therefore safe to, instead of saying (load
x), always say (load (compile-file x)), because that will do the
appropriate deferring of warnings to the end of the file and the compiled
definitions will be the same. I don't think that is quite true however:
the compiler is allowed to perform various optimisations around calls to
definitions in the same file (compilation unit?) which might make debugging
harder in that case (and of course things like eval-when will behave
differently, but if you have things like that in your file you can probably
be assumed to understand their implications).

However, I think that for almost all purposes, for a compile-only
implementation, it should be fine to always simply say (load (compile-file
...)): that's what I do, anyway. In the few cases where I want the
compiler not to optimise calls to things to help debugging I add notinline
declarations.


Here's a question for implementors: is there any reason why load should not
add an implicit with-compilation-unit when loading a source file? Would
that do what I think it should (ie suppress these warnings)? Would it be
conforming?

--tim

Duane Rettig

unread,
Apr 15, 2012, 9:58:18 AM4/15/12
to
On Apr 15, 5:10 am, Tim Bradshaw <t...@tfeb.org> wrote:
> I may have missed it, but I am not sure if anyone has really give a concise
> and correct answer to this (there have been concise and wrong ones such as
> the various "define x before you define y which calls x" ones.

I guess that depends on if there exists a concise and correct answer.
"Have you stopped beating your wife yet?"

> Here's a question for implementors: is there any reason why load should not
> add an implicit with-compilation-unit when loading a source file?  Would
> that do what I think it should (ie suppress these warnings)?  Would it be
> conforming?

As you implied, the compilation of a function when its defining form
is evaluated is optional and incidental. But in the eval-when scheme
of things, there is no :compile-toplevel time - it is all (including
the compilation of each function) part of the :execute time. So no, I
wouldn't suggest the addition of a with-compilation-unit around
something that is not being handled at :compile-toplevel time. Note
that there may be some side-effects of the kind you're looking for,
but those may be incidental and perhaps even accidental, and there
would be no reason to count on them in any implementation or in any
future version of an implementation in which it accidentally works.

On the implementation side, w-c-u leaves a lot of wiggle-room. The
value of the :override argument is unspecified (except that it is
mandated to have the value of nil when it is the one wrapped around a
compile-file). Whether or not cl:compile is enclosed in a w-c-u form
or not, and whether its :override value is nil or not, are
unspecified. On one hand, the name "compilation" in the name implies
anything having to do with compiling, but on the other hand, the name
"unit" implies multiple items acting as one. An incidental
compilation of an evaluated form might or might not be grouped
together into a unit.

Duane

Tim Bradshaw

unread,
Apr 15, 2012, 11:45:06 AM4/15/12
to
On 2012-04-15 13:58:18 +0000, Duane Rettig said:

> As you implied, the compilation of a function when its defining form
> is evaluated is optional and incidental. But in the eval-when scheme
> of things, there is no :compile-toplevel time - it is all (including
> the compilation of each function) part of the :execute time. So no, I
> wouldn't suggest the addition of a with-compilation-unit around
> something that is not being handled at :compile-toplevel time. Note
> that there may be some side-effects of the kind you're looking for,
> but those may be incidental and perhaps even accidental, and there
> would be no reason to count on them in any implementation or in any
> future version of an implementation in which it accidentally works.

I think what I meant was not that it would be right to literally wrap
with-compilation-unit around calls to load, but that such
implementations might want to wrap something which does the
delaying-warnings-to-the-end thing (which presumably they have
available inside the implementation), to avoid this kind of
spurious-warning thing. Sorry, I should have worded it more carefully.

Duane Rettig

unread,
Apr 15, 2012, 5:08:07 PM4/15/12
to
I'm not so concerned about careful words; it is the higher level
concept that interests me. If you generalize what you're asking for,
it's a kind of "block-evaluation" idea, where everything within an
"evaluation unit" (if you will) is treated as one entity. Block
compilation is a similar thing, but almost always the impetus for
block compilation is for efficiency, and block compilation and
dynamism are at odds with each other, so it becomes a tradeoff between
the efficiency that block compilation provides and the late-binding
and rebinding that dynamism allows. I see no such equivalent tradeoff
in a block evaluation; the delay of warnings that one _might_ get when
a function is defined and _might_ be compiled just doesn't seem worth
it to me. And I see no other advantage to block-evaluation...

Duane

Paul Wallich

unread,
Apr 15, 2012, 5:36:25 PM4/15/12
to
Speaking very naively, it seems that (unless all you do is delay certain
warnings) careless block-execution could change semantics. If, for
example you do anything in the loaded file for effects other than to
produce once-only definitions and once-only symbol bindings.

paul

Tim Bradshaw

unread,
Apr 15, 2012, 6:45:48 PM4/15/12
to
Duane Rettig <du...@franz.com> wrote:
> I see no such equivalent tradeoff
> in a block evaluation; the delay of warnings that one _might_ get when
> a function is defined and _might_ be compiled just doesn't seem worth
> it to me. And I see no other advantage to block-evaluation...

I think that suppressing spurious warnings is extremely important, because
I always try to ensure that there are *no* warnings, as it is much easier
to notice the change from zero to non-zero than from 100 to 101, say. But
I also can't see why I would ever load things uncompiled, so, well...

arnuld

unread,
Apr 16, 2012, 4:36:42 AM4/16/12
to
That works with me (no warnings at all):


* (compile-file "acl-ch-3.lisp")

; compiling file "/home/arnuld/programs/Common-Lisp/acl-
ch-3.lisp" (written 13 APR 2012 04:30:39 PM):
; compiling (DEFUN COMPRESS ...)
; compiling (DEFUN COMPR ...)
; compiling (DEFUN N-ELTS ...)

; /home/arnuld/programs/Common-Lisp/acl-ch-3.fasl written
; compilation finished in 0:00:01.132
#P"/home/arnuld/programs/Common-Lisp/acl-ch-3.fasl"
NIL
NIL
* (load "acl-ch-3.fasl")

T
*





--
arnuld
http://LispMachine.Wordpress.com

Alex Mizrahi

unread,
Apr 16, 2012, 8:13:38 AM4/16/12
to
> It's tempting to say that it is therefore safe to, instead of saying (load
> x), always say (load (compile-file x)), because that will do the
> appropriate deferring of warnings to the end of the file and the compiled
> definitions will be the same. I don't think that is quite true however:

I'd say `(load (compile-file x))` should be a normal way of doing things
in application, this is what ASDF would do when loading code.

Simple LOAD is more like a special purpose tool for special cases (like
when one is too lazy to add eval-when, or has some obscure problem with
compiler). Having style warnings in these special cases isn't really a
problem. SBCL is just very chatty, people should get used to it. (Or
hide warnings if they are too annoying.)

Tim Bradshaw

unread,
Apr 16, 2012, 6:03:41 PM4/16/12
to
On 2012-04-15 21:08:07 +0000, Duane Rettig said:

> And I see no other advantage to block-evaluation...

Well, the advantage in this case is that loading a source file would
not result in a slew of spurious warnings, but only warnings about
functions which really were unknown. That would matter a lot to me: an
implementation which produces spurious warning is toxic.

Tim Bradshaw

unread,
Apr 16, 2012, 6:06:45 PM4/16/12
to
On 2012-04-16 12:13:38 +0000, Alex Mizrahi said:

> Simple LOAD is more like a special purpose tool for special cases (like
> when one is too lazy to add eval-when, or has some obscure problem with
> compiler).

Or, for instance you don't want all the hairy inlining or assumptions
that can be made about definitions within the same file without adding
a slew of declarations.

Pascal Costanza

unread,
Apr 17, 2012, 3:21:05 AM4/17/12
to
There are good cases when load is more efficient: For example when
loading a script that is executed just once. Then compiling it first
before executing it is a waste of time. (For example, I use LML for
generating my websites, and I load the scripts with clisp, because it's
guaranteed to be interpreted there, which makes the website generation a
lot (!) faster.)

Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
The views expressed are my own, and not those of my employer.

Alex Mizrahi

unread,
Apr 17, 2012, 3:52:37 AM4/17/12
to
>> Simple LOAD is more like a special purpose tool for special cases
>> (like when one is too lazy to add eval-when, or has some obscure
>> problem with compiler).

> Or, for instance you don't want all the hairy inlining or assumptions
> that can be made about definitions within the same file without adding a
> slew of declarations.

This falls into "have some obscure problems with compiler".

Tim Bradshaw

unread,
Apr 18, 2012, 6:22:14 PM4/18/12
to
On 2012-04-17 07:52:37 +0000, Alex Mizrahi said:

> his falls into "have some obscure problems with compiler".

Only if you're used to a compiler from prehistory which never optimises
anything.

Kaz Kylheku

unread,
Apr 18, 2012, 6:44:05 PM4/18/12
to
On 2012-04-16, Alex Mizrahi <alex.m...@gmail.com> wrote:
>> It's tempting to say that it is therefore safe to, instead of saying (load
>> x), always say (load (compile-file x)), because that will do the
>> appropriate deferring of warnings to the end of the file and the compiled
>> definitions will be the same. I don't think that is quite true however:
>
> I'd say `(load (compile-file x))` should be a normal way of doing things
> in application, this is what ASDF would do when loading code.

That may be what ASDF does when the operation is asdf:load-op.

That isn't what ASDF does when the operation is asdf:load-source-op.

Always compiling is great if your Lisp is as good at debugging compiled code as
it as a debugging uncompiled code.

In some Lisps, like CLISP, that isn't the case. For instance, you can't STEP
into a compiled function at all.

WJ

unread,
Apr 22, 2012, 12:54:26 AM4/22/12
to
arnuld wrote:

> This program runs fine. I get style warnings. I know that you have to
> "defvar" a variable and then do "setf" to assign a value but what about
> function warning in my case, what to do about them ? (SBCL 1.0.55)
>
>
>
> ;;; ACL chpater 3 examples
>
>
> ;; compression algorithm a.k.a run-length-encoding
> (defun compress (x)
> (if (consp x)
> (compr (car x) 1 (cdr x))
> x))
>
>
> (defun compr (elt n lst)
> (if (null lst)
> (n-elts elt n)
> (let ((next (car lst)))
> (if (eql next elt)
> (compr elt (+ n 1) (cdr lst))
> (cons (n-elts elt n)
> (compr next 1 (cdr lst)))))))
>
>
> (defun n-elts (elt n)
> (if (> n 1)
> (list n elt)
> elt))
>
>
> =========================== OUTPUT ==================================
> * (load "acl-ch-3.lisp")
>
> ; file: /home/arnuld/programs/Common-Lisp/acl-ch-3.lisp
> ; in: DEFUN COMPRESS
> ; (COMPR (CAR X) 1 (CDR X))
> ;
> ; caught STYLE-WARNING:
> ; undefined function: COMPR
> ;
> ; compilation unit finished
> ; Undefined function:
> ; COMPR
> ; caught 1 STYLE-WARNING condition
>
> ; in: DEFUN COMPR
> ; (N-ELTS ELT N)
> ;
> ; caught STYLE-WARNING:
> ; undefined function: N-ELTS
> ;
> ; compilation unit finished
> ; Undefined function:
> ; N-ELTS
> ; caught 1 STYLE-WARNING condition
>
> T
>
> * (compress '(1 1 1 0 1 0 0 0 1))
>
> ((3 1) 0 1 (3 0) . 1)
> *

Racket:

(define (n-elts elt n)
(if (> n 1) (cons n elt) elt))

(define (compr item cnt accum alist)
(if (null? alist)
(reverse (cons (n-elts item cnt) accum))
(if (equal? item (car alist))
(compr item (+ 1 cnt) accum (cdr alist))
(compr (car alist) 1 (cons (n-elts item cnt) accum) (cdr alist)))))

(define (compress alist)
(if (null? alist)
null
(compr (car alist) 1 '() (cdr alist))))

(compress '(1 1 1 0 1 0 0 0 1))

==> '((3 . 1) 0 1 (3 . 0) 1)

0 new messages