This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
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