From: N. Raghavendra
Subject: Works in CMUCL but not in CLISP
Date: 
Message-ID: <79eaf3a4.0303232232.63631ccc@posting.google.com>
Hello,

Please see the file "foo.lisp" below. I can evaluate

         (compile-file "/tmp/foo.lisp")

in CMUCL without any error, but in CLISP it produces the error
"EVAL: variable MY-MAX has no value".

However, if I comment out the definition of the function FOO,
then I can evaluate the above expression even in CLISP.

I am wondering if there is something wrong with my syntax, or
whether there is a problem in CLISP's implementation of `loop'.

;;;; foo.lisp --- `compile-file' problem case

(defconstant my-max 10000)

(deftype my-integer ()
  "Type of non-negative integers less than MY-MAX."
  `(mod ,my-max))

(defun foo (m)
  "Print the integers 0,...,M-1."
  (declare (type my-integer m))
  (loop for i of-type my-integer = 0 then (+ 1 i)
        until (= i m)
        do (format t "~D " i)))

(defun bar (m)
  "Print the integers 0,...,M-1."
  (declare (type my-integer m))
  (loop for i of-type my-integer from 0 below m
        do (format t "~D " i)))

;;;; foo.lisp ends here.

Any help is appreciated.

Best regards,
Raghavendra.

-- 
N. Raghavendra <·····@atc.tcs.co.in> | OpenPGP public key available
Tata Consultancy Services            | at http://www.keyserver.net/
Hyderabad                            |      Key ID: 0x03618806

From: Kalle Olavi Niemitalo
Subject: Re: Works in CMUCL but not in CLISP
Date: 
Message-ID: <87r88xxlbb.fsf@Astalo.kon.iki.fi>
·····@atc.tcs.co.in (N. Raghavendra) writes:

> (defconstant my-max 10000)

"An implementation may choose to evaluate the value-form at
compile time, load time, or both."

MY-MAX does not necessarily have a value at compile time.

> (deftype my-integer ()
>   "Type of non-negative integers less than MY-MAX."
>   `(mod ,my-max))

"The programmer must ensure that the body of a deftype form can
be evaluated at compile time if name is referenced in subsequent
type declarations."

If MY-INTEGER is referenced in subsequent type declarations,
`(mod ,my-max) must be able to be evaluated at compile time.
Which it isn't, if MY-MAX doesn't yet have a value.

To ensure that MY-MAX has a value at compile time, you can wrap
the DEFCONSTANT form in a suitable EVAL-WHEN.
From: N. Raghavendra
Subject: Re: Works in CMUCL but not in CLISP
Date: 
Message-ID: <79eaf3a4.0303240238.71456134@posting.google.com>
Kalle Olavi Niemitalo <···@iki.fi> wrote in message news:<··············@Astalo.kon.iki.fi>...

> "The programmer must ensure that the body of a deftype form can
> be evaluated at compile time if name is referenced in subsequent
> type declarations."
> 
> If MY-INTEGER is referenced in subsequent type declarations,
> `(mod ,my-max) must be able to be evaluated at compile time.
> Which it isn't, if MY-MAX doesn't yet have a value.
> 
> To ensure that MY-MAX has a value at compile time, you can wrap
> the DEFCONSTANT form in a suitable EVAL-WHEN.

Hi Kalle,

Thanks very much. Yes, if I wrap the `defconstant' form as

  (eval-when (:compile-toplevel :load-toplevel :execute)
    (defconstant my-max 10000))

it works in CLISP too.

However, I still don't understand why the file compiled without
errors in CLISP, if I commented out the function FOO. That is,
if I modify the file "foo.lisp" as follows, then I can evaluate

  (compile-file "/tmp/foo.lisp")

in CLISP (and CMUCL) without errors.

;;;; foo.lisp --- `compile-file' problem case

(defconstant my-max 10000)

(deftype my-integer ()
  "Type of non-negative integers less than MY-MAX."
  `(mod ,my-max))

(defun bar (m)
  "Print the integers 0,...,M-1."
  (declare (type my-integer m))
  (loop for i of-type my-integer from 0 below m
        do (format t "~D " i)))

;;;; foo.lisp ends here.

I haven't wrapped the `defconstant' in `eval-when', yet the
file compiles in CLISP. What is the explanation for this
difference in behaviour?

Best regards,
Raghavendra.

-- 
N. Raghavendra <·····@atc.tcs.co.in> | OpenPGP public key available
Tata Consultancy Services            | at http://www.keyserver.net/
Hyderabad                            |      Key ID: 0x03618806
From: Kaz Kylheku
Subject: Re: Works in CMUCL but not in CLISP
Date: 
Message-ID: <cf333042.0303241030.5dac4194@posting.google.com>
·····@atc.tcs.co.in (N. Raghavendra) wrote in message news:<····························@posting.google.com>...
> I haven't wrapped the `defconstant' in `eval-when', yet the
> file compiles in CLISP. What is the explanation for this
> difference in behaviour?

The explanation is that a DEFTYPE form is not necessarily evaluated,
even if the type name appears in declarations. Perhaps in compiling
function BAR, the CLISP compiler does not require sufficiently deep
access to the properties of that type that it would need to evaluate
the form.

Remember, DEFTYPE does not evaluate the form, it only records it. It's
a little bit like promise/force lazy evaluation; you promise that this
form can be evaluated by the compiler, and it force that at its
discretion.