Special properties of the 'set key John Cowan (12 Aug 2020 12:50 UTC)
Re: Special properties of the 'set key hga@xxxxxx (12 Aug 2020 13:18 UTC)
Re: Special properties of the 'set key Lassi Kortela (13 Aug 2020 06:58 UTC)
Re: Special properties of the 'set key hga@xxxxxx (13 Aug 2020 10:55 UTC)
Re: Special properties of the 'set key Lassi Kortela (14 Aug 2020 07:37 UTC)
Sub-set key and zero/nonzero success/failure status sets Lassi Kortela (14 Aug 2020 08:47 UTC)
Re: Special properties of the 'set key John Cowan (14 Aug 2020 04:28 UTC)
Re: Special properties of the 'set key Lassi Kortela (14 Aug 2020 08:20 UTC)

Re: Special properties of the 'set key Lassi Kortela 14 Aug 2020 08:20 UTC

> The rationale for a general classification property, call it type or
> whatever, is that it gives the exception handler an indication of what
> other properties it can expect to find.

We need to put on our math student hats and respect the zero case. A
status object with zero properties gives you the zero value #f for the
'set property by default. That zero value implies you have zero
guarantees about what else to find in the object :)

Please note that a mandatory 'set property can still be #f which will
give no more information about anything. If we mandate it to be non-#f
then people can still create status objects where all the other
properties are either missing or have useless or misleading values.

We are exhibiting a textbook case of spec writer's disease. Thinking we
can coerce future strangers into good behavior by anticipating their use
cases.

Instead, we should build the spec from the bottom up, starting from what
we know and not going further than we can find concrete evidence for.

The status object is a tagged collection with symbols for keys. We know
a lot about collections. Think about Scheme's hash-table abstraction. A
hash-table can have zero values, it has particular enumerators but
nothing to return a plist, hides the concrete representation.

We have concrete evidence about what errno values and SQLSTATE codes
exist in the wild. Hence we can design something for those.

There are many other future use cases for status objects that we know
nothing about, and to misappropriate Wittgenstein (because what could be
more fun), "Whereof one cannot speak, thereof one must be silent."

> If a foreign-status object is a
> Posix error, it will have an errno and a #define name.  If it is a
> database engine error, it will have a SQL state and possibly a
> proprietary number and symbol too.

Mandating a 'set property does not mandate a 'code property so you still
won't know which error occurred (if any; most error sets reserve a code
for success).

> If it is a libsodium-style system,
> it will have none of these, only a message.

We can specify that 'message is expected to be a string -- a convention
we can expect everyone to follow out of simple self-interest. A message
is usable even without the set.

>     The bare minimum is all properties optional with #f defaults.
>
> I think that's subminimal.

It's the zero case.

> If there are no keys at all, all we know is
> what a baby tells us when it howls: "Something's wrong".

We don't even know that something's wrong since a status object can also
represent success. We know just as little about success or failure with
an empty status object as with one that has only 'set.

> If there are keys but no classifier key, we don't know how to interpret
> what we are told, because the same keys inevitably mean different things
> in different contexts.

In that case both 'set and 'code should be mandatory. Or should it be
'set AND ('code OR 'message)? Does that cover everything? Etc... It
never ends.

This is how those bizarre laws about throwing moose off airplanes get
started.

>      > We have to decide if we're going to have a foreign-status-plist.
>      > There's an argument for having both it and foreign-status-keys.
>
> I agree that we should have both.

IMHO two iterators (which they in effect are) is a sign that we're not
being coherent about what we really want with the abstraction.

> Even Python programmers deal with concrete types like lists, sets,
> dicts, etc.  But I agree that it's a minor point.  My reason for wanting
> the type to be first is so that pattern matching can provide a first-cut
> analysis of foreign-status objects.

Ah, that makes sense. But I would recommend:

(case (foreign-status-ref st 'set)
   ((errno)
    (do-something-to (foreign-status-ref st 'code))
    ...)
   ((windows)
    ...))

If you want:

(let ((plist (foreign-status-plist st)))
   (case (cadr plist)
     ((errno)
      (do-something-to (plist-ref/default st 'code #f))
      ...)
     ((windows)
      ...)))

Then you just admitted that our would-be abstraction is just indirection
in disguise. We've become Java experts :)

Note how the benefits of abstraction are lost. We need to care that it's
a plist, and give our own #f default in plist-ref instead of relying on
defaults of the error object.

If we add transparent lambdas... it looks like we're precluded from
adding any with this approach, unless they are all called by
`foreign-status-plist` in an indeterminate order.

Draft #2 of a contentious SRFI is coming up and we're already painting
ourselves into a corner, making some kind of postmodern mash-up of
abstract and concrete that doesn't really give the benefits of either.

Perlis: "Functions delay binding; data structures induce binding. Moral:
Structure data late in the programming process."

<http://www.cs.yale.edu/homes/perlis-alan/quotes.html>

> We shouldn't be abstract for the sake of being abstract.  We should be
> abstract only when there is a substantial gain from having more than one
> representation.

I agree, but I think there are gains.

If we want a concrete representation, I suggest (cons 'foreign-status
plist); no need for a SRFI.