From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-vk1-xa29.google.com (mail-vk1-xa29.google.com [IPv6:2607:f8b0:4864:20::a29]) by sourceware.org (Postfix) with ESMTPS id 91AF03858D32 for ; Thu, 1 Dec 2022 23:15:19 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 91AF03858D32 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-vk1-xa29.google.com with SMTP id u9so1584573vkk.4 for ; Thu, 01 Dec 2022 15:15:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=M8DRY47Y2M9okb+rhnkMkAFNNXlGLEH2XuoTH4v/3U8=; b=pvykDJ7QVNGXcKtmY7Lo7moCy3Yuj5slFFy/Z60oAtSQvtD/1K0rcMh3IXQuFQLgWq x2mZlKrZr1pGo7SNa5kjbIpff2FJyE568E+ztdMCiP06EiMPQ+wBSkgijB8J+wUOgga0 bLHia1FdTL1HAIQVE8FUZFU/70sWdUAlWUjkRoXccCnFlZP5YD8XUzK5FCcbRe3wNez4 qMR2A67XBOjE6wW4jPFiiLb5nrVX8WC7MRG3r5PfNWLOXEcfZwOyC1bPiVm3tbZ6n3gn FDYSROPk2uPThcQ/0JPMAWCnNkTIiFhnBqsfk639GGa14IA5GtwKkbW3aRiuO1m7T30O 5MeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=M8DRY47Y2M9okb+rhnkMkAFNNXlGLEH2XuoTH4v/3U8=; b=KoJamvc2rsraPgf7N31ZiVQCY8BMtGQT+Yq1Y2sViZ0w1k3vxiQsWUcRSMvavizqv4 nkPqsc39UoUfQWv1u7nt3wk58EAEi6BmAiph/cyFgN0a8H+ETwGCh4jI7euZ5xhWHmFk oCHIB2m7OVwCLWflX9uE8PQ6FXqfiwbsYyC0yMDt+6V1oioEIF5gfNjJmAX/gpRqAzAT f1KfN55/2x3S71RMkijD9mkjsmt7IyiHXpX6F1qLvRv84ev7/fIktD4fy48FFIr+4r5C b7Xk5KxiEQps6HsidnFJ6o7xU9WhXmtJkiaJPKI7dLhB8EKllkNG1de8wwtenZS9GR+9 pIkA== X-Gm-Message-State: ANoB5pkhgCMA2Xp1iaJfk2+164d2BcYIFJ+REQwN9Jo3DXlGzythSlaC kI+O6P0Wv/rjZ1qfqSxMrHlmDUGpi/FnXL8clds259XK+ao= X-Google-Smtp-Source: AA0mqf4cyTXD1mCbWxSORKVL9+us8cm+7QjNG/uhoVJMdeoFb/S2whwoDp5sOJhL/u0Ky49iHBBpgKWlmE9aiYHT+zs= X-Received: by 2002:a1f:c645:0:b0:3b8:685e:22eb with SMTP id w66-20020a1fc645000000b003b8685e22ebmr29808170vkf.33.1669936518707; Thu, 01 Dec 2022 15:15:18 -0800 (PST) MIME-Version: 1.0 References: In-Reply-To: From: Panicz Maciej Godek Date: Fri, 2 Dec 2022 00:15:07 +0100 Message-ID: Subject: Re: Having Named Parts To: Per Bothner Cc: kawa@sourceware.org Content-Type: multipart/alternative; boundary="000000000000febee305eecc64de" X-Spam-Status: No, score=-0.0 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --000000000000febee305eecc64de Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable czw., 1 gru 2022 o 23:16 Per Bothner napisa=C5=82(a): > > > On 12/1/22 03:19, Panicz Maciej Godek via Kawa wrote: > > 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 > > That would be a nicer syntax, but there could be some problems combining > the concepts of hash-table (extensible with arbitrary keys, not > necessarily strings) > and structures (with a fixed set of keys). JavaScript does it, and it > does make > things more convenient. > > There are a lot of issues to consider. Should key names be strings or > symbols? > What about keys that are not names (keys or strings)? I think they have to be Strings, because of how the HasNamedPart interface is defined. > How does this conflict > with existing usage of colon-notation, and how do we deal with those? > > So I'm not sure if hash tables should implement HasNamedParts by default. > > No, I don't think so either. But I think it would be nice if Kawa facilitated adding such classes. For the development of GRASP, I have built a macro called define-type , which is used for defining record-like classes. It is used like this: (define-type (Extent width: real height: real)) And it defines a class that can be instantiated as (define e ::Extent (Extent width: 10 height: 20)) I also have a pattern matcher which supports this notation, so I can write things like (match e ((Extent width: size height: size) 'square) ((Position width: w height: h) 'rectangle)) I like it way more than any SRFI record proposals I've seen. Also, with Kawa's syntax extensions I can write (set! e:width 50) and it Just Works. I find this experience very satisfying (to be honest, I'm quite surprised that many modern languages like Java or Haskell have much worse capabilities of defining structures than the C language). And I thought it would be nice to have a more flexible record-like type that I call Bundle (referring to David Hume's "bundle theory of meaning") -- so that it would also work in the context of pattern matching etc. I don't expect it to be the main interface to hash tables. An alternative is to use function-call notation, like we do for vectors: > (TABLE KEY) > (set! (TABLE KEY) VALUE) > This has the advantage that it does't conflict with other uses of > colon-notation. > However, it doesn't provide a constructor syntax "for free". > > Yes, I actually use that a lot in GRASP. I have defined a bunch of macros such as define-mapping (which uses a normal hash table underneath) or define-property (which uses a weak-key table) that is used like this: (define-property (dotted? cell::cons)::boolean #f) The nice thing about this is that it lets me provide the default value very naturally (and I could also signal error for missing keys). I also have a variant of weak-key which can accept more than one argument, that is called define-cache (and it's achieved by means of "currying", i.e. constructing hash tables that return hash tables etc.) But the difference between those hash tables and bundles is that bundles are meant to be externalizable, whereas properties are essentially opaque. I brought up these concerns on the mailing list years ago. If someone can > find these old message it might be helpful ... > > > I have found that Kawa offers a gnu.mapping.HasNamedParts interface whi= ch > > facilitates value reference, ...s > > 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. > > That is probably OK, except use 'put' instead of 'set' to be consistent > with java.util.Map. > Also, 'put' needs a default implementation, which should probably > throw UnsupportedOperationException. (Defaults were added in Java 8. It > is probably > OK to require Java 8 as a minimum at this point - though Android might be > an issue.) > > Actually Android SDK ships with a tool called d8, which is a replacement for their dx converter, which handles the Java 8 bytecode (I was even able to generate byte code for API level 1 with it) > Do compare with the getNamedPart and apply 2 method in GetNamedPart. > They handles various extra cases, that might not be appropriate for a > setter. > > > By the way, the interface also contains isConstant method, which doesn't > > seem to be documented anywhere. > > isConstant(KEY) returns true is the binding for KEY is immutable. > It is used to optimize namespace resolution. > > I think that also - for consistency - the > > interface should also provide a boolean hasPartNamed(String name) metho= d. > > > > 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. > > That is probably the case. > > > Is there any way out of this situation? > > If there was a clean problem-free solution I would have already done so .= .. > That doesn't mean we shouldn't have a better syntax for hash-tables, > or that this is a dead end - but there are definitely a number of issues > to consider. > > Again, I don't want to push for having an opinionated way of dealing with hash tables. I think it would be sufficient if Kawa could provide their users (or me in particular :D) with the means of creating various different solutions and experimenting with them. I think that supporting setters for HasNamedPart and in CompileBuildObject would simply be consistent with the idea of the HasNamedPart interface, and it doesn't seem to break anything --000000000000febee305eecc64de--