From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 127047 invoked by alias); 1 Nov 2018 13:41:12 -0000 Mailing-List: contact kawa-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: kawa-owner@sourceware.org Received: (qmail 127036 invoked by uid 89); 1 Nov 2018 13:41:11 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-5.4 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_2,KAM_LAZY_DOMAIN_SECURITY autolearn=ham version=3.3.2 spammy=Hope, H*MI:squirrel, H*u:SquirrelMail, H*UA:SVN X-HELO: mail.theptrgroup.com Received: from mail.theptrgroup.com (HELO mail.theptrgroup.com) (71.178.251.9) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 01 Nov 2018 13:41:09 +0000 Received: from mail.theptrgroup.com (localhost [127.0.0.1]) by mail.theptrgroup.com (Postfix) with ESMTP id 078AA4033D for ; Thu, 1 Nov 2018 09:41:06 -0400 (EDT) Received: from 108.28.77.99 (SquirrelMail authenticated user jrh) by mail.theptrgroup.com with HTTP; Thu, 1 Nov 2018 09:41:06 -0400 Message-ID: <0ce1028e9d7a71afbb5f7abc57e2b707.squirrel@mail.theptrgroup.com> Date: Thu, 01 Nov 2018 13:41:00 -0000 Subject: Re: JavaFX unexpected warning From: "Jamison Hope" To: kawa@sourceware.org Reply-To: jrh@theptrgroup.com User-Agent: SquirrelMail/1.4.23 [SVN] MIME-Version: 1.0 Content-Type: text/plain;charset=iso-8859-1 Content-Transfer-Encoding: 8bit X-IsSubscribed: yes X-SW-Source: 2018-q4/txt/msg00021.txt.bz2 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