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: issue: class field and its usage from lambda


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


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