On Jan 5, 2014, at 12:44 AM, Guido van Rossum <gu...@python.org> wrote:

> On Sat, Jan 4, 2014 at 10:11 PM, Glyph <gl...@twistedmatrix.com> wrote:
>> Twisted's syntax is actually pretty bad [...]
> 
> Noted.
> 
>> "connected UDP" is a strange beast, and it doesn't make UDP a connected 
>> protocol; there's still no connection state machine, no way to tell if a 
>> particular session is connected or disconnected.
> 
> Technically, in the Tulip implementation it corresponds to whether the
> private variable transport._address is None or not. Of course I may
> not understand what you mean by "session" in this context. :-)

I mean that for a given "connected" UDP object, you don't have individual 
"connections" (what I meant by the word "session").  You have one always-on 
pipe that is talking to a given address, whether that address exists or not, as 
opposed to TCP or SCTP or websockets, where there are discrete connections with 
beginnings and ends.

>>>> FWIW: https://twistedmatrix.com/documents/current/core/howto/udp.html#auto3
>>>> 
>>>> Finally: yes, syntactically, there is nothing which would distinguish an
>>>> ordered, reliable datagram interface from and unordered, unreliable 
>>>> datagram
>>>> interface (at least a connected one).
>>>> 
>>>> Mmh, but shouldn't the interface _identity_ also express semantics?
>>> 
>>> That seems an idea from Twisted. I don't want to go that way. I prefer
>>> giving the transport object an inquiry method if necessary; that's how
>>> asyncio does it for the capability to use write_eof() (which works for
>>> TCP but not for SSL/TLS).
>> 
>> The principle that we use type-names to identify discrete sets of behavior 
>> is an ideal that Twisted strives to adhere to, but it seems like a pretty 
>> basic idea about type systems, not an idea we came up with.  ("We use types 
>> for nouns" in the words of Nathaniel Manista & Augie Fackler, both of whom 
>> are very much not associated with Twisted ;-).)  It's just having a 
>> consistent way to talk about sets of methods and attributes and stuff.  
>> Isn't this the whole reason that ABCMeta.register exists, so you can use 
>> ABCs in this way?  Then the inquiry method is always consistent, 
>> 'isinstance'.
> 
> Hm. I really don't like using isinstance() for this particular set of
> purposes (checking if a datagram transport is reliable or not, or
> checking whether it is connected or not). I fear that there would be a
> proliferation of little interface classes that would be more confusing
> than enlightening -- in particular, whenever you mention something
> starting with I-something when talking about Twisted I usually feel
> more confused than enlightened.

The main issue with I-somethings in Twisted is that there's a lot of them, and 
each one has some nuances so the underlying concepts are often confusing in 
themselves.  Plus, the way the documentation is presented, it's often far from 
obvious how to get from an abstract description of some behavior to a concrete 
implementation of that behavior.

But these tiny interface types is a solution to a real problem.  Tulip is still 
at a pretty minimal set of interfaces now, and perhaps it can stay there, in 
which case this issue is somewhat moot.  But if it can't, a proliferation of 
tiny interface types is _way_ better than a proliferation of ad-hoc prose 
passages describing the relationship between required attributes and methods 
and their differing semantics.

For what it's worth, it's somewhat unusual in Twisted to use the equivalent of 
isinstance to do any runtime checking; they're mostly useful as a documentation 
convention; duck-typing and all.  However, it is very helpful for debugging to 
be able to add type-checking logic for cases where an instance of a particular 
type is set in a constructor or setter method and then used again later, so 
that you can see the type error when it's initially set and the caller is still 
on the stack; and it's helpful to have a common language between that type of 
type-checking and the documentation explaining what things are.

>>>> If I get a transport, and want to adjust behavior according to whether the
>>>> transport is unreliable, even today I am not supposed to do that
>>>> via isinstance(transport, DatagramTransport), since DatagramTransport
>>>> doesn't imply any semantics, but only specifies a programmatic interface 
>>>> (on
>>>> a syntactical level)?
>>> 
>>> You're already writing your protocol code specific to either a
>>> datagram or a stream transport, because the protocol API is
>>> (intentionally) different. So there's never a question about which
>>> kind of transport you have.
>> 
>> I think that the point that Tobias was trying to make here is that if you 
>> have some generic string-syntax way of generating a transport (like 
>> endpoints) and the user can enter any transport-type they want, how does an 
>> application say "I am only going to work over a reliable+ordered transport". 
>>  In Twisted (and in Zope) there's a pattern of using a zope Interface or a 
>> python type object to identify the required semantics (as he pointed out 
>> above).
> 
> Which I specifically don't like (as I pointed out above :-).
> 
> I read between the lines of the Twisted endpoints docs that they don't
> support anything besides streams. I suspect that the use case for the
> inquiry discussed here is purely theoretical.

I believe Tobias actually cares about the actual additional framing and typing 
features of WebSockets, which _do_ have different semantics from TCP.  
Personally I feel like these features are just dumb over-engineering, and 
should be ignored as much as possible.  So I'm given to agree with you about 
their theoretical nature but I don't think he would :-).

(I also think SCTP is pretty much doomed unless someone figures out how to run 
it on top of UDP or TCP...)

-glyph

Reply via email to