[Asdf] sdfInputData: from an array to a map and then to just a data schema (dataqualities) item?

Carsten Bormann <cabo@tzi.org> Thu, 12 November 2020 06:24 UTC

Return-Path: <cabo@tzi.org>
X-Original-To: asdf@ietfa.amsl.com
Delivered-To: asdf@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 2217E3A146B for <asdf@ietfa.amsl.com>; Wed, 11 Nov 2020 22:24:46 -0800 (PST)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -1.898
X-Spam-Level:
X-Spam-Status: No, score=-1.898 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id NzBLBrx7pSXo for <asdf@ietfa.amsl.com>; Wed, 11 Nov 2020 22:24:43 -0800 (PST)
Received: from gabriel-vm-2.zfn.uni-bremen.de (gabriel-vm-2.zfn.uni-bremen.de [134.102.50.17]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id BABF63A146A for <asdf@ietf.org>; Wed, 11 Nov 2020 22:24:42 -0800 (PST)
Received: from [192.168.217.118] (p548dcc60.dip0.t-ipconnect.de [84.141.204.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by gabriel-vm-2.zfn.uni-bremen.de (Postfix) with ESMTPSA id 4CWs5P0VLVzySb; Thu, 12 Nov 2020 07:24:41 +0100 (CET)
From: Carsten Bormann <cabo@tzi.org>
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: quoted-printable
X-Mao-Original-Outgoing-Id: 626855080.530381-6013d27650e1c329e4c2071f64728632
Mime-Version: 1.0 (Mac OS X Mail 13.4 \(3608.120.23.2.4\))
Date: Thu, 12 Nov 2020 07:24:40 +0100
Message-Id: <32E8590A-9B2F-493B-928F-BF7B7C01FEB5@tzi.org>
To: asdf@ietf.org
X-Mailer: Apple Mail (2.3608.120.23.2.4)
Archived-At: <https://mailarchive.ietf.org/arch/msg/asdf/E9CmSMr-naQeiLBgTanRjkX0NaE>
Subject: [Asdf] sdfInputData: from an array to a map and then to just a data schema (dataqualities) item?
X-BeenThere: asdf@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: "A Semantic Description Format \(SDF\) for Things and their Interactions and Data" <asdf.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/asdf>, <mailto:asdf-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/asdf/>
List-Post: <mailto:asdf@ietf.org>
List-Help: <mailto:asdf-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/asdf>, <mailto:asdf-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 12 Nov 2020 06:24:46 -0000

Yesterday, at the hackathon, we had a discussion about sdfInputData.

In SDF 1.0, this is an array of JSON pointers (to sdfData items, i.e. “types” (data schema definitions, which are called »dataqualities« in the current syntax)).

          "sdfInputData": [
            "#/sdfObject/OnOff/sdfAction/OffWithEffect/sdfData/EffectIdentifier", 
            "#/sdfObject/OnOff/sdfAction/OffWithEffect/sdfData/EffectVariant"
          ],

(Note that this is not an array at the data schema definition level; it is an array at the specification syntax level.  One has to be very careful about these distinctions in a specification language that uses JSON both as the generic data model as well as the representation language for the specification itself.)

There are two problems with this:

— the input parameters are just typed, but not named.  It can get confusing very quickly if the same type is used for multiple parameters.

The above is a bit like

  void OffWithEffect(EffectIdentifier, EffectVariant)

which works as long as the types happen to be descriptive of the parameters.
But, in, say:

          "sdfInputData": [
            "#/sdfData/Channelvalue", 
            "#/sdfData/Channelvalue", 
            "#/sdfData/Channelvalue", 
          ],

which of these is R, G, or B?

— there is some ceremony here in requiring setting up separate sdfData items and then pointing to them; we don’t require those for (SDF) properties (which can define their types inline).

So we came up with replacing the array of pointers with a map, and using data schema definitions (dataqualities) as values in the map — if a reference is indeed required, that can be put in as sdfRef.
So, in the example, if an sdfRef were actually desirable, this becomes:

          "sdfInputData": {
            identifier: {
              sdfRef: “#/.../EffectIdentifier"
            },
            variant: {
              sdfRef: “#/.../EffectVariant"
            }
          },

Which is more like

  void OffWithEffect(identifier: EffectIdentifier, variant: EffectVariant)

Great.
Now this is where the discussion derailed and then time ran out.
It was noted that an sdfInputData now superficially looked like a map (sure, its specification is represented as a map at the specification syntax level) and, once we start supporting complex types in SDF (this is where the discussion derailed) we could use json-schema.org’s »type: object« to specify this map:

          "sdfInputData": {
            type: object,
            properties: {
              identifier: {
                sdfRef: “#/.../EffectIdentifier"
              },
              variant: {
                sdfRef: “#/.../EffectVariant"
              }
            }
          },

This is the equivalent of always having to build a structure to supply multiple parameters:

  void OffWithEffect(struct {
      identifier: EffectIdentifier, variant: EffectVariant
    }
  )

Of course, once we do this, there is no reason to only allow »type: object« here, so people could use integers, arrays, … there as well.

Is this really the direction we want to go?
I’m not aware of any programming language that only ever can supply a single parameter to a procedure call.  Actions are not exactly procedure calls, but I still think the analogy holds well.

On the other hand, protocol bindings such as that to CoAP’s FETCH could directly pick up the map (»type: object«) as the request body, so this may seem natural to some.

(Behind this is the related complex data discussion, issue #4: We avoided introducing »type: object« into SDF 1.0 because we wanted to understand where aggregation is needed and whether that always is appropriately described as aggregation on the data schema level, or whether we would be better off with aggregation at the SDF structural level.  The above goes into the direction of offloading more of the aggregation into data schema level land, which may be the lazy thing to do, but also may be missing some opportunities.  In the extreme, why don’t we define an entire sdfThing as a »type: object« then?)

Grüße, Carsten