Hi,

I found the following situation when trying to add OpCodes for setting
and deleting tags to OpCodes.hs.

OpTagsSet and OpTagsDel take two required parameters ("kind" and
"tags"), and then both take "name", which is defined in Python as:

    # Name is only meaningful for nodes and instances
    ("name", ht.NoDefault, ht.TMaybeString,
     "Name of object where tag(s) should be added"),

The resulting combination, NoDefault + TMaybeString, is that the field
can be None, but even in that case it must be explicitly specified
(i.e., it must be present in the serialization even if as null). The
CLI, for example, solves this by using "cluster" as the value for name
in the case of `gnt-cluster add-tags`, though it could have as well used
None (I may send a patch for that, actually).

>From the Haskell point of view, however, defining this field with
optionalField is not quite correct, since a value of Nothing will result
in the field not getting included in the serialization (using a
non-empty string as dummy value, as the CLI does, would work, of
course), and thus the job failing.

Then I thought of defining the field as required, but use a type of
Maybe String, instead of String. But (a) THH.hs is already using Maybe
internally for optional fields; and (b) at the moment it just gets
serialized into a <dict> structure, e.g. ("Just", "xxx"), or ("Nothing",
null).

I'm trying to think what the best way to proceed would be, and I see
several options (from the simplest and less correct, to the more complex
and possibly more correct):

  (1) Change the Python definition to specify a default value of None.
      (OpTagsGet/Set/Del are one of the two groups that uses NoDefault +
      TMaybeString, the other one being Op{Repair,Modify}NodeStorage).

  (2) Define the field as required, forcing the programmer to always
      specify a value, even if it's just a dummy one.

  (3) Define the field as optional, but still expect the programmer to
      specify a dummy value with Just even in the cases in which it's
      not required.

  (4) Have an additional flag in the definition of Field that says if it
      should always be included in the serialization, even if the value
      is Nothing.

      (However, at least in the case of "name" above, we would want to
      combine this with making the field optional, so that one would not
      have to specify a dummy string; in which case, there is a
      difference in API use, in which a Python programmer that forgot
      to specify the name would get a PreReq failure error, and a
      Haskell programmer would get a runtime error – NoneType has no
      upper() method or so.)

  (5) [This one probably wouldn't work] Allow the OpCode definitions in
      Haskell to have an explicit type of Maybe x, so that if the field
      is not marked as optional, it will still get serialized as null if
      the value is Nothing.

  (6) ... other?


If we don't find a clear winner, or the implementation is complex and
would take some time, I would suggest using (2) for now, since there's
precedent for it in the Python codebase already.

Thanks,

-- 
Dato Simó | [email protected]
Corp Fleet Management / Ganeti SRE (Dublin)

Reply via email to