<?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>Wed, 07 Jan 2009 07:53:03 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
		<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[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.<br />
<br />
Perl's Coro provides coroutines, not continuations.<br />
<br />
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).]]></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[[...] - &quot;Osfameron&quot;: Some thoughts on Python saved by osoy232008-09-19 - Implementation Language saved by gaastra342008-09-19 - Making a [...]]]></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[Bill Mill: I'm relatively sure that continuations are more powerful than coroutines, although I don't have any specific examples.]]></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[&gt; Is that called "filter" in Python? <br />
<br />
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.]]></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[@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>. <br />
<br />
Are coroutines isomorphic to continuations?]]></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 &#62;= (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.

#
# THE DO NOTATION
#

import re
import compiler


# PARSE ASSIGNMENT "x &#60;- 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 &#60;- .....
#       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 &#60;- l[0]
             q &#60;- 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 &#60;- 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 &#60;- Liste(["1" , "2" ])
                   y  &#60;- Liste(["3" , "4" ])
                   Liste.mreturn (x + " and " + y)
                 """))

print test.value



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[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 :<br />
<br />
1 - he copies the generator by replaying it from the beginng, it's not very efficient.<br />
2 - lambdas in python are restraint to only expression<br />
<br />
Furthermore when trying to implement monad in Python i noticed some more issues. Imagine you want a function :<br />
<br />
def foo(a):<br />
   return do x &gt;= (lamnda x : N(a))<br />
<br />
'a' occrus in a lambda in an expression, that's bad !<br />
<br />
I tried to use the same technique as in Ruby but cecause of the complexity of the Python bytecode i gaved up.<br />
<br />
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.<br />
<br />
#<br />
# THE DO NOTATION<br />
#<br />
<br />
import re<br />
import compiler<br />
<br />
<br />
# PARSE ASSIGNMENT "x &lt;- m"<br />
doasgn = re.compile(r"^\s*(\w+)\s*&gt; (" + dolist(l[1:]) + ")")<br />
<br />
<br />
# TRANSORM A DO BLOCK INTO A BIND EXPRESSION<br />
do    = lambda s : dolist(dostmt.findall(s))<br />
# COMPILE A DO BLOCK INTO A CODE EXPRESSION<br />
cdo   = lambda s : compiler.compile(do(s),'compiledo.py','eval')<br />
<br />
# PYTHON HAS PROBLEMS TO SEE LOCAL VARIABLES  WHEN EVALUATING :<br />
#<br />
# def test(x) :<br />
#   return eval(do("""<br />
#       List.mreturn(x)<br />
#       """)<br />
#<br />
# print test(5).run()<br />
#<br />
# Will give the good result but :<br />
#<br />
# def test(x) :<br />
#   return eval(do("""<br />
#       y &lt;- .....<br />
#       List.mreturn(x)<br />
#       """)<br />
#<br />
# print test(5).run()<br />
#<br />
# Will give the error : NameError: global name 'x' is not defined<br />
# To avoid that, we build a closure from the list of local variables<br />
# with (lambda x : ...)(locals()["x"])<br />
# So x is in the context of the expression with the good value in locals<br />
<br />
def closure(v,m):<br />
  l = v<br />
  for x in m.keys() :<br />
   l = "((lambda " + x + " : " + l + ")(m[\"" + x + "\"]))"<br />
  return "(lambda m : " + l + ")"<br />
<br />
<br />
# JUST TO EVALUATE THE BLOCK<br />
def rundo(g,l,s):<br />
  return eval(closure(do(s),l),g,l)(l)<br />
<br />
<br />
###########<br />
# MONADES #<br />
###########<br />
<br />
class Monad:<br />
    value=None<br />
    def __init__(self,val):<br />
        self.value=val<br />
<br />
    @staticmethod<br />
    def mreturn(val):<br />
        raise NotImplementedError<br />
<br />
    @classmethod<br />
    def sequence(self,l):<br />
       if len(l) == 0:<br />
          return self.mreturn([])<br />
       else :<br />
          return rundo(globals(),locals(),"""<br />
             x &lt;- l[0]<br />
             q &lt;- self.sequence(l[1:])<br />
             self.mreturn([x] + q)<br />
            """)<br />
<br />
    @classmethod<br />
    def foldM(self,f,i,l):<br />
      if len(l) == 0 :<br />
        return self.mreturn(i)<br />
      else :<br />
        return rundo(globals(),locals(),"""<br />
           x &lt;- f(i,l[0])<br />
           self.foldM(f,x,l[1:])<br />
          """)<br />
 <br />
    def bind(self, func):<br />
        raise NotImplementedError<br />
<br />
    def __ge__(self, bindee):<br />
        return self.bind(bindee)<br />
<br />
    def __rshift__(self, bindee_without_arg):<br />
        return self.bind(lambda _ : bindee_without_arg)<br />
<br />
<br />
################<br />
# MONADE LISTE #<br />
################<br />
<br />
def concat(x) :<br />
  res = []<br />
  for y in x :<br />
    res.extend(y)<br />
  return res<br />
<br />
class Liste(Monad):<br />
    @staticmethod<br />
    def mreturn(val) :<br />
        return Liste([val])<br />
<br />
    @staticmethod<br />
    def mreturnL(val) :<br />
        return Liste(val)<br />
<br />
    def bind(self,func):<br />
        def fval(x):<br />
           return func(x).value<br />
<br />
        return Liste(concat(map(fval,self.value)))<br />
<br />
    @staticmethod<br />
    def zero():<br />
        return Liste([])<br />
<br />
def guard(b):<br />
    if b :<br />
       return Liste.mreturn(())<br />
    else :<br />
       return Liste.zero()<br />
<br />
# EXEMPLES<br />
<br />
test = eval(do("""<br />
                   x &lt;- Liste(["1" , "2" ])<br />
                   y  &lt;- Liste(["3" , "4" ])<br />
                   Liste.mreturn (x + " and " + y)<br />
                 """))<br />
<br />
print test.value<br />
<br />
<br />
<br />
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.<br />
<br />
Good post anyway :)]]></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[lambda's in python don't really mix with the indentation oriented syntax, the none-deprecated equivalent is<br />
def some_name():<br />
        pass<br />
foo(some_name)<br />
<br />
if you can make up enough meaningfull names, it's better ;)]]></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[&gt; Guido wanted to remove (I think) reduce, grep, map from the core language, and there was much gnashing of teeth.<br />
<br />
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.<br />
<br />
&gt; CPAN is a big advantage for the Perl community<br />
<br />
<a href="http://pypi.python.org/" rel="nofollow">PyPI</a> is still no CPAN, but it's coming along.]]></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[&gt; Things that you miss out on include multiline strings<br />
<br />
errmmm... no you don't.<br />
<br />
def foobar():<br />
    return """this is a long string that is triple-quoted<br />
therefore it is a<br />
multiline<br />
string"""]]></content:encoded>
	</item>
	<item>
		<title>By: dolio</title>
		<link>http://greenokapi.net/blog/2008/09/25/some-thoughts-on-python/#comment-73</link>
		<dc:creator>dolio</dc:creator>
		<pubDate>Thu, 25 Sep 2008 00:54:47 +0000</pubDate>
		<guid isPermaLink="false">http://greenokapi.net/blog/?p=152#comment-73</guid>
		<description>Are you sure Python has continuations? I was under the impression that it had generators (which your stuff about the 'yield' keyword seems to indicate you're talking about), but those are not full first-class continuations (and Coro sounds like coroutines, which are also not continuations).

It's possible that things have changed without my hearing about it, though (I don't watch Python very closely).

Ruby, for instance, has continuations (see Kernel#callcc or something of that sort).</description>
		<content:encoded><![CDATA[Are you sure Python has continuations? I was under the impression that it had generators (which your stuff about the 'yield' keyword seems to indicate you're talking about), but those are not full first-class continuations (and Coro sounds like coroutines, which are also not continuations).<br />
<br />
It's possible that things have changed without my hearing about it, though (I don't watch Python very closely).<br />
<br />
Ruby, for instance, has continuations (see Kernel#callcc or something of that sort).]]></content:encoded>
	</item>
</channel>
</rss>
