<div class="gmail_quote">On Fri, Jul 31, 2009 at 11:35 PM, Edward Z. Yang <span dir="ltr">&lt;<a href="mailto:ezyang@mit.edu">ezyang@mit.edu</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Excerpts from Itamar Shtull-Trauring&#39;s message of Fri Jul 31 22:26:29 -0400 2009:<br>
<div class="im">&gt; The problem with this is that it perpetuates the misunderstanding the<br>
&gt; Deferreds *make* things asynchronous, even with the intro that says<br>
&gt; otherwise. I think it&#39;s better to assume already asynchronous code,<br>
&gt; handling the transition from synchronous to async in an intro event loop<br>
&gt; howto.<br>
<br>
</div>Either way, the function that the first segment of the new docs do belong<br>
somewhere.  The documentation that traditionally served this purpose<br>
has been removed.</blockquote><div><br>I&#39;m actually inclined to agree.  Understanding what Deferreds are <i>for</i> sort of implies an understanding of why one would want to have a list of callbacks in the first place, which implies a need to understand asynchronous programming.<br>
<br>Realistically, I don&#39;t think there are a lot of people out there who have managed to do anything at all useful with Twisted without undersanding Deferreds.<br><br>I think it might be useful to lead into this section with a specific example problem though, rather than a very vague general template for the category of problems.  Once you&#39;ve demonstrated a specific problem, you can always expand the general category by briefly listing some other problems which are similar.<br>
<br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">As for perpetuating the misunderstanding of Deferreds making things<br>
asynchronous, I completely agree!  However, I think this is something<br>
that can be fixed by spelling out the distinction between &quot;writing<br>
asynchronous code&quot; and &quot;interacting with asynchronous code&quot;, and not<br>
just omitting the important paradigm shift that comes with sync-&gt;async.</blockquote><div><br>By the time you have to spell out that distinction, I think it&#39;s too late.  By the time the user is dealing with a Deferred, they should have a pretty good idea that it&#39;s just a list of functions that will be called at some point in the future; if you have to say &quot;here&#39;s this magic thing, oh, by the way, it turns out it&#39;s just a list of functions&quot; they&#39;re still going to think something&#39;s magic about it.<br>
<br>If you want an example that doesn&#39;t involve any reactor integration, you might try showing a program that polls a directory for a file being added.  If you want to simultaneously wait for a file named &quot;1&quot; and a file named &quot;2&quot;, you need to use callbacks, otherwise &quot;waiting&quot; for 2 will prevent the code for 1 from running immediately if 1 shows up first.<br>
<br>I&#39;m not really sure this can be done in a simple enough way to be useful, so take it with a grain of thought.<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
&gt; A better comparative exposition might be with normal callbacks, e.g.:<br></blockquote><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div class="im">

&gt;<br>
&gt; &quot;def foo(x, gotResultCallback): pass&quot; vs. &quot;def foo(x): # return<br>
&gt; Deferred&quot;.<br>
&gt;<br>
&gt; At the very least having that async but callbacky version in the middle<br>
&gt; helps understanding.<br>
<br>
</div>I briefly gloss on this, but I agree that this is an important point<br>
that could be further expanded.  We could have implemented asynchronous<br>
mechanisms using normal callbacks, but we decided to use Deferreds instead.<br>
</blockquote><div><br>Definitely agreed here.  For those users who are used to &quot;normal&quot; callbacks (if there is such a thing), this explanation would be helpful to explain why you need them rather than just passing functions around.  For users who aren&#39;t even familiar with passing functions around, this would fill an important intermediate gap.<br>
 </div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">It&#39;s not clear to me if the common case of confusion of Deferreds occurs<br>
in people who &quot;know callbacks&quot; but &quot;don&#39;t know Deferreds.&quot;  As an incoming<br>
developer who was familiar with asynchronous programming, my primary problem<br>
was the ill-defined behavior of callback chains (which I resolved by<br>
hunkering down and reading the source code) rather than any fundamental<br>
misunderstanding of what Deferreds were supposed to do.<br>
<div class="im"></div></blockquote><div><br>I think we need an expanded version of the &quot;visual explanation&quot; here: &lt;<a href="http://twistedmatrix.com/projects/core/documentation/howto/defer.html">http://twistedmatrix.com/projects/core/documentation/howto/defer.html</a>&gt; (one that uses complete sentences and more than one diagram), as well as an expanded analogy to try:except: blocks in &#39;synchronous&#39; python. <br>
<br>I object to the classification of the behavior of callback chains as &quot;ill-defined&quot;.  It might have been poorly-explained, but that&#39;s very different :).<br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div class="im">&gt; It also omits half the story: how you *create* Deferreds. There should<br>
&gt; be a section on that as well.<br>
<br>
</div>I agree.  In fact, it might be worth making the document a little longer<br>
to address this point, because I realize now that even if you&#39;re not<br>
writing asynchronous code, you&#39;ll often need to baton Deferreds to<br>
make the execution flow work the way you want them to.<br></blockquote><div> <br>+1.  Dealing with Deferred creation is a good way to introduce users to the non-magicness of Deferreds.  It&#39;s less common to create one than to consume one, but understanding how to create them should make it easier to understand how to consume them.<br>
<br></div></div>