Python syntax in Lisp and Scheme

Ask a Question related to Ruby, Design and Development.

  1. #1

    Default Re: Python syntax in Lisp and Scheme

    Rene van Bevern <rvb@rvb.dyndns.org> wrote in message news:<slrnbnr2pu.1qe.rvb@negoyl.vb-network>...
    > I know at least one more person who came to LISP/Scheme over ruby. Maybe
    > it needs ruby and python to enlighten people without confusing them with
    > a syntax they are not used to first. ;)
    I can't remember how *exactly* I came to use scheme (unfortuantely I
    don't keep a diary), but trying to reconstruct it looks something like
    this:

    I am actually not a programmer, but mostly a linguist. About four
    years ago I got interested in computational linguistics and decided to
    learn a programming language. The first programming book I picked up
    was "The Gentle Introduction..." (Common Lisp). I made sense to me but
    I couldn't find a plug'n' play lisp implementation (I was pretty
    computer-illiterate at the time: could only manage v. basic stuff on
    Windoze). So I put that aside and decided to have a go at Perl (widely
    used in NLP). That was much easier, I installed the ActiveState win32
    port no problems and picked Perl up from online tutorials and the
    multitude of other easily accessible Perl resources. After I've played
    with perl for a while I heard about Python and Ruby, which to me
    looked like more sophisticated versions of Perl, and I switched to
    Ruby for most of my toy and not-so-toy scripts. While reading
    ruby-talk and other ruby-stuff I kept coming across references to
    Scheme and Lisp, which I was already vaguely familiar with from my
    perusal of the "Gentle Introduction". At this point I was already
    using Linux and so could easily install Clisp and half a dozen Scheme
    implementations. Schemes such as Gauche, Bigloo and PLT seemed like
    they were better suited to writing the sort of small programs or CGI
    scripts that I was using Perl and Ruby for, so I sort of settled for
    Scheme. (Sometime during this time I also learned Prolog in a
    university course and it made me aware of the various advantages, as
    well as some disadvantages, of using a very high level languages in
    comp-ling).
    At the moment I am quite happy with Scheme although I do miss the
    large lively communities and the amout of libraries associated with
    Perl, Python and Ruby. I hope the "revival" of Lisp-like languages
    some of you have observed will gain momentum and that CL anb Scheme
    will catch up with Python and Ruby in the areas where they are behind.

    Cheers,
    --
    Grzegorz
    Grzegorz Chrupala Guest

  2. Similar Questions and Discussions

    1. Backup scheme
      Hi, I have a script that runs and zips a file, then copies it to another directory on another system. It also goes through and renames each file...
    2. [ANN] ruby-lisp-0.1
      ruby-lisp-0.1 is Released! ========================== I have just released the ruby-lisp module to the world. Check it out at ...
    3. [PYTHON] YAPVRA (Yet Another Python vs. Ruby Article)
      Interesting blog post from a Pythonista on "Linguistic Simplicity," and why Ruby fails to pass muster. ...
    4. [Q]Ruby LISP-ish stuff
      Saluton! * Moses Hall; 2003-07-11, 23:45 UTC: This usually is called 'tail' while self is called 'head'. Gis, Josef 'Jupp' Schugt --
    5. Reasonable partition scheme
      I just bought a 120 GB HDD as a replacement. I now have a 20Gb Quantum Fireball with a fast access time and a 120GB Samsung with slower access time....
  3. #2

    Default Re: Python syntax in Lisp and Scheme

    Alex Martelli wrote:
    >
    > Tut-tut. You are claiming, for example, that I mentioned the lack
    > of distinction between expressions and statements as "too complex for
    > Python to support": I assert your claim is demonstrably false, and
    > that I NEVER said that it would be COMPLEX for Python to support such
    > a lack. What I *DID* say on the subject, and I quote, was:
    Sorry if I inadvertantly distorted your words. What I meant by my admittedly
    rhetorical statement wa something like: "these features either introduce
    too much complexity, or are messy, or otherwise incompatible with Python's
    philosophy and for this reason the language refuses to support them." Not
    necessarily too complex to *implement*. I do realize that
    no-statements-just-expressions is not a particularly challenging design
    issue.
    > It makes the _learner_'s job simple (the rule he must learn is simple),
    That is plausible.
    > and it makes the _programmer_'s job simple (the rule he must apply to
    > understand what will happens if he codes in way X is simple)
    This makes less sense. The rule may be simple but it also limits the
    expressiveness of the language and forces the programmer to work around the
    limitations in a contorted and far from "simple" way.

    > I thought the total inability to nest method definitions (while in Python
    > you get perfectly normal lexical closures, except that you can't _rebind_
    > outer-scope names -- hey, in functional programming languages you can't
    > rebind ANY name, yet nobody every claimed that this means they "don't have
    > true lexical closures"...!-), and more generally the deep split between
    > the space of objects and that of methods (a split that's simply not there
    > in Python), would have been show-stoppers for a Schemer, but it's always
    > nice to learn otherwise.
    I don't really feel quite qualified discuss Ruby's design decisions wrt the
    relation between methods, procedures and objects, but I don't think the
    split between methods and objects is as deep as you claim:

    irb(main):011:0> meth="f-o-o".method(:split)
    => #<Method: String#split>
    irb(main):012:0> meth.class
    => Method
    irb(main):013:0> meth.kind_of?(Object)
    => true
    irb(main):014:0> meth.call('-')
    => ["f", "o", "o"]
    irb(main):015:0>

    I do tend to think that Ruby would be better off with a more unified
    treatment of blocks, procedures and methods, but my understanding of the
    issues involved is very incomplete. Perhaps Smalltalk experts would be more
    qualified to comment on this.

    --
    Grzegorz
    [url]http://pithekos.net[/url]

    Grzegorz Chrupała Guest

  4. #3

    Default Re: Python syntax in Lisp and Scheme



    Grzegorz Chrupala wrote:
    > Rene van Bevern <rvb@rvb.dyndns.org> wrote in message news:<slrnbnr2pu.1qe.rvb@negoyl.vb-network>...
    >
    >
    >>I know at least one more person who came to LISP/Scheme over ruby. Maybe
    >>it needs ruby and python to enlighten people without confusing them with
    >>a syntax they are not used to first. ;)
    >
    >
    > I can't remember how *exactly* I came to use scheme (unfortuantely I
    > don't keep a diary), but trying to reconstruct it looks something like
    > this:
    It would be valuable to have what you wrote next in:

    [url]http://alu.cliki.net/The%20Road%20to%20Lisp%20Survey[/url]

    Lisp there is defined as "any member of the Lisp family".

    Aside: oh, great. Now the survey is going to get thrown off the ALU
    Cliki by the Iki Police. um, could you all find something less
    productive to focus on? Cutting and pasting thirty pages is /so/ helpful
    to the Lisp community. Not!!!

    You can be response #78...oops, #79.

    Or e-mail me a go-ahead and I'll do the legwork.

    kenny

    Kenny Tilton Guest

  5. #4

    Default Re: Python syntax in Lisp and Scheme


    On Friday, October 3, 2003, at 07:12 PM, Grzegorz Chrupala wrote:
    > Rene van Bevern <rvb@rvb.dyndns.org> wrote in message
    > news:<slrnbnr2pu.1qe.rvb@negoyl.vb-network>...
    >
    >> I know at least one more person who came to LISP/Scheme over ruby.
    >> Maybe
    >> it needs ruby and python to enlighten people without confusing them
    >> with
    >> a syntax they are not used to first. ;)
    >
    > [snip]
    > At the moment I am quite happy with Scheme although I do miss the
    > large lively communities and the amout of libraries associated with
    > Perl, Python and Ruby. I hope the "revival" of Lisp-like languages
    > some of you have observed will gain momentum and that CL anb Scheme
    > will catch up with Python and Ruby in the areas where they are behind.
    >
    > [snip]
    It's nice to see this thread from the Python group migrate over here to
    Ruby. I recommend reading the thread for some interesting thoughts on
    Lisp/Scheme, Python and programming languages in general.

    I think Scheme is an excellent language and that learning both Scheme
    and Ruby is a good idea.

    Regards,

    Mark


    Mark Wilson Guest

  6. #5

    Default Re: Python syntax in Lisp and Scheme

    Grzegorz Chrupala wrote:
    ...
    >> >>> def foo(n):
    >> ... box = [n]
    >> ... def foo(i): box[0]+=i; return box[0]
    >> ... return foo
    >> ...
    >
    > It's still a hack that shows an area where Python has unnecessary
    > limitations, isn't it?
    Debatable, and debated. See the "Rebinding names in enclosing
    scopes" section of [url]http://www.python.org/peps/pep-0227.html[/url] .

    Essentially, Guido prefers classes (and instances thereof) to
    closures as a way to bundle state and behavior; thus he most
    emphatically does not want to add _any_ complication at all,
    when the only benefit would be to have "more than one obvious
    way to do it".

    Guido's generally adamant stance for simplicity has been the
    key determinant in the evolution of Python. Guido is also on
    record as promising that the major focus in the next release
    of Python where he can introduce backwards incompatibilities
    (i.e. the next major-number-incrementing release, 3.0, perhaps,
    say, 3 years from now) will be the _elimination_ of many of
    the "more than one way to do it"s that have accumulated along
    the years mostly for reasons of keeping backwards compatibility
    (e.g., lambda, map, reduce, and filter, which Guido mildly
    regrets ever having accepted into the language).

    > As Paul Graham says (<URL:http://www.paulgraham.com/icad.html>):
    >
    >> Python users might legitimately ask why they can't just write
    >>
    >> def foo(n):
    >> return lambda i: return n += i
    The rule Python currently use to determine whether a variable
    is local is maximally simple: if the name gets bound (assigned
    to) in local scope, it's a local variable. Making this rule
    *any* more complicated (e.g. to allow assignments to names in
    enclosing scopes) would just allow "more than one way to do
    it" (making closures a viable alternative to classes in more
    cases) and therefore it just won't happen. Python is about
    offering one, and preferably only one, obvious way to do it,
    for any value of "it". And another key principle of the Zen
    of Python is "simple is better than complex".

    Anybody who doesn't value simplicity and uniformity is quite
    unlikely to be comfortable with Python -- and this should
    amply answer the question about the motivations for reason
    number 1 why the above foo is unacceptable in Python (the
    lambda's body can't rebind name n in an enclosing scope).

    Python draws a firm distinction between expressions and
    statements. Again, the deep motivation behind this key
    distinction can be found in several points in the Zen of
    Python, such as "flat is better than nested" (doing away
    with the expression/statement separation allows and indeed
    encourages deep nesting) and "sparse is better than dense"
    (that 'doing away' would encourage expression/statements
    with a very high density of operations being performed).

    This firm distinction should easily explain other reasons
    why the above foo is unacceptable in Python: n+=i is a
    statement (not an expression) and therefore it cannot be
    held by a 'return' keyword; 'return' is a statement and
    therefore cannot be in the body of a 'lambda' keyword.
    >> or even
    >>
    >> def foo(n):
    >> lambda i: n += i
    And this touches on yet another point of the Zen of Python:
    explicit is better than implicit. Having a function
    implicitly return the last expression it computes would
    violate this point (and is in fact somewhat error-prone,
    in my experience, in the several languages that adopt
    this rule).

    Somebody who is unhappy with this drive for explicitness,
    simplicity, uniformity, and so on, cannot be happy with
    Python. If he wants a very similar language from most
    points of view, BUT with very different philosophies, he
    might well be quite happy with Ruby. Ruby does away with
    any expression/statement distinction; it makes the 'return'
    optional, as a method returns the last thing it computes;
    it revels in "more than one way to do it", clever and cool
    hacks, not perhaps to the extent of Perl, but close enough.

    In Ruby, the spaces of methods and data are separate (i.e.,
    most everything is "an object" -- but, differently from
    Python, methods are not objects in Ruby), and I do not
    think, therefore, that you can write a method that builds
    and returns another method, and bind the latter to a name --
    but you can return an object with a .call method, a la:

    def outer(a) proc do |b| a+=b end end

    x = outer(23)
    puts x.call(100) # emits 123
    puts x.call(100) # emits 223

    [i.e., I can't think of any way you could just use x(100)
    at the end of such a snippet in Ruby -- perhaps somebody
    more expert of Ruby than I am can confirm or correct...?]
    but apart from this it seems closer to what the above
    quotes appear to be probing for. In particular, it lets
    you be MUCH, MUCH denser, if that is your purpose in life,
    easily squeezing that outer function into a (short) line.
    Python is NOT about making code very dense, indeed, as
    above mentioned, it sees _sparseness_ as a plus; a typical
    Pythonista would cringe at the density of that 'outer'
    and by contrast REVEL at the "sparsity" and "explicitness"
    (due to the many names involved:-) of, e.g.:

    def make_accumulator(initial_value):
    accumulator = Bunch(value=initial_value)
    def accumulate(addend):
    accumulator.value += addend
    return accumulator.value
    return accumulate

    accumulate = make_accumulator(23)
    print accumulate(100) # emits 123
    print accumulate(100) # emits 223


    (using the popular Bunch class commonly defined as:
    class Bunch(object):
    def __init__(self, **kwds):
    self.__dict__.update(kwds)
    ). There is, of course, a cultural gulf between this
    verbose 6-liner [using an auxiliary class strictly for
    reasons of better readability...!] and the terse Ruby
    1-liner above, and no doubt most practitioners of both
    languages would in practice choose intermediate levels,
    such as un-densifying the Ruby function into:


    def outer(a)
    proc do |b|
    a+b
    end
    end

    or shortening/densifying the Python one into:

    def make_accumulator(a):
    value = [a]
    def accumulate(b):
    value[0] += b
    return value[0]
    return accumulate

    but I think the "purer" (more extreme) versions are
    interesting "tipizations" for the languages, anyway.


    Alex

    Alex Martelli Guest

  7. #6

    Default Re: Python syntax in Lisp and Scheme

    >>>>> "A" == Alex Martelli <aleax@aleax.it> writes:

    A> [i.e., I can't think of any way you could just use x(100)
    A> at the end of such a snippet in Ruby -- perhaps somebody
    A> more expert of Ruby than I am can confirm or correct...?]

    Module#define_method


    Guy Decoux

    ts Guest

  8. #7

    Default Re: Python syntax in Lisp and Scheme

    "Alex Martelli" wrote:
    ....
    > def outer(a) proc do |b| a+=b end end
    >
    > x = outer(23)
    > puts x.call(100) # emits 123
    > puts x.call(100) # emits 223
    >
    > [i.e., I can't think of any way you could just use x(100)
    > at the end of such a snippet in Ruby -- perhaps somebody
    > more expert of Ruby than I am can confirm or correct...?]
    Guy is probably thinking about something like this

    ---
    def outer(sym,a)
    Object.instance_eval {
    private # define a private method
    define_method(sym) {|b| a+=b }
    }
    end

    outer(:x,24)

    p x(100) # 124
    p x(100) # 224
    ---


    but there is no way to write a ``method returning
    method ::outer in Ruby that could be used in the form

    ----
    x = outer(24)
    x(100)
    ----

    On the other hand, using []-calling convention
    and your original definition, you get - at least
    visually - fairly close.

    ---
    def outer(a) proc do |b| a+=b end end

    x = outer(23)
    puts x[100] # emits 123
    puts x[100] # emits 223
    ---


    /Christoph


    Christoph Guest

  9. #8

    Default Re: Python syntax in Lisp and Scheme

    "Grzegorz ChrupaÅ,a" wrote:
    ....
    >
    > I don't really feel quite qualified discuss Ruby's design decisions wrt
    the
    > relation between methods, procedures and objects, but I don't think the
    > split between methods and objects is as deep as you claim:
    There is a huge difference between ``garden variety'' Ruby functions,
    usually called methods, ala

    def foo() end

    and Method objects like

    meth = "meth".method(:foo)

    The former really ``live'' outside of Ruby's object space, the latter are
    concrete living breathing objects - i.e. instances of the Method class.


    ---
    def enumerate_method_objects
    cnt = ObjectSpace.each_object(Method) {|mth|
    p mth
    }
    puts "There are #{cnt} Method objects\n\n"
    end

    class String
    def foo
    self + " hello"
    end
    end


    ##
    ary = [1,2]
    ruby = "Ruby"

    enumerate_method_objects() # no Method object exists

    ## create two Method objects
    ary_length = ary.method(:length)
    ruby_foo = ruby.method(:foo)

    enumerate_method_objects() # 2 Method object exists

    ## manipulate the objects ``ary'' and ``ruby'' a bit
    p ary << 3 # [1, 2, 3]
    p ruby << " says" # "Ruby says"

    ## use the method objects
    p ary_length[] # 3
    p ruby_foo[] # "Ruby says hello"

    ## which is pretty much the same as writing

    p ary.length() # 3
    p ruby.foo() # "Ruby says hello"

    ---

    resulting

    ---
    There are 0 Method objects

    #<Method: String#foo>
    #<Method: Array#length>
    There are 2 Method objects

    [1, 2, 3]
    "Ruby says"
    3
    "Ruby says hello"
    3
    "Ruby says hello"
    ---

    > I do tend to think that Ruby would be better off with a more unified
    > treatment of blocks, procedures and methods, but my understanding of the
    > issues involved is very incomplete. Perhaps Smalltalk experts would be
    more
    > qualified to comment on this.

    By not elevating function (methods) into real objects, you pretty much
    avoided the problem of users complaining about the lack of higher order
    function objects:-)


    /Christoph


    Christoph Guest

  10. #9

    Default Re: Python syntax in Lisp and Scheme

    In <blnsoq$1fdh$1@ulysses.news.tiscali.de> Christoph wrote:
    > There is a huge difference between ``garden variety'' Ruby functions,
    > usually called methods, ala
    >
    > def foo() end
    >
    > and Method objects like
    >
    > meth = "meth".method(:foo)
    >
    > The former really ``live'' outside of Ruby's object space, the latter
    > are concrete living breathing objects - i.e. instances of the Method
    > class.
    Where do they live? I haven't yet delved far enough into Ruby's
    internals to see. But observe:

    irb(main):001:0> def foo() end; meth = method(:foo)
    #<Method: Object(Object)#foo>

    It seems that regardless of whether they exist in ObjectSpace or not,
    classless methods can indeed be treated as objects.

    And actually, now that I dug a little further, they seem to just be made
    private methods of Object.

    irb(main):006:0> Object.private_methods.include? 'foo'
    true

    As to the design wisdom of this, I can't comment too much, though it
    does strike me intuitively as a little hackish.
    Kevin Bullock Guest

  11. #10

    Default Re: Python syntax in Lisp and Scheme

    il Wed, 15 Oct 2003 18:08:31 +0000 (UTC), Kevin Bullock
    <bullok@mnsu.edu> ha scritto::

    >
    >Where do they live? I haven't yet delved far enough into Ruby's
    >internals to see. But observe:
    >
    >irb(main):001:0> def foo() end; meth = method(:foo)
    >#<Method: Object(Object)#foo>
    >
    >It seems that regardless of whether they exist in ObjectSpace or not,
    >classless methods can indeed be treated as objects.
    I think you missed the point.
    what he meant is that 'foo' is not a real object unless you define it
    via method(:foo).
    The fact that it is a function-like method instead of a method bound
    to a object is not important.
    >And actually, now that I dug a little further, they seem to just be made
    >private methods of Object.
    >
    >irb(main):006:0> Object.private_methods.include? 'foo'
    >true
    actually, private method of Kernel, I suppose.
    It may sem hakish to you, but if this won't be like this how would you
    do it ?

    if you require a class to define a method you would end with
    java-like

    class Useless
    def self.met
    ..
    end
    end

    class My
    def f
    Useless.met
    OntherUseless.met2
    ...
    end
    end

    isntead of

    def met
    ....
    end
    def f
    met
    met2
    ...
    end

    BTW you should use a klass (or a module) for the method unless
    klass.is_a?Useless :)
    gabriele renzi Guest

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139