This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [GSoC] Parameter protocols in CL


On 07/19/2012 03:00 PM, Charles Turner wrote:
Well, I think I've finally found the offending bit of code, after
going through all the primitives, uncommenting a method at a time!
Sigh.

  ;; FIXME: Do this through a thread-location instead.
  (defun in-package (name)
    (let ((package (find-package-or-error name)))
      (progn
        (invoke-static class::|gnu.kawa.lispexpr.LispPackage|
  		     '|setCurrentPackage| package)
        (setq *package* package))))

Note that in-package does (at least ultimately need to be a macro, because it needs to be expanded at compile-time (as well as run-time) - though only at top-level, according to the HyperSpec.

(in-package "CL-USER") ; <-- This causes the literals error (guess
what position it was in a 400-line file. That's right, the bottom.)

The "Literals: Internal error" is due to the way literals are handler.
An overview is in http://www.gnu.org/software/kawa/internals/code-generation.html.
Look for the section Literals.


Basically, if a literal is to be written to a classfile, then the
compiler checks if its class is Externalizable, in which case it calls
LitTable#writeExternal. In this case we get the inherited Namedspace#writeExternal,
which pushes (name, prefix). The the compiler looks for a constructor, or
a "valueOf" or a "make" method in the class, so it can generate code to
call that method - which will then re-construct the literal at class-loading time.
The is a valueOf method in NameSpace - but none in LispPackage.


So what you need to do is add a method to LispPackage like:

public static LispPackage(String uri, SimpleSymbol prefix) { ... }

or better, override writeExternal:

  public void writeExternal(ObjectOutput out) throws IOException
  {
    out.writeObject(getName());
    out.writeObject(prefix);
  }

and then implement:

public static LispPackage(String name) { ... }

where the ... should be the equivalent of find-package-or-error.

Now there is still a mystery to me why you sometimes get this error
and sometimes not.

It's the (setq *package* package). I've made *package* a
defStdAliasFld, which I still don't see anything wrong about. It seems
like similar static members that follow this approach in Scheme are
constants, whilst the variable ones are thread locations. Is that the
case? Two days on the hunt for this... Did I miss something well known
in the programming community, or could we do with a better diagnostic
here?

Not sure.


If what I said above is remotely correct, I suppose you also
have to declare the aliased static field as a constant somewhere?

What do you mean? I assume you've looked at (say) *print-base* as it is defined in Scheme.java. That binds the name "*print-base*" to the ThreadLocation DisplayFormat.outBase. You shouldn't need to do anything else - unless you need to trap assignments to *package* so you can set other side-effects.

The two statements:
  (invoke-static class::|gnu.kawa.lispexpr.LispPackage|
     		     '|setCurrentPackage| package)
and:
       (setq *package* package))))
should have the same effect.  Both have the effect of updating
a ThreadLocation.

Sorry about the time I spent on this bug! Just couldn't understand
what was happening :'-(

I've spent embarrassing amount on time on what turned out to be something simple. We all have. And not just when I was starting out - quite recently. And in this case we're working our way through how to implement Common Lisp symbols and packages, which is non-trivial, while I'm distracted by other issues, so haven't been able to help as much as I'd like. -- --Per Bothner per@bothner.com http://per.bothner.com/



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]