<?xml version="1.0" encoding="UTF-8" standalone="no"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:base="https://dirtsimple.org/wp-atom.php" xml:lang="en-US">
	<title type="text">dirtSimple.org (Software &amp; Tech Feed)</title>
	<subtitle type="text"/>

	<updated>2021-07-04T21:29:17Z</updated>

	<link href="https://dirtsimple.org" rel="alternate" type="text/html"/>
	<id>https://dirtsimple.org/feed/atom</id>
	<link href="https://dirtsimple.org/topics/code/feed/atom?is_burning=1" rel="self" type="application/atom+xml"/>

	<generator uri="https://wordpress.org/" version="4.9.8">WordPress</generator>
<icon>/favicon.ico</icon>
	<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[What Stands In The Way, Becomes The Way]]></title>
		<link href="https://dirtsimple.org/2019/10/what-stands-in-the-way.html" rel="alternate" type="text/html"/>
		<id>urn:uuid:565227b6-6803-4f75-8466-db2d8b3073e4</id>
		<updated>2019-10-21T05:14:10Z</updated>
		<published>2019-10-21T05:14:10Z</published>
		<category scheme="https://dirtsimple.org" term="Self-Improvement"/><category scheme="https://dirtsimple.org" term="Entrepreneurship"/><category scheme="https://dirtsimple.org" term="News &amp; Announcements"/>		<summary type="html"><![CDATA[<p>I was always a stubborn child.When my parents told me, “you can’t”, I would ask, “why not?”They said I couldn’t have everything I wanted. That there was no fast and sure way to make money. That I needed things other than my intellect to get by in the world.I didn’t understand. And I didn’t believe.Despite [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2019/10/what-stands-in-the-way.html">What Stands In The Way, Becomes The Way</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2019/10/what-stands-in-the-way.html"><![CDATA[<p>I was always a stubborn child.</p><p>When my parents told me, “you can’t”, I would ask, “why not?”</p><p>They said I couldn’t have everything I wanted.  That there was no fast and sure way to make money.  That I needed things other than my intellect to get by in the world.</p><p>I didn’t understand.  And I didn’t believe.</p><p>Despite my glasses and messy dark hair, I was less Harry Potter and more Hermione Granger: believing everything I read in books, obsessed with the right ways to do things, and always willing to tell everybody else how to do it better!</p><p>After breezing through (and testing out of) grade school and high school, then jumping straight into a startup even before going to college, the world was my oyster.  Life looked easy from there.</p><h4>Boy was I in for a rough time!</h4><p>Have you ever heard that saying, “What brought you here, won’t get you there?”</p><p>Real life is funny like that.  We step out of our small pond and find ourselves surrounded with bigger fish.  Or we find that despite all those people telling us, “you’re so good at that, you should start your own business”, not as many of them are willing to be your customers once you do…  and that running a business is a lot harder than you thought it would be!</p><p>No matter your field, no matter your level of talent or ability, there always comes a point where simply <em>trying harder</em> is not an option, because no matter how hard you try, you find yourself going in circles, repeating the same mistakes, and spiraling down the drain.</p><p>When I started this blog in 2004, I’d just left another startup with a wad of cash burning a hole in my pocket, and an even bigger list of questions burning holes in my heart:</p><ul><li>Can people really change?  Can <em>I?</em>
</li><li>Why are some people so successful, while others with more talent or better products fail so miserably?</li><li>How could I be so successful at helping other people (or businesses, or software projects) achieve <em>their</em> goals, and yet so thoroughly sh**ty at achieving my own?</li></ul><p>I set out to answer those questions by writing about my experiences, both in my personal life and my software development work.  And at the time, I had <em>absolutely no idea</em> I was going to turn into some kind self-help guru.</p><h4>But life is funny like that.</h4><p>It turns out that change and motivation and success and all that jazz, have an <em>awful lot</em> in common with software development.  Not the programming bits, mind you.  But the debugging bits.  The <em>hacking</em>.</p><p>Turns out, you can debug your mind and your life in pretty much <em>exactly</em> the way you do a computer program.  Hack in and rewire yourself, the way you’d crack root on your phone or gaming console.</p><p>You don’t actually have to be a hacker or coder to do it, but the resemblance is <em>uncanny</em>.</p><p>When I started this blog, I’d barely heard of Marcus Aurelius, except for knowing that he was this cool Roman Emperor dude who wrote some important stuff.  But now, after 15 years of wrestling with the big questions, I just recently found out that he’d <em>already written down</em> the central theme of <strong>everything</strong> I’ve been studying, experimenting with, and learning since I started:</p><blockquote><p>The impediment to action advances action.<br />
What stands in the way <em>becomes</em> the way.</p></blockquote><p>You can’t fix a bug in a program by trying to avoid it.  In fact, you do the opposite!  A programmer fixing a bug tries to <em>repeat</em> the bug, as much as possible, until they understand it.  A hacker puts bad data into the system they’re trying to crack, intentionally provoking errors to find a way “in”.</p><p>And just as with everything else in life, when it comes to debugging, <strong>trying harder is not an action plan</strong>.</p><p>You can’t “try harder” to fix a bug, solve a problem, or have a good idea.  All you can do is become more <em>curious</em>, and <strong>ask better questions</strong>.  You have to treat your obstacles as <em>information</em>.  As clues that tell you…</p><h4>How Things <em>Really</em> Work</h4><p>And as it happened, one of the reasons I was so good at helping <em>other</em> people, is because I was really good at “asking better questions”.</p><p>While one of the reasons my personal life was so sh**ty, was that I never asked <em>myself</em> any of those questions, before I started this blog.</p><p>When things got tough, I tried harder…  or I gave up.</p><p>But neither of these approaches can work for us in the long run.  Sooner or later, something comes along that’s harder than you…  or can’t be run away from.  (<a href="https://dirtsimple.org/2005/10/stars-i-dont-know.html">Hurricanes</a> and <a href="https://dirtsimple.org/2005/12/island-within.html">crooked roofers</a> were only the beginning!)</p><p>But I started asking better questions, and started getting better results.</p><p>I learned what <a href="https://dirtsimple.org/2005/08/multiple-self.html">makes us tick</a>, and <a href="https://dirtsimple.org/2005/11/refactored-self-part-1.html">how to change it</a>.  Got excited, started a business, got successful…</p><p>And crashed again.</p><p>Now, this is the point where I’m required by law to say something like, “it was the best thing that ever happened to me,” or else they’ll revoke my guru license.</p><p>F**k that.  It was <strong>awful</strong>.  My own failures to reach my goals aside, I had to deal with health issues (mine <em>and</em> my wife’s) and the financial difficulties that go with them.</p><p>If there was <em>any</em> other way to learn what I’ve learned, to achieve what I achieved…  I’d sign up in a heartbeat.  If I could write down everything I learned and put it in a book and mail it to my past self… well,</p><h4>I’d probably still f**k it up!</h4><p>For the past five years, this blog has sat idle, mocking me.  The software I’d used to run it had become non-viable, and I was so depressed I felt I had nothing much of worth to actually say.</p><p>Things were so bad, I started thinking maybe my parents were right.  Maybe you <em>can’t</em> have what you want.  Maybe life <em>was</em> hard and full of disappointment.  Or maybe Kenny Rogers was right, and “the best that you could hope for / was to die in your sleep”.</p><p>The truth was, despite my skill at helping others, despite the things I learned about how to change – even myself – my personal <em>philosophy</em> was still rooted in optimism.  A belief that surely <em>anything</em> must be possible, and that – much like Hermione Granger – I could learn to do <em>anything</em> if I just read the right books.</p><p>But that kind of philosophy doesn’t stand up to the real pains of life.</p><p>Building a new philosophy took time, and a lot of false starts.  I had to learn for myself, the hard way, the meaning of some of Marcus Aurelius’ other words:</p><blockquote><p>Objective judgment, now at this very moment.<br />
Unselfish action, now at this very moment.<br />
Willing acceptance—now at this very moment—of all external events.<br />
That’s all you need.</p></blockquote><p>These words are kind of cryptic, and they may not mean what you <em>think</em> they mean.</p><p>If I had read them before, I doubt I would have understood that “unselfish action” has nothing to do with who your actions benefit, but rather, that you are focused on the <em>outcome</em> of your actions, rather than on how they <em>reflect upon yourself</em>.</p><p>And I doubt I would have understood that “objective judgment” doesn’t mean, “use an outside perspective to find better ways to criticize yourself”!</p><p>Or that “willing acceptance” wasn’t just another way to phrase my father’s constant refrain that I would “just have to learn to live with being disappointed”.</p><p>And I certainly wouldn’t have guessed that all three sentences are just different ways of saying the <em>same thing</em>:</p><h4>All results are <em>feedback</em>.</h4><p>All results are <em>information</em>.  Clues.  Hints.  A treasure map to our goals, or at least the next level in our personal game.  And we can only decipher them by being willing to <em>follow</em> the feedback we are given, weighing it without regard to what we might think it might say about us as a person, or that it might present us with unpleasant facts about the nature of the world around us.</p><p>But if you can find yourself <em>curious</em> instead of giving up…</p><p>And if you’re willing to <strong>follow where the clues lead</strong>, instead of trying harder and harder to make things go the way you want them to…</p><p>You will find yourself playing the game on a whole new level.</p><p>15 years ago, I could follow the clues in <em>other people’s</em> goals, because I wasn’t attached to the outcome.</p><p>And then I learned to follow the clues in my <em>mind</em>, to become less attached to my own goals, yet at the same time more motivated to act on them.</p><p>And then finally, I had to learn to follow the clues left by <em>life</em>, that told me how I needed to change in areas I didn’t really <strong>want</strong> to…</p><p>But would make me happier, more at <em>peace</em>, and more <strong>in love with life</strong> than I ever dared dream possible.</p><p>So here I am, starting up the blog again.  With new things to say, and do, and maybe even sell.</p><p>I’ve given it a fifteenth-anniversary facelift, and a new catchphrase to boot, straight out of Marcus Aurelius’s playbook:</p><h4>What Stands In The Way, <em>Becomes</em> The Way</h4><p>Because if you want to level up your life, transcend your limitations, and maybe even stare death in the eye without blinking, you would do well to remember this:</p><p>Despite what society tells us, it is not about keeping our “eyes on the prize”.  Nor is it really true that obstacles are just, “those frightful things we see when we take our eyes off the goal”.  Nor can we truly say that our problems are “opportunities”…  even though we can <em>make</em> opportunities from them.</p><p>No, the real truth about our problems – whether in business, software development, or life itself – is that they are <em>clues</em>.  Clues that tell us what we need to <strong>change</strong>.</p><p>In our actions, in our <em>plans</em>, or in our minds and hearts.</p><p>Our problems are a messenger, that tell us that <strong>what we’re doing isn’t working</strong>, and that <em>trying harder won’t help</em>.</p><p>They tell us that our ideas of the way things <em>ought</em> to be, don’t match with how they really <em>are</em>.  That the things we think we know are <strong>wrong</strong>.  That the things we want to pretend we have or can get were never really <em>real</em>, and the things we want to believe, we may need to let go of.</p><p>And that, although we are always free to <em>argue</em> with reality…  we will only lose (as Byron Katie puts it), “100% of the time”.</p><p>I won’t lie: letting go of our arguments, giving up on our stubborness…  it’s hard nearly every single time.  Sometimes it even feels like dying, or like giving up on everything you ever wanted or held dear.</p><p>And yet…</p><p>On the other side, the moment you <em>truly</em> act with “willing acceptance”, “objective judgment”, or “un[self-conscious] action”…</p><p>Not as a trick or a hack, but <em>for real</em>…</p><h4>Your life is transformed.</h4><p>Maybe only in one small way, some tiny area.  But it’s changed.</p><p>And it’s real.  And it’s different.</p><p>Because <em>you’re</em> different.</p><p>And then you wonder what all the fuss was about, because you can’t even remember why you were so stubbornly insistent that life had to be the way you thought, or else it just wasn’t <em>right</em>.</p><p>Yeah, yeah… I know: that’s all very inspiring and all, but <em>how</em>, exactly, do you <strong>do that</strong>?</p><p>Well…  that’s why I’m writing new articles again.  <img src="https://s.w.org/images/core/emoji/11/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p><p>So stay tuned!  (And if you haven’t already, follow on Twitter or Facebook, or better yet: use the RSS feed or sign up for email notifications, so you’re not as dependent on Big Social Media to decide what you do and don’t hear about.)</p><p>–PJ</p><p>P.S. Welcome back to dirt Simple!  Although the facelift is basically done, some reorganization and updates are still in progress.  There may still be some broken links for a little while, and some things might take a little while to come back.  But almost everything from the old site is still here, and accessible via the same URLs as before.</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2019/10/what-stands-in-the-way.html">What Stands In The Way, Becomes The Way</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2019/10/what-stands-in-the-way.html#comments" rel="replies" thr:count="0" type="text/html"/>
		<link href="https://dirtsimple.org/2019/10/what-stands-in-the-way.html/feed/atom" rel="replies" thr:count="0" type="application/atom+xml"/>
		<thr:total>0</thr:total>
		</entry>
		<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[WSGI, Web Frameworks, and Requests: Explicit or Implicit?]]></title>
		<link href="https://dirtsimple.org/2011/08/wsgi-web-frameworks-and-requests.html" rel="alternate" type="text/html"/>
		<id>tag:blogger.com,1999:blog-8674831.post-9217096005178432709</id>
		<updated>2011-08-02T21:46:52Z</updated>
		<published>2011-08-02T18:47:38Z</published>
		<category scheme="https://dirtsimple.org" term="Software Development"/>		<summary type="html"><![CDATA[<p>In Python web programming and frameworks, there is a constant juggling act that takes place between “explicit” and “implicit”.  Too explicit, and the code may get too verbose or unwieldy.  Too implicit, and the code may lose clarity or maintainability.And nowhere can this tension be more clearly seen, than in the area of “request” objects.  After [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2011/08/wsgi-web-frameworks-and-requests.html">WSGI, Web Frameworks, and Requests: Explicit or Implicit?</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2011/08/wsgi-web-frameworks-and-requests.html"><![CDATA[<p>In Python web programming and frameworks, there is a constant juggling act that takes place between “explicit” and “implicit”.  Too explicit, and the code may get too verbose or unwieldy.  Too implicit, and the code may lose clarity or maintainability.</p><p>And nowhere can this tension be more clearly seen, than in the area of “request” objects.  After all, nearly every web programming framework has some notion of a “request” at its core: usually some sort of object with an API.</p><p>Now, as you may recall from my <a href="https://dirtsimple.org/2011/08/is-wsgi-lite-library-or-protocol-and.html">previous article</a>, the Web-SIG originally set out in 2003 to standardize a <strong>universal</strong> “request” API for Python, but I diverted this effort towards a different sort of request API – the WSGI “environ” object.</p><p>Where web framework request APIs usually emphasize methods and properties, the WSGI “environ” object is just a big bag of data.  It doesn’t <em>have</em> any operations or properties.</p><p>But the upside to this downside, is that the enviornment is <em>extensible</em>, in a way that a request object is not.  You can add whatever you want to it, and you can call functions on it to do things that a request object would do with methods.  (Yay, freedom!)</p><p>But the <em>new</em> downside to that upside, is that if you want to use library functions on the environ instead of framework “request” object methods, you now have to pass the environ back into the library functions!  (Boo, hiss.)</p><h4>Binding To The Environment</h4><p>So, WSGI-era web libraries (like WebOb and Werkzeug) tend to define their next-generation “request” objects as wrappers bound to the environ.  As Ian Bicking put it:</p><blockquote><p>“Everything WebOb does is basically functions on the environ”</p></blockquote><p>Of course, this isn’t the <em>only</em> strategy for managing request information.  Some web app frameworks dodge the argument-passing issue by using thread locals, or worse yet, global variables.  But they’re <em>still</em> trying to solve the same problem: connecting actions that a web application needs to perform, with some notion of the “current request”.</p><p>And in both cases, a key driver for the API design is brevity and ease-of-use (implicit) vs. clarity and consistency (explicit).</p><p>On the explicit side, It’s annoying to be constantly saying “foo = bar(environ, etc)”, if only because it somehow looks less Pythonic than “foo = request.bar(etc)”.</p><p>So in effect, what we want in our frameworks is a way to (implicitly) <em>bind</em> operations to the “request”, so that it isn’t necessary to explicitly spell out the connection in every line of code.  (Even if we’re still <em>explicitly</em> referencing the request object.)</p><p>In fact, we don’t even want to have to include boilerplate like ‘request = Request(environ)’ at the top of our apps’ code, and so we’d much rather have this binding take place <strong>outside</strong> our code entirely.</p><p>Now, <em>this</em> is where things get really interesting!  In order to get rid of this boilerplate, web libraries and frameworks will usually do one of two things.  Either:</p><ol><li>They provide a decorator to change the calling signature while keeping external WSGI compliance (like WebOb), or</li><li>They ditch WSGI entirely and use a different calling signature  (like Django)</li></ol><p>And in either case, we’re now more or less back where we started, pre-WSGI, as you are now writing code with a calling signature that’s implicitly coupled to a specific library or framework.</p><p>Sure, you get certain benefits in exchange for making this commitment, and you’re less tightly coupled to libraries using option 1.  But it’s still a pretty exclusive commitment.  If you want to use code from more than one library, you’re going to have to write the boilerplate for each of them, except for whichever one you choose to be your “primary” &#8211; the main one that calls you and/or decorates your code.</p><h4>The Original Goal Of WSGI</h4><p>Now, the original idea for WSGI (well, <em>my</em> original idea, anyway) was that by letting “request” objects wrap the environ, and using “functions on the environ”, we could get <em>out</em> of this situation.  As I wrote in the original <a href="http://www.python.org/dev/peps/pep-0333/#rationale-and-goals">PEP 333 rationale section</a>:</p><blockquote><p>“If middleware can be both simple and robust, and WSGI is widely available in servers and frameworks, it allows for the possibility of an entirely new kind of Python web application framework: one consisting of loosely-coupled WSGI middleware components.</p><p>“Indeed, existing framework authors may even choose to refactor their frameworks’ existing services to be provided in this way, becoming more like libraries used with WSGI, and less like monolithic frameworks. This would then allow application developers to choose “best-of-breed” components for specific functionality, rather than having to commit to all the pros and cons of a single framework.”</p></blockquote><p>But what I didn’t understand then, was just how <em>annoying</em> it is to have to explicitly pass the environ into every library function you wanted to use!</p><p>(Actually, it’s not just that it’s annoying from a number-of-keystrokes point of view, it’s also more foreign to a Python programmer’s sensibilities.  We don’t usually mind <em>receiving</em> an explicit “self”, but for some reason, we seem to hate <strong>sending</strong> one!)</p><p>And that (in a somewhat roundabout way) is how I ended up adding the experimental “binding” protocol to <a href="https://dirtsimple.org/2011/08/is-wsgi-lite-library-or-protocol-and.html">WSGI Lite</a>.</p><p>Specifically, what the binding protocol provides, is a way to <em>generically</em> bind things to the environ dictionary, and pass them into your application’s calling signature, while retaining WSGI compliance for any code that calls your function.</p><p>In other words, the binding protocol is a way to make it so that you can use as many libraries, functions, or objects for your request as you want, without needing to pass an ‘environ’ parameter to them over and over.</p><p>Now, in the simplest case, you can just use the binding protocol as a generic way to obtain any given library’s request objects.  You can say, “my ‘request’ parameter maps to a WebOb request”, for example.</p><p>But the really <em>interesting</em> cases come about, when you stop thinking in terms of “request” objects, and start thinking about what your application reallly <em>does</em>.</p><h4>The Meaning of “Lite”</h4><p>For example, why not bind a session object to your function’s ‘session’ argument?  Or maybe what you <em>really</em> want is to just receive an authenticated user object in your ‘user’ parameter, and a cart object in your ‘cart’ parameter, instead of first getting a session, just so you can <em>get</em> to the user and cart.</p><p>In other words, what if you made your <strong>application goals</strong> more explicit?</p><p>Now currently, getting access to such application-specific objects requires either painfully-verbose boilerplate off of a raw WSGI environment, or an increasingly tight coupling to an increasingly monolithic framework that does more of the work for you.</p><p>But, with the Lite binding protocol, you can now represent <em>anything</em> that’s tied to “the current request”, just by creating a callable object that takes an environment parameter.</p><p>Which means you don’t really need “request” objects any more in your main code, because you can simply arrange to be <em>called with whatever objects you need</em>, to do the thing you’re actually <strong>doing</strong>.</p><p>And so your application code stops being about manipulating “web stuff”, to focus more on whatever it is that your app actually <em>does</em>…  while still being just a WSGI app from the point of view of its caller.</p><p>(This by the way, is part of why I dubbed the concept “WSGI Lite”, despite the fact that it adds new protocols to WSGI: it effectively lets you take most of the “WSGI” out of “WSGI applications”.)</p><h4>The Great “Apps vs. Controllers” Debate</h4><p>Now, if you look at how *non-*WSGI-centric, “full-stack” frameworks (like Django, TurboGears, etc.) operate, they often have things they call “controllers”: functions with more specialized signatures for doing this kind of “more app, less web” kind of stuff.  However, these frameworks tend to end up being very un-WSGI internally, because plain WSGI doesn’t handle this sort of thing very well.</p><p>However, with the WSGI Lite binding protocol, you can write controllers with whatever signature you like, while remaining “WSGI all the way down”.  Anything you want as an argument, you can just create a binding rule for, which can be as simple as a string (to pull out an environ key) a short function that computes a value, or a tiny classmethod that returns an object wrapping the environ.</p><p>And, if it’s a callable (like a function or a method), it <em>too</em> can use the binding protocol, and ask for its arguments to be calculated from the request.</p><p>And that means that you can take, say, a generic binding rule that fetches a parsed form, and use it to write an application-specific binding rule that looks up something in a database.</p><p>At which point, you can now write a controller that uses that binding rule to get something it needs as an argument.</p><h4>Where All This Is Going</h4><p>Now, if you look at where all this is going, you’ll see that you’re going to end up with a very small application body: just the code that actually <em>does</em> things with the information that came in, and decides what to send back out.</p><p>Something, in fact, that looks very much like a “controller” would in a non-WSGI, full-stack web framework…  yet isn’t locked in to one particular full stack framework.</p><p>Now, I don’t know how clear any of the above was without code examples.  (Probably not very.)  But the endgame that I’m trying to describe, is a future in which both “full stack” and “WSGI-centric” frameworks use a <em>common protocol</em> to provide their features to applications.</p><p>And, more importantly, a future where <strong>full-stack features do not require <em>learning</em> a full stack framework</strong>.</p><p>And where <strong>every application is its own framework</strong>.</p><p>In effect, the binding protocol is a tool that allows every app to define its own embedded DSL: the set of high-level data objects and operations that it needs in order to do whatever it does.</p><p>And these high-level, application-specific objects and operations are composed of lower-level, domain-generic objects and operations (such as form parsers and validators, URL parameter extractors, session and cookie managers, etc.), obtained from libraries or frameworks.</p><p>And all of these objects are passed around via the environment and binding rules, while retaining WSGI Lite calling signatures…  making the entire thing “WSGI all the way down”.</p><p>And yet, the <em>code</em> contained in those applications would not look like “WSGI” as we know it today.  For example:</p><pre><code class="language-python">@lite(
    user = myapp.authorized_user,
    output = myapp.format_chooser,
)
def todo_list(environ, user, output):
    return output(user.todo_items())
</code></pre><p>Or, perhaps the Python 3 version would look like this:</p><pre><code class="language-python">@lite
def todo_list(
        environ,
        user:   myapp.authorized_user,
        output: myapp.format_chooser
    ):
    return output(user.todo_items())
</code></pre><p>Neither of these looks anything like “WSGI” code as we know it today &#8211; it’s more like a full-stack framework’s code. But, where the bindings in a full-stack framework are <em>implicit</em> (like automatically formatting the output with a template or turning it into JSON), all of the bindings here are <strong>explicit</strong>.</p><p>And not only is explicit better than implicit, but…</p><h4>Readability Counts!</h4><p>You can see right away, for example, that this app is using some sort of chooser to render the output in some request-determined format, and you can track down the relevant code, without having to first learn all of the implicit knowledge of a particular framework’s construction.</p><p>And, the <em>point</em> of this app function is immediately obvious &#8211; it displays a user’s todo list. (Something that would otherwise be hidden under a pile of web I/O code, if this were written to plain WSGI or with a WSGI-centric library or framework.)</p><p>And what this means is, if this approach becomes a focal point for Python web development, then being a Python web programmer would not be a matter of being a “Django developer” or “TurboGears developer” or “Pyramid Developer” or any <em>other</em> sort of developer…</p><p>Other than a <em>Python</em> developer.</p><p>Because any Python developer could pick this up, without having to have all the implicit, framework-specific knowledge already in their head.</p><p>And hopefully, this will help get us to a situation where, instead of people saying, “you should use Python for your web app because framework X is great”…</p><p>People will say, “you should use Python for your web app because it lets you focus on what your application is really doing, and no matter what libraries you use, your code will be readable and maintainable, even by people who haven’t used those libraries.”</p><p>Or maybe just, “you should use Python for your web app because <em>it’s a great language for web development</em>!”</p><h4>Plumbing The Pipe Dream</h4><p>Now, is all that just a pipe dream?</p><p>Maybe so. After all, there are still a <strong>lot</strong> of hurdles between here and there!</p><p>(For starters, I think that the actual binding protocol probably still needs some work!)</p><p>But if you want to make a “pipe” dream real, you’ve got to start with the requirements for the <strong>plumbing</strong>.</p><p>So right now, I’m collecting use cases from frameworks as I encounter them, to see what services the popular frameworks provide, and how they could be expressed as bindings.</p><p>But I’m <em>also</em> really interested in the problems that such frameworks have, in terms of how they currently communicate state, configuration, and other information to user code. Are there any open issues the binding protocol could solve now, or could solve with some additions?</p><p>Because that’s what’s really going to make the difference to adoption here. The authors of established libraries and frameworks aren’t going to change things just beacuse I said this is a neat idea!</p><p>But if we can make the protocol <em>solve</em> some existing problems – like helping to get rid of thread-local objects, for example – then folks have another reason to get on board with a common protocol, besides it <em>being</em> a common protocol.</p><p>So, that’s the interesting question that lies ahead:</p><p>Do you have any warts in your current app, library, or framework that this might help you solve? Or a feature you think it could help you add?</p><p>Leave me a comment here, or drop me an email via the Web-SIG!</p><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2011/08/wsgi-web-frameworks-and-requests.html">WSGI, Web Frameworks, and Requests: Explicit or Implicit?</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2011/08/wsgi-web-frameworks-and-requests.html#comments" rel="replies" thr:count="4" type="text/html"/>
		<link href="https://dirtsimple.org/2011/08/wsgi-web-frameworks-and-requests.html/feed/atom" rel="replies" thr:count="4" type="application/atom+xml"/>
		<thr:total>4</thr:total>
		</entry>
		<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[Is WSGI Lite a Library or a Protocol? (And Why You Should Care)]]></title>
		<link href="https://dirtsimple.org/2011/08/is-wsgi-lite-library-or-protocol-and.html" rel="alternate" type="text/html"/>
		<id>tag:blogger.com,1999:blog-8674831.post-3584372398539341275</id>
		<updated>2011-08-01T19:57:57Z</updated>
		<published>2011-08-01T14:44:10Z</published>
		<category scheme="https://dirtsimple.org" term="Software Development"/>		<summary type="html"><![CDATA[<p>In retrospect, my article yesterday about WSGI Lite made a rather glaring mistake: instead of carefully laying out the background rationale and explaining where WSGI Lite fits in to today’s Python world, I threw a bunch of links at people and went “Whee!  It’s neat!”So, in hindsight, I should’ve expected reactions like “huh?”  “wha?” and [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2011/08/is-wsgi-lite-library-or-protocol-and.html">Is WSGI Lite a Library or a Protocol? (And Why You Should Care)</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2011/08/is-wsgi-lite-library-or-protocol-and.html"><![CDATA[<p>In retrospect, my article yesterday about WSGI Lite made a rather glaring mistake: instead of carefully laying out the background rationale and explaining where WSGI Lite fits in to today’s Python world, I threw a bunch of links at people and went “Whee!  It’s neat!”</p><p>So, in hindsight, I should’ve expected reactions like “huh?”  “wha?” and “don’t we already have WebOb and Werkzeug?”</p><p>My bad, guys.  I totally failed to highlight the really crucial point about WSGI Lite, and that is the distinction between “wsgi_lite” (the proof-of-concept/future reference library) and “WSGI Lite” (the PEPpable protocol).</p><p>See, in my mind, “wsgi_lite” the library is no more a competitor to WebOb and Werkzeug than the standard library’s “wsgiref” package is a competitor to mod_wsgi: just because it has a server in there, doesn’t mean it competes with servers!</p><p>I think it’s a pretty safe bet to say that most WSGI (protocol) code does not use wsgiref (library), except maybe indirectly via something else.  And the same thing may well end up being true of wsgi_lite (the library) and WSGI Lite (the protocol).</p><p>Yeah, it’s a little confusing.  I get that now.  When I was first writing the code, I called it “WSGI 2”, and the decorators were <code>@wsgi2</code> and <code>@wsgi1</code>, instead of <code>@lite</code> and <code>lighten()</code>.  I was even having the decorators change the <code>wsgi.version</code> environment key from (1,0) to (2,0) and back.</p><p>However, as the work progressed, the versioning didn’t make a lot of sense to me, because in a sense, the core bits of the protocol weren’t changing.  Instead, there were a handful of small protocols that, put together, make a new way of doing WSGI.  So I ended up deciding to call it “WSGI Lite”, and dropped the version fudging.</p><p>But if you look at what is happening with the actual underlying protocol, I really am proposing something like a WSGI 2 here, or probably more like a 1.1.  (Sort of.)  The key point is that it’s a protocol that can work in <em>today’s</em> WSGI stacks, without needing a massive rewrite effort.</p><p>Granted, this means that if you have some pet gripes with WSGI, then Lite may or may not be able to solve them.  A couple people have approached me privately about those issues, and I’d like to start hashing them out on the Web-SIG shortly.</p><p>But in the meantime, I’d like to take the rest of this article to lay out just what (and <strong>why</strong>) WSGI Lite, <em>the protocol</em>, is.  (As opposed to wsgi_lite, the proof-of-concept implementation of the protocol.)</p><h4>Why A New Protocol?</h4><p>Because WSGI <em>rots your brain</em>.</p><p>Or, to put it less dramatically, it is damn near impossible to write correct WSGI middleware because there are too darn many things to think about.</p><p>In the Reddit thread about Armin’s article, one person posted a bunch of links to the various patches they had to do to a piece of WSGI code in order to make it work correctly with various corner cases in the protocol, as bugs cropped up in interaction with other WSGI code.</p><p>And I took one quick look at one of those patches, and saw that it <em>still had bugs</em>.</p><p>Granted, it was a resource-leak bug, but that’s not the point.  It shouldn’t be so frickin’ easy to make that kind of mistake.  (And the author was not exactly a newbie to either WSGI or web programming.)</p><p>And as I started writing my proof-of-concept (for what I originally thought of as “WSGI 2” rather than “WSGI Lite”), I discovered all kinds of <strong>other</strong> mistakes that people could make in their middleware, that had never even <em>occurred</em> to me before.</p><p>Even Ian Bicking, author of WebOb, realized after reading the WSGI Lite docs that WebOb contained a latent bug I described there!</p><p>So, something <em>has</em> to be done.  WebOb and Werkzeug are great libraries, but if libraries could solve the problem, it would already be solved.  That’s why wsgi_lite (the <strong>library</strong>), is really just a test bed for WSGI Lite, (the <strong>protocol</strong>).</p><p>And the aim of WSGI Lite is not to solve all WSGI 1 problems, nor even the entire subset of WSGI 1 problems that can be addressed in a reasonably performant, backwards-compatible way using a pair of decorators.</p><p>Rather, the aim is to eliminate certain key <strong>obstacles</strong> to solving those problems.</p><h4>Protocols, WSGI, and Game Theory</h4><p>Back when I first proposed the idea that became WSGI (late 2003), the goal of the Web-SIG was to define standard “request” and “response” objects for the standard library.</p><p>So my counter-proposal to instead define a <em>protocol</em>, and not actually put any <em>code</em> for the protocol into the standard library, may have seemed a bit loopy to some folks.  Perhaps a bit like, “let’s solve this problem by <em>not</em> solving this problem!”</p><p>But the reason that I did it – and the reason it ended up working so well that damn near every dynamic language ends up more-or-less cloning WSGI these days – is because of <strong>game theory</strong>.</p><p>Essentially, there was never any serious chance that a bunch of web framework developers with investment in existing APIs were ever going to get together and agree on the One True Request and One True Response: there were just too many differences in fundamental approaches, and way too much opportunity for bikeshedding.</p><p>In game theory terms, you could say there was no <a href="http://en.wikipedia.org/wiki/Focal_point_(game_theory)">Schelling Point</a>.  As Wikipedia puts it:</p><blockquote><p>Consider a simple example: two people unable to communicate with each other are each shown a panel of four squares and asked to select one; if and only if they both select the <em>same</em> one, they will each receive a prize. Three of the squares are blue and one is red. Assuming they each know nothing about the other player, but that they each do want to win the prize, then they will, reasonably, <em>both</em> choose the red square. Of course, the red square is not in a sense a <em>better</em> square; they could win by both choosing any square. </p></blockquote><p>In other words, in trying to design the One True Request and One True Response, there was no single obvious “square” to choose: everything was up for grabs, so nobody could win the “prize” (i.e., the benefits of having a One True anything in common).</p><p>So what I did with my WSGI proposal was deliberately <em>create</em> a Schelling Point: a single red square in a board full of blues.</p><p>And the <em>way</em> that I did it, was to specifically remove <strong>any</strong> semblance of an API that would make WSGI look like another blue square.</p><p>Voila: the Web-SIG was able to shift from discussions about what color to paint the bikeshed, to substantive discussions about the guts of HTTP and what requirements we had for interfacing with it.</p><p>Now, notice that I’m <em>not</em> saying that I came up with WSGI by myself and I was a genius.  What I’m saying is, I gave the Web-SIG something to <em>collaborate</em> on, instead of something to <em>compete</em> over.</p><p>Let me repeat that: something to <strong>collaborate on</strong>, instead of something to <strong>compete over</strong>.</p><p>I could not have written the WSGI PEP by myself: I didn’t have nearly enough information.  But the Web-SIG, in <em>collaboration</em> mode, could.</p><p>So what does all this have to do with WSGI Lite?</p><p>Well, once again, the idea is to create a collaborative Schelling Point: a <em>protocol</em>, rather than an API.  Because, once again, no one can agree on The One True WSGI Wrapper, when all we have are competing implementations with distinct APIs.</p><p>Granted, I may have shot myself in the foot this time, by starting with a proof-of-concept library rather than a PEP explaining the protocols!</p><p>Unfortunately, due to the nature of the requirements, I couldn’t be <strong>sure</strong> the protocols would work without prototyping an implementation first, and still can’t be sure the protocols <em>really</em> work without some community testing.  (And the shape of the protocols themselves evolved <em>considerably</em> over the last three days of implementing, documenting, realizing something sucked, then fixing it and trying again!)</p><p>But what are these protocols exactly?  What do they do, and why are they important?</p><h4>The First Protocol: Calling Convention</h4><p>The WSGI Lite protocol consists of a few basic elements working together:</p><ul><li>A revised calling convention and return protocol</li><li>A server API extension for resource closing</li><li>An “argument binding” protocol</li></ul><p>The first of these things is something that’s been proposed for a long time, and there seems to be fairly widespread consensus that a Rack-style calling convention is a good idea.  WebOb, for example, already has some APIs that work on that calling convention, and I’ve never heard anybody saying that calling convention was <em>bad</em>, or that the current WSGI convention is <em>better</em>.</p><p>(Actually, the closest thing I’ve seen to somebody saying that, would be in the Hacker News thread about yesterday’s article: somebody thought that WSGI Lite forces async code to use greenlets.  But that’s a mistake, because WSGI Lite only requires greenlets or threads for code that uses write().  WSGI Lite response bodies can still be produced just as asynchronously as a standard WSGI response body can.)</p><p>Anyway, so, the first protocol is well-known to WSGIans, and largely uncontroversial, hence the “uhh..  don’t we already have that?” reaction from some quarters.  What’s been lacking is a co-ordinated way to <em>move forward</em> on that.</p><p>To put it another way, since that protocol lacks any “official” status or name, it’s not really possible to use it as a Schelling Point of co-ordination between users and library authors.  Ian can’t point to WebOb and say, “WebOb lets you use the [thingy] protocol”, instead, he has to say, “WebOb is cool, you should use it.”  Meanwhile, Armin is over there on the other side of the room, saying, “Werkzeug is cool, you should use it” too.</p><p>Meanwhile, the poor user is left in the middle of the room, scratching his or her head and going, “Uh, so what should I use now?”, with respect to any “enhanced WSGI” APIs.</p><p>So, as far as this first sub-protocol is concerned, the ultimate point of WSGI Lite is going to be to nail down and “bless” a detailed and <strong>specific</strong> flavor of the calling protocol, to provide that co-ordination point for libraries to say what they offer to people, and for people to make choices about using them.</p><p>I seriously doubt that this is a very controversial proposal.  After all, many people have said they want this calling protocol, and some leading WSGIans (hm, that term even has the word “Ian” in it!) have actually implemented more or less that protocol in their libraries.</p><p>What’s more, people have been asking <em>me</em> to do something about getting this protocol “out there”, reflecting their subconscious realization that a Schelling Point is indeed <strong>needed</strong> to do this, and that <em>I’m</em> the most obvious “red square” for co-ordination where WSGI is concerned.</p><p>So be it.</p><p>That’s why Armin’s article finally pushed me to actually <strong>implement</strong> something…  and that’s when I discovered the need for the <em>other</em> two sub-protocols in WSGI Lite.</p><h4>The Second Protocol: Resource Management</h4><p>See, as I was writing the decorators (called <code>@wsgi2</code> and <code>@wsgi1</code> at the time), I quickly began to notice that the <code>close()</code> part of WSGI was even more of a problem than I previously thought.</p><p>I won’t go into detail here about the specific problems, or the protocol itself, as they’re both laid out in the README file for the wsgi_lite library.  Suffice to say here that under plain WSGI 1, resource closing is fragile because any one piece of middleware can inadvertently break the close() chain.  This is likely more of a problem for WSGI code running on non-refcounting Pythons, but it can cause headaches even on CPython.</p><p>So, in order to solve that problem, I created a new resource closing protocol that allows applications to close multiple resources and to bypass broken WSGI 1 middleware.</p><p>This, I also expect to be a fairly uncontroversial protocol proposal.  The problem it addresses is not widely understood, nor is there a big popular push for it, but it’s an annoying little problem that can bite you in the butt and make debugging difficult, especially on “alternative implementations” of Python.</p><p>However, as I began trying to <em>use</em> this new protocol, and writing the early documentation for it, I discovered even <strong>more</strong> problems with WSGI!</p><p>Specifically, I noticed that it was damn hard to document my new closing protocol in such a way that it could actually be used correctly without having to learn even <strong>more</strong> arbitrary rules about what to call when and where to fetch it from.</p><p>Indeed, I ended up with something that looked <em>just as hard to get right</em>, as WSGI middleware was in the first place!</p><p>And when I looked at it more closely, I saw two things that were going on.</p><p>The first, was that most people don’t realize when you pass a WSGI environment to a WSGI app, it’s <strong>not yours any more</strong>.  The application is allowed to clear it, put junk in it, or whatever.  So you absolutely <strong>cannot</strong> use that environment dictionary once you pass it on.</p><p>And this put the closing protocol in a bit of a bind, because the closing protocol needed to be <em>called late</em> in an app or piece of middleware, but <em>retrieved early</em>.</p><p>So, if you wrote the <em>natural</em> thing, the <strong>obvious</strong> thing, and pulled the closing key out of the environment at the point nearest where you were going to <em>use</em> it, then your code would have a latent bug in it.</p><p>And that’s just <strong>evil</strong>.</p><p>This is the point at which I realized just how much <strong>brain rot</strong> the bare WSGI protocol has in it: there are <strong>lots</strong> of little things like this that will bite you in the butt, <em>punishing</em> you for doing the simple, obvious, straightforward thing.</p><p>And so that’s when I realized that I needed…</p><h4>The Third Protocol: Argument/Extension Binding</h4><p>See, the new resource closing protocol I came up with is not the only WSGI environment extension out there – there are lots of others.  But they share a few potential issues in <strong>common</strong>:</p><ol><li>Being pulled out of the environ at a point where they’re no longer valid,</li><li>Having to write boilerplate to check for their existence, and fall back to something else, and</li><li>Mutually-incompatible decorators provided by libraries to fix problems 1 and 2!</li></ol><p>That is, even if a library provides decorator support for its particular WSGI extension, you generally can’t use more than <strong>one</strong> of them at a time.</p><p>And so, the argument/extension binding protocol fixes this by providing an <strong>argument-level</strong> decoration protocol, to replace function-level decoration as the way to solve problems 1 and 2 in existing libraries.</p><p>The idea here is that instead of trying to use a session decorator from library 1 and an authentication decorator from library 2, you can just use a single decorator with two keyword arguments.</p><p>This idea evolved gradually, as I first wrote a <code>@with_closing</code> decorator specifically to address the resource closing issue, and then noticed what having lots of decorators like that would lead to.  (And, sure enough, existing WSGI library wrappers have mutually-incompatible decorators for these purposes.)</p><p>Anyway, the argument binding protocol is basically a way to map keyword arguments to things that are derived in some way from the request environment.  It could be a parsed form, a session, an authenticated user, a cart…  you name it, you can have it.</p><p>In other words, the idea is once again to have a Schelling Point where libraries can be used <em>collaboratively</em>, instead of having to compete for users.  It also makes it easier for individual users to write one-offs for their particular application.  Writing a WSGI Lite argument binding is a few lines of code over top of whatever kind of request-based object(s) you have in your application, and you can then use them anywhere.</p><p>Or…  and this is the bigger point: you can then <strong>split out</strong> your nifty cart or session or whatever, and make it available to other users as a library, <em>without</em> needing to know dip about decorators.</p><p>And, again, it’s a co-ordination point, because you can say, “Here’s my new session library &#8211; and it supports WSGI Lite argument binding.”  The binding protocol becomes something that libraries have in common, allowing users to focus on functionality instead of screwing around with which color bikeshed the decorator is.</p><p>Now, if you’re not clear on the technical bits of what I’m on about here, the argument binding protocol is explained on the wsgi_lite homepage.  The basic idea, though, is that you can call <code>@lite(keyword1=binding_rule1, keyword2=binding_rule2...)</code>, and bind your function’s keyword arguments to objects like sessions, requests, carts, users, and arbitrary WSGI extensions.  The binding rules can be strings, callables, or sequences of the above, and the first rule that yields a result from the environment gets passed in to your function as a keyword argument.  And if no rule for that keyword yields a result, the keyword doesn’t get passed to your function.</p><p>So, this allows you to use normal Python function argument defaults to fall back on if you don’t get the object you’re looking for, <em>and</em> it allows you to get a standard Python error when one of your arguments goes missing: you don’t need to write code to check for the argument and raise your own error when it’s missing.</p><p>Under Python 3, it might be that the decorator could just use argument annotations to do the same thing (instead of duplicating argument names in the decorator) but I haven’t tried that yet.</p><p>The point, though, is that by defining a binding <strong>protocol</strong>, you can use it in lots of different ways.  Given the protocol I’ve specified, you could go out there right <em>now</em> and write yourself a Python 3 decorator that looks for binding rules in argument annotations, and applies them according to the rules of the binding protocol.  And users of your decorator would immediately be able to use anybody else’s session, request, cart, or whatever other WSGI Lite argument bindings were out there, in their Python 3 argument annotations.</p><p>Likewise, you can, right now, write yourself a binding for your session, request, cart, or whatever objects, and be assured that people will be able to use them with any decorator (or other tool) that uses “WSGI Lite binding rules”.</p><p>Even in tools that haven’t been <em>thought of</em> yet, let alone implemented.</p><p>And that’s the power of a <strong>protocol</strong>, versus a mere library.</p><p>Now, all in all, the argument binding sub-protocol is perhaps the most potentially-controversial part of the WSGI Lite protocol suite.  It’s totally new, and as far as I know, unprecedented in the WSGI world.  And if you’re the developer of a heavyweight WSGI library or framework, it might not seem very important to you.</p><p>However, the point of it isn’t to re-solve a problem you’ve already solved for your own library, or to replace your API.  Rather, it’s a way to allow people to make <em>smaller libraries</em>, by 1) shrinking the unit of reuse to the argument, rather than the decorator, and 2) lowering the entry barrier for a library to be written, by removing the need for a big API or a complex decorator.</p><p>And of course, it also lets you add binding rules on top of your existing big library, to offer users an enticement or “gateway drug” to using the rest of your library.  You can, in effect, begin advertising your library as a <em>catalog of bindings</em>, rather than trying to get people to drink <strong>all</strong> of your library’s cool-aid at once.</p><h4>So, Where Do We Go From Here?</h4><p>Well, at this point, the protocols are out there, but they don’t have any “official” standing, except for my attempt at declaring them “red squares”.  That is, they’re potential points of co-ordination, and they have my backing as a potential “way forward” for the next-generation of WSGI.</p><p>But this doesn’t mean they won’t <em>change</em> between now and any real “official” status (like a PEP).</p><p>My original effort at WSGI – originally called “WCI” – was not very much like WSGI at all.  The fundamental idea in WCI and WSGI was the same, sure, but the final implementation was very different.</p><p>And the same thing might happen with WSGI Lite, too.</p><p>Indeed, I’ve already gotten emails from a couple of big WSGIans about potential changes to WSGI Lite to fix other problems…  and so some things may well happen there.</p><p>Mostly, though, what I want to do with WSGI Lite is create protocols that allow lightweight, <em>collaborative</em> solutions to those problems.</p><p>For example, rather than trying to fix all of the warts in <code>wsgi.input</code> in the core Lite protocol, I’d rather see some proposals for <strong>bindings</strong> that people can use to fix those problems.</p><p>Instead of us trying, yet again, to create the One True Input Object!</p><p>Now, is that really possible with <code>wsgi.input</code>, or any of the other warts that people would like to see fixed in the “next generation” of WSGI?</p><p>I don’t know.</p><p>But I think it’s worth a shot at <em>finding out</em>.  And if there are some clear wins to be had by tweaking the three Lite sub-protocols, or adding some others to the mix, I’m <strong>all ears</strong>.</p><p>These are things that need to be hashed out a bit before the protocols are PEPpable, and yes, perhaps a bit of API bikeshedding may be needed as well.</p><p>And you know what?</p><p>I’m kind of looking forward to it.</p><p>See you on the Web-SIG!</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2011/08/is-wsgi-lite-library-or-protocol-and.html">Is WSGI Lite a Library or a Protocol? (And Why You Should Care)</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2011/08/is-wsgi-lite-library-or-protocol-and.html#comments" rel="replies" thr:count="3" type="text/html"/>
		<link href="https://dirtsimple.org/2011/08/is-wsgi-lite-library-or-protocol-and.html/feed/atom" rel="replies" thr:count="3" type="application/atom+xml"/>
		<thr:total>3</thr:total>
		</entry>
		<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[WSGI Is Dead: Long Live WSGI Lite!]]></title>
		<link href="https://dirtsimple.org/2011/07/wsgi-is-dead-long-live-wsgi-lite.html" rel="alternate" type="text/html"/>
		<id>tag:blogger.com,1999:blog-8674831.post-6410011968893245369</id>
		<updated>2011-08-01T19:57:26Z</updated>
		<published>2011-08-01T00:58:53Z</published>
		<category scheme="https://dirtsimple.org" term="Software Development"/>		<summary type="html"><![CDATA[<p>Almost a decade ago, back when I first proposed the idea of WSGI to the Web-SIG, I had a rather idealistic vision of how WSGI could be a kind of “framework dissolver”.  I envisioned a future in which everything was pluggable, and there would no longer be any reason to have monolithic application frameworks, because [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2011/07/wsgi-is-dead-long-live-wsgi-lite.html">WSGI Is Dead: Long Live WSGI Lite!</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2011/07/wsgi-is-dead-long-live-wsgi-lite.html"><![CDATA[<p>Almost a decade ago, back when I first proposed the idea of WSGI to the Web-SIG, I had a rather idealistic vision of how WSGI could be a kind of “framework dissolver”.  I envisioned a future in which everything was pluggable, and there would no longer be any reason to have monolithic application frameworks, because everything could be done with libraries, middleware, and decorators.</p><p>Alas, that idealistic future didn’t come to pass.  In fact, as far back as 2007, I had already noticed it wasn’t working, and <a href="https://dirtsimple.org/2007/02/wsgi-middleware-considered-harmful.html">proposed an idea for a WSGI 2 protocol</a> that would resolve the problems…  and then proceeded to do nothing for the next few years.  (Well, I’ve been doing <em>other</em> things, like working on setuptools, Chandler, and my own business.  I just wasn’t working on <em>web apps</em> or WSGI!)</p><p>Anyway, last week, Armin Ronacher wrote a great article on his blog called <a href="http://lucumr.pocoo.org/2011/7/27/the-pluggable-pipedream/">WSGI and the Pluggable Pipe Dream</a>, about this very topic.  If you haven’t read it, I urge you to do so, as it provides in-depth coverage of many of WSGI’s dark corners and design decisions that are not widely understood by people who weren’t involved in the original design, or who haven’t spent a lot of time working with it.</p><p>But I was a little disappointed with the end of the article, because Armin’s build-up led me to believe he had a solution to the problems of dealing with crud like start_response, write, close, and all that in WSGI middleware.  But really, his claim ended up being that even if somebody invented something <em>better</em> than WSGI, there would be no way to <strong>replace</strong> it, because of all the investment in the existing protocol.</p><p>So, I decided to <strong>do</strong> something about that.</p><img src="https://dirtsimple.org//2011/07/9163302.jpg" alt="CHALLENGE ACCEPTED!" width="400" height="300" /><p>Introducing <a href="https://github.com/pjeby/wsgi_lite/">WSGI Lite</a>, WSGI’s new younger brother.</p><p>WSGI Lite is a protocol that’s basically the same thing as the “WSGI 2” calling convention I proposed four years ago, and pretty much the same as what other languages’ versions of WSGI use.  There’s no start_response, close, write, or exc_info to mess with, and I even threw in a <em>massively</em> improved way to manage post-request resource release and cleanup operations.</p><p>Now, if WSGI Lite were just a WSGI alternative, Armin’s article would be right: nobody would use it, because it’d be in competition with WSGI, and we’d have to basically “<strong>Shut…  Down…  Everything</strong>”  in order to replace it.</p><p>But the WSGI Lite protocol is actually <em>backwards compatible</em> with WSGI.  You can write code to the WSGI Lite API, and transparently interoperate with existing WSGI servers, apps, and middleware.</p><p>Which means, you don’t have to <em>replace</em> anything; you can just start using it, wherever it’s appropriate or useful to do so.</p><p>All it takes, is two decorators: one to declare an app as being a “lite” app, and one to allow you to call standard WSGI apps using the “lite” calling protocol.  (And, as a special bonus, the decorator you use for new code can also automatically bind environment keys, session/request objects, or other cool things to your app or middleware’s keyword arguments.  It’s <em>tres chic</em>.)</p><p>I’m hoping that this will revitalize the “pluggable pipe dream”, and make it a little less dream, a little more <a href="http://web.archive.org/web/20111004231659/http://svn.colorstudy.com/home/ianb/wsgi-tutorial/diagram-urldispatch.png">pipe</a>.</p><p>So <a href="http://pypi.python.org/pypi/wsgi_lite">try it out</a>, and let me know what you think.</p><p><em>Update: on reflection, the above article is woefully inadequate to explain the actual rationale of the WSGI Lite protocol or its implementation, so I’ve written a</em> <a href="https://dirtsimple.org/2011/08/is-wsgi-lite-library-or-protocol-and.html"><em>follow-up piece</em></a> <em>to cover that.  Check it out!</em></p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2011/07/wsgi-is-dead-long-live-wsgi-lite.html">WSGI Is Dead: Long Live WSGI Lite!</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2011/07/wsgi-is-dead-long-live-wsgi-lite.html#comments" rel="replies" thr:count="4" type="text/html"/>
		<link href="https://dirtsimple.org/2011/07/wsgi-is-dead-long-live-wsgi-lite.html/feed/atom" rel="replies" thr:count="4" type="application/atom+xml"/>
		<thr:total>4</thr:total>
		</entry>
		<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[The simplest(?) way to do tree-based queries in SQL]]></title>
		<link href="https://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html" rel="alternate" type="text/html"/>
		<id>tag:blogger.com,1999:blog-8674831.post-4934975456648782670</id>
		<updated>2014-04-19T16:13:57Z</updated>
		<published>2010-11-06T18:57:28Z</published>
		<category scheme="https://dirtsimple.org" term="Software Development"/>		<summary type="html"><![CDATA[<p>The other day I was looking around at “tree” model libraries for Django, and I noticed that there are an awful lot of algorithms people use to manage hierarchies in SQL out there, but the one that is simplest (at least in my view) seems to not be very widely known at all.There’s the obvious [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html">The simplest(?) way to do tree-based queries in SQL</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html"><![CDATA[<p>The other day I was looking around at “tree” model libraries for Django, and I noticed that there are an awful lot of algorithms people use to manage hierarchies in SQL out there, but the one that is simplest (at least in my view) seems to not be very widely known at all.</p><p>There’s the obvious way of simply giving records a “pointer” (foreign key) referring to their parent.  The upside is, it’s easy and it’s normalized: the data means exactly what it says and there’s no duplication.  The downside is, you can’t really retrieve an entire <em>tree</em> from the database, without doing <strong>lots</strong> of SQL queries.  Likewise if you need to be able to find all the children of X at any moment, or be able check within another query whether any of X’s ancestors are Y.  It really doesn’t work for that sort of thing at all.</p><p>That’s when people start coming up with all sorts of tricks, like storing a path string and using prefix searches (with BETWEEN or LIKE), or storing a beginning and end number (aka the <a href="http://en.wikipedia.org/wiki/Nested_set_model">“nested sets” approach</a>), or having a fixed maximum hierarchy depth and representing the materialized path using individual fields (used in Drupal’s menu system).</p><p>The advantage to these systems is that they don’t take a lot of space, but the disadvantage is that nearly all the maintenance has to be done in the application – often involving quite a few SQL queries!  So, in essence, these approaches trade lots of queries at retrieval time, for lots of queries at update and insert/delete time, and often some additional programming complexity.</p><p>But I don’t think I’ve ever seen an article on my <em>preferred</em> way of managing hierarchies in SQL, and that’s using what I call a <strong>closure table</strong>.</p><h4>Closure Tables</h4><p>A closure table gives you the ability to do all the same sorts of “find me all children of X, to depth N” queries as any of the other methods, just by doing a join against the closure table.</p><p>But the <em>killer</em> feature of the closure table, is that to add or remove a parent-child relationship, you only need to run *one* SQL query – a query so simple that even the least-powerful SQL databases can be configured to run it as a trigger on the main table!</p><p>Let’s take a look at how this works.  A closure table is simply a table that maintains the “transitive closure” of the parent-child relationships in the base table.  So, let’s say you’re modelling a directory structure, and you have a “directory” table, with a foreign key “parent_dir” pointing to each row’s parent directory.</p><p>With this structure, you can only query direct (depth 1) relationships, but by adding a “closure” table with fields for “parent”, “child”, and “depth”, you can represent the hierarchy to whatever depth is present.  So, if directory C is a child of directory B, and directory B is a child of A, then the base table would look like this:</p><table><thead><tr><th>id</th><th>parent_dir</th><th>name</th></tr></thead><tbody><tr><td>1</td><td>0</td><td>A</td></tr><tr><td>2</td><td>1</td><td>B</td></tr><tr><td>3</td><td>2</td><td>C</td></tr></tbody></table><p>And the closure table would look like this:</p><table><thead><tr><th>parent</th><th>child</th><th>depth</th></tr></thead><tbody><tr><td>1</td><td>1</td><td>0</td></tr><tr><td>2</td><td>2</td><td>0</td></tr><tr><td>3</td><td>3</td><td>0</td></tr><tr><td>1</td><td>2</td><td>1</td></tr><tr><td>2</td><td>3</td><td>1</td></tr><tr><td>1</td><td>3</td><td>2</td></tr></tbody></table><p>In other words, the closure table says, “A is a child of itself at depth 0”, “B is a child of A at depth 1”, and “C is a child of A at depth 2”.  The total number of records in the closure table is equal to the number of records in the base table, times the average depth of the tree(s) in the base table.  (That is, each base table row has a row in the closure table, plus one row for each of its parents.)</p><h4>Inserting Links</h4><p>Now wait a minute, you may say.  This looks <em>way</em> more complicated and tricky than a materialized path or even the nested sets thingy.  I mean, how would you even <em>begin</em> to write the code to maintain such a thing?</p><p>Well, to make PARENT_ITEM a parent of CHILD_ITEM, the code looks like this:</p><pre><code class="language-sql">insert into closure(parent, child, depth)
select p.parent, c.child, p.depth+c.depth+1
  from closure p, closure c
 where p.child=PARENT_ITEM and c.parent=CHILD_ITEM
</code></pre><p>In other words, it’s something your average SQL database can do without breaking a sweat. I mean, it’s like baby SQL, for crying out loud. Okay, so maybe <em>deliberately</em> doing a <a href="https://web.archive.org/web/20150316221354/http://www.fluffycat.com/SQL/Cartesian-Joins/">cartesian product join</a> isn’t something you everyday, but every database can still <strong>do</strong> it.</p><p>And it’s not even a particularly performance intensive query! It basically just says, “make every parent of PARENT_ITEM (implicitly including itself) a parent of every child of CHILD_ITEM (again including itself), at the appropriate depth.</p><p>The cost of doing this operation is directly proportional to the size of the subtree under CHILD_ITEM, so if you’re adding a leaf node to the tree, this will simply insert parent entries for the new leaf, and nothing else. If you’re adding a new parent to an existing tree, on the other hand, then it will insert a new row for every node already in the subtree being “adopted”.</p><p>Of course, in other “materialized path” strategies, you’re <em>still</em> paying the same kinds of proportionate maintenance costs to update a deep tree, except that you’re doing string manipulation or resetting a bunch of fields – usually in code that then makes a bunch of SQL queries… and gods help you if your tree is actually <strong>too big to fit in memory</strong>.</p><p>(Even the nested sets model has similar update costs: you can certainly delegate most of the bulk operations to the database, but if you have a frequently-updated, very large tree, the nested sets approach will end up shuffling position pointers a <em>lot</em> more frequently than the closure table will end up with new rows.)</p><p>So how does this query actually work? And how do you delete or update relationships?</p><h4>How This Works</h4><p>Well, the real secret to making the closure table work is the rows with depth 0. Without that little innovation, you’d actually have to do four separate inserts, or a giant union query (yuck!) to add everything you need for a new link.</p><p>Let’s start out with our tables in a “flat” structure, with nobody being a parent of anybody else, but with the (self,self,0) entries already in the closure table:</p><table><thead><tr><th>id</th><th>parent_dir</th><th>name</th></tr></thead><tbody><tr><td>1</td><td>0</td><td>A</td></tr><tr><td>2</td><td>0</td><td>B</td></tr><tr><td>3</td><td>0</td><td>C</td></tr></tbody></table><table><thead><tr><th>parent</th><th>child</th><th>depth</th></tr></thead><tbody><tr><td>1</td><td>1</td><td>0</td></tr><tr><td>2</td><td>2</td><td>0</td></tr><tr><td>3</td><td>3</td><td>0</td></tr></tbody></table><p>Now, if we change the base table to make B into C’s parent:</p><table><thead><tr><th>id</th><th>parent_dir</th><th>name</th></tr></thead><tbody><tr><td>1</td><td>0</td><td>A</td></tr><tr><td>2</td><td>0</td><td>B</td></tr><tr><td>3</td><td>2</td><td>C</td></tr></tbody></table><p>And then run the SELECT part of the link-insertion query with a parent of 2 and a child of 3, we get:</p><table><thead><tr><th>p.parent</th><th>c.child</th><th>p.depth+c.depth+1</th></tr></thead><tbody><tr><td>2</td><td>3</td><td>1</td></tr></tbody></table><p>Resulting in a new closure table entry for the added link:</p><table><thead><tr><th>parent</th><th>child</th><th>depth</th></tr></thead><tbody><tr><td>1</td><td>1</td><td>0</td></tr><tr><td>2</td><td>2</td><td>0</td></tr><tr><td>3</td><td>3</td><td>0</td></tr><tr><td>2</td><td>3</td><td>1</td></tr></tbody></table><p>Okay, that seems easy enough. But what if we now make B a child of A?</p><table><thead><tr><th>id</th><th>parent_dir</th><th>name</th></tr></thead><tbody><tr><td>1</td><td>0</td><td>A</td></tr><tr><td>2</td><td>1</td><td>B</td></tr><tr><td>3</td><td>2</td><td>C</td></tr></tbody></table><p>Now our SELECT (using PARENT_ITEM=1 and CHILD_ITEM=2) returns:</p><table><thead><tr><th>p.parent</th><th>c.child</th><th>p.depth+c.depth+1</th></tr></thead><tbody><tr><td>1</td><td>2</td><td>1</td></tr><tr><td>1</td><td>3</td><td>2</td></tr></tbody></table><p>And our closure table now looks like this:</p><table><thead><tr><th>parent</th><th>child</th><th>depth</th></tr></thead><tbody><tr><td>1</td><td>1</td><td>0</td></tr><tr><td>2</td><td>2</td><td>0</td></tr><tr><td>3</td><td>3</td><td>0</td></tr><tr><td>1</td><td>2</td><td>1</td></tr><tr><td>2</td><td>3</td><td>1</td></tr><tr><td>1</td><td>3</td><td>2</td></tr></tbody></table><p>Voila! Because the closure table contains correct information for every part of the tree that <em>already</em> exists, our query can make use of that information to fill in the rest of the new information that <em>should</em> exist.</p><h4>Removing Links</h4><p>Removing a link works similarly, using a query like this:</p><pre><code class="language-sql">delete link
  from closure p, closure link, closure c
 where p.parent = link.parent and c.child = link.child
   and p.child=PARENT_ITEM    and c.parent=CHILD_ITEM
</code></pre><p>This is the exact same query, just flipped so as to <em>delete</em> the rows instead of inserting them.</p><p>Now, imagine if you hooked these two queries up to triggers: you could simply do whatever operations you want on the base table, and let the database do the rest!</p><p>Of course, you’d need a couple of extra actions when a row was inserted or deleted in the base table: at insert time, you need to insert the (self,self,0) entry in the closure table (followed by an optional link addition if the new row was inserted with a parent), and at deletion time, you need to delete both the self-link, and all the links that depend on it:</p><pre><code class="language-sql">delete link
  from closure p, closure link, closure c, closure to_delete
 where p.parent = link.parent      and c.child = link.child
   and p.child  = to_delete.parent and c.parent= to_delete.child
   and (to_delete.parent=TO_DELETE or to_delete.child=TO_DELETE)
   and to_delete.depth&lt;2 
</code></pre><p>Essentially, this is just a fancy way of doing the earlier link-removal operation for each of the target item’s neighboring links – i.e., ones with depth 0 or 1. (The links with a greater depth are taken care of by the first few lines of the query.)</p><p>So now, you have just a little bit of logic to do in three triggers for your base table, to get this set up, and presto! No additional code needed. Just work on the base table normally, and run any hiearchical queries through the closure table. (And make sure you’ve got unique indexes on (parent, depth, child) and (child, parent, depth), so those queries can really <em>fly</em>.)</p><h4>So Why Aren’t You Doing This Already?</h4><p>Sure, I know, not every database supports triggers… or do they? Sure, maybe if you’re on MySQL…. and it’s still the 1990’s! <em>SQLite</em> has triggers these days, for crying out loud.</p><p>Your database library doesn’t support them? Okay, fine. Write the equivalent of triggers in whatever your library <em>does</em> support – like a post-save signal in Django’s case – and enjoy. (You can probably even set up your closure table as a many-to-many “through” table in Django’s case, though I haven’t actually tried that yet.)</p><p>Really, there are only a few reasons not to use a closure table when hierarchical queries are required, and most of them boil down to, “I have a small tree (i.e.human-readable in its entirety) and I need to display the whole thing in hierarchical order using SORT BY”.</p><p>And even in the application I first used closure tables for (which had tens of thousands of items in various parent-child relationships), there were also some <em>smaller</em> hierarchies that could’ve used a materialized path or nested sets approach, and if I were doing that application over, I’d have probably used them.</p><p>But, if you have a huge set of hierarchical relationships (a large “forest” of large trees), and need to be able to query over the transitive closure (i.e., do “recursive” parent/child lookups from SQL), IMO a closure table is the only way to go. (And if you’re in an “enterprisey” environment where lots of programs touch the data, using triggers or stored procedures to maintain that closure table is a must!)</p><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html">The simplest(?) way to do tree-based queries in SQL</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html#comments" rel="replies" thr:count="33" type="text/html"/>
		<link href="https://dirtsimple.org/2010/11/simplest-way-to-do-tree-based-queries.html/feed/atom" rel="replies" thr:count="33" type="application/atom+xml"/>
		<thr:total>33</thr:total>
		</entry>
		<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[Simplifying prioritized methods in PEAK-Rules]]></title>
		<link href="https://dirtsimple.org/2010/08/simplifying-prioritized-methods-in-peak.html" rel="alternate" type="text/html"/>
		<id>tag:blogger.com,1999:blog-8674831.post-249148837079175194</id>
		<updated>2010-08-11T01:02:44Z</updated>
		<published>2010-08-10T21:39:14Z</published>
		<category scheme="https://dirtsimple.org" term="Software Development"/>		<summary type="html"><![CDATA[<p>Recently, I’ve been scouting around the web for examples of what people have been doing with PEAK-Rules (and the older RuleDispatch package) to get an idea of what else I should put in (if anything) before making the first official release.One of the interesting things I found was a package called prioritized_methods, which advertises itself [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2010/08/simplifying-prioritized-methods-in-peak.html">Simplifying prioritized methods in PEAK-Rules</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2010/08/simplifying-prioritized-methods-in-peak.html"><![CDATA[<p>Recently, I’ve been scouting around the web for examples of what people have been doing with <a href="http://pypi.python.org/pypi/PEAK-Rules">PEAK-Rules</a> (and the older RuleDispatch package) to get an idea of what else I should put in (if anything) before making the first official release.</p><p>One of the interesting things I found was a package called <a href="http://pypi.python.org/pypi/prioritized_methods">prioritized_methods</a>, which advertises itself as a “prioritized” version of PEAK-Rules, and appears to have been used in the ToscaWidgets project at one point.</p><p>Prioritized methods certainly seem like a useful idea, but I was a bit bothered by the specific implementation, because it showed just how weak PEAK-Rules’ extensibility documentation is at this point.</p><p>Really, it shouldn’t be that <strong>hard</strong> to implement manual method priorities in PEAK-Rules.  I mean, prioritized_methods is like 150 lines plus docstrings, it has to define several new method types and decorators to replace those in PEAK-Rules, and if you want to use it with a new method type of your own, you’re already screwed by potential incompatibilities.</p><p>In short, I clearly wasn’t exposing a good enough API or providing good enough examples.  <img src="https://s.w.org/images/core/emoji/11/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p><p>So, there <em>had</em> to be a better way, and in fact I immediately thought of one that ought to be doable in a dozen lines of code or so, that would make a perfect demo for PEAK-Rules’ <a href="http://peak.telecommunity.com/DevCenter/PEAK-Rules/Predicates">predicates module documentation</a>:</p><pre><code class="language-python">from peak.rules import implies, when
from peak.rules.criteria import Test
from peak.rules.predicates import Const, expressionSignature

class priority(int):
    &quot;&quot;&quot;A simple priority&quot;&quot;&quot;

when(implies, (priority, priority))(lambda p1,p2: p1&gt;p2)

@when(expressionSignature,
      &quot;isinstance(expr, Const) and &quot;
      &quot;isinstance(expr.value, priority)&quot;)
def test_for_priority(expr):
    return Test(None, expr.value)
</code></pre><p>What this code does is create an integer subclass called <code>priority</code>, that can then be used in rule definitions, e.g.:</p><pre><code class="language-python">@when(some_func, &quot;isinstance(foo, Bar) and priority(1)&quot;)
</code></pre><p>Then, between two otherwise-identical rules, the one with a priority will win over the one without, or the higher priority will win if both have priorities.</p><p>All you have to do to use it, is import the <code>priority </code> type into the modules where you want to use it. No new decorators or special method types are needed, and it will continue to work with any <strong>new</strong> method types added to PEAK-Rules or defined by third parties!</p><p>Pretty neat, huh?</p><p>There was just one downside to it, and that’s that it didn’t work. <img src="https://s.w.org/images/core/emoji/11/72x72/1f641.png" alt="🙁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p><p>As it happens, PEAK-Rules’ predicate dispatch engine barfed on using None as a test expression (in the <code>Test(None, expr.value)</code> part), and I had to <a href="http://svn.eby-sarna.com/PEAK-Rules/peak/rules/predicates.py?rev=2648&amp;view=diff&amp;r1=2648&amp;r2=2647&amp;p1=PEAK-Rules/peak/rules/predicates.py&amp;p2=/PEAK-Rules/peak/rules/predicates.py">tweak a few lines</a> to make it skip over indexing and code generation for tests on None. But, once that was done, I was able to add a tested version of the above as a <a href="http://peak.telecommunity.com/DevCenter/PEAK-Rules/Predicates#expression-to-predicate-conversion">doctest demo</a>.</p><p>Anyway, if you’re doing anything interesting with PEAK-Rules, or find yourself needing to extend it in some way, I’d love to <a href="http://www.eby-sarna.com/mailman/listinfo/PEAK/">hear from you</a>. Right now, it’s pretty easy for <em>me</em> to add cool features like the one above, but I’m guessing that there are still some gaps in the <a href="http://peak.telecommunity.com/DevCenter/PEAK-Rules">current documentation</a> for anybody <em>else</em> trying to implement nifty new features like the above.</p><p>So, I’m especially interested in any problems you had doing extensions, as well as success stories. (I’d really like to start firming up the extension APIs soon, as well as their docs!)</p><link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/default.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2010/08/simplifying-prioritized-methods-in-peak.html">Simplifying prioritized methods in PEAK-Rules</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2010/08/simplifying-prioritized-methods-in-peak.html#comments" rel="replies" thr:count="8" type="text/html"/>
		<link href="https://dirtsimple.org/2010/08/simplifying-prioritized-methods-in-peak.html/feed/atom" rel="replies" thr:count="8" type="application/atom+xml"/>
		<thr:total>8</thr:total>
		</entry>
		<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[Python Gets Out&#8230;]]></title>
		<link href="https://dirtsimple.org/2008/09/python-gets-out.html" rel="alternate" type="text/html"/>
		<id>tag:blogger.com,1999:blog-8674831.post-8821652646695768784</id>
		<updated>2008-09-06T20:37:08Z</updated>
		<published>2008-09-06T20:19:07Z</published>
		<category scheme="https://dirtsimple.org" term="Software Development"/>		<summary type="html"><![CDATA[<p>Python seems to keep turning up in the most unusual places.  Today I went to the library and borrowed a couple of books on graphic design to assist in making some layout decisions for the book I’m working on.  One was a book I’d read before, Editing By Design, which I’d used to help with [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2008/09/python-gets-out.html">Python Gets Out&#8230;</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2008/09/python-gets-out.html"><![CDATA[<p>Python seems to keep turning up in the most unusual places.  Today I went to the library and borrowed a couple of books on graphic design to assist in making some layout decisions for <a href="http://thinkingthingsdone.com/">the book I’m working on</a>.  One was a book I’d read before, <em>Editing By Design</em>, which I’d used to help with the design of my earlier book, “You, Version 2.0”.  The other was a book called (appropriately enough) “The Layout Book”.  I was skimming through it, when I came across a page with this near the bottom (I’ve elided a few items from the middle):</p><blockquote><p>“Simple is better than complicated.
Quiet is better than loud.
Unobtrusive is better than exciting.
Small is better than large.
…
The obvious is better than that which must be sought.
Few elements are better than many.
A system is better than single elements.”</p></blockquote><p>The block of text was a quote, attributed to one Dieter Rams.  “Wow,” I thought, “I wonder if Tim Peters’s Zen of Python was a play off of this…”</p><p>Then I turn the page.</p><p>At the very top of a collection of “methodologies”, I see:</p><blockquote><p>“Python philosophy</p><p>Derived from computer programming, the main points of the Python approach were presented by developer Tim Peters in <em>The Zen of Python</em>.   Key points include: beautiful is better than ugly, explicit is better than implicit…“</p></blockquote><p>Small world, eh?</p><p>–PJ</p><p>P.S. I’m still amused by the mentions of Python in Charles Stross’s science fiction novels, especially the one where the future hero is described as doing his game programming work in Python 3000, almost as if it were some highly-futuristic language.  <img src="https://s.w.org/images/core/emoji/11/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p><p>P.P.S. In case you hadn’t guessed, the reason I’m not doing more programming (or blogging about programming) right now is because I’m working on the book…  in which, incidentally, I’m attempting to take a truly <em>algorithmic</em> approach – not to mention a highly <em>test-driven</em> one – to such diverse matters as motivation, belief, creativity, time management, and even optimism.</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2008/09/python-gets-out.html">Python Gets Out&#8230;</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2008/09/python-gets-out.html#comments" rel="replies" thr:count="4" type="text/html"/>
		<link href="https://dirtsimple.org/2008/09/python-gets-out.html/feed/atom" rel="replies" thr:count="4" type="application/atom+xml"/>
		<thr:total>4</thr:total>
		</entry>
		<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[reddit &#8211; now with PJE inside]]></title>
		<link href="https://dirtsimple.org/2008/02/reddit-now-with-pje-inside.html" rel="alternate" type="text/html"/>
		<id>tag:blogger.com,1999:blog-8674831.post-3323028151163809030</id>
		<updated>2008-02-23T18:40:39Z</updated>
		<published>2008-02-23T18:32:06Z</published>
		<category scheme="https://dirtsimple.org" term="Software Development"/>		<summary type="html"><![CDATA[<p>Until I saw this neat traceback from the innards of reddit, the success of WSGI and eggs was a lot more abstract.  But now, it appears they’ve got some street cred (along with Pylons, Paste, Beaker, and flup, it looks like).OTOH, since reddit was first built with Lisp and then rebuilt with web.py, (making this [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2008/02/reddit-now-with-pje-inside.html">reddit &#8211; now with PJE inside</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2008/02/reddit-now-with-pje-inside.html"><![CDATA[<p>Until I saw this <a href="http://img46.imageshack.us/img46/6994/72691639kt1.png">neat traceback from the innards of reddit</a>, the success of <a href="http://www.python.org/dev/peps/pep-0333/">WSGI</a> and <a href="http://peak.telecommunity.com/DevCenter/setuptools">eggs</a> was a lot more abstract.  But now, it appears they’ve got some street cred (along with Pylons, Paste, Beaker, and flup, it looks like).</p><p>OTOH, since <a href="http://reddit.com/">reddit</a> was first built with Lisp and then rebuilt with web.py, (making this version 3), and since now they’ve gone all mainstream and “sold out” to Conde Nast, maybe that means my work is “corporate” and “enterprisey”, now, instead.  <img src="https://s.w.org/images/core/emoji/11/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2008/02/reddit-now-with-pje-inside.html">reddit &#8211; now with PJE inside</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2008/02/reddit-now-with-pje-inside.html#comments" rel="replies" thr:count="1" type="text/html"/>
		<link href="https://dirtsimple.org/2008/02/reddit-now-with-pje-inside.html/feed/atom" rel="replies" thr:count="1" type="application/atom+xml"/>
		<thr:total>1</thr:total>
		</entry>
		<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[The Library Paradox]]></title>
		<link href="https://dirtsimple.org/2008/02/library-paradox.html" rel="alternate" type="text/html"/>
		<id>tag:blogger.com,1999:blog-8674831.post-4437055276532659016</id>
		<updated>2008-02-17T16:01:28Z</updated>
		<published>2008-02-17T15:49:36Z</published>
		<category scheme="https://dirtsimple.org" term="Software Development"/>		<summary type="html"><![CDATA[<p>Every so often, I see a new package listed on the Python Package Index that claims – in its tag line, no less – that it offers some feature “without external dependencies”.The authors of such packages must think it’s a truly valuable feature, to list it in the tag line (“description” field of their setup [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2008/02/library-paradox.html">The Library Paradox</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2008/02/library-paradox.html"><![CDATA[<p>Every so often, I see a new package listed on the <a href="http://pypi.python.org/pypi">Python Package Index</a> that claims – in its <strong>tag line</strong>, no less – that it offers some feature “without external dependencies”.</p><p>The authors of such packages must think it’s a truly valuable feature, to list it in the tag line (“description” field of their setup script).</p><p>But I’m a little confused by why they’re uploading it to the Cheeseshop.  After all, anybody who believes that a lack of dependencies is <strong>good</strong>…  isn’t going to be able to use it!  <img src="https://s.w.org/images/core/emoji/11/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p><p>And anyone who doesn’t care that much about dependencies (perhaps because they use <a href="http://pypi.python.org/pypi/setuptools">setuptools</a>?) was probably already using whatever package the new package is intended to replace.</p><p>Sure, if the package also offers some other features, a better API, or something like that, it gives people more choices, encourages competition and all that other good stuff.  And I certainly don’t want to discourage anyone from uploading useful things to PyPI.</p><p>I’m just puzzled by the idea of advertising that your package has no external dependencies, when, as far as anybody <em>else</em> is conerned, it <strong>is</strong> an external dependency.  Seems like that space could be better used to promote whatever <em>other</em> benefits the library brings.</p><p>Just one of those “things that make you go hmmm” I suppose.</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2008/02/library-paradox.html">The Library Paradox</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2008/02/library-paradox.html#comments" rel="replies" thr:count="9" type="text/html"/>
		<link href="https://dirtsimple.org/2008/02/library-paradox.html/feed/atom" rel="replies" thr:count="9" type="application/atom+xml"/>
		<thr:total>9</thr:total>
		</entry>
		<entry>
		<author>
			<name>PJ Eby</name>
					</author>
		<title type="html"><![CDATA[Rumors of Chandler&#8217;s Death Are Greatly Exaggerated]]></title>
		<link href="https://dirtsimple.org/2008/01/rumors-of-chandler-death-are-greatly.html" rel="alternate" type="text/html"/>
		<id>tag:blogger.com,1999:blog-8674831.post-1621791441526518606</id>
		<updated>2008-01-25T01:48:24Z</updated>
		<published>2008-01-25T00:37:51Z</published>
		<category scheme="https://dirtsimple.org" term="Software Development"/>		<summary type="html"><![CDATA[<p>I don’t usually like to blog about my client work, but in this case I’ll make an exception, since so many other people are blogging about it who don’t have any idea what they’re talking about.A lot of these people, it seems, think that the Chandler project is dead, dying, or a “failure” of some [&#8230;]</p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2008/01/rumors-of-chandler-death-are-greatly.html">Rumors of Chandler&#8217;s Death Are Greatly Exaggerated</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></summary>
		<content type="html" xml:base="https://dirtsimple.org/2008/01/rumors-of-chandler-death-are-greatly.html"><![CDATA[<p>I don’t usually like to blog about my client work, but in this case I’ll make an exception, since so many other people are blogging about it who don’t have any idea what they’re talking about.</p><p>A lot of these people, it seems, think that <a href="http://chandlerproject.org/">the Chandler project</a> is dead, dying, or a “failure” of some kind.  And that’s simply not true.</p><p>Could the project have delivered more, in less time?  Sure, absolutely.</p><p>Does it have anything to do with the tools used?  Absolutely not.</p><p>Is the project dead?  Not at all.</p><p>Did it achieve its original goals?  No.</p><p>Is it likely to achieve its original goals?  I’m inclined to say no.</p><p>Does that matter?  Hardly!</p><p>Why?  Because in addition to creating a nice desktop application that:</p><ul><li>does online/offline calendars with overlays, recurrence and timezone support, date parsing, etc.</li><li>has an extensible sharing framework that allows peer-to-peer or server sync with a variety of protocols, including CalDAV and gData</li><li>allows plugins to extend the data model and include that data in peer and server sharing</li><li>has an Eclipse-like plugin model allowing extenders and extendees with sophisticated UI extensibility</li></ul><p><strong>and</strong> a nice CalDAV server with an AJAX UI, the Chandler project has <strong>also</strong> funded (through paid developer time) a lot of open source libraries and tools, especially for Python.  Here’s a <strong>partial</strong> list of other projects that are or were funded by Chandler, in whole or in part:</p><ul><li>
<a href="http://peak.telecommunity.com/DevCenter/setuptools">setuptools</a> and <a href="http://peak.telecommunity.com/DevCenter/EasyInstall">EasyInstall</a>
</li><li>
<a href="http://windmill.osafoundation.org/">Windmill</a>
</li><li>
<a href="http://pylucene.osafoundation.org/">PyLucene</a>
</li><li>
<a href="http://pyicu.osafoundation.org/">PyICU</a>
</li><li>
<a href="http://svn.osafoundation.org/pylucene/trunk/jcc/jcc/README">jcc</a>
</li><li>
<a href="http://chandlerproject.org/bin/view/Projects/ZanshinProject">zanshin</a>
</li><li>
<a href="http://pypi.python.org/pypi/simplegeneric">simplegeneric</a>
</li><li>
<a href="http://pypi.python.org/pypi/vobject">vobject</a>
</li><li>
<a href="http://pypi.python.org/pypi/Trellis">Trellis</a>
</li><li>
<a href="http://www.python.org/dev/peps/pep-0342/">PEP 342</a> and related features of Python 2.5</li><li>
<a href="http://wxpython.org/">wxPython</a>
</li><li>
<a href="http://chandlerproject.org/Projects/MeTooCrypto">m2crypto</a>
</li></ul><p>I’m sure I’ve missed some, even among the things that I personally worked on.</p><p>Anyway, the point is that between the client, server, and libraries, the Chandler project has produced quite a lot of working code, all of which would remain useful and beneficial to the community,  <em>even if the organization had already been disbanded</em>.</p><p>But it <strong>hasn’t</strong> disbanded.  On Tuesday I’ll be in San Francisco, meeting with the other members of the team, as we hash out our strategy for moving forward.  It is certainly <em>possible</em> that we’ll decide to just wrap up the outstanding work on bug fixes, quality improvement, and so on for the existing packages, and not try to continue past the end of this year.  It’s also possible that we’ll decide to push forward with new feature work, or focus on integrating our cool calendar/plugin platform with other open source applications.  Really, there are quite a few possibilities there.</p><p>What a lot of people outside <a href="http://osafoundation.org/">OSAF</a> don’t get about this is that the re-org is a <strong>good</strong> thing.  Don’t get me wrong &#8211; it’s not so good for the people who got laid off.  But for the project, it was a godsend.</p><p>See, out of all the junk that people have been writing for years and years about the project, almost nobody has actually seen what the <em>real</em> problem is, why Chandler didn’t get anywhere near the original, highly-ambitious goals.</p><p>Sure, people have pointed fingers at lots of things, and the idea that there was plenty of time and resources with no hard deadlines is often brought up as a culprit.  But that’s not quite right, either.</p><p>Having worked on, in, and around the project for about three years now, I can tell you quite simply what the problem was, and why the re-org fixes that problem.</p><p>There was <strong>no objective basis for decision-making</strong>.</p><p>It’s that simple, really.  Without an objective basis, there was no way to argue from anything except opinion, with nobody’s opinion being more important than anyone else’s.  There was no benevolent dictator but Mitch, and Mitch had already stopped being available day-to-day before I even started working for them.  (And I’ve heard that even when he <em>was</em> the benevolent dictator, he was perhaps sometimes a bit <strong>too</strong> benevolent – i.e., inclined to just let people choose their own direction/vision for what the project was going to be.)</p><p>Thus, there was no unified design, architecture, vision, nothing.  We had fiefdoms, not because anybody wanted to shut anybody else out, but because the natural response of a good developer faced with chaos is to find a way to organize the part that he or she can deal with.  It was easier for each person to just go and focus on the things he or she cared about, than to try to build consensus in the absence of an objective idea of what “success” was supposed be.</p><p>Now, you can point to inadequate specification, lack of constraints, and all sorts of other contributing factors as to <strong>why</strong> there was no objective criteria for success.  But to me, those aren’t really central.  You could have every single one of those things correct, for example, and <em>still</em> find some <strong>other</strong> way to create a culture that lacks objective criteria!</p><p>And it’s the lack of these common, objective criteria that does you in, regardless of <strong>why</strong> the criteria are lacking.  Without them, you can’t really have productive discussions or planning, whenever the necessary action crosses organizational boundaries.  (Since different sub-groups will have their own views and criteria, with no <strong>common</strong> criteria to sync against.)</p><p>Anyway, next week, we’re actually going to sit down and work on <strong>defining</strong> some objective criteria for the Chandler project as a whole, going forward.  Those criteria may not be what Mitch originally had in mind, and they may be considerably less ambitious.  But, my sincere hope is that they will be sufficiently objective, to allow us a chance at achieving them this year.</p><p>So, if and when the project is <em>really</em> dead, we’ll certainly <a href="http://www.imdb.com/title/tt0071853/quotes#qt0256269">say so</a>.  In the meantime, IMO, the obituaries are more than a little premature.  We’re only <a href="http://www.mtholyoke.edu/~ebarnes/python/dead-parrot.htm">pinin’ for some criteria</a>, you see.  <img src="https://s.w.org/images/core/emoji/11/72x72/1f609.png" alt="😉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p>The post <a rel="nofollow" href="https://dirtsimple.org/2008/01/rumors-of-chandler-death-are-greatly.html">Rumors of Chandler&#8217;s Death Are Greatly Exaggerated</a> appeared first on <a rel="nofollow" href="https://dirtsimple.org">dirtSimple.org</a>.</p>
]]></content>
			<link href="https://dirtsimple.org/2008/01/rumors-of-chandler-death-are-greatly.html#comments" rel="replies" thr:count="3" type="text/html"/>
		<link href="https://dirtsimple.org/2008/01/rumors-of-chandler-death-are-greatly.html/feed/atom" rel="replies" thr:count="3" type="application/atom+xml"/>
		<thr:total>3</thr:total>
		</entry>
	</feed>