<?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"
	>
<channel>
	<title>Comments on: Some thoughts on Python</title>
	<atom:link href="http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/feed/" rel="self" type="application/rss+xml" />
	<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/</link>
	<description>Perl, Haskell, stuff</description>
	<pubDate>Sun, 21 Mar 2010 00:03:02 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
		<item>
		<title>By: Sal</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-1295</link>
		<dc:creator>Sal</dc:creator>
		<pubDate>Sun, 22 Feb 2009 06:57:15 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-1295</guid>
		<description>I think whitespace is most understood. It is usually seen as a *gross* feature when you start perusing the language. However once you are have some momentum and actually start using the language, you will come to realize that it is one of its strengths; Code just seems to flow and productivity increases. Long time Perl master Eric Raymond discovered this as well (http://www.linuxjournal.com/article/3882).</description>
		<content:encoded><![CDATA[<p>I think whitespace is most understood. It is usually seen as a <em>gross</em> feature when you start perusing the language. However once you are have some momentum and actually start using the language, you will come to realize that it is one of its strengths; Code just seems to flow and productivity increases. Long time Perl master Eric Raymond discovered this as well (http://www.linuxjournal.com/article/3882).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Brock</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-91</link>
		<dc:creator>Brock</dc:creator>
		<pubDate>Mon, 06 Oct 2008 17:02:47 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-91</guid>
		<description>Coroutines are "one-shot" continuations. That is, with full continuations you can re-activate the same bundle of state multiple times. With coroutines you can stop-and-bundle some state, but you can only resume it once.

Perl's Coro provides coroutines, not continuations.

Interestingly enough, for one interesting use of continuations -- inverting the control of web applications ala Seaside -- it turns out that coroutines are Good Enough (tm).</description>
		<content:encoded><![CDATA[<p>Coroutines are "one-shot" continuations. That is, with full continuations you can re-activate the same bundle of state multiple times. With coroutines you can stop-and-bundle some state, but you can only resume it once.</p>

<p>Perl's Coro provides coroutines, not continuations.</p>

<p>Interestingly enough, for one interesting use of continuations -- inverting the control of web applications ala Seaside -- it turns out that coroutines are Good Enough (tm).</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Websites tagged "pygame" on Postsaver</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-90</link>
		<dc:creator>Websites tagged "pygame" on Postsaver</dc:creator>
		<pubDate>Fri, 03 Oct 2008 08:32:07 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-90</guid>
		<description>[...] - &#34;Osfameron&#34;: Some thoughts on Python saved by osoy232008-09-19 - Implementation Language saved by gaastra342008-09-19 - Making a [...]</description>
		<content:encoded><![CDATA[<p>[...] - &quot;Osfameron&quot;: Some thoughts on Python saved by osoy232008-09-19 - Implementation Language saved by gaastra342008-09-19 - Making a [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: dolio</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-89</link>
		<dc:creator>dolio</dc:creator>
		<pubDate>Fri, 26 Sep 2008 00:08:56 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-89</guid>
		<description>Bill Mill: I'm relatively sure that continuations are more powerful than coroutines, although I don't have any specific examples.</description>
		<content:encoded><![CDATA[<p>Bill Mill: I'm relatively sure that continuations are more powerful than coroutines, although I don't have any specific examples.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bill Mill</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-85</link>
		<dc:creator>Bill Mill</dc:creator>
		<pubDate>Thu, 25 Sep 2008 15:43:51 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-85</guid>
		<description>&#62; Is that called "filter" in Python? 

ahha - yes. Guido &lt;a href="http://www.artima.com/weblogs/viewpost.jsp?thread=211200" rel="nofollow"&gt;likes filter when used with builtins&lt;/a&gt;, but thinks a list comp is clearer than filter with a lambda.</description>
		<content:encoded><![CDATA[<p>&gt; Is that called "filter" in Python? </p>

<p>ahha - yes. Guido <a href="http://www.artima.com/weblogs/viewpost.jsp?thread=211200" rel="nofollow">likes filter when used with builtins</a>, but thinks a list comp is clearer than filter with a lambda.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bill Mill</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-84</link>
		<dc:creator>Bill Mill</dc:creator>
		<pubDate>Thu, 25 Sep 2008 15:38:56 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-84</guid>
		<description>@dolio python 2.5 gained generators that can be sent values; this makes them &lt;a href="http://www.python.org/dev/peps/pep-0342/" rel="nofollow"&gt;isomorphic to coroutines&lt;/a&gt;. 

Are coroutines isomorphic to continuations?</description>
		<content:encoded><![CDATA[<p>@dolio python 2.5 gained generators that can be sent values; this makes them <a href="http://www.python.org/dev/peps/pep-0342/" rel="nofollow">isomorphic to coroutines</a>. </p>

<p>Are coroutines isomorphic to continuations?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: GTof</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-83</link>
		<dc:creator>GTof</dc:creator>
		<pubDate>Thu, 25 Sep 2008 10:37:03 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-83</guid>
		<description>About Python, Ruby and the monads, i think it's the opposite. Monads on Ruby are very simple thanks to http://github.com/aanand/ruby-do-notation/tree/master  and the blocks of Ruby. The impementation in http://www.valuedlessons.com/2008/01/monads-in-python-with-nice-syntax.html have two problem :

1 - he copies the generator by replaying it from the beginng, it's not very efficient.
2 - lambdas in python are restraint to only expression

Furthermore when trying to implement monad in Python i noticed some more issues. Imagine you want a function :

def foo(a):
   return do x &gt;= (lamnda x : N(a))

'a' occrus in a lambda in an expression, that's bad !

I tried to use the same technique as in Ruby but cecause of the complexity of the Python bytecode i gaved up.

If you want you can use the code i've done to simulate do-notation. It works but code need to be in strings which are parsed, transformed and interpreded. it's not as beatiful as in Ruby.

&lt;code&gt;&lt;pre&gt;
 # THE DO NOTATION
 
 import re
 import compiler

 #  PARSE ASSIGNMENT "x &lt;- m"
 doasgn = re.compile(r"^\s*(\w+)\s*&#62; (" + dolist(l[1:]) + ")")
 
 # TRANSORM A DO BLOCK INTO A BIND EXPRESSION
 do    = lambda s : dolist(dostmt.findall(s))
 # COMPILE A DO BLOCK INTO A CODE EXPRESSION
 cdo   = lambda s : compiler.compile(do(s),'compiledo.py','eval')
 
 # PYTHON HAS PROBLEMS TO SEE LOCAL VARIABLES  WHEN EVALUATING :
 # def test(x) :
 #   return eval(do("""
 #       List.mreturn(x)
 #       """)
 #
 # print test(5).run()
 #
 # Will give the good result but :
 #
 # def test(x) :
 #   return eval(do("""
 #       y &lt;- .....
 #       List.mreturn(x)
 #       """)
 #
 # print test(5).run()
 #
 # Will give the error : NameError: global name 'x' is not defined
 # To avoid that, we build a closure from the list of local variables
 # with (lambda x : ...)(locals()["x"])
 # So x is in the context of the expression with the good value in locals 

 def closure(v,m):
   l = v
   for x in m.keys() :
    l = "((lambda " + x + " : " + l + ")(m[\"" + x + "\"]))"
   return "(lambda m : " + l + ")"

 # JUST TO EVALUATE THE BLOCK
 def rundo(g,l,s):
   return eval(closure(do(s),l),g,l)(l)

 # MONADES #

 class Monad:
     value=None
     def __init__(self,val):
         self.value=val

     @staticmethod
     def mreturn(val):
         raise NotImplementedError

     @classmethod
     def sequence(self,l):
        if len(l) == 0:
           return self.mreturn([])
        else :
           return rundo(globals(),locals(),"""
              x &lt;- l[0]
              q &lt;- self.sequence(l[1:])
              self.mreturn([x] + q)
             """)

     @classmethod
     def foldM(self,f,i,l):
       if len(l) == 0 :
         return self.mreturn(i)
       else :
         return rundo(globals(),locals(),"""
            x &lt;- f(i,l[0])
            self.foldM(f,x,l[1:])
           """)
  
     def bind(self, func):
         raise NotImplementedError

     def __ge__(self, bindee):
         return self.bind(bindee)

     def __rshift__(self, bindee_without_arg):
        return self.bind(lambda _ : bindee_without_arg)

 # MONADE LISTE #

 def concat(x) :
   res = []
   for y in x :
     res.extend(y)
   return res 

 class Liste(Monad):
     @staticmethod
     def mreturn(val) :
         return Liste([val])

     @staticmethod
     def mreturnL(val) :
         return Liste(val) 

     def bind(self,func):
         def fval(x):
            return func(x).value

         return Liste(concat(map(fval,self.value)))

     @staticmethod
     def zero():
         return Liste([])
 
 def guard(b):
     if b :
        return Liste.mreturn(())
     else :
        return Liste.zero()

 # EXEMPLES

 test = eval(do("""
                    x &lt;- Liste(["1" , "2" ])
                    y  &lt;- Liste(["3" , "4" ])
                    Liste.mreturn (x + " and " + y)
                  """))

 print test.value
&lt;/pre&gt;&lt;/code&gt;

Another point. Continuation and may yield be différent on one other point i think. When you want to use delimited continuation, i wonder if it's possible to implement shift/reset with yield. Maybe yes.

Good post anyway :)</description>
		<content:encoded><![CDATA[<p>About Python, Ruby and the monads, i think it's the opposite. Monads on Ruby are very simple thanks to <a href="http://github.com/aanand/ruby-do-notation/tree/master" rel="nofollow">http://github.com/aanand/ruby-do-notation/tree/master</a>  and the blocks of Ruby. The impementation in <a href="http://www.valuedlessons.com/2008/01/monads-in-python-with-nice-syntax.html" rel="nofollow">http://www.valuedlessons.com/2008/01/monads-in-python-with-nice-syntax.html</a> have two problem :</p>

<p>1 - he copies the generator by replaying it from the beginng, it's not very efficient.
2 - lambdas in python are restraint to only expression</p>

<p>Furthermore when trying to implement monad in Python i noticed some more issues. Imagine you want a function :</p>

<p>def foo(a):
   return do x >= (lamnda x : N(a))</p>

<p>'a' occrus in a lambda in an expression, that's bad !</p>

<p>I tried to use the same technique as in Ruby but cecause of the complexity of the Python bytecode i gaved up.</p>

<p>If you want you can use the code i've done to simulate do-notation. It works but code need to be in strings which are parsed, transformed and interpreded. it's not as beatiful as in Ruby.</p>

<p><code><pre>
 # THE DO NOTATION</pre></code></p>

<p>import re
 import compiler</p>

<p>#  PARSE ASSIGNMENT "x &lt;- m"
 doasgn = re.compile(r"^\s<em>(\w+)\s</em>&gt; (" + dolist(l[1:]) + ")")</p>

<p># TRANSORM A DO BLOCK INTO A BIND EXPRESSION
 do    = lambda s : dolist(dostmt.findall(s))
 # COMPILE A DO BLOCK INTO A CODE EXPRESSION
 cdo   = lambda s : compiler.compile(do(s),'compiledo.py','eval')</p>

<p># PYTHON HAS PROBLEMS TO SEE LOCAL VARIABLES  WHEN EVALUATING :
 # def test(x) :
 #   return eval(do("""
 #       List.mreturn(x)
 #       """)
 #
 # print test(5).run()
 #
 # Will give the good result but :
 #
 # def test(x) :
 #   return eval(do("""
 #       y &lt;- .....
 #       List.mreturn(x)
 #       """)
 #
 # print test(5).run()
 #
 # Will give the error : NameError: global name 'x' is not defined
 # To avoid that, we build a closure from the list of local variables
 # with (lambda x : ...)(locals()["x"])
 # So x is in the context of the expression with the good value in locals </p>

<p>def closure(v,m):
   l = v
   for x in m.keys() :
    l = "((lambda " + x + " : " + l + ")(m[\"" + x + "\"]))"
   return "(lambda m : " + l + ")"</p>

<p># JUST TO EVALUATE THE BLOCK
 def rundo(g,l,s):
   return eval(closure(do(s),l),g,l)(l)</p>

<p># MONADES #</p>

<p>class Monad:
     value=None
     def <strong>init</strong>(self,val):
         self.value=val</p>

<pre><code> @staticmethod
 def mreturn(val):
     raise NotImplementedError

 @classmethod
 def sequence(self,l):
    if len(l) == 0:
       return self.mreturn([])
    else :
       return rundo(globals(),locals(),"""
          x &lt;- l[0]
          q &lt;- self.sequence(l[1:])
          self.mreturn([x] + q)
         """)

 @classmethod
 def foldM(self,f,i,l):
   if len(l) == 0 :
     return self.mreturn(i)
   else :
     return rundo(globals(),locals(),"""
        x &lt;- f(i,l[0])
        self.foldM(f,x,l[1:])
       """)

 def bind(self, func):
     raise NotImplementedError

 def __ge__(self, bindee):
     return self.bind(bindee)

 def __rshift__(self, bindee_without_arg):
    return self.bind(lambda _ : bindee_without_arg)
</code></pre>

<p># MONADE LISTE #</p>

<p>def concat(x) :
   res = []
   for y in x :
     res.extend(y)
   return res </p>

<p>class Liste(Monad):
     @staticmethod
     def mreturn(val) :
         return Liste([val])</p>

<pre><code> @staticmethod
 def mreturnL(val) :
     return Liste(val) 

 def bind(self,func):
     def fval(x):
        return func(x).value

     return Liste(concat(map(fval,self.value)))

 @staticmethod
 def zero():
     return Liste([])
</code></pre>

<p>def guard(b):
     if b :
        return Liste.mreturn(())
     else :
        return Liste.zero()</p>

<p># EXEMPLES</p>

<p>test = eval(do("""
                    x &lt;- Liste(["1" , "2" ])
                    y  &lt;- Liste(["3" , "4" ])
                    Liste.mreturn (x + " and " + y)
                  """))</p>

<p>print test.value
</p>

<p>Another point. Continuation and may yield be différent on one other point i think. When you want to use delimited continuation, i wonder if it's possible to implement shift/reset with yield. Maybe yes.</p>

<p>Good post anyway :)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Pawel Murias</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-79</link>
		<dc:creator>Pawel Murias</dc:creator>
		<pubDate>Thu, 25 Sep 2008 08:02:48 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-79</guid>
		<description>lambda's in python don't really mix with the indentation oriented syntax, the none-deprecated equivalent is
def some_name():
        pass
foo(some_name)

if you can make up enough meaningfull names, it's better ;)</description>
		<content:encoded><![CDATA[<p>lambda's in python don't really mix with the indentation oriented syntax, the none-deprecated equivalent is
def some<em>name():
        pass
foo(some</em>name)</p>

<p>if you can make up enough meaningfull names, it's better ;)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bill Mill</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-75</link>
		<dc:creator>Bill Mill</dc:creator>
		<pubDate>Thu, 25 Sep 2008 03:36:05 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-75</guid>
		<description>&#62; Guido wanted to remove (I think) reduce, grep, map from the core language, and there was much gnashing of teeth.

Nope, reduce got moved to the &lt;a href="http://docs.python.org/dev/3.0/library/functools.html" rel="nofollow"&gt;standard library&lt;/a&gt; instead of the builtin functions because list comprehensions are now the built-in way to perform reduces. map() is still in the builtins and there's never been a grep() function, I'm not sure what you're talking about there.

&#62; CPAN is a big advantage for the Perl community

&lt;a href="http://pypi.python.org/" rel="nofollow"&gt;PyPI&lt;/a&gt; is still no CPAN, but it's coming along.</description>
		<content:encoded><![CDATA[<p>&gt; Guido wanted to remove (I think) reduce, grep, map from the core language, and there was much gnashing of teeth.</p>

<p>Nope, reduce got moved to the <a href="http://docs.python.org/dev/3.0/library/functools.html" rel="nofollow">standard library</a> instead of the builtin functions because list comprehensions are now the built-in way to perform reduces. map() is still in the builtins and there's never been a grep() function, I'm not sure what you're talking about there.</p>

<p>&gt; CPAN is a big advantage for the Perl community</p>

<p><a href="http://pypi.python.org/" rel="nofollow">PyPI</a> is still no CPAN, but it's coming along.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bill Mill</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-74</link>
		<dc:creator>Bill Mill</dc:creator>
		<pubDate>Thu, 25 Sep 2008 03:30:02 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-74</guid>
		<description>&#62; Things that you miss out on include multiline strings

errmmm... no you don't.

def foobar():
    return """this is a long string that is triple-quoted
therefore it is a
multiline
string"""</description>
		<content:encoded><![CDATA[<p>&gt; Things that you miss out on include multiline strings</p>

<p>errmmm... no you don't.</p>

<p>def foobar():
    return """this is a long string that is triple-quoted
therefore it is a
multiline
string"""</p>
]]></content:encoded>
	</item>
</channel>
</rss>
