<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	>
<channel>
	<title>Comments on: Opening Python Classes</title>
	<atom:link href="http://blog.ianbicking.org/2007/08/08/opening-python-classes/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/</link>
	<description></description>
	<pubDate>Tue, 06 Jan 2009 13:54:25 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Martin Aspeli</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-139</link>
		<dc:creator>Martin Aspeli</dc:creator>
		<pubDate>Mon, 13 Aug 2007 11:38:02 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-139</guid>
		<description>"About the incompatibilities argument - you’re right it would be problematic to patch around this, but I don’t believe it’s a problem of the language, but rather of packaging. If those time comprehensions were packaged separately (or there would be a method to cherry-pick in the require call) you could easily exclude them from the import and define your own versions. In the way or another - it’s not the problem with open classes, it’s just an inconvenient way DHH bundled different things together into active support. And remember you’d have to face those problems in any other language as well - messing with other modules internals is risky, no less in Python than in Ruby."

No, it's a problem of the language. Or rather, of the culture of the language and the way people use it. It's infeasible in any language to have import/require statements that are so detailed you need to know lots and lots of detail about each module. If you had to "require" the "days" syntax and the "ago" syntax and also the "forwards" but not the "backwards" because you needed the one from module "foo" but not from "bar"... well, you'd spend more time working out what to import than you'd spend writing useful code. In general, importing a module from which you only actually need a subset should not have bad side-effects. That places an unnecessary burden on both the author and the user of the module.

Like people have pointed out, you *can* do this in all kinds of languages, including Python, but in Python this kind of thing is frowned upon: monkey patching is a necessary evil that you do in moderation and aim to refactor away (for the most part).

Predictability has a lot of benefits. I *hate* languages (like VB) that make parentheses optional in most cases, because it's hard to see what's a function and you end up having to learn various special cases about when something is required and when it's not. That doesn't make things easier, it makes them confusing and inconsistent. People who write code learn (either explicitly or implicitly) the underlying structure of the lanaguage (much like for a natural language) and then intuitively understand how to apply that structure to new problems that are like ones they've seen before. The fewer rules and more internally consistent they are, the more predictable the language and ultimately the less time the developer wastes on debugging things that don't work the way he/she thinks it should work.</description>
		<content:encoded><![CDATA[<p>&#8220;About the incompatibilities argument - you’re right it would be problematic to patch around this, but I don’t believe it’s a problem of the language, but rather of packaging. If those time comprehensions were packaged separately (or there would be a method to cherry-pick in the require call) you could easily exclude them from the import and define your own versions. In the way or another - it’s not the problem with open classes, it’s just an inconvenient way DHH bundled different things together into active support. And remember you’d have to face those problems in any other language as well - messing with other modules internals is risky, no less in Python than in Ruby.&#8221;</p>

<p>No, it&#8217;s a problem of the language. Or rather, of the culture of the language and the way people use it. It&#8217;s infeasible in any language to have import/require statements that are so detailed you need to know lots and lots of detail about each module. If you had to &#8220;require&#8221; the &#8220;days&#8221; syntax and the &#8220;ago&#8221; syntax and also the &#8220;forwards&#8221; but not the &#8220;backwards&#8221; because you needed the one from module &#8220;foo&#8221; but not from &#8220;bar&#8221;&#8230; well, you&#8217;d spend more time working out what to import than you&#8217;d spend writing useful code. In general, importing a module from which you only actually need a subset should not have bad side-effects. That places an unnecessary burden on both the author and the user of the module.</p>

<p>Like people have pointed out, you <em>can</em> do this in all kinds of languages, including Python, but in Python this kind of thing is frowned upon: monkey patching is a necessary evil that you do in moderation and aim to refactor away (for the most part).</p>

<p>Predictability has a lot of benefits. I <em>hate</em> languages (like VB) that make parentheses optional in most cases, because it&#8217;s hard to see what&#8217;s a function and you end up having to learn various special cases about when something is required and when it&#8217;s not. That doesn&#8217;t make things easier, it makes them confusing and inconsistent. People who write code learn (either explicitly or implicitly) the underlying structure of the lanaguage (much like for a natural language) and then intuitively understand how to apply that structure to new problems that are like ones they&#8217;ve seen before. The fewer rules and more internally consistent they are, the more predictable the language and ultimately the less time the developer wastes on debugging things that don&#8217;t work the way he/she thinks it should work.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Jim</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-117</link>
		<dc:creator>Jim</dc:creator>
		<pubDate>Fri, 10 Aug 2007 08:06:34 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-117</guid>
		<description>&#62; Optional parentheses are actually very useful

Do you really mean that though?  *Useful*?  You may very well *prefer* them, but unless they actually provide functionality, they aren't *useful*.</description>
		<content:encoded><![CDATA[<p>&gt; Optional parentheses are actually very useful</p>

<p>Do you really mean that though?  <em>Useful</em>?  You may very well <em>prefer</em> them, but unless they actually provide functionality, they aren&#8217;t <em>useful</em>.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Boddie</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-115</link>
		<dc:creator>Paul Boddie</dc:creator>
		<pubDate>Thu, 09 Aug 2007 22:57:03 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-115</guid>
		<description>I'm not arguing about whether Lisp or Ruby work, but whether more flexible syntax plus guesswork on the part of the language plus environment make for a sane DSL or a sane environment.

I guess it's just a case of "not in my Python" on my part, but I'm tired of seeing excuses for DSLs really amounting to the fact that people need new toys to be bothered to write new libraries. It's not as if we're using Java where patterns and boilerplate are needed all over the place: you can get quite far with Python, even if you need to actually write Python code - shock horror!

Seeing inline dialects in code reminds me of things like Pro*C Embedded SQL, although DSL proponents would have you write the SQL in some bizarre variant of Python - something which you can see in various Python projects, in fact. A diversity of languages is a good thing, I agree, but I dispute the DSL movement's emphasis on where the diversity should be.</description>
		<content:encoded><![CDATA[<p>I&#8217;m not arguing about whether Lisp or Ruby work, but whether more flexible syntax plus guesswork on the part of the language plus environment make for a sane DSL or a sane environment.</p>

<p>I guess it&#8217;s just a case of &#8220;not in my Python&#8221; on my part, but I&#8217;m tired of seeing excuses for DSLs really amounting to the fact that people need new toys to be bothered to write new libraries. It&#8217;s not as if we&#8217;re using Java where patterns and boilerplate are needed all over the place: you can get quite far with Python, even if you need to actually write Python code - shock horror!</p>

<p>Seeing inline dialects in code reminds me of things like Pro*C Embedded SQL, although DSL proponents would have you write the SQL in some bizarre variant of Python - something which you can see in various Python projects, in fact. A diversity of languages is a good thing, I agree, but I dispute the DSL movement&#8217;s emphasis on where the diversity should be.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michał Kwiatkowski</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-114</link>
		<dc:creator>Michał Kwiatkowski</dc:creator>
		<pubDate>Thu, 09 Aug 2007 20:57:24 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-114</guid>
		<description>Paul,

Optional parentheses are actually very useful, I use them all the time while hacking in [ipython](http://ipython.scipy.org/) ;-).

*just so they can lay out their code in a way which looks like some prose in a natural language or another language, but is really a combination of coincidences and side-effects*

Ruby works. Really. So does Lisp. It's up to a programmer to properly use language capabilities. You can write beautiful code in C/Python/Ruby/Lisp/whatever, but it's completely up to your skills if you shoot yourself in the foot or not. Some APIs (or DSLs if you like) people write in Ruby are in fact *a combination of coincidences and side-effects*, but most of them are not. It's really not that different from Python or any other language.

You agree on the usefulness of DSLs - why not have the ability to program them in the same language as the rest of your application? Why force the programmer to design/learn new language while he is already comfortable with the one he uses? Messing with built-in classes is risky, sure, but a programmer should know that already. Things shouldn't be hard to implement just to scare the clueless newbies (they will misuse the language in a way or another).

Now just don't get me wrong. I believe Python has much of its value in its purity. I personally like predictability Python brings, because it means I can easier understand and hack on other people's code. It's really a great language to maintain code in. That means I also would strongly reject ruby-ish changes to Python. It's a different language than Ruby and there is value in this. At the same time I really like the way you can quickly try out DSL/API ideas in Ruby (or Smalltalk/Lisp for that matter). There's a place for both Python and Ruby in this world and there's no point in saying that people using the other one are crazy/uneducated/stupid. There are different needs and so there are different tools to satisfy them.</description>
		<content:encoded><![CDATA[<p>Paul,</p>

<p>Optional parentheses are actually very useful, I use them all the time while hacking in <a href="http://ipython.scipy.org/">ipython</a> ;-).</p>

<p><em>just so they can lay out their code in a way which looks like some prose in a natural language or another language, but is really a combination of coincidences and side-effects</em></p>

<p>Ruby works. Really. So does Lisp. It&#8217;s up to a programmer to properly use language capabilities. You can write beautiful code in C/Python/Ruby/Lisp/whatever, but it&#8217;s completely up to your skills if you shoot yourself in the foot or not. Some APIs (or DSLs if you like) people write in Ruby are in fact <em>a combination of coincidences and side-effects</em>, but most of them are not. It&#8217;s really not that different from Python or any other language.</p>

<p>You agree on the usefulness of DSLs - why not have the ability to program them in the same language as the rest of your application? Why force the programmer to design/learn new language while he is already comfortable with the one he uses? Messing with built-in classes is risky, sure, but a programmer should know that already. Things shouldn&#8217;t be hard to implement just to scare the clueless newbies (they will misuse the language in a way or another).</p>

<p>Now just don&#8217;t get me wrong. I believe Python has much of its value in its purity. I personally like predictability Python brings, because it means I can easier understand and hack on other people&#8217;s code. It&#8217;s really a great language to maintain code in. That means I also would strongly reject ruby-ish changes to Python. It&#8217;s a different language than Ruby and there is value in this. At the same time I really like the way you can quickly try out DSL/API ideas in Ruby (or Smalltalk/Lisp for that matter). There&#8217;s a place for both Python and Ruby in this world and there&#8217;s no point in saying that people using the other one are crazy/uneducated/stupid. There are different needs and so there are different tools to satisfy them.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Boddie</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-113</link>
		<dc:creator>Paul Boddie</dc:creator>
		<pubDate>Thu, 09 Aug 2007 19:24:16 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-113</guid>
		<description>Michal, Ian: They may seem like strong words, but the Ruby flavour of DSLs (which some people argue are not really proper DSLs) tends to lead people to suggest things like making parentheses optional for function calls in Python, just so they can lay out their code in a way which looks like some prose in a natural language or another language, but is really a combination of coincidences and side-effects. Meanwhile, with pyparsing and similar tools, how hard would it be for such people to write a proper parser for a proper language?

Listen to this podcast for some deeper thought into DSLs:

http://www.se-radio.net/index.php?post_id=211178

And take a look at EasyExtend for a more convincing Python-related approach:

http://www.fiber-space.de/EasyExtend/doc/EE.html

P.S. Apologies for the ASCIIfication of your name, erm, Michal - Ian's software doesn't like the last letter of your name, preferring to substitute it with another character which it won't let me reproduce either.</description>
		<content:encoded><![CDATA[<p>Michal, Ian: They may seem like strong words, but the Ruby flavour of DSLs (which some people argue are not really proper DSLs) tends to lead people to suggest things like making parentheses optional for function calls in Python, just so they can lay out their code in a way which looks like some prose in a natural language or another language, but is really a combination of coincidences and side-effects. Meanwhile, with pyparsing and similar tools, how hard would it be for such people to write a proper parser for a proper language?</p>

<p>Listen to this podcast for some deeper thought into DSLs:</p>

<p><a href="http://www.se-radio.net/index.php?post&#95;id=211178" rel="nofollow">http://www.se-radio.net/index.php?post_id=211178</a></p>

<p>And take a look at EasyExtend for a more convincing Python-related approach:</p>

<p><a href="http://www.fiber-space.de/EasyExtend/doc/EE.html" rel="nofollow">http://www.fiber-space.de/EasyExtend/doc/EE.html</a></p>

<p>P.S. Apologies for the ASCIIfication of your name, erm, Michal - Ian&#8217;s software doesn&#8217;t like the last letter of your name, preferring to substitute it with another character which it won&#8217;t let me reproduce either.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: fijal</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-112</link>
		<dc:creator>fijal</dc:creator>
		<pubDate>Thu, 09 Aug 2007 18:00:27 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-112</guid>
		<description>Hum. we do have such a thing for in-house use in pypy.

You say:

    class SomeClass(extendable):
      def one_method(self):
        pass

    class __extend__(SomeClass):
      def second_method(self):
        pass
      
and just works (by metaclass trick), doesn't work for builtin types.</description>
		<content:encoded><![CDATA[<p>Hum. we do have such a thing for in-house use in pypy.</p>

<p>You say:</p>

<pre><code>class SomeClass(extendable):
  def one_method(self):
    pass

class __extend__(SomeClass):
  def second_method(self):
    pass
</code></pre>

<p>and just works (by metaclass trick), doesn&#8217;t work for builtin types.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michał Kwiatkowski</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-111</link>
		<dc:creator>Michał Kwiatkowski</dc:creator>
		<pubDate>Thu, 09 Aug 2007 16:05:44 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-111</guid>
		<description>Actually `7.days.ago` will evaluate to a Time object, so it's not equivalent to `time.time() - 7*24*60*60` (which is an integer in Python).

Methods will be there if you `require 'active_support'` at the top of your program or you use Rails (which imports active support for you), it's that easy. You don't expect to get datetime class in Python without importing datetime module, do you?

You **can** change them, because (as you found out) you know where they are. Look at `ActiveSupport::CoreExtensions::Numeric::Time` and override methods that interests you.

About the incompatibilities argument - you're right it would be problematic to patch around this, but I don't believe it's a problem of the language, but rather of packaging. If those time comprehensions were packaged separately (or there would be a method to cherry-pick in the require call) you could easily exclude them from the import and define your own versions. In the way or another - it's not the problem with open classes, it's just an inconvenient way DHH bundled different things together into active support. And remember you'd have to face those problems in any other language as well - messing with other modules internals is risky, no less in Python than in Ruby.</description>
		<content:encoded><![CDATA[<p>Actually <code>7.days.ago</code> will evaluate to a Time object, so it&#8217;s not equivalent to <code>time.time() - 7*24*60*60</code> (which is an integer in Python).</p>

<p>Methods will be there if you <code>require 'active_support'</code> at the top of your program or you use Rails (which imports active support for you), it&#8217;s that easy. You don&#8217;t expect to get datetime class in Python without importing datetime module, do you?</p>

<p>You <strong>can</strong> change them, because (as you found out) you know where they are. Look at <code>ActiveSupport::CoreExtensions::Numeric::Time</code> and override methods that interests you.</p>

<p>About the incompatibilities argument - you&#8217;re right it would be problematic to patch around this, but I don&#8217;t believe it&#8217;s a problem of the language, but rather of packaging. If those time comprehensions were packaged separately (or there would be a method to cherry-pick in the require call) you could easily exclude them from the import and define your own versions. In the way or another - it&#8217;s not the problem with open classes, it&#8217;s just an inconvenient way DHH bundled different things together into active support. And remember you&#8217;d have to face those problems in any other language as well - messing with other modules internals is risky, no less in Python than in Ruby.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-110</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Thu, 09 Aug 2007 15:35:33 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-110</guid>
		<description>There is, however, lots of room to bash &lt;code&gt;7.days&lt;/code&gt;, since I believe it is equal to 7x24x60x60==604800.  That is, it doesn't even return any kind of time delta object, it just converts a number of days to a number of seconds with no units.  Adding &lt;code&gt;.ago&lt;/code&gt; it becomes equivalent to &lt;code&gt;time.time() - 7\*24\*60\*60&lt;/code&gt;.

All of which is fine for some code you hack out.  Maybe there wasn't a good time/time-delta object in Ruby when this code was written.  It would certainly have been a poor choice to have fixed *that* problem when DHH was initially writing Rails.  But because of the *way* in which this was implemented it can't be changed, you can't really tell where it comes from (&lt;code&gt;ActiveSupport::CoreExtensions::Numeric::Time&lt;/code&gt;, it turns out), and now you can neither really be sure the methods will be there (they'll only be there if you are using Rails), nor can you add your own improved methods without causing all kinds of frustrating incompatibilities for yourself and everyone else.</description>
		<content:encoded><![CDATA[<p>There is, however, lots of room to bash <code>7.days</code>, since I believe it is equal to 7&#215;24x60&#215;60==604800.  That is, it doesn&#8217;t even return any kind of time delta object, it just converts a number of days to a number of seconds with no units.  Adding <code>.ago</code> it becomes equivalent to <code>time.time() - 7&#42;24&#42;60&#42;60</code>.</p>

<p>All of which is fine for some code you hack out.  Maybe there wasn&#8217;t a good time/time-delta object in Ruby when this code was written.  It would certainly have been a poor choice to have fixed <em>that</em> problem when DHH was initially writing Rails.  But because of the <em>way</em> in which this was implemented it can&#8217;t be changed, you can&#8217;t really tell where it comes from (<code>ActiveSupport::CoreExtensions::Numeric::Time</code>, it turns out), and now you can neither really be sure the methods will be there (they&#8217;ll only be there if you are using Rails), nor can you add your own improved methods without causing all kinds of frustrating incompatibilities for yourself and everyone else.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Michał Kwiatkowski</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-109</link>
		<dc:creator>Michał Kwiatkowski</dc:creator>
		<pubDate>Thu, 09 Aug 2007 15:24:09 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-109</guid>
		<description>*Ah yes, domain-specific languages on the cheap: the source of many requests for changes to the Python language, just so people who can’t write parsers can pretend to almost write English or some other natural language directly in their programs.*

Why such strong words? Even people who **can** write parsers would probably not do so in Python for implementation of those kind of language enhancements, because it would be time expensive, inconvenient, non-standard, etc. In Ruby it's much easier to extend the language itself, which in part gives you more freedom in designing API for specific needs (like date comprehensions in the `7.days.ago` example). This power comes with a cost. Sometimes you want to pay it and sometimes not, so there's a place for both Python and Ruby in this world. No reason to bash one or the other.</description>
		<content:encoded><![CDATA[<p><em>Ah yes, domain-specific languages on the cheap: the source of many requests for changes to the Python language, just so people who can’t write parsers can pretend to almost write English or some other natural language directly in their programs.</em></p>

<p>Why such strong words? Even people who <strong>can</strong> write parsers would probably not do so in Python for implementation of those kind of language enhancements, because it would be time expensive, inconvenient, non-standard, etc. In Ruby it&#8217;s much easier to extend the language itself, which in part gives you more freedom in designing API for specific needs (like date comprehensions in the <code>7.days.ago</code> example). This power comes with a cost. Sometimes you want to pay it and sometimes not, so there&#8217;s a place for both Python and Ruby in this world. No reason to bash one or the other.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2007/08/08/opening-python-classes/comment-page-1/#comment-108</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Thu, 09 Aug 2007 15:06:27 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2007/08/08/opening-python-classes/#comment-108</guid>
		<description>At one point I got into a small argument with some guy about how I thought &lt;code&gt;"markdown string".to_html&lt;/code&gt; was a really stupid idea, and he just thought it was obvious and wonderful, and that I clearly didn't understand object oriented programming.

I think it's when people try to tell me about how I don't understand object oriented programming (because how could someone understand such things if they use Python?) that gets me a bit testy.

ActiveResource's Hash.to_xml method is similarly nutty, as though there was just some canonical way to turn any hash into an XML structure.</description>
		<content:encoded><![CDATA[<p>At one point I got into a small argument with some guy about how I thought <code>"markdown string".to_html</code> was a really stupid idea, and he just thought it was obvious and wonderful, and that I clearly didn&#8217;t understand object oriented programming.</p>

<p>I think it&#8217;s when people try to tell me about how I don&#8217;t understand object oriented programming (because how could someone understand such things if they use Python?) that gets me a bit testy.</p>

<p>ActiveResource&#8217;s Hash.to_xml method is similarly nutty, as though there was just some canonical way to turn any hash into an XML structure.</p>
]]></content:encoded>
	</item>
</channel>
</rss>
