<?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: Monkeypatching and dead ends</title>
	<atom:link href="http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/</link>
	<description></description>
	<lastBuildDate>Fri, 06 May 2011 07:16:39 +0000</lastBuildDate>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<item>
		<title>By: Mikael Jansson</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16281</link>
		<dc:creator>Mikael Jansson</dc:creator>
		<pubDate>Fri, 28 Mar 2008 22:37:31 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16281</guid>
		<description>My gut feeling is that eval is used because there is no proper support in the language to achieve whatever you&#039;re trying to do with the code passed on to eval.

Generally, you don&#039;t want to use eval in Common Lisp, but among newbies it&#039;s common to think it should be used in many places where you should do it in another, easier &amp; cleaner way.  Have a look at http://www.faqs.org/faqs/lisp-faq/part3/section-13.html (&quot;When is it right to use eval&quot;) for more info.

Same thing goes for macros: newbies tend to think of them as working like their crippled relatives in the C world, and as such use them as a way to inline code.  With strange results. :)</description>
		<content:encoded><![CDATA[<p>My gut feeling is that eval is used because there is no proper support in the language to achieve whatever you&#8217;re trying to do with the code passed on to eval.</p>

<p>Generally, you don&#8217;t want to use eval in Common Lisp, but among newbies it&#8217;s common to think it should be used in many places where you should do it in another, easier &amp; cleaner way.  Have a look at <a href="http://www.faqs.org/faqs/lisp-faq/part3/section-13.html" rel="nofollow">http://www.faqs.org/faqs/lisp-faq/part3/section-13.html</a> (&#8220;When is it right to use eval&#8221;) for more info.</p>

<p>Same thing goes for macros: newbies tend to think of them as working like their crippled relatives in the C world, and as such use them as a way to inline code.  With strange results. :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16241</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Wed, 26 Mar 2008 17:16:43 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16241</guid>
		<description>Expanding on the SQLObject reference: certainly SQLObject uses a number of metaprogramming techniques, and especially when it was written quite a few of those techniques were very novel.  I am glad I had those new features (in Python 2.2) to aid in that development.  But I also know that, in retrospect, many of the techniques I used, I wouldn&#039;t use if rewriting it.  Of course I still would use many of those techniques, and it&#039;s hard to know ahead of time which will work well, and when they will work well.

This is really what I&#039;m referring to: the *wise* use of advanced features is essential.  Python, Common Lisp, Ruby, etc, all give programmers the ability to create very clever and unmaintainable code.  I wouldn&#039;t blame any one feature for this either -- for instance, `eval` is very dangerous, but I certainly wouldn&#039;t remove it.  Runtime patching of code is similar.  Or, to give an example from SQLObject, I do operator overloading there in a particularly peculiar way, using operators to build expressions instead of calculate expressions.  *Generally* I would say that&#039;s a dangerously clever technique.  *Specifically* for that problem (constructing SQL expressions) I think it works well.  Experience and experimentation is generally the best guide for figuring this out.  But that experience doesn&#039;t have to be entirely personal; the community has experience and can offer important guidance.

As an example in Ruby and Python, community experience will come down on anyone using `eval` for anything that doesn&#039;t *absolutely* require `eval`.  In Ruby it still is seen as a valid metaprogramming technique.  I don&#039;t know the Common Lisp community well enough to know what community convention accepts and avoids, but I&#039;m sure there as in any community there are particular standards.</description>
		<content:encoded><![CDATA[<p>Expanding on the SQLObject reference: certainly SQLObject uses a number of metaprogramming techniques, and especially when it was written quite a few of those techniques were very novel.  I am glad I had those new features (in Python 2.2) to aid in that development.  But I also know that, in retrospect, many of the techniques I used, I wouldn&#8217;t use if rewriting it.  Of course I still would use many of those techniques, and it&#8217;s hard to know ahead of time which will work well, and when they will work well.</p>

<p>This is really what I&#8217;m referring to: the <em>wise</em> use of advanced features is essential.  Python, Common Lisp, Ruby, etc, all give programmers the ability to create very clever and unmaintainable code.  I wouldn&#8217;t blame any one feature for this either &#8212; for instance, <code>eval</code> is very dangerous, but I certainly wouldn&#8217;t remove it.  Runtime patching of code is similar.  Or, to give an example from SQLObject, I do operator overloading there in a particularly peculiar way, using operators to build expressions instead of calculate expressions.  <em>Generally</em> I would say that&#8217;s a dangerously clever technique.  <em>Specifically</em> for that problem (constructing SQL expressions) I think it works well.  Experience and experimentation is generally the best guide for figuring this out.  But that experience doesn&#8217;t have to be entirely personal; the community has experience and can offer important guidance.</p>

<p>As an example in Ruby and Python, community experience will come down on anyone using <code>eval</code> for anything that doesn&#8217;t <em>absolutely</em> require <code>eval</code>.  In Ruby it still is seen as a valid metaprogramming technique.  I don&#8217;t know the Common Lisp community well enough to know what community convention accepts and avoids, but I&#8217;m sure there as in any community there are particular standards.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Paul Boddie</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16239</link>
		<dc:creator>Paul Boddie</dc:creator>
		<pubDate>Wed, 26 Mar 2008 16:23:19 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16239</guid>
		<description>Mikael Jansson: &quot;As the author of the (excellent!) ORM SqlObject, you should know what it means for productivity to work in a higher abstraction level: Python instead of raw SQL. Now, imagine being able to abstract the actual syntax of the language away, and move even closer to your problem domain.&quot;

Who says SQL isn&#039;t the right abstraction level for many problems? Maybe the average &quot;CRUD&quot; application benefits from things like SQLObject, but the most significant complaint about most ORM solutions is how they reinvent SQL badly in the solution developer&#039;s language of choice, and how you have to jump through hoops to write something that may be difficult in SQL, but which is natural in that language. I&#039;ve done a fair amount of work with relatively large databases of late and I can&#039;t see how hiding the database system (and its very useful query analysis tools) would have been beneficial.

&quot;A good example of this is the (define-binary-class …) macro Peter Seibel (in the book Practical Common Lisp) creates for his ID3-parser. You essentially define a bunch of classes and functions, automatically, by just defining the layout of the binary file. Enter a bunch of clever macros which then fill the rest out for you.

I think declarative structure parsing is very nice, and there are solutions like this in Python.

&quot;Even though you might not actually start using Lisp, I strongly suggest you read Practical Common Lisp, as I believe it will make you see a lot of things in a new light. (It did to me, and I’ve written my fair share of Python, including a commercial TurboGears-based deployment, attended EuroPython and been quite the Python advocate.)&quot;

I hope you&#039;ll make it back to EuroPython this year, too. ;-)</description>
		<content:encoded><![CDATA[<p>Mikael Jansson: &#8220;As the author of the (excellent!) ORM SqlObject, you should know what it means for productivity to work in a higher abstraction level: Python instead of raw SQL. Now, imagine being able to abstract the actual syntax of the language away, and move even closer to your problem domain.&#8221;</p>

<p>Who says SQL isn&#8217;t the right abstraction level for many problems? Maybe the average &#8220;CRUD&#8221; application benefits from things like SQLObject, but the most significant complaint about most ORM solutions is how they reinvent SQL badly in the solution developer&#8217;s language of choice, and how you have to jump through hoops to write something that may be difficult in SQL, but which is natural in that language. I&#8217;ve done a fair amount of work with relatively large databases of late and I can&#8217;t see how hiding the database system (and its very useful query analysis tools) would have been beneficial.</p>

<p>&#8220;A good example of this is the (define-binary-class …) macro Peter Seibel (in the book Practical Common Lisp) creates for his ID3-parser. You essentially define a bunch of classes and functions, automatically, by just defining the layout of the binary file. Enter a bunch of clever macros which then fill the rest out for you.</p>

<p>I think declarative structure parsing is very nice, and there are solutions like this in Python.</p>

<p>&#8220;Even though you might not actually start using Lisp, I strongly suggest you read Practical Common Lisp, as I believe it will make you see a lot of things in a new light. (It did to me, and I’ve written my fair share of Python, including a commercial TurboGears-based deployment, attended EuroPython and been quite the Python advocate.)&#8221;</p>

<p>I hope you&#8217;ll make it back to EuroPython this year, too. ;-)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Russell Nelson</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16230</link>
		<dc:creator>Russell Nelson</dc:creator>
		<pubDate>Wed, 26 Mar 2008 01:51:19 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16230</guid>
		<description>rj, I&#039;ve programmed Lisp in an academic context (toy programs) and I&#039;ve written serious programs in Python (gps interface).  I would never, EVER consider Python to be ANYTHING like Lisp.  Ever.</description>
		<content:encoded><![CDATA[<p>rj, I&#8217;ve programmed Lisp in an academic context (toy programs) and I&#8217;ve written serious programs in Python (gps interface).  I would never, EVER consider Python to be ANYTHING like Lisp.  Ever.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mikael Jansson</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16203</link>
		<dc:creator>Mikael Jansson</dc:creator>
		<pubDate>Mon, 24 Mar 2008 12:43:45 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16203</guid>
		<description>Ian,

You are correct. 

In fact, monkey patching isn&#039;t necessary in Common Lisp, because of/thanks to multiple dispatch (which follows from methods not belonging to classes, i.e. the reason for having to monkey patch).

It seems the problem doesn&#039;t happen at all. I wonder what similar issues happen in Lisp?</description>
		<content:encoded><![CDATA[<p>Ian,</p>

<p>You are correct. </p>

<p>In fact, monkey patching isn&#8217;t necessary in Common Lisp, because of/thanks to multiple dispatch (which follows from methods not belonging to classes, i.e. the reason for having to monkey patch).</p>

<p>It seems the problem doesn&#8217;t happen at all. I wonder what similar issues happen in Lisp?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16188</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Mon, 24 Mar 2008 00:10:34 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16188</guid>
		<description>Mikael: I see the extension of generic methods, at least in the safe non-monkeypatchy way, and using before/after/around, as more like subclassing and overriding methods.  Monkeypatched code has the same patterns, though they aren&#039;t explicitly named.</description>
		<content:encoded><![CDATA[<p>Mikael: I see the extension of generic methods, at least in the safe non-monkeypatchy way, and using before/after/around, as more like subclassing and overriding methods.  Monkeypatched code has the same patterns, though they aren&#8217;t explicitly named.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Mikael Jansson</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16187</link>
		<dc:creator>Mikael Jansson</dc:creator>
		<pubDate>Sun, 23 Mar 2008 23:10:36 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16187</guid>
		<description>Ian (#18),

&quot;&quot;&quot;In the case of 3 it’s quite dangerous. I don’t see how
generic functions make it any less dangerous.&quot;&quot;&quot;

Quoting [Peter Seibel](http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html) again:

&quot;&quot;&quot;The methods I&#039;ve been discussing so far are called primary methods. Primary methods, as their name suggests, are responsible for providing the primary implementation of a generic function. The standard method combination also supports three kinds of auxiliary methods: :before, :after, and :around methods. An auxiliary method definition is written with DEFMETHOD like a primary method but with a method qualifier, which names the type of method, between the name of the method and the parameter list.

[...]

Auxiliary methods are just a convenient way to express certain common patterns more concisely and concretely. They don&#039;t actually allow you to do anything you couldn&#039;t do by combining primary methods with diligent adherence to a few coding conventions and some extra typing. Perhaps their biggest benefit is that they provide a uniform framework for extending generic functions. Often a library will define a generic function and provide a default primary method, allowing users of the library to customize its behavior by defining appropriate auxiliary methods.&quot;&quot;&quot;

Something like that, maybe?</description>
		<content:encoded><![CDATA[<p>Ian (#18),</p>

<p>&#8220;&#8221;"In the case of 3 it’s quite dangerous. I don’t see how
generic functions make it any less dangerous.&#8221;"&#8221;</p>

<p>Quoting <a href="http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html">Peter Seibel</a> again:</p>

<p>&#8220;&#8221;"The methods I&#8217;ve been discussing so far are called primary methods. Primary methods, as their name suggests, are responsible for providing the primary implementation of a generic function. The standard method combination also supports three kinds of auxiliary methods: :before, :after, and :around methods. An auxiliary method definition is written with DEFMETHOD like a primary method but with a method qualifier, which names the type of method, between the name of the method and the parameter list.</p>

<p>[...]</p>

<p>Auxiliary methods are just a convenient way to express certain common patterns more concisely and concretely. They don&#8217;t actually allow you to do anything you couldn&#8217;t do by combining primary methods with diligent adherence to a few coding conventions and some extra typing. Perhaps their biggest benefit is that they provide a uniform framework for extending generic functions. Often a library will define a generic function and provide a default primary method, allowing users of the library to customize its behavior by defining appropriate auxiliary methods.&#8221;"&#8221;</p>

<p>Something like that, maybe?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16186</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Sun, 23 Mar 2008 22:21:28 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16186</guid>
		<description>chromatic: by low level stuff, I meant stuff like decent function signatures and nested data structures.  Perl&#039;s data structures are indefensibly awful.  I spend most of my programming time fiddling with data structures, not doing metaprogramming.  Even if Perl&#039;s metaprogramming facilities were better than Python&#039;s (maybe they are, I don&#039;t know), so long as its *basic* programming facilities are so flawed it hardly matters.</description>
		<content:encoded><![CDATA[<p>chromatic: by low level stuff, I meant stuff like decent function signatures and nested data structures.  Perl&#8217;s data structures are indefensibly awful.  I spend most of my programming time fiddling with data structures, not doing metaprogramming.  Even if Perl&#8217;s metaprogramming facilities were better than Python&#8217;s (maybe they are, I don&#8217;t know), so long as its <em>basic</em> programming facilities are so flawed it hardly matters.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: chromatic</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16185</link>
		<dc:creator>chromatic</dc:creator>
		<pubDate>Sun, 23 Mar 2008 22:08:20 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16185</guid>
		<description>I know the Python party line about anonymous functions is &quot;Why would you ever want to do that?&quot;, and I know the workaround for read-only closed-over variables is to use an aggregate, but I find the irony particularly delicious when a Python programmer complains that Perl doesn&#039;t have robust &quot;low level stuff&quot; with regard to closures and metaclasses.

(The explicit referencing semantics in Perl 5 seem to me to stem from autoflattening in list context, which is a deliberate design decision.  They&#039;re an improvement over nested structures in Perl 4, but they&#039;re definitely one of the least beautiful parts of that version of the language.)</description>
		<content:encoded><![CDATA[<p>I know the Python party line about anonymous functions is &#8220;Why would you ever want to do that?&#8221;, and I know the workaround for read-only closed-over variables is to use an aggregate, but I find the irony particularly delicious when a Python programmer complains that Perl doesn&#8217;t have robust &#8220;low level stuff&#8221; with regard to closures and metaclasses.</p>

<p>(The explicit referencing semantics in Perl 5 seem to me to stem from autoflattening in list context, which is a deliberate design decision.  They&#8217;re an improvement over nested structures in Perl 4, but they&#8217;re definitely one of the least beautiful parts of that version of the language.)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ian Bicking</title>
		<link>http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/comment-page-1/#comment-16181</link>
		<dc:creator>Ian Bicking</dc:creator>
		<pubDate>Sun, 23 Mar 2008 20:20:44 +0000</pubDate>
		<guid isPermaLink="false">http://blog.ianbicking.org/2008/03/21/monkeypatching-and-dead-ends/#comment-16181</guid>
		<description>Aristotle: regular expressions were only an example, of course, not a summary of Perl.  I think Perl sags badly under the weight of Very Bad Decisions, like references.  A language without well behaved nested data structures is just silly.  Of course you *can* write all kinds of high-level stuff with Perl.  You can do so with C too.  I don&#039;t say that *just* sarcastically, as people *have* made complex dynamic systems with C.  (Maybe it&#039;s unfair to lump Perl with the much-less-expressive PHP.)  

The &quot;high level&quot; in Python that I&#039;m trying to refer to isn&#039;t really that high.  Not crazy programming techniques, just high enough that you can safely trust that all the basics of programs -- functions, conditionals, loops -- work safely and well, and you can focus on the stuff that is more challenging.  So I would argue that low level abstraction problems in Perl are more concerning than the ability to do highly abstract code.  Once you start using closures and metaclasses and other things you have to watch what you are doing, in either language.  But I feel much safer doing these high level things when I know the low level stuff is robust.  Perl hasn&#039;t made it robust.

There might be a point when even these high-level abstractions are robust.  For instance, I&#039;d feel more comfortable with closures if they could be introspected better.  That the state in a closer is just inferred (at least in Python) makes it an awkward abstraction.  We move up by small steps, and &quot;high-level&quot; and &quot;low-level&quot; is really just a way of placing language on a spectrum specific to *this current time* in development.  I would certainly hope that the high level of today becomes the low level of tomorrow.</description>
		<content:encoded><![CDATA[<p>Aristotle: regular expressions were only an example, of course, not a summary of Perl.  I think Perl sags badly under the weight of Very Bad Decisions, like references.  A language without well behaved nested data structures is just silly.  Of course you <em>can</em> write all kinds of high-level stuff with Perl.  You can do so with C too.  I don&#8217;t say that <em>just</em> sarcastically, as people <em>have</em> made complex dynamic systems with C.  (Maybe it&#8217;s unfair to lump Perl with the much-less-expressive PHP.)  </p>

<p>The &#8220;high level&#8221; in Python that I&#8217;m trying to refer to isn&#8217;t really that high.  Not crazy programming techniques, just high enough that you can safely trust that all the basics of programs &#8212; functions, conditionals, loops &#8212; work safely and well, and you can focus on the stuff that is more challenging.  So I would argue that low level abstraction problems in Perl are more concerning than the ability to do highly abstract code.  Once you start using closures and metaclasses and other things you have to watch what you are doing, in either language.  But I feel much safer doing these high level things when I know the low level stuff is robust.  Perl hasn&#8217;t made it robust.</p>

<p>There might be a point when even these high-level abstractions are robust.  For instance, I&#8217;d feel more comfortable with closures if they could be introspected better.  That the state in a closer is just inferred (at least in Python) makes it an awkward abstraction.  We move up by small steps, and &#8220;high-level&#8221; and &#8220;low-level&#8221; is really just a way of placing language on a spectrum specific to <em>this current time</em> in development.  I would certainly hope that the high level of today becomes the low level of tomorrow.</p>
]]></content:encoded>
	</item>
</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.633 seconds -->

