On Wed, Apr 21, 2021 at 7:31 PM Paul Bryan <pbr...@anode.ca> wrote:
> As demonstrated, protocols don't get us there because duck typing isn't a 
> matter of having an object exhibit all of the attributes of a duck, but 
> rather some subset of attributes to be used by the consumer. I want this duck 
> to quack; someone else will want it to waddle.

A HUGE insight I learned studying Go is that Protocols should be
defined near the code that CONSUMES it, and not near the code that
PROVIDES it. That's exactly the opposite of how we use ABCs, or Java
folks use interfaces (most of the time).

Cheers,

Luciano


On Wed, Apr 21, 2021 at 7:31 PM Paul Bryan <pbr...@anode.ca> wrote:
>
> As demonstrated, protocols don't get us there because duck typing isn't a 
> matter of having an object exhibit all of the attributes of a duck, but 
> rather some subset of attributes to be used by the consumer. I want this duck 
> to quack; someone else will want it to waddle. I don't see how type hints 
> could reasonably support "file like object" in the duck type sense (unless 
> the consumer were to specify the exact attributes of the duck it's interested 
> in, which I fear would become a tedious type writing style).
>
> I too have sensed static typing driving the typing development agenda in 
> Python recently, causing other typing methods to take a back seat, so to 
> speak. I add my voice to those requesting Python handle other typing methods.
>
> Barring an innovation to allow a "subset" of a type to be declared in a type 
> hint, I would conclude that static typing and duck typing are diametrically 
> opposed. If we agree that both are valuable, developers could build consensus 
> on that point, and work to ensure that one does not move forward at the 
> expense of the other.
>
> Paul
>
> On Wed, 2021-04-21 at 12:36 -0700, Christopher Barker wrote:
>
> Thanks Mark for posting this. I know some of us are uneasy about the pace of 
> the typing train ....
>
> On Tue, Apr 20, 2021 at 11:20 AM Nathaniel Smith <n...@pobox.com> wrote:
>
> > If you guarded your code with `isinstance(foo, Sequence)` then I could
> > not use it with my `Foo` even if my `Foo` quacked like a sequence. I was
> > forced to use nominal typing; inheriting from Sequence, or explicitly
> > registering as a Sequence.
>
> You say this like it's a bad thing, but how is this avoidable, even in
> principle? Structural typing lets you check whether Foo is duck-shaped
> -- has appropriate attribute names, etc. But quacking like a duck is
> harder: you also have to implement the Sequence behavioral contract,
> and realistically the only way to know that is if the author of Foo
> tells you.
>
>
> But that's not what duck typing is (at least to me :-) ) For a given 
> function, I need the passed in object to quack (and yes, I need that quack to 
> sound like a duck) -- but I usually don't care whether that object waddles 
> like a duck.
>
> So yes, isinstance(obj, Sequence) is really the only way to know that obj is 
> a Sequence in every important way -- but if you only need it to do one or two 
> things like a Sequence, then you don't care.
>
> And this is not uncommon -- I suspect it's very rare for a single function to 
> use most of the methods of a given ABC (or protocol, or whatever).
>
> And a lot of the standard library works exactly this way. Two examples 
> (chosen arbitrarily, I just happen to have thought about how they work):
>
> json.load() simply calls ``fp.read()``, and passes the result on down to 
> json.loads(). That's it -- no checking of anything.
>
> If fp does not have a read() method, you get an AttributeError. If fp has a 
> read() method, but it returns something other than a string, then you get 
> some other Exception. And if it returns a string, but that string isn't valid 
> JSON, you get yet another kind of error.
>
> In short, json.load(fp, ...) requires fp to have a read() method that returns 
> a valid JSON string. But it doesn't check, nor does it need to, if it's 
> getting an actual io.TextIOBase object. Is that the right one? I'm not 
> totally sure, which I kind of think makes my point -- I've been using 
> "file-like" objects for years (decades) without worrying about it.
>
> Example 2:
>
> The str.translate method takes:
>
> "a mapping of Unicode ordinals to Unicode ordinals, strings, or None"
>
> Ok, then you need to pass in a Mapping, yes? Well, no you don't. The docs go 
> on to say:
>
> The table must implement lookup/indexing via __getitem__, for instance a
> dictionary or list.
>
> Ah -- so we don't need a Mapping -- we need anything indexable by an integer 
> that contains "ordinals, strings, or None". What the heck ABC could we use 
> for that?
>
> The ABCs do have an already complex hierarchy of containers, but there is no 
> "Indexable", (quacks) and certainly no "indexable and returns these 
> particular things. (quacks a certain way). (maybe there's something in the 
> typing module that would work for static typing -- I have no idea).
>
> I'm pretty sure this particular API was designed to accommodate the old py2 
> str.translate, which took a length-256 sequence, while also accommodating 
> full Unicode, which would have required a 2^32 length sequence to do the same 
> thing :-)
>
> But again -- this is duck typing, built into the stdlib, and it works just 
> fine.
>
> Granted, until PEP 563 (kind of) , there has been nothing that weakens or 
> disallows such duck typing -- those of us that want to write fully duck-typed 
> code can continue to do so.
>
> But there is the "culture" of Python -- and it has been very much shifting 
> toward more typing -- A recent publication (sorry can't find it now -- my 
> google fu is failing me) examined code on PyPi and found a lot of type hints 
> -- many of which were apparently not being used with a static type checker. 
> So why were they there?
>
> And I've seen a lot more isinstance(Some_ABC) code lately as well.
>
> From looking at the work of my beginning students, I can tell that they are 
> seeing examples out there that use more typing, to the point that they think 
> it's a best practice (or maybe even required?). Maybe it is -- but if the 
> community is moving that way, we should be honest about it.
>
>
> I'm not even sure that this *is* nominal typing. You could just as
> well argue that "the operation `isinstance(..., Sequence)` returns
> `True`" is just another of the behavioral constraints that are
> required to quack like a sequence.
>
>
> I'm not sure of the definition of "nominal" typing -- but it absolutely is 
> NOT duck typing (As Luciano pointed out, Alex Martelli coined the term Goose 
> Typing for this).
>
> The big distinction is whether we want to know if the object is a duck, or if 
> we only need it to do one or two things like a duck.
>
> -CHB
>
>
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-dev@python.org/message/ZXI3RTBVW44WGX44D4OFSH6GXL3SYPVO/
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>
> _______________________________________________
> Python-Dev mailing list -- python-dev@python.org
> To unsubscribe send an email to python-dev-le...@python.org
> https://mail.python.org/mailman3/lists/python-dev.python.org/
> Message archived at 
> https://mail.python.org/archives/list/python-dev@python.org/message/PDW6UUK2QFS3J6B6SIQGUE2E7J7IELIS/
> Code of Conduct: http://python.org/psf/codeofconduct/



-- 
Luciano Ramalho
|  Author of Fluent Python (O'Reilly, 2015)
|     http://shop.oreilly.com/product/0636920032519.do
|  Technical Principal at ThoughtWorks
|  Twitter: @ramalhoorg
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/FDAJK5KJ5FOCXK2FZPM4S4TH7HYSCX5W/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to