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


On Jun 25, 2012, at 1:54 PM, Charles Turner wrote:

Right, after the Internet failure, I'm back online!

Welcome back!


The implementation of DEFPACKAGE has implied implementing lots of
other bits of missing functionality. Here are some of the headaches I
had while I was offline.

Am I missing something about the implementation of PUSH? My first attempt was

(defmacro (push x lst)
 `(setq ,lst (cons ,x ,lst)))

I realised that isn't going to work for all cases. It seems like I
need to know the "setf expansion" lst before going any further, but of
course we don't have SETF, and even if we did, I'm not sure if I've
completely misunderstood something. The hyperspec is quite pedantic
about the order of evaluation of this form, so I'm weary to just go
ahead and use Java.

A conforming PUSH does need generalized references a la SETF or SRFI-17 set!.
But for now, if using SETQ like that is enough to move on, then go for it.
We can call it a bug to be fixed later.


SETQ doesn't seem to be working from with LET:

(let ((res nil))
 (setq res 5)
 res) ;=> nil

Hmm, are you seeing a warning in there? [Not sure if our local versions have diverged.]


#|kawa:1|# (let ((res nil)) (setq res 5) res)
/dev/stdin:1:18: warning - no declaration seen for res
()

That tells me that inside of SETQ it's not finding the correct res. Sure enough,
it looked for one at top level, didn't find one, and made a new binding there:


#|kawa:2|# res
5

Looks like setq#rewriteForm needs to have a tr.rewrite(name) in there to get
a ReferenceExp the way set_b#rewriteForm does.


On a side note:
I'm a little puzzled by why setq will accept a String as the variable,
and why it explicitly uses the String "nil" as the variable if it sees
CommonLisp.FALSE (i.e. nil). Both of these expressions seem like they
should be errors (and in fact *are* errors in SBCL):
(setq "hello" "world")
(setq nil 5)
Some brief svn log spelunking seems to indicate that it's been that way
for a very long time.

However, SET! does work, which I know I probably shouldn't be using,
but I wanted to try getting further on DEFPACKAGE after spending a
while on this bug.

For the moment, if it works then go for it. We can fix it later.


Then another one bit me

PRIMITIVE-THROW isn't working in CL:

(primitive-throw (<java.io.IOException>:new
((format #f "cannot delete ~a" file):toString)))
/dev/stdin:2:18: warning - no field or setter 'new' in class java.io.IOException
java.io.IOException
at atInteractiveLevel$2.run(stdin:2)
...


I wanted a better exception framework than ERROR, but I couldn't get
the above to work. Works fine in Scheme of course. Spent a while on
this one, couldn't fix it, littered my code with terrible error
messages using ERROR alone.

Instead of :new (which relies on colons working as they do in Scheme), try MAKE. Something like:

(primitive-throw (make <java.io.IOException> (invoke (format #f "cannot delete ~a" file) 'toString)))

Got bitten again,

Kawa doesn't handle supplied-p parameters, so writing code like this
seems impossible:

(defun f (x y &key (test #'eql testp) (test-not nil notp))
 (when (and testp notp)
   (error "cant supply both")))

Right, that doesn't work yet. Maybe you can do something like this instead?


(defun f (x y keyword val)
  (cond ((eq keyword :test) ...)
        ((eq keyword :test-not) ...)
        ...))

Kawa currently expects a type parameter in this place (the processing
is done l 235 in Lambda.java). I assume setting the value of the TESTP
and NOTP declarations to NIL if the compiler has to automatically set
the values to NIL would be the method.

LambdaExp#enterFunction inserts calls to Keyword#searchForKeyword to scan
the argument list for each keyword. It doesn't currently distinguish between
a default value and an identical found value. We'll probably need to change
it to either return the index instead , or return both the found (or default)
keyword value along with the appropriate supplied-p value, e.g. as a Pair.


public static Object searchForKeyword(...)
{
...
if (vals[i] == keyword)
return new Pair(vals[i+1], Language.getDefaultLanguage().booleanObject(true));
...
return new Pair(dfault, Language.getDefaultLanguage().booleanObject(false));
}


Either way we would also need to change that part of LambdaExp to do the
appropriate thing.


Another option right now (yes, a total hack) would be to do something like
this:


(defun f (x y &key (test 'test-default) (test-not 'test-not-default))
  (when (and (not (eq test 'test-default))
             (not (eq test-not 'test-not-default)))
        (error "can't supply both"))
  (when (eq test 'test-default) (setq test #'eql))
  (when (eq test-not 'test-not-default) (setq test-not nil))
  ...)

i.e. choose default values that are only meaningful as default tokens,
not as the actual defaults you intend to use.

I also noticed a weird bit of behaviour (noticed whilst puzzling over
why my PUSH wasn't working):

#|kawa:4|# '(1 . ())
(1)
#|kawa:5|# '(1 . nil)
(1 . nil)
#|kawa:6|# (eq '() nil)
t

I think that one is because (quote nil) is not currently evaluating to nil, as it should:


#|kawa:1|# (eq '() ())
t
#|kawa:2|# (eq '() nil)
t
#|kawa:3|# (eq 'nil nil)
()
#|kawa:4|# '(1 . nil)
(1 . nil)
#|kawa:5|# `(1 . ,nil)
(1)


So, I'm currently trying my best to implement DEFPACKAGE with the
stuff I have, as I've been unable to fix the above problems.

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]