This is the mail archive of the
kawa@sourceware.org
mailing list for the Kawa project.
Re: issue: class field and its usage from lambda
- From: Fushacko Tito <imdagger at yandex dot ru>
- To: Per Bothner <per at bothner dot com>
- Cc: "kawa at sourceware dot org" <kawa at sourceware dot org>
- Date: Sun, 16 Sep 2012 04:48:13 +0400
- Subject: Re: issue: class field and its usage from lambda
- References: <33481344355500@web19g.yandex.ru> <50222A60.50207@bothner.com>
Hi, I have little bit different trouble, but it's related to this topic:
$ kawa --version
Kawa 1.12.1 (revision 7291)
Copyright (C) 2011 Per Bothner
I'm trying to use kawa class and function that returns multiple values, there is
example of code which causes issue for me now:
(module-export Bug)
(define-class Bug ()
(x ::int)
((f)
(receive ((a ::int) (b ::int)) (values 1 2)
(set! x b))))
((Bug):f)
It successfully compiles with no warnings:
$ kawa --main -C test.scm
(compiling test.scm to test)
But program's execution result doesn't looks good for me:
java.lang.IncompatibleClassChangeError: Class test$frame does not implement the requested interface test$Bug
at test$Bug$class.lambda2(test.scm:7)
at test$frame.apply2(test.scm:6)
at gnu.expr.ModuleBody.applyN(ModuleBody.java:237)
at gnu.expr.ModuleMethod.applyN(ModuleMethod.java:216)
at gnu.mapping.Values.call_with(Values.java:128)
at kawa.standard.call_with_values.callWithValues(call_with_values.java:15)
at test$Bug$class.f(test.scm:6)
at test$Bug$class.f(test.scm)
at test.run(test.scm:9)
at gnu.expr.ModuleBody.runAsMain(ModuleBody.java:152)
at test.main(test.scm)
I have decompiled class produced by kawa and got it:
...
public class class
implements test.Bug
{
public int x;
public static Object f(test.Bug this)
{
test.frame localframe = new test.frame(); localframe.$this$ = this;
return call_with_values.callWithValues(test.lambda$Fn1, localframe.lambda$Fn2);
}
static Object lambda1() { return misc.values(new Object[] { test.Lit0, test.Lit1 }); }
static void lambda2(test.frame closureEnv, int a, int b) {
closureEnv.setX(b);
}
...
public Object f()
{
return f(this);
}
}
It was decompiled version with bug. But later I tried to add "(this):" to field, and code worked
correctly. I have decompiled this class again:
public class class
implements test.Bug
{
public int x;
public static Object f(test.Bug this)
{
test.frame localframe = new test.frame(); localframe.$this$ = this;
return call_with_values.callWithValues(test.lambda$Fn1, localframe.lambda$Fn2);
}
static Object lambda1() { return misc.values(new Object[] { test.Lit0, test.Lit1 }); }
static void lambda2(test.frame closureEnv, int a, int b) {
closureEnv.$this$.setX(b);
}
public int getX()
{
return this.x;
}
public void setX(int paramInt)
{
this.x = paramInt;
}
public Object f()
{
return f(this);
}
}
Pay more attention on lambda2 method, it's different. Here is the issue in the first case, because
method tries to call set field function directly from context (but it's not correct as
I understand, correct me if I'm not right).
And I have not stopped at this and tried to replace define-class by define-simple-class, and it looked
good for me, because lambda2 worked with closureEnv.$this$.x
import kawa.lib.misc;
import kawa.standard.call_with_values;
public class Bug
{
public int x;
public Object f()
{
test.frame localframe = new test.frame(); localframe.$this$ = this;
return call_with_values.callWithValues(test.lambda$Fn1, localframe.lambda$Fn2); }
static Object lambda1() { return misc.values(new Object[] { test.Lit0, test.Lit1 }); }
static void lambda2(test.frame closureEnv, int a, int b) { closureEnv.$this$.x = b;
}
}
08.08.2012, 12:59, "Per Bothner" <per@bothner.com>:
> On 08/07/2012 09:05 AM, Fushacko Tito wrote:
>
>> (define-class FailClass ()
>> (x ::float access: 'private init: 0.0)
>>
>> ((wrap-x) (lambda () x))
>>
>> ((calculate-position)
>> (letrec ( (wrap-func (lambda () (wrap-x))) )
>> (wrap-func))))
>>
>> For both Kawa 1.12.1 (revision 7282) and Kawa 1.12 release i got this traceback:
>> [imdagger@blacktears]$ java -jar /home/imdagger/kawa/kawa/kawa-1.12.1.jar -C test.scm
>> (compiling test.scm to test)
>> test.scm:4: internal error while compiling test.scm
>> java.lang.NullPointerException
>> at gnu.expr.LambdaExp.setCallersNeedStaticLink(LambdaExp.java:209)
>
> I checked in a fix for this in the Subversion repository.
>
> This is related to using define-class rather than define-simple-class;
> the manual discusses the difference:
> http://www.gnu.org/software/kawa/Defining-new-classes.html
> --
> --Per Bothner
> per@bothner.com http://per.bothner.com/
--
Alex Moiseenko