public inbox for kawa@sourceware.org
 help / color / mirror / Atom feed
From: Panicz Maciej Godek <godek.maciek@gmail.com>
To: kawa@sourceware.org
Subject: Having Named Parts
Date: Thu, 1 Dec 2022 12:19:15 +0100	[thread overview]
Message-ID: <CAMFYt2YcXwmn+YRG+BDaXO5XVc1=VZV6bHK=CwpeyZQVVWGWUA@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3706 bytes --]

Hi,
I've been trying to build a simple wrapper for a hash table,
that I call Bundle, such that

(Bundle x: 5 y: 10)

would return a bundle object, let's call it b, so that I could refer to its
fields using

b:x

and modify them using

(set! b:x new-value)

And such that it would print itself as

(Bundle x: 5 y: 10)

and be equal to every other object with the same keys and values.

I have found that Kawa offers a gnu.mapping.HasNamedParts interface which
facilitates value reference, so that if I define the following class, it
lets me refer to the contents of a hash map:

(define-simple-class Bundle (gnu.mapping.HasNamedParts)
  (table ::java.util.Map (java.util.HashMap))
  ((get key::String)
   (table:get key))
  ((isConstant key::String)::boolean #f)
  ((*init*) ;for test purposes
   (table:put ("x":toString) 5)))

(define b ::Bundle (Bundle))

#|kawa|# b:x
5

However, when I invoke
(set! b:x 5)
Kawa responds with the following error:

java.lang.RuntimeException: no such field x in Bundle
        at gnu.kawa.reflect.SlotSet.apply(SlotSet.java:115)
        at gnu.kawa.reflect.SlotSet.setField(SlotSet.java:25)
        at gnu.kawa.functions.SetNamedPart.apply3(SetNamedPart.java:52)
        at gnu.mapping.Procedure3.applyToObject(Procedure3.java:61)
        at gnu.mapping.Procedure.applyToConsumerDefault(Procedure.java:75)
        at gnu.mapping.CallContext.runUntilDone(CallContext.java:586)
        at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:343)
        at kawa.Shell.run(Shell.java:300)
        at kawa.Shell.run(Shell.java:183)
        at kawa.repl.processArgs(repl.java:724)
        at kawa.repl.main(repl.java:830)

I also saw that there is the gnu.mapping.HasSetter interface, but the
getSetter method seems not to be invoked in that context.

The source code for the gnu.kawa.functions.SetNamedPart.apply3 method
reveals, that there was a plan for supporting this -- the method begins
with a commented-out fragment:

    /*
    if (container implements HasNamedParts)
      return ((HasNamedParts) container).getNamedPart(part);
    */

which wouldn't work with current Kawa, because the HasNamedParts interface
doesn't containt getNamedPart method, and instead it contains a method
called get. I think that this could be fixed by:
- adding a method Object set(String key, Object value) to the HasNamedParts
interface
- uncommenting and fixing the above snippet to invoke the above method.

By the way, the interface also contains isConstant method, which doesn't
seem to be documented anywhere. I think that also - for consistency - the
interface should also provide a boolean hasPartNamed(String name) method.

But this only solves one problem, and there's another one, namely - when I
try to initialize Bundle as, say

(Bundle x: 5 y: 10)

I get the following warnings:

/dev/tty:6:20: warning - no field or setter 'x' in class Bundle
/dev/tty:6:20: warning - no field or setter 'y' in class Bundle

These are issued from the build() method in
gnu.kawa.reflect.CompileBuildObject. It does seem that this class doesn't
take into account the existence of the HasNamedParts interface at all (but
I don't understand it well enough to come up with any idea of fixing it).
And the *init* method doesn't seem to accept variable-length arguments.

On the other hand, if I wanted to provide a lot of *init* methods like

   ((*init* k1::gnu.expr.Keyword v1)
   (table:put (keyword->string k1) v1))

  ((*init* k1::gnu.expr.Keyword v1 k2::gnu.expr.Keyword v2)
   (table:put (keyword->string k1) v1)
   (table:put (keyword->string k2) v2))

then I'd need to quote the keywords in order to make it work (which isn't
something that I want).

Is there any way out of this situation?

             reply	other threads:[~2022-12-01 11:19 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-12-01 11:19 Panicz Maciej Godek [this message]
2022-12-01 22:16 ` Per Bothner
2022-12-01 23:15   ` Panicz Maciej Godek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAMFYt2YcXwmn+YRG+BDaXO5XVc1=VZV6bHK=CwpeyZQVVWGWUA@mail.gmail.com' \
    --to=godek.maciek@gmail.com \
    --cc=kawa@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).