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 | Extending Common Lisp support


Charlie, feel free not to read this before Saturday.

On May 24, 2012, at 4:24 AM, Charles Turner wrote:

On 23 May 2012 23:36, Jamison Hope <jrh@theptrgroup.com> wrote:
1. I presume that this change in PropertyLocation.java

- if (symbol instanceof Symbol) + if (symbol instanceof Symbol && lloc != null)

is intended to avoid a possible NullPointerException? But after that
if block there's an unguarded "lloc.set(plist);" anyway, so you'll
still get the NPE, just at a different line number.

I vaguely remember doing this, must have come across the bug a while ago when I was torturing the compiler. Sorry about that. There's a load of stuff in my svn diff that can only be described as experimental tinkering that I didn't intend to send in my rushed patch. I tried to delete most of this, but clearly that one leaked through :-)

No worries, I've got a handful of local modifications to keep track of as well.

2. In moving the bulk of checkDefaultBinding() from SchemeCompilation.java
to Translator.java, the XmlNamespace/unitNamespace checks have been
effectively reordered to be after the "ends with '?'" check. Does that
have any functional repercussions? (I suspect not, but haven't tested
either.)

I was conscious of this at the time. That was one of the reasons I asked whether relying on the test suite was OK for refactorings. I had planned to test these things when I got time to do so, but as you mentioned, it's quite a rabbit hole, and whilst I was "in the zone", I just tried to refactor as much as possible without horrifically breaking everything and then go back over it with the tooth comb.

Yup, just something to keep in mind. It looks like it does affect things
a little, if you try to use an XML-namespaced symbol ending with a question
mark:


Old behavior:

$ kawa
#|kawa:1|# html:p
ElementType {http://www.w3.org/1999/xhtml}:p
#|kawa:2|# html:p?
ElementType {http://www.w3.org/1999/xhtml}:p?
#|kawa:3|# (html:p? 123)
<p? xmlns="http://www.w3.org/1999/xhtml";>123</p?>
#|kawa:4|# (html:p? (html:p 123))
<p? xmlns="http://www.w3.org/1999/xhtml";><p>123</p></p?>


New behavior:


$ kawa
#|kawa:1|# html:p
ElementType {http://www.w3.org/1999/xhtml}:p
#|kawa:2|# html:p?
#<procedure p?>
#|kawa:3|# (html:p? 123)
#f
#|kawa:4|# (html:p? (html:p 123))
#t

Question for everybody and not just Charles:
Will this matter? I'm no XML guy, but if I'm reading the XML 1.0 and
1.1 specs correctly, '?' is not allowed in an element name anyway.
Both http://www.w3.org/TR/2008/REC-xml-20081126/#sec-common-syn and
http://www.w3.org/TR/2006/REC-xml11-20060816/#sec-common-syn contain
the following language:

The ASCII symbols and punctuation marks, along with a fairly large
group of Unicode symbol characters, are excluded from names because
they are more useful as delimiters in contexts where XML names are
used outside XML documents; providing this group gives those contexts
hard guarantees about what cannot be part of an XML name.


So Charlie, unless somebody complains, I think we can mark this down as
a benign change in functionality.

3. Also in the checkDefaultBinding() relocation, Translator.java now has:

int len = name.length(); char ch0 = name.charAt(0);

where the SchemeCompilation version used to have an "if (length == 0)"
check in between. Could that be a problem? Is name ever the empty string?

I probably intended to keep that check. I don't think you can trigger that error from the language (I'm probably wrong about that), but it certainly should be there as a consistency check I think.

Agreed.


4. Scheme.getNamedType() directly calls LispLanguage.getLispTypeMap().get(),
but it looks like it should be calling LispLanguage.getNamedLispType()
instead, as that's where the name.startsWith("clisp:") stuff is now.
Also, evaluating |clisp:boolean| in Scheme doesn't work anymore, even if
LispLanguage.getLispTypeMap().get is replaced with
LispLanguage.getNamedLispType. It looks like this is because
LispLanguage.getNamedLispType("boolean") returns null.

I noticed that one when compiling the distribution. I figured I'd done the refactoring wrong at the time, or that I need to add some extra machinery. This is because the common lisp boolean type is now visible only to CommonLisp (it's initialised in CommonLisp#getTypeFor) and the type name "boolean" is only checked properly when we're in that language. I'm still not sure what's the best way to fix this problem, but I didn't have much time to spend on it.

Re |clisp:boolean|, I got it to work again by adding

types.put ("boolean", Type.booleanType);


to the getLispTypeMap() initialization, so that then

Class clas = getNamedLispType(name.substring(colon+1)).getReflectClass();


succeeds and passes Boolean.TYPE to CommonLisp's getTypeFor(Class), which
then
returns CommonLisp's booleanType.

So I've repeated what you already know above then :-). I hadn't thought of this solution. It doesn't seem too hackish to me, isn't this one of the uses of reflection when we're in such a situation? (I'm not very experienced with reflection, so please elaborate if I'm missing the point).

Yeah, maybe it's not so bad. All of the other primitive type names are there,
so it does seem a little peculiar for boolean to be missing. It just struck
me as hackish yesterday after I started to realize how many conversions between
Strings, Types, and Classes go on when it tries to resolve | clisp:boolean|.


I think I've mostly convinced myself that the lookup should stick with
Strings, with LispLanguage#getNamedLispType(String name) changed to look
something like this:

  public static Type getNamedLispType (String name)
  {
    System.out.println("LispLanguage.getNamedLispType("+name+")");
    getLispTypeMap();
    Type type = (Type) types.get(name);

int colon = name.indexOf(':');

    if (type == null && colon > 0)
      {
	String lang = name.substring(0,colon);
	Language interp = Language.getInstance(lang);
	if (interp == null)
	    throw new RuntimeException("unknown type '" + name
				       + "' - unknown language '"
				       + lang + '\'');

type = interp.getNamedType(name.substring(colon+1));

	if (type != null)
	  types.put(name, type);
      }
    return type;
  }

instead of recursively doing
Class clas = getNamedLispType(name.substring(colon +1)).getReflectClass();
which requires the un-prefixed named type to be found in LispLanguage's
type map to resolve it to a Type (and then to a Class) before asking for
interp's translation.


If we stick with Strings, then we can (in principle, at least) reference
types only defined by a particular lisp language. For example, from Scheme
have |clisp:t| resolve to java.lang.Object, and from Emacs Lisp have
|scheme:s8vector| resolve to gnu.lists.S8Vector, even though LispLanguage
knows nothing of "t" or "s8vector".


[Note that I generalized the check for "elisp:" or "clisp:" to permit any
of the language names known to Language#getInstance.]


That's because CommonLisp doesn't override Lisp2's getNamedType(), which
just
defers to LispLanguage.getNamedLispType(). The only way to get the correct
Type
is to (somehow) first get the corresponding Class and pass it to
getTypeFor(Class).
In particular, note that CommonLisp.getTypeFor(String) will not do the right
thing.
I think this is related to the "CL not is not not" bug I came across a few
weeks ago.


This is turning out to be quite the rabbit hole.

Unfortunately exams interrupted me when I'd loaded my interpretation of all this stuff ties together into my head. So I'll have to reinitialise after exams to finish it.

Understood. Context switches are expensive for humans. I don't mean to be
disturbing your study time right now, sorry!


It looks like you're at least far enough along that class literals work,
and even if you still have to call it |clisp:boolean| I think you should
be able to finish translating PrimOps.scm now (if you incorporate my above
hack).

PrimOps (which I renamed primitives.lisp, oops just realised I didn't add this to my working copy) is finished. Other than a few return types I may have omitted :-D

Awesome!


Clearly there's a sizable mess here with getTypeFor(String) vs
getTypeFor(Class)
vs getNamedType(String) vs string2Type(String), and that's tangential to
your
actual proposed summer project.


Per, what if you and I (yes, I am aware that likely simplifies to "I") take
over
that part of it so that Charlie can focus on DECLARE, sequences, and LOOP?
(Will 1.12 be coming soon so we can check some of this stuff in?)

I'm not complaining that someone wants to take this off me, but I hope I'm not falling behind too soon. My exams finish on Saturday, so I will be able to focus my full attention on the problem. I suppose with this kind of thing, were I to continue focusing on it, I should stay in closer contact with one of the mentors so that it's easier to follow what I've been doing and so that I can be told when a particular approach isn't a good design decision.

I'm not worried about you falling behind, but now that we've officially
entered the GSOC coding period (as of the 21st), I want to make sure that
you're primarily addressing the deliverables that you signed up for.




Thanks for your time,
Charlie.

-- Jamison Hope The PTR Group www.theptrgroup.com




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