public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
* JavaFX unexpected warning
@ 2018-10-31  9:31 Arie van Wingerden
  2018-10-31  9:49 ` Sudarshan S Chawathe
  0 siblings, 1 reply; 8+ messages in thread
From: Arie van Wingerden @ 2018-10-31  9:31 UTC (permalink / raw)
  To: kawa

OK. I have the code below to gently tap into javaFX possibilities. What I
wish to accomplish is change the button color when button is clicked.

It does work, however, I get this unexpected warning:
   .\test.scm:14:29: warning - no known slot 'setStyle' in java.lang.Object

Any ideas why?

(require 'javafx-defs)

(javafx-application)


> (define rect

  (Rectangle

   x: 25  y: 40  width: 100  height: 50

   fill: Color:RED))


> (define button

  (Button

  text: "Click Me Three"

  layout-x: 25

  layout-y: 100

    on-action: (lambda (e) (button:setStyle "-fx-background-color:
> #ff0000"))))


> (javafx-scene

 title: "Hello Animation"

 width: 600 height: 450  fill: Color:LIGHTGREEN

 rect

 button)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: JavaFX unexpected warning
  2018-10-31  9:31 JavaFX unexpected warning Arie van Wingerden
@ 2018-10-31  9:49 ` Sudarshan S Chawathe
  2018-10-31 11:17   ` Arie van Wingerden
  0 siblings, 1 reply; 8+ messages in thread
From: Sudarshan S Chawathe @ 2018-10-31  9:49 UTC (permalink / raw)
  To: Arie van Wingerden; +Cc: kawa

> It does work, however, I get this unexpected warning:
>    .\test.scm:14:29: warning - no known slot 'setStyle' in java.lang.Object
> 
> Any ideas why?

Kawa cannot be sure that the Button procedure returns an object of
Button type, and so only assumes it is an Object and then wonders
whether that Object will have the required setStyle method.

> > (define button

Changing the above to something like

   (define button ::javafx.scene.control.Button

should fix the problem.

Regards,

-chaw

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: JavaFX unexpected warning
  2018-10-31  9:49 ` Sudarshan S Chawathe
@ 2018-10-31 11:17   ` Arie van Wingerden
  2018-10-31 17:23     ` Per Bothner
  0 siblings, 1 reply; 8+ messages in thread
From: Arie van Wingerden @ 2018-10-31 11:17 UTC (permalink / raw)
  To: chaw; +Cc: kawa

Thanks for the tip, works OK now!

So I have to consider two things:
- I can specify type hints in Kawa
- and I'll have to get used to the underlying Java api then ;)

/Arie

Op wo 31 okt. 2018 om 10:48 schreef Sudarshan S Chawathe <chaw@eip10.org>:

> > It does work, however, I get this unexpected warning:
> >    .\test.scm:14:29: warning - no known slot 'setStyle' in
> java.lang.Object
> >
> > Any ideas why?
>
> Kawa cannot be sure that the Button procedure returns an object of
> Button type, and so only assumes it is an Object and then wonders
> whether that Object will have the required setStyle method.
>
> > > (define button
>
> Changing the above to something like
>
>    (define button ::javafx.scene.control.Button
>
> should fix the problem.
>
> Regards,
>
> -chaw
>
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: JavaFX unexpected warning
  2018-10-31 11:17   ` Arie van Wingerden
@ 2018-10-31 17:23     ` Per Bothner
  2018-11-01  5:32       ` Per Bothner
  0 siblings, 1 reply; 8+ messages in thread
From: Per Bothner @ 2018-10-31 17:23 UTC (permalink / raw)
  To: Arie van Wingerden; +Cc: kawa

On 10/31/18 4:17 AM, Arie van Wingerden wrote:
> Thanks for the tip, works OK now!
> 
> So I have to consider two things:

> - I can specify type hints in Kawa

I'm this particular case, it seems Kawa should be able to figure out the type of 'button', since
it actually does figure out the type of the Button call.  The complication is that
this is a self-reference: 'button' is referenced in the initializing expression.
To get this to work we have to defer analyzing the arguments to Button until
after we've deduced the type for 'button'.  This is in principle possible,
but may be too complicated.  For one thing it interacts to data flow analysis.
(Everything is tied together and criss-crosses in the "InlineCall" analysis phase.)

This could be fixed if we implemented an optimization which sets the 'button'
variable before we set its fields.  This has a big advantage in that it enables
building self-referential data structures more easily, as well as data structures that
mutually reference each other.  It would have the side-effect of fixing this mini-bug.

I've thought into doing the above optimization, but I don't remember how far I got.
(There are lot of old corners in Kawa.)

Anyway, I'm looking into it.

> - and I'll have to get used to the underlying Java api then ;)

'Afraid so.  There is no complete Kawa wrapper around the JavaFX API.
However, Kawa does have a number of convenience features. For example:
https://www.gnu.org/software/kawa/Allocating-objects.html

-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: JavaFX unexpected warning
  2018-10-31 17:23     ` Per Bothner
@ 2018-11-01  5:32       ` Per Bothner
  2018-11-01 10:21         ` Arie van Wingerden
  0 siblings, 1 reply; 8+ messages in thread
From: Per Bothner @ 2018-11-01  5:32 UTC (permalink / raw)
  To: kawa

On 10/31/18 10:23 AM, Per Bothner wrote:
> This could be fixed if we implemented an optimization which sets the 'button'
> variable before we set its fields.  This has a big advantage in that it enables
> building self-referential data structures more easily, as well as data structures that
> mutually reference each other.  It would have the side-effect of fixing this mini-bug.
> 
> I've thought into doing the above optimization, but I don't remember how far I got.
> (There are lot of old corners in Kawa.)
> 
> Anyway, I'm looking into it.

It looks like more work than I want to spend right now, but I came up with
an approach that I think makes sense.  I wrote it up in the "Ideas and tasks for
contributing to Kawa" section (in the git version of the manual but not yet online):


  3.6.1 Recusively initialized data structures
--------------------------------------------
(GSoC)

    Kawa has convenient syntax to *note allocate and initialize objects:
Allocating objects, but it gets messier it you want to initialize
multiple objects that reference each other.  Likewise for a single
object “tree” which contains links to the root.  In this example, we
will looks at two vectors, but the feature is more useful for tree
structures.  Assume:
      (define-constant list1 [1 2 list2])
      (define-constant list2 ['a 'b list1])
    The compiler translates this to:
      (define-constant list1
         (let ((t (object[] length: 3))) ;; allocate native Java array
            (set! (t 0) 1)
            (set! (t 1) 2)
            (set! (t 2) list2)
            (FVector:makeConstant t)))
      (define-constant list2
         (let ((t (object[] length: 3))) ;; allocate native Java array
            (set! (t 0) 'a)
            (set! (t 1) 'b)
            (set! (t 2) list1)
            (FVector:makeConstant t)))
    The problem is that ‘list2’ has not been created when we evaluate the
initializing expression for ‘list’.

    We can solve the problem by re-writing:
      (define-private tmp1 (object[] length: 3))
      (define-constant list1 (FVector:makeConstant tmp1)
      (define-private tmp2 (object[] length: 3))
      (define-constant list2 (FVector:makeConstant tmp2)
      (set! (tmp1 0) 1)
      (set! (tmp1 1) 2)
      (set! (tmp1 2) list2)
      (set! (tmp2 0) 1)
      (set! (tmp2 1) 2)
      (set! (tmp2 2) list1)

    The complication is that the code for re-writing vector and object
constructors is spread out (depending on the result type), and not where
we deal with initializing the variables.  One solution is to introduce
an inlineable helper function ‘$build$’ defined as:
      (define ($build$ raw-value create init)
        (let ((result (create raw-value))
          (init raw-value result)
          result))
    Then we can re-write the above code to:
      (define-constant list1
        ($build$
          (object[] length: 3)
          (lambda (raw) (FVector:makeConstant raw))
          (lambda (raw result)
            ($init-raw-array$ raw 1 2 list2))))
      (define-constant list2
        ($build$
          (object[] length: 3)
          (lambda (raw) (FVector:makeConstant raw))
          (lambda (raw result)
            ($init-raw-array$ raw 'a 'b list1))))
    Note that the call to ‘$build$’, as well as the generated ‘lambda’
expressions, are all easily inlineable.

    Now assume if at the top-level BODY if there is a sequence of
‘define-constant’ definitions initialized with calls to ‘$build$’.  Now
it is relatively easy to move all the ‘init’ calls after all ‘alloc’ and
‘create’ expressions.  The ‘$init-raw-array$’ calls are expanded after
the code has been re-ordered.

    The project includes both implementing the above framework, as well
as updating type-specific (and default) object creation to use the
framework.  It would also be good to have compiler warnings if accessing
an uninitialized object.



-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: JavaFX unexpected warning
  2018-11-01  5:32       ` Per Bothner
@ 2018-11-01 10:21         ` Arie van Wingerden
  0 siblings, 0 replies; 8+ messages in thread
From: Arie van Wingerden @ 2018-11-01 10:21 UTC (permalink / raw)
  To: Per Bothner; +Cc: kawa

Hi Per,

thanks for this effort.
At the moment it is of course not a real problem, if I only can get around
it.
But it would be a nice "to have" thing.

You created a *very* nice product :-)

/Arie


Op do 1 nov. 2018 om 06:33 schreef Per Bothner <per@bothner.com>:

> On 10/31/18 10:23 AM, Per Bothner wrote:
> > This could be fixed if we implemented an optimization which sets the
> 'button'
> > variable before we set its fields.  This has a big advantage in that it
> enables
> > building self-referential data structures more easily, as well as data
> structures that
> > mutually reference each other.  It would have the side-effect of fixing
> this mini-bug.
> >
> > I've thought into doing the above optimization, but I don't remember how
> far I got.
> > (There are lot of old corners in Kawa.)
> >
> > Anyway, I'm looking into it.
>
> It looks like more work than I want to spend right now, but I came up with
> an approach that I think makes sense.  I wrote it up in the "Ideas and
> tasks for
> contributing to Kawa" section (in the git version of the manual but not
> yet online):
>
>
>   3.6.1 Recusively initialized data structures
> --------------------------------------------
> (GSoC)
>
>     Kawa has convenient syntax to *note allocate and initialize objects:
> Allocating objects, but it gets messier it you want to initialize
> multiple objects that reference each other.  Likewise for a single
> object “tree” which contains links to the root.  In this example, we
> will looks at two vectors, but the feature is more useful for tree
> structures.  Assume:
>       (define-constant list1 [1 2 list2])
>       (define-constant list2 ['a 'b list1])
>     The compiler translates this to:
>       (define-constant list1
>          (let ((t (object[] length: 3))) ;; allocate native Java array
>             (set! (t 0) 1)
>             (set! (t 1) 2)
>             (set! (t 2) list2)
>             (FVector:makeConstant t)))
>       (define-constant list2
>          (let ((t (object[] length: 3))) ;; allocate native Java array
>             (set! (t 0) 'a)
>             (set! (t 1) 'b)
>             (set! (t 2) list1)
>             (FVector:makeConstant t)))
>     The problem is that ‘list2’ has not been created when we evaluate the
> initializing expression for ‘list’.
>
>     We can solve the problem by re-writing:
>       (define-private tmp1 (object[] length: 3))
>       (define-constant list1 (FVector:makeConstant tmp1)
>       (define-private tmp2 (object[] length: 3))
>       (define-constant list2 (FVector:makeConstant tmp2)
>       (set! (tmp1 0) 1)
>       (set! (tmp1 1) 2)
>       (set! (tmp1 2) list2)
>       (set! (tmp2 0) 1)
>       (set! (tmp2 1) 2)
>       (set! (tmp2 2) list1)
>
>     The complication is that the code for re-writing vector and object
> constructors is spread out (depending on the result type), and not where
> we deal with initializing the variables.  One solution is to introduce
> an inlineable helper function ‘$build$’ defined as:
>       (define ($build$ raw-value create init)
>         (let ((result (create raw-value))
>           (init raw-value result)
>           result))
>     Then we can re-write the above code to:
>       (define-constant list1
>         ($build$
>           (object[] length: 3)
>           (lambda (raw) (FVector:makeConstant raw))
>           (lambda (raw result)
>             ($init-raw-array$ raw 1 2 list2))))
>       (define-constant list2
>         ($build$
>           (object[] length: 3)
>           (lambda (raw) (FVector:makeConstant raw))
>           (lambda (raw result)
>             ($init-raw-array$ raw 'a 'b list1))))
>     Note that the call to ‘$build$’, as well as the generated ‘lambda’
> expressions, are all easily inlineable.
>
>     Now assume if at the top-level BODY if there is a sequence of
> ‘define-constant’ definitions initialized with calls to ‘$build$’.  Now
> it is relatively easy to move all the ‘init’ calls after all ‘alloc’ and
> ‘create’ expressions.  The ‘$init-raw-array$’ calls are expanded after
> the code has been re-ordered.
>
>     The project includes both implementing the above framework, as well
> as updating type-specific (and default) object creation to use the
> framework.  It would also be good to have compiler warnings if accessing
> an uninitialized object.
>
>
>
> --
>         --Per Bothner
> per@bothner.com   http://per.bothner.com/
>

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: JavaFX unexpected warning
  2018-11-01 13:41 Jamison Hope
@ 2018-11-01 15:08 ` Per Bothner
  0 siblings, 0 replies; 8+ messages in thread
From: Per Bothner @ 2018-11-01 15:08 UTC (permalink / raw)
  To: kawa

On 11/1/18 6:41 AM, Jamison Hope wrote:
> Is there anything in the (existing) letrec implementation that could help
> here? It seems like you’re describing transforming the two define-constant
> calls into basically a letrec except without actually introducing a new
> scope.

They key trick is splitting object creating into two separate parts: Allocating
the object, and initializing the properties of the object.  And then assigning
each variable with the allocated object(s) before doing further initialization.
Letrec won't do that.

However, letrec would do what we needed if we used promises
(https://www.gnu.org/software/kawa/Lazy-evaluation.html#Blank-promises).
In that cases we initialize each variable with a blank promise as a place-holder.
Then we evaluate each initialization, and bind the promise with the result.
Any recursive reference will grab the unforced promise, which does what we
need - as long as the promise isn't forced.  And that is the problem,
since if you need to coerce a field value to a specific type you may hang.
Plus whoever uses the created object (such as a GUI library) has to know how
to deal with promises.

The JavaFX API does support a kind a promises, since the various components
are "properties" that can be bound.   The old JavaFX 1.0 language handled
these dependencies automatically, but it was abandoned because of complexity
and performance concerns (plus lack of take-up - plus Oracle taking over ...).
If JavaFX had become more popular it might be worth figuring out a good way
to express JavaFX bindings and constraints wih Kawa compiler support, but
JavaFX never took off and is basically in maintenance mode.

I'm interested in supporting "logic programming" in some way, which we can
think of as more complicated networks of objects with constraints.
(This might be more suited for the KaShell language (http://kashell.org)
than the Kawa-Scheme language.)  The trick is not adding overhead unless you ask for it!

> Remind me, can you (define-constant x …) with x already a bound
> identifier?

You can define-constant in an inner scope.  The '!' operator is like
define-constant, plus pattern-matching, plus complaining if a declaration
in an inner scope hides one in an outer scope (like Java).

> Is there a danger that this reordering might capture the wrong
> list2 when building list1? I’m thinking along the lines of letrec vs let*.

Without the ordering you would get #!null instead of list2 - because list2 hasn't
been assigned yet.

> Would this optimization apply to any other kinds of variable binding, or
> just adjacent define-constant expressions?

As designed it would only apply to define-constant and the '!' operator.
We could generalize it to variables that are only assigned to once.  However,
we are changing the semantics (say if the "raw allocation function" is
a constructor method with side-effects), so I think it makes sense to
restrict this to explicit "constant" variables.
-- 
	--Per Bothner
per@bothner.com   http://per.bothner.com/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: JavaFX unexpected warning
@ 2018-11-01 13:41 Jamison Hope
  2018-11-01 15:08 ` Per Bothner
  0 siblings, 1 reply; 8+ messages in thread
From: Jamison Hope @ 2018-11-01 13:41 UTC (permalink / raw)
  To: kawa

On Thu, November 1, 2018 1:24 am, Per Bothner wrote:
> On 10/31/18 10:23 AM, Per Bothner wrote:
>> This could be fixed if we implemented an optimization which sets the
>> 'button'
>> variable before we set its fields.  This has a big advantage in that it
>> enables
>> building self-referential data structures more easily, as well as data
>> structures that
>> mutually reference each other.  It would have the side-effect of fixing
>> this mini-bug.
>>
>> I've thought into doing the above optimization, but I don't remember how
>> far I got.
>> (There are lot of old corners in Kawa.)
>>
>> Anyway, I'm looking into it.
>
> It looks like more work than I want to spend right now, but I came up with
> an approach that I think makes sense.  I wrote it up in the "Ideas and
> tasks for
> contributing to Kawa" section (in the git version of the manual but not
> yet online):
>
>
>   3.6.1 Recusively initialized data structures
> --------------------------------------------
> (GSoC)
>
>     Kawa has convenient syntax to *note allocate and initialize objects:
> Allocating objects, but it gets messier it you want to initialize
> multiple objects that reference each other.  Likewise for a single
> object “tree” which contains links to the root.  In this example, we
> will looks at two vectors, but the feature is more useful for tree
> structures.  Assume:
>       (define-constant list1 [1 2 list2])
>       (define-constant list2 ['a 'b list1])
>     The compiler translates this to:
>       (define-constant list1
>          (let ((t (object[] length: 3))) ;; allocate native Java array
>             (set! (t 0) 1)
>             (set! (t 1) 2)
>             (set! (t 2) list2)
>             (FVector:makeConstant t)))
>       (define-constant list2
>          (let ((t (object[] length: 3))) ;; allocate native Java array
>             (set! (t 0) 'a)
>             (set! (t 1) 'b)
>             (set! (t 2) list1)
>             (FVector:makeConstant t)))
>     The problem is that ‘list2’ has not been created when we evaluate
> the
> initializing expression for ‘list’.
>
>     We can solve the problem by re-writing:
>       (define-private tmp1 (object[] length: 3))
>       (define-constant list1 (FVector:makeConstant tmp1)
>       (define-private tmp2 (object[] length: 3))
>       (define-constant list2 (FVector:makeConstant tmp2)
>       (set! (tmp1 0) 1)
>       (set! (tmp1 1) 2)
>       (set! (tmp1 2) list2)
>       (set! (tmp2 0) 1)
>       (set! (tmp2 1) 2)
>       (set! (tmp2 2) list1)
>
>     The complication is that the code for re-writing vector and object
> constructors is spread out (depending on the result type), and not where
> we deal with initializing the variables.  One solution is to introduce
> an inlineable helper function ‘$build$’ defined as:
>       (define ($build$ raw-value create init)
>         (let ((result (create raw-value))
>           (init raw-value result)
>           result))
>     Then we can re-write the above code to:
>       (define-constant list1
>         ($build$
>           (object[] length: 3)
>           (lambda (raw) (FVector:makeConstant raw))
>           (lambda (raw result)
>             ($init-raw-array$ raw 1 2 list2))))
>       (define-constant list2
>         ($build$
>           (object[] length: 3)
>           (lambda (raw) (FVector:makeConstant raw))
>           (lambda (raw result)
>             ($init-raw-array$ raw 'a 'b list1))))
>     Note that the call to ‘$build$’, as well as the generated
> ‘lambda’
> expressions, are all easily inlineable.
>
>     Now assume if at the top-level BODY if there is a sequence of
> ‘define-constant’ definitions initialized with calls to ‘$build$’.
>  Now
> it is relatively easy to move all the ‘init’ calls after all
> ‘alloc’ and
> ‘create’ expressions.  The ‘$init-raw-array$’ calls are expanded
> after
> the code has been re-ordered.
>
>     The project includes both implementing the above framework, as well
> as updating type-specific (and default) object creation to use the
> framework.  It would also be good to have compiler warnings if accessing
> an uninitialized object.

Is there anything in the (existing) letrec implementation that could help
here? It seems like youÂ’re describing transforming the two define-constant
calls into basically a letrec except without actually introducing a new
scope.

Remind me, can you (define-constant x Â…) with x already a bound
identifier? Is there a danger that this reordering might capture the wrong
list2 when building list1? IÂ’m thinking along the lines of letrec vs let*.
Would this optimization apply to any other kinds of variable binding, or
just adjacent define-constant expressions?

-- 
Jamison Hope
jrh@theptrgroup.com

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-11-01 15:08 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-31  9:31 JavaFX unexpected warning Arie van Wingerden
2018-10-31  9:49 ` Sudarshan S Chawathe
2018-10-31 11:17   ` Arie van Wingerden
2018-10-31 17:23     ` Per Bothner
2018-11-01  5:32       ` Per Bothner
2018-11-01 10:21         ` Arie van Wingerden
2018-11-01 13:41 Jamison Hope
2018-11-01 15:08 ` Per Bothner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).