Syntax across languages

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • bearophileHUGS@lycos.com

    Syntax across languages

    This post comes from a boring morning, if you are busy ignore this.
    This post is only for relaxed people.

    I've found this page, "Syntax Across Languages", it contains many
    errors and omissions, but it's interesting.


    Compared to the other languages Python comes out rather well, in quick
    scan only few things look better in other languages (usually all/most
    things are possible in all languages, so it's often just a matter of
    brevity, elegance, etc):

    - Nestable Pascal-like comments (useful): (* ... *)

    - Information about the current line and file as Ruby:
    __LINE__ __FILE__
    Instead of the python version:
    inspect.stack()[0][2] inspect.stack()[0][1]

    - ~== for approximate FP equality

    - comparison returns 4 values (i.e. inferior, equal, superior or not
    comparable), as in Pliant:
    "compare"

    - identity function: "identity" as in Common Lisp (probably of little
    use in Python).

    - Exception retrying: after catching an exception, tell the snippet to
    be re-run
    "retry" as in Ruby

    - object cloning: obj.copy() obj.deepcopy()

    - accessing parent method:
    super as in Ruby, instead as in Python:
    super(Class, self).meth(args )

    - recursive "flatten" as in Ruby (useful)

    Probably there are some errors of mine too, there are many things I
    don't know aboyt Python yet.

    Bye,
    bearophile

  • Fredrik Lundh

    #2
    Re: Syntax across languages

    bearophileHUGS@ lycos.com wrote:
    [color=blue]
    > - Information about the current line and file as Ruby:
    > __LINE__ __FILE__
    > Instead of the python version:
    > inspect.stack()[0][2] inspect.stack()[0][1][/color]

    (that's (mostly) CPython-dependent, and should be avoided)
    [color=blue]
    > - ~== for approximate FP equality[/color]

    str(a) == str(b)
    [color=blue]
    > - comparison returns 4 values (i.e. inferior, equal, superior or not
    > comparable), as in Pliant: "compare"[/color]
    [color=blue][color=green][color=darkred]
    >>> cmp("a", "b")[/color][/color][/color]
    -1[color=blue][color=green][color=darkred]
    >>> cmp("a", "a")[/color][/color][/color]
    0[color=blue][color=green][color=darkred]
    >>> cmp("b", "a")[/color][/color][/color]
    1[color=blue][color=green][color=darkred]
    >>> cmp("ä", u"ä")[/color][/color][/color]
    Traceback (most recent call last):
    File "<stdin>", line 1, in ?
    UnicodeDecodeEr ror: 'ascii' codec can't decode byte /.../

    sure looks like four possible outcomes.
    [color=blue]
    > - identity function: "identity" as in Common Lisp (probably of little
    > use in Python).[/color]

    id(a)
    [color=blue]
    > - Exception retrying: after catching an exception, tell the snippet to
    > be re-run "retry" as in Ruby[/color]
    [color=blue][color=green][color=darkred]
    >>> x = 0
    >>> while 1:[/color][/color][/color]
    .... try:
    .... x += 1
    .... if x <= 5:
    .... raise ValueError
    .... except ValueError:
    .... print "retry"
    .... continue
    .... else:
    .... break
    ....
    retry
    retry
    retry
    retry
    retry[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]
    [color=blue]
    > - object cloning: obj.copy() obj.deepcopy()[/color]

    import copy

    (cloning is usually a sign of a design problem in python. if you think
    you need it, you probably don't. if you really think you need it, import
    copy.)
    [color=blue]
    > - recursive "flatten" as in Ruby (useful)[/color]

    if you can define the semantics, it's a few lines of code. if you're not
    sure about the semantics, a built-in won't help you...

    etc.

    </F>



    Comment

    • bearophileHUGS@lycos.com

      #3
      Re: Syntax across languages

      Thank you for the comments, Fredrik Lundh.
      [color=blue]
      >(that's (mostly) CPython-dependent, and should be avoided)<[/color]

      Then a non CPython-dependent way of doing it can be even more useful.

      [color=blue]
      >sure looks like four possible outcomes.<[/color]

      Right (but to me four explicit answers seem better than three answers
      and an exception still).

      [color=blue]
      >id(a)<[/color]

      I think in Python it can be something more like (but it's of little
      use):
      def identity(x): return x
      Or:
      identity = lambda x: x

      [color=blue]
      >(cloning is usually a sign of a design problem in python. if you think[/color]
      you need it, you probably don't. if you really think you need it,
      import
      copy.)<

      I agree (importing a module is worse than using a standard copy method,
      but I think this can be seen as a way to discourage the use of copy in
      Python).

      [color=blue]
      >if you can define the semantics, it's a few lines of code. if you're not[/color]
      sure about the semantics, a built-in won't help you...<

      I think the language needs a fast built-in version of it. If something
      is both inside Mathematica and Ruby, then probably it can be useful in
      Python too :-)

      Bye and thank you,
      bearophile

      Comment

      • Fredrik Lundh

        #4
        Re: Syntax across languages

        bearophileHUGS@ lycos.com wrote:
        [color=blue][color=green]
        > >if you can define the semantics, it's a few lines of code. if you're not[/color]
        > sure about the semantics, a built-in won't help you...<
        >
        > I think the language needs a fast built-in version of it. If something
        > is both inside Mathematica and Ruby, then probably it can be useful in
        > Python too :-)[/color]

        numpy already has one:



        (it's probably there in scipy too, but the scipy docs don't appear to be
        freely available. hmm...)

        PIL also has one:



        there's also one in Tkinter:
        [color=blue][color=green][color=darkred]
        >>> import Tkinter
        >>> Tkinter._flatte n(["abc", 1, 2, (3, 4, 5), None, [6, 7, 8, (9,)]])[/color][/color][/color]
        ('abc', 1, 2, 3, 4, 5, 6, 7, 8, 9)

        to create a generic version, you have to decide which sequences to
        treat like sequences, and which sequences you don't want to treat
        like sequences...

        </F>



        Comment

        • Fredrik Lundh

          #5
          Re: Syntax across languages

          bearophileHUGS@ lycos.com wrote:
          [color=blue][color=green]
          > >sure looks like four possible outcomes.<[/color]
          >
          > Right (but to me four explicit answers seem better than three answers
          > and an exception still).[/color]

          def cmp4(a, b):
          try:
          return cmp(a, b)
          except:
          return None

          </F>



          Comment

          • bearophileHUGS@lycos.com

            #6
            Re: Syntax across languages

            Thank you Fredrik Lundh for showing everybody that indeed lot of people
            feel the need of such function in Python too.
            [color=blue]
            >to create a generic version, you have to decide which sequences to treat like sequences<[/color]

            In my version I give the function some parameter(s) to define what I
            want to flatten. I'll probably put it in the cookbook...

            Bye,
            Bearophile

            Comment

            • Fredrik Lundh

              #7
              Re: Syntax across languages

              bearophileHUGS@ lycos.com wrote:
              [color=blue]
              > Thank you Fredrik Lundh for showing everybody that indeed lot of people
              > feel the need of such function in Python too.[/color]

              you seem to be missing the point: all those versions are highly optimized,
              and tuned for the specific use-cases. a generic flatten would be useless
              in all three cases.

              </F>



              Comment

              • beza1e1

                #8
                Re: Syntax across languages

                >>> id("blub")
                -1210548288

                This is not identity in a mathematical view.

                def identity(x): return x

                It has is uses. I had some kind of parser and had a dict like this:
                {case: function, ...} It had to be a dict, because i wanted to
                dynamically add and remove cases. In some cases nothing had to be done.
                To represent this in the dict a identity function is needed. There
                surely are other ways, but identity was the most expressive in my eyes.

                Nice read, by the way. Thanks for sharing ;)

                Comment

                • bonono@gmail.com

                  #9
                  Re: Syntax across languages

                  just curious, how can this identity function be used ? In haskell,
                  because all functions are curried, I can sort of visualize/understand
                  how id is used. Not quite understand how it can be used in python.

                  beza1e1 wrote:[color=blue][color=green][color=darkred]
                  > >>> id("blub")[/color][/color]
                  > -1210548288
                  >
                  > This is not identity in a mathematical view.
                  >
                  > def identity(x): return x
                  >
                  > It has is uses. I had some kind of parser and had a dict like this:
                  > {case: function, ...} It had to be a dict, because i wanted to
                  > dynamically add and remove cases. In some cases nothing had to be done.
                  > To represent this in the dict a identity function is needed. There
                  > surely are other ways, but identity was the most expressive in my eyes.
                  >
                  > Nice read, by the way. Thanks for sharing ;)[/color]

                  Comment

                  • Fredrik Lundh

                    #10
                    Re: Syntax across languages

                    "beza1e1" wrote:
                    [color=blue]
                    > It has is uses. I had some kind of parser and had a dict like this:
                    > {case: function, ...} It had to be a dict, because i wanted to
                    > dynamically add and remove cases. In some cases nothing had to be done.
                    > To represent this in the dict a identity function is needed.[/color]

                    in Python, that's spelled "lambda x: x" (or "None", in some contexts)

                    </F>



                    Comment

                    • garabik-news-2005-05@kassiopeia.juls.savba.sk

                      #11
                      Re: Syntax across languages

                      Fredrik Lundh <fredrik@python ware.com> wrote:[color=blue]
                      >[color=green]
                      >> - comparison returns 4 values (i.e. inferior, equal, superior or not
                      >> comparable), as in Pliant: "compare"[/color]
                      >[color=green][color=darkred]
                      >>>> cmp("a", "b")[/color][/color]
                      > -1[color=green][color=darkred]
                      >>>> cmp("a", "a")[/color][/color]
                      > 0[color=green][color=darkred]
                      >>>> cmp("b", "a")[/color][/color]
                      > 1[color=green][color=darkred]
                      >>>> cmp("ä", u"ä")[/color][/color]
                      > Traceback (most recent call last):
                      > File "<stdin>", line 1, in ?
                      > UnicodeDecodeEr ror: 'ascii' codec can't decode byte /.../[/color]

                      that is not because of the comparison, but because of the coercion:
                      [color=blue][color=green][color=darkred]
                      >>> 'ä'+u'ä'[/color][/color][/color]
                      Traceback (most recent call last):
                      File "<stdin>", line 1, in ?
                      UnicodeDecodeEr ror: 'ascii' codec can't decode byte 0xc3 in position 0: ordinal not in range(128)[color=blue][color=green][color=darkred]
                      >>>[/color][/color][/color]
                      [color=blue]
                      >
                      > sure looks like four possible outcomes.[/color]

                      [color=blue][color=green][color=darkred]
                      >>> cmp(1, 1+2j)[/color][/color][/color]
                      Traceback (most recent call last):
                      File "<stdin>", line 1, in ?
                      TypeError: cannot compare complex numbers using <, <=, >, >=


                      a fifth one :-)


                      --
                      -----------------------------------------------------------
                      | Radovan Garabík http://kassiopeia.juls.savba.sk/~garabik/ |
                      | __..--^^^--..__ garabik @ kassiopeia.juls .savba.sk |
                      -----------------------------------------------------------
                      Antivirus alert: file .signature infected by signature virus.
                      Hi! I'm a signature virus! Copy me into your signature file to help me spread!

                      Comment

                      • Alex Martelli

                        #12
                        Re: Syntax across languages

                        <bearophileHUGS @lycos.com> wrote:
                        ...[color=blue]
                        > - Information about the current line and file as Ruby:
                        > __LINE__ __FILE__
                        > Instead of the python version:
                        > inspect.stack()[0][2] inspect.stack()[0][1][/color]

                        __file__ is around in Python, too, but there's no __line__ (directly).
                        [color=blue]
                        > - identity function: "identity" as in Common Lisp (probably of little
                        > use in Python).[/color]

                        I've seen enough occurrences of "lambda x: x" in Python code with a
                        generally functional style that I'd love to have operator.identi ty (and
                        a few more trivial functions like that) for readability;-)
                        [color=blue]
                        > - object cloning: obj.copy() obj.deepcopy()[/color]

                        Like (say) container.lengt h() versus len(container), I'm perfectly
                        comfortable relying on functions rather than methods. It even makes it
                        easier to allow several alternative ways for an object to provide such
                        functionality (e.g. by implementing __getstate__ and maybe __setstate__
                        as opposed to __copy__ and maybe __deepcopy__) -- which would be
                        feasible even with a method, of course (Template Method DP), but IS
                        easier when relying on functions (and operators).
                        [color=blue]
                        > - accessing parent method:
                        > super as in Ruby, instead as in Python:
                        > super(Class, self).meth(args )[/color]

                        Ruby's syntax may be better for a single-inheritance language, but
                        Python's, while less elegant, may be more appropriate in the presence of
                        multiple inheritance.
                        [color=blue]
                        > - recursive "flatten" as in Ruby (useful)[/color]

                        Usage too rare to deserve a built-in method, IMHO, considering the ease
                        of coding the equivalent:

                        def flatten(x):
                        if not isinstance(x, list): yield x
                        for y in x: yield flatten(y)

                        What I _do_ envy Ruby's syntax, a little, is the convention of ending
                        methodnames with exclamation mark to indicate "modifies in-place" (and,
                        secondarily, question mark to indicate predicates). The distinction
                        between, e.g.,
                        y = x.sort()
                        and
                        x.sort!()
                        in Ruby is much clearer, IMHO, than that between, say,
                        y = sorted(x)
                        and
                        x.sort()
                        in Python...


                        Alex

                        Comment

                        • Alex Martelli

                          #13
                          Re: Syntax across languages

                          bonono@gmail.co m <bonono@gmail.c om> wrote:
                          [color=blue]
                          > just curious, how can this identity function be used ? In haskell,
                          > because all functions are curried, I can sort of visualize/understand
                          > how id is used. Not quite understand how it can be used in python.[/color]

                          There was a very recent example posted to this group (by Robin Becker, I
                          believe, looking for ways to "override property"), something like:
                          def __init__(self, validate=None):
                          if not validate: validate = lambda x: x
                          self.validate = validate
                          and later on, self.validate is always unconditionally called to extract
                          a valid value from an input argument to another method -- a nicer style,
                          arguably, than assigning self.validate unconditionally and then having
                          to test each and every time in the other method. Such subcases of the
                          well-known "Null Object" design pattern, where you don't want to store
                          None to mean "no such object" but, to avoid repeated testing, rather
                          want to store an object which "reliably does nothing", are reasonably
                          common. In an abstract way, they're somewhat akin to having the 'pass'
                          statement in the language itself;-).


                          Alex

                          Comment

                          • skip@pobox.com

                            #14
                            Re: Syntax across languages


                            Alex> I've seen enough occurrences of "lambda x: x" in Python code with
                            Alex> a generally functional style that I'd love to have
                            Alex> operator.identi ty (and a few more trivial functions like that) for
                            Alex> readability;-)

                            But, but, but [Skip gets momentarily apoplectic, then recovers...]
                            "operator.ident ity" is way more to type than "lambda x: x". Plus you have
                            to remember to import the operator module. <0.5 wink>

                            Not to mention which (from "pydoc operator"):

                            [The operator module] exports a set of functions implemented in C
                            corresponding to the intrinsic operators of Python.

                            Last time I checked, Python didn't have an intrinsic "identity" operator.

                            For which reason, I'd be -1 on the idea of an identity function, certainly
                            in the operator module.

                            Skip

                            Comment

                            • Alex Martelli

                              #15
                              Re: Syntax across languages

                              <skip@pobox.com > wrote:
                              [color=blue]
                              > Alex> I've seen enough occurrences of "lambda x: x" in Python code with
                              > Alex> a generally functional style that I'd love to have
                              > Alex> operator.identi ty (and a few more trivial functions like that) for
                              > Alex> readability;-)
                              >
                              > But, but, but [Skip gets momentarily apoplectic, then recovers...]
                              > "operator.ident ity" is way more to type than "lambda x: x". Plus you have
                              > to remember to import the operator module. <0.5 wink>[/color]

                              But, it's way more readable, IMHO.

                              [color=blue]
                              > Not to mention which (from "pydoc operator"):
                              >
                              > [The operator module] exports a set of functions implemented in C
                              > corresponding to the intrinsic operators of Python.
                              >
                              > Last time I checked, Python didn't have an intrinsic "identity" operator.[/color]

                              attrgetter and itemgetter don't exactly correspond to "intrinsic
                              operators", either (getitem, and the built-in getattr, are more like
                              that)... yet module operator exports them today, offering more readable
                              (and faster) alternatives to "lambda x: x[y]" and "lambda x: getattr(x,
                              y)".

                              [color=blue]
                              > For which reason, I'd be -1 on the idea of an identity function, certainly
                              > in the operator module.[/color]

                              I'm not at all wedded to having 'identity' in the operator module (which
                              may arguably be the wrong placement for 'attrgetter' and 'itemgetter'
                              too). But identity is a useful primitive for a functional style of
                              Python programming, so having it SOMEwhere would be nice, IMHO.


                              Alex

                              Comment

                              Working...