Is there an order-preserving Environment quark?

A type is an interface. You probably meant to quote the “program to interfaces, not implementations”".

I don’t know if GoF would really say that, but Guido van Rossum probably would (and Didier Rémy would even more certainly argue that). What you are saying here is that SC should prefer duck typing tests to nominal typing tests. I don’t know if GoF has a position on this.

In more appropriate CS/PL theory terms, duck typing is a structural type system as opposed to a nominative/nominal one.

Aside: I don’t think GoF talks about a duck typing equivalent in C++ teribly clearly (they drop the C++ template mention here and there to say that it can be used to avoid inheritance when implemnting this-or-that pattern), but Abrahams & Curtovoy have made a more clear point about that in their Template Metaprogramming book. But this is essentially type erasure in C++, a concept that GoF never actually got to making explicit. (And type erasure is only really a pattern if you want to embrace the GoF book criticism that it mostly proposes “manually expanded macros” that could mostly be addressed by better language features.)

After Python added its optional static type checker, they have struggled with the same problem, i.e. conflicting notions of type. Their solution (PEP544) was to invent a notion of “protocol” that duplicates duck typing at the static type checker level. (“Protocol” is what other statically typed languages would call interface, but protocols can be “slapped on top” without the base class having any idea about them.) But as it turns out, they wanted the “cool new thing” at runtime too in some cases:

@runtime_checkable decorator and narrowing types by isinstance()
The default semantics is that isinstance() and issubclass() fail for protocol types. This is in the spirit of duck typing – protocols basically would be used to model duck typing statically, not explicitly at runtime.
However, it should be possible for protocol types to implement custom instance and class checks when this makes sense, […] The most type checkers can do is to treat isinstance(obj, Iterator) roughly as a simpler way to write hasattr(x, ‘iter’) and hasattr(x, ‘next’). […]

The last bit could be a minimalistic way to do interfaces/protocols in SC too, sans a static typechecker, i.e. just check an array of methods exists.

~suppotsProtocol = { |obj, protoc| protoc.every {|m| obj.respondsTo(m)} };
~protocolMinimalDict = [ \put, \putAll, \at ]; // maybe some more
~suppotsProtocol.(Dictionary.new, ~protocolMinimalDict)

There’s of course not much functionality in this, but if it were “made official” it might dissuade the use of isKindOf when not strictly necessary. It would be a lot more work to decide a good set of protocols though, as the current lack of such a notion in SC entails that everything that’s implemented is the class’ protocol… (which does get us to the 1st quote in this post on interfaces vs implementations.)