3 ms·
How can two objects present exactly the same API without either one knowingly emulating the other? Examples always seem to use one method taking no args, which
by erik_seaberg 6y ago
How can two objects present exactly the same API without either one knowingly emulating the other? Examples always seem to use one method taking no args, which don’t seem realistic.
- XorNot 6y agoWhat's missing in this example is stub typing of the output values. Scientist.quack really shouldn't be returning plain strings, and neither should ducky.quack if the data in them is contextually different. Things should only become basic types at the last possible moment.
- neolog 6y agoWhich language ecosystems operate like that in practice?
- morelisp 6y agoGo has no subtyping and only supports polymorphism via structural types (and some weak support for untyped constant values). It also has very convenient syntax to define newtypes from primitives (or non-primitives, but this is less commonly used).
- morelisp 6y ago> Examples always seem to use one method taking no args, which don’t seem realistic. This is one of the reasons it is so rare to actually have confusable types in a real program.
- nemothekid 6y agoOne thing I did come across once before is when two APIs do something similar such as parsing and provide the same name. A couple of years ago I remember I was working with an API in Go that the function Scan which was `fn(interface{}) -> Error`, which was used to decode SQL values. I pulled in another library which provided that function but in a separate context - text parsing. The interfaces matched, the compiler accepted it, but the application blew up at runtime.
- SatvikBeri 6y agoA common example I ran into is machine learning methods and data transformations such as scaling have have `fit` and `transform` methods, and I'd like to write code that can take multiple such objects and compose them in a pipeline, along with some custom logic. Structural typing makes that easy to typecheck, nominal typing makes it difficult because those two classes don't have a parent class that contains those methods. Extending this, if the class has a `partial_fit` method, sometimes I want to use that, and fallback to `fit` when it doesn't.
- neolog 6y agoNominal typing just means someone has to declare that LinearClassifier implements Classifier. That could be done by the LinearClassifier maintainer or by the user.
- morelisp 6y agoWhat languages let the user do this?
- neolog 6y agoPython's zope.interface can do it. Julia's still figuring out their trait system, but some implementations allow that. I don't know Clojure but I wouldn't be surprised to hear if their Spec allows it.
- morelisp 6y agoI don't think either zope.interface or spec is really thought of as a nominal typing system? Certainly not spec. zope.interface of course can late-bind classes to interfaces but only because it's actually a runtime thing and Python late-binds everything.
- kuschku 6y agoBefore Android supported Optional, there were dozens of independent reimplementations of the API. All exactly identical, but all in different namespaces and therefore not compatible. And the official one obviously couldn't be used.
- lmm 6y agoConsider an immutable list and a read-only view of a mutable list (that another thread may mutate concurrently). They offer exactly the same API, but it's a major mistake to pass one where the other was expected.