Why I chose Python over Ruby

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Francois

    #1

    Why I chose Python over Ruby

    I discovered Python a few months ago and soon decided to invest time in
    learning it well. While surfing the net for Python, I also saw the hype
    over Ruby and tried to find out more about it, before I definitely
    embarked on studying and practicing Python. I recently found two
    sufficient answers for choosing Python - which is a personal choice and
    others may differ, but I'd like to share it anyway :

    1) In Ruby there is a risk of "Variable/Method Ambiguity" when calling
    a method with no parameters without using () :

    Here is an excerpt from the book "Programmin g Ruby The Pragmatic
    Programmer's Guide".



    "When Ruby sees a name such as ``a'' in an expression, it needs to
    determine if it is a local variable reference or a call to a method
    with no parameters. To decide which is the case, Ruby uses a heuristic.
    As Ruby reads a source file, it keeps track of symbols that have been
    assigned to. It assumes that these symbols are variables. When it
    subsequently comes across a symbol that might be either a variable or a
    method call, it checks to see if it has seen a prior assignment to that
    symbol. If so, it treats the symbol as a variable; otherwise it treats
    it as a method call. As a somewhat pathological case of this, consider
    the following code fragment, submitted by Clemens Hintze."

    def a
    print "Function 'a' called\n"
    99
    end

    for i in 1..2
    if i == 2
    print "a=", a, "\n"
    else
    a = 1
    print "a=", a, "\n"
    end
    end

    OUTPUTS >>

    a=1
    Function 'a' called
    a=99

    "During the parse, Ruby sees the use of ``a'' in the first print
    statement and, as it hasn't yet seen any assignment to ``a,'' assumes
    that it is a method call. By the time it gets to the second print
    statement, though, it has seen an assignment, and so treats ``a'' as a
    variable.
    Note that the assignment does not have to be executed---Ruby just has
    to have seen it. This program does not raise an error."

    I tried the code above at the interactive Ruby 1.8.2 interpreter :



    2) Ruby does not have true first-class functions living in the same
    namespace as other variables while Python does :

    In Python :

    def sayHello (name) :
    return "Hello " + name
    print sayHello("Mr. Bond")
    m = sayHello
    print m
    print m("Miss Moneypenny")

    OUTPUTS >>

    Hello Mr. Bond
    <function sayHello at 0x0102E870>
    Hello Miss Moneypenny

    In Ruby you need extra syntax that ruins the "first-class-ness" :

    def sayHello (name)
    return "Hello " + name
    end
    puts sayHello("Mr. Bond")
    m = Class.method(:s ayHello)
    puts m
    puts m.call("Miss Moneypenny")

    OUTPUTS >>

    Hello Mr. Bond
    #<Method: Class(Object)#s ayHello>
    Hello Miss Moneypenny

    4) Conclusion

    Since I did a lot of work in Scheme, rigor and consistency are most
    important to me, and Python certainly meets this requirement.

    --- Python newbie

  • Sybren Stüvel

    #2
    Re: Why I chose Python over Ruby

    Francois wrote:
    [color=blue]
    > I discovered Python a few months ago and soon decided to invest time
    > in learning it well. While surfing the net for Python, I also saw
    > the hype over Ruby and tried to find out more about it, before I
    > definitely embarked on studying and practicing Python. I recently
    > found two sufficient answers for choosing Python - which is a
    > personal choice and others may differ, but I'd like to share it
    > anyway[/color]

    Thanks for sharing that. I had a gut feeling Python would be better
    than Ruby, but I never took the time to study Ruby. Now I do have some
    nice stones to throw at Ruby-fanatics ;-)

    Sybren

    Comment

    • Alex Martelli

      #3
      Re: Why I chose Python over Ruby

      Francois <florasol@hotma il.com> wrote:
      [color=blue]
      > Since I did a lot of work in Scheme, rigor and consistency are most
      > important to me, and Python certainly meets this requirement.[/color]

      It does pretty well, with some tempering of pragmatism -- but, to play
      devil's advocate, Ruby isn't far in this respect. In either case, you
      will find more rigor and consistency in good languages of a more
      academic bent, such as Haskell, but will surely find a lot in either
      Ruby or Python.

      The trick about distinguishing a name's exact nature based on whether
      the compiler sees an assignment to that name in some part of code is
      found in both languages, albeit in different ways. In Ruby, as you've
      pointed out, it's the heuristic used to disambiguate local variable
      access from zero-argument method calls, and the "part of code" is the
      function up to the point of access. In Python, it's used to disambiguate
      local from global or free variables, and the "part of code" is the body
      of the whole function (Ruby does not need to make this latter
      distinction because it strops global names with a leading sigil -- $a is
      always the global variable a, just like @a is always the instance
      attribute a, which we'd write self.a in Python). Another subtle case in
      Ruby is whether an assignment such as a=23 _within a block_ is meant to
      be local to the block or meant to rebind local name 'a' within the
      enclosing function; again, the heuristic is similar, depending only on
      whether the compiler had seen another assignment to a before it saw the
      block (Python forbids the rebinding of variables coming from an
      enclosing but non-global scope, to avoid facing this issue).

      All in all, Python is more likely with these heuristics to respect the
      principles (from the "zen of python", import this at an interactive
      prompt): in face of ambiguity, refuse the temptation to guess; errors
      should not pass silently, unless explicitly silenced. I.e., any Python
      code which accidentally runs afoul of these heuristics is likely to
      raise an exception, alerting you to the situation. Ruby strives rather
      for a "do what I mean" ethos, and obviously some people prefer that.

      I also share your preference for a single namespace for callable and
      non-callable values, as in Python (and Scheme, Lisp, C++, ...), rather
      than disjoint namespaces as in Ruby (and Smalltalk), but I do not see it
      as a question of rigor and consistency at all -- e.g., I do not perceive
      Smalltalk as less rigorous or consistent than C++, on the contrary.

      So, I agree with your choice, and I think I understand your motivations,
      but I do not entirely share your motivations, personally speaking.


      Alex

      Comment

      • Francois

        #4
        Re: Why I chose Python over Ruby

        Alex Martelli wrote:[color=blue]
        >
        > I also share your preference for a single namespace for callable and
        > non-callable values, as in Python (and Scheme, Lisp, C++, ...), rather
        > than disjoint namespaces as in Ruby (and Smalltalk), but I do not see it
        > as a question of rigor and consistency at all -- e.g., I do not perceive
        > Smalltalk as less rigorous or consistent than C++, on the contrary.
        >
        > So, I agree with your choice, and I think I understand your motivations,
        > but I do not entirely share your motivations, personally speaking.
        >[/color]

        Thanks Alex for your excellent explanations. I have the Python Cookbook
        2nd Ed., and I highly appreciate your knowledge and experience.

        I guess my choice of words "rigor and consistency" was not very good.
        In this context "rigor" meant enforcing rules (for example having to
        use parentheses to call a method) to prevent ambiguity rather than
        depending on heuristics. Also "consistenc y" meant doing things as
        uniformly as possible (for example always call a method with the same
        syntax, whether the variable referencing it is the original name or an
        alias).

        -- Francois

        Comment

        • mensanator@aol.com

          #5
          Re: Why I chose Python over Ruby


          Francois wrote:[color=blue]
          > I discovered Python a few months ago and soon decided to invest time in
          > learning it well. While surfing the net for Python, I also saw the hype
          > over Ruby and tried to find out more about it, before I definitely
          > embarked on studying and practicing Python. I recently found two
          > sufficient answers for choosing Python - which is a personal choice and
          > others may differ, but I'd like to share it anyway :
          >
          > 1) In Ruby there is a risk of "Variable/Method Ambiguity" when calling
          > a method with no parameters without using () :[/color]
          <snip>
          [color=blue]
          > 2) Ruby does not have true first-class functions living in the same
          > namespace as other variables while Python does :[/color]
          <snip>
          [color=blue]
          > 4) Conclusion[/color]
          <snip>
          [color=blue]
          > Since I did a lot of work in Scheme, rigor and consistency are most
          > important to me,[/color]

          What happened to 3)?
          [color=blue]
          >and Python certainly meets this requirement.
          >
          > --- Python newbie[/color]

          Comment

          • Francois

            #6
            Re: Why I chose Python over Ruby

            mensanator@aol. com wrote:[color=blue]
            > What happened to 3)?
            >[/color]
            "4)" should have read "3)". I found the typo after I posted. I guess I
            lack "rigor" myself !

            Comment

            • Francois

              #7
              Re: Why I chose Python over Ruby

              Alex Martelli wrote:[color=blue]
              >
              > I also share your preference for a single namespace for callable and
              > non-callable values, as in Python (and Scheme, Lisp, C++, ...), rather
              > than disjoint namespaces as in Ruby (and Smalltalk), but I do not see it
              > as a question of rigor and consistency at all -- e.g., I do not perceive
              > Smalltalk as less rigorous or consistent than C++, on the contrary.
              >
              > So, I agree with your choice, and I think I understand your motivations,
              > but I do not entirely share your motivations, personally speaking.
              >[/color]

              Thanks Alex for your excellent explanations. I have the Python Cookbook
              2nd Ed., and I highly appreciate your knowledge and experience.

              I guess my choice of words "rigor and consistency" was not very good.
              In this context "rigor" meant enforcing rules (for example having to
              use parentheses to call a function) to prevent ambiguity rather than
              depending on heuristics. Also "consistenc y" meant doing things as
              uniformly as possible (for example always call a function with the same
              syntax, whether the variable referencing it is the original name or an
              alias).

              -- Francois

              Comment

              • Alex Martelli

                #8
                Re: Why I chose Python over Ruby

                Francois <florasol@hotma il.com> wrote:
                ...[color=blue]
                > I guess my choice of words "rigor and consistency" was not very good.
                > In this context "rigor" meant enforcing rules (for example having to
                > use parentheses to call a method) to prevent ambiguity rather than
                > depending on heuristics. Also "consistenc y" meant doing things as
                > uniformly as possible (for example always call a method with the same
                > syntax, whether the variable referencing it is the original name or an
                > alias).[/color]

                Ah yes, these are definitely valid nuances for the terms you've used, I
                admit that. Python's yearning for "only one obvious way" to do
                something, even though it's a goal to aim for rather than a reality in
                every case, surely does play towards these preferences, while Ruby (not
                quite as much as Perl, but still) has a more exhuberant approach, where
                having multiple obvious ways to do the same thing is seen as a plus, not
                a minus (a classic tiny example is the ability to get the number of
                items of an array a by EITHER a.size or a.length, just like for a C++
                std::string, with no difference whatsoever among the two synonyms).

                So, I'm NOT saying your word choice was not very good: you used words
                who do mean what you intend (among other meanings, but then, that's the
                curse AND blessing of natural language;-). But anyway, thanks for the
                clarification! Maybe "uniformity " (though it, too, may suggest
                different and not accurate things) could be usefully added to help
                communicate your intended meaning (or maybe, for most people, if they
                hear all of "rigor, consistency, uniformity", would think of some Nazi
                language woefully constraining their expression...?-)


                Alex

                Comment

                • Alex Martelli

                  #9
                  Re: Why I chose Python over Ruby

                  mensanator@aol. com <mensanator@aol .com> wrote:
                  ...[color=blue][color=green]
                  > > 1) In Ruby there is a risk of "Variable/Method Ambiguity" when calling[/color][/color]
                  ...[color=blue][color=green]
                  > > 2) Ruby does not have true first-class functions living in the same[/color][/color]
                  ...[color=blue][color=green]
                  > > 4) Conclusion[/color][/color]
                  ...[color=blue]
                  > What happened to 3)?[/color]

                  I thought the OP was counting up by powers of 2 to indicate the
                  "exponentia l" nature of the issues...;-)


                  Alex

                  Comment

                  • Schüle Daniel

                    #10
                    Re: Why I chose Python over Ruby

                    Hi Alex

                    [...]
                    [color=blue]
                    > The trick about distinguishing a name's exact nature based on whether
                    > the compiler sees an assignment to that name in some part of code is
                    > found in both languages, albeit in different ways. In Ruby, as you've
                    > pointed out, it's the heuristic used to disambiguate local variable
                    > access from zero-argument method calls, and the "part of code" is the
                    > function up to the point of access. In Python, it's used to disambiguate
                    > local from global or free variables, and the "part of code" is the body
                    > of the whole function (Ruby does not need to make this latter
                    > distinction because it strops global names with a leading sigil -- $a is
                    > always the global variable a, just like @a is always the instance
                    > attribute a, which we'd write self.a in Python). Another subtle case in
                    > Ruby is whether an assignment such as a=23 _within a block_ is meant to
                    > be local to the block or meant to rebind local name 'a' within the
                    > enclosing function; again, the heuristic is similar, depending only on
                    > whether the compiler had seen another assignment to a before it saw the
                    > block (Python forbids the rebinding of variables coming from an
                    > enclosing but non-global scope, to avoid facing this issue).[/color]

                    I am not sure what you mean here
                    can you elaborate on this please
                    [color=blue][color=green][color=darkred]
                    >>> def a():[/color][/color][/color]
                    .... q = []
                    .... def b(x):
                    .... def c(y):
                    .... def d(z):
                    .... q.append(x)
                    .... q.append(y)
                    .... q.append(z)
                    .... d(1)
                    .... c(2)
                    .... b(3)
                    .... return q
                    ....[color=blue][color=green][color=darkred]
                    >>> a()[/color][/color][/color]
                    [3, 2, 1]

                    As far as I know this snippet would work only from version 2.2
                    maybe you are talking about older versions of Python

                    Regards, Daniel

                    Comment

                    • Marcin MielżyÅ„ski

                      #11
                      Re: Why I chose Python over Ruby

                      Francois wrote:[color=blue]
                      > I discovered Python a few months ago and soon decided to invest time in
                      > learning it well. While surfing the net for Python, I also saw the hype
                      > over Ruby and tried to find out more about it, before I definitely
                      > embarked on studying and practicing Python. I recently found two
                      > sufficient answers for choosing Python - which is a personal choice and
                      > others may differ, but I'd like to share it anyway :[/color]

                      I use both Python and Ruby and I think You are a little bit unfair in
                      your judgements.

                      [color=blue]
                      >
                      > 1) In Ruby there is a risk of "Variable/Method Ambiguity" when calling
                      > a method with no parameters without using () :[/color]
                      [color=blue]
                      >
                      > def a
                      > print "Function 'a' called\n"
                      > 99
                      > end
                      >
                      > for i in 1..2
                      > if i == 2
                      > print "a=", a, "\n"
                      > else
                      > a = 1
                      > print "a=", a, "\n"
                      > end
                      > end
                      >
                      > OUTPUTS >>
                      >
                      > a=1
                      > Function 'a' called
                      > a=99
                      >[/color]

                      Yes, I agree with that, but being aware of that I have never had any
                      problems. And this problem a arises only in method bodies. When a
                      receiver is specified, there is no ambiguousity (Ruby objects dont have
                      public fields)
                      [color=blue]
                      >
                      > 2) Ruby does not have true first-class functions living in the same
                      > namespace as other variables while Python does :
                      >[/color]

                      Wrong! Ruby has first class functions and unlike Python Ruby supports
                      _true_ closures (Python supports only readonly closures). The first
                      class Ruby functions are the _blocks_.
                      [color=blue]
                      > In Python :
                      >
                      > def sayHello (name) :
                      > return "Hello " + name
                      > print sayHello("Mr. Bond")
                      > m = sayHello
                      > print m
                      > print m("Miss Moneypenny")
                      >
                      > OUTPUTS >>
                      >
                      > Hello Mr. Bond
                      > <function sayHello at 0x0102E870>
                      > Hello Miss Moneypenny
                      >
                      > In Ruby you need extra syntax that ruins the "first-class-ness" :[/color]

                      No, blocks again...
                      [color=blue]
                      >
                      > def sayHello (name)
                      > return "Hello " + name
                      > end
                      > puts sayHello("Mr. Bond")
                      > m = Class.method(:s ayHello)
                      > puts m
                      > puts m.call("Miss Moneypenny")
                      >
                      > OUTPUTS >>
                      >
                      > Hello Mr. Bond
                      > #<Method: Class(Object)#s ayHello>
                      > Hello Miss Moneypenny
                      >
                      > 4) Conclusion
                      >
                      > Since I did a lot of work in Scheme, rigor and consistency are most
                      > important to me, and Python certainly meets this requirement.
                      >
                      > --- Python newbie
                      >[/color]

                      Depends, I like Pythons constructs consistency, but I also like Rubys
                      object model constency

                      lopex

                      Comment

                      • Xavier Morel

                        #12
                        Re: Why I chose Python over Ruby

                        I'll just play the devil's advocate here

                        Francois wrote:[color=blue]
                        > 1) In Ruby there is a risk of "Variable/Method Ambiguity" when calling
                        > a method with no parameters without using () :
                        >[/color]
                        Yes, but that's in my opinion a programmer error, not necessarily a
                        language error.
                        [color=blue]
                        > 2) Ruby does not have true first-class functions living in the same
                        > namespace as other variables while Python does :
                        >
                        > In Ruby you need extra syntax that ruins the "first-class-ness" :
                        >[/color]
                        The extra syntax is a side-effect of the parensless call of method, it
                        doesn't mean that methods are not first-class objects.

                        And Ruby solved this issue with blocks/procs (that and closures are the
                        only reasons I found for blocks to exist in ruby). In python you pass
                        functions around, Ruby's equivalent of unbound functions are
                        blocks/procs, what your code created here is a ruby method, equivalent
                        to a bound method in Python, the semantics are really different (and in
                        Python using this bound method would also require extra work).

                        Comment

                        • Terry Reedy

                          #13
                          Re: Why I chose Python over Ruby


                          "Schüle Daniel" <uval@rz.uni-karlsruhe.de> wrote in message
                          news:dufm2r$p89 $1@news2.rz.uni-karlsruhe.de...[color=blue][color=green]
                          >> block (Python forbids the rebinding of variables coming from an
                          >> enclosing but non-global scope, to avoid facing this issue).[/color]
                          >
                          > I am not sure what you mean here
                          > can you elaborate on this please
                          >[color=green][color=darkred]
                          > >>> def a():[/color][/color]
                          > ... q = []
                          > ... def b(x):
                          > ... def c(y):
                          > ... def d(z):
                          > ... q.append(x)
                          > ... q.append(y)
                          > ... q.append(z)
                          > ... d(1)
                          > ... c(2)
                          > ... b(3)
                          > ... return q
                          > ...[color=green][color=darkred]
                          > >>> a()[/color][/color]
                          > [3, 2, 1][/color]

                          You are mutating q, not rebinding it. As another poster discovered,
                          replacing the appends by the nominally equivalent augmented assignments:

                          q += [x] #etc

                          does not work. Since the compiler does not know the type of q, it assumes
                          that it needs to be rebound and compiles code to do so, even though here is
                          would be to the same object. That makes q an (uninitialized) local.

                          Terry Jan Reedy




                          Comment

                          • Roy Smith

                            #14
                            Re: Why I chose Python over Ruby

                            Xavier Morel <xavier.morel@m asklinn.net> wrote:
                            [color=blue]
                            > Francois wrote:[color=green]
                            > > 1) In Ruby there is a risk of "Variable/Method Ambiguity" when calling
                            > > a method with no parameters without using () :
                            > >[/color]
                            > Yes, but that's in my opinion a programmer error, not necessarily a
                            > language error.[/color]

                            In Python, you can make exactly the opposite error. Both of these are
                            perfectly legal and reasonable things to write, where foo is a function:

                            a = foo
                            a = foo()

                            Actually, if you want to have a little fun, try:

                            def foo:
                            return foo

                            then you can write:

                            a = foo
                            a = foo()
                            a = foo()()
                            a = foo()()()
                            a = foo()()()()
                            etc.

                            Comment

                            • Bil Kleb

                              #15
                              Re: Why I chose Python over Ruby

                              Xavier Morel wrote:[color=blue]
                              >[color=green]
                              >> 2) Ruby does not have true first-class functions living in the same
                              >> namespace as other variables while Python does :
                              >>
                              >> In Ruby you need extra syntax that ruins the "first-class-ness" :
                              >>[/color]
                              > The extra syntax is a side-effect of the parensless call of method, it
                              > doesn't mean that methods are not first-class objects.[/color]

                              The parensless calls also allow one to write beautiful
                              DSLs with Ruby.

                              --
                              Bil
                              FUN3D suite of CFD simulation and design tools

                              Comment

                              Working...