What's better about Ruby than Python?

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

    Re: What's better about Ruby than Python?

    Andrew Dalke wrote:[color=blue]
    > Olivier Drolet:
    >[color=green]
    >>Macros, as found in Common Lisp, do not change the underlying language
    >>at all! Common Lisp macros, when run, always expand into 100% ANSI
    >>Common Lisp code![/color]
    >
    >
    > I've created a new language, called Speech. It's based on the core
    > primitives found in the International Phonetic Alphabet. I've made some
    > demos using Speech. One is English and another is Xhosa. This just
    > goes to show how powerful Speech is because it can handle so many
    > domains. And it's extensible! Anything you say can be expressed in
    > Speech![/color]

    I believe you unwittingly locate an issue. Machine translation of human
    languages has been an unescapable project for computer scientists, a challenge
    that has consistently revealed harder to achieve than expected. Idiomatic
    machine translation of *programming* languages, in comparison, looks like a
    toy problem, an appetizer. But all the endless debates in the p.l. newsgroups
    certainly show one thing : we don't expect idiomatic translation between
    computer languages to solve our problems. While it clearly could.

    I believe our reasons for not doing it boil down to : (a) the issue of
    *conservation* of programming languages *biodiversity* not having gained
    attention as the key issue it is (b) lack of imagination by programmers too
    engrossed with pet language advocacy.

    What I mean is that the metaphor you use puts the joke on you (or us). You
    should really distinguish between the case of translating between *existing*
    "sibling" languages (be they human languages or programming languages) and
    otoh the case of translating between a newly-bred variant of a language and a
    parent language.

    Isn't it the case that most objections to macros fail to persist invariant if
    we set the purpose of our "macro" facility, to that of *grafting some
    language's surface syntax and basic control structures onto some other
    language's objects and library ? This, to illustrate and set a positive
    criterion, well enough that (say) we will be able to manage with (basically)
    the first language's syntax mode under emacs, what will really run as code in
    the second language* ?


    Comment

    • Matthias

      Re: What's better about Ruby than Python?

      Chris Reedy wrote:[color=blue]
      > I'm curious. Why do you feel such a need for macros? With metaclasses,
      > etc., etc., what significant advantage would macros buy you? Do you have
      > any examples where you think you could make a significantly crisper and
      > easier to read and understand program with macros than without.[/color]

      The first thing I would do with macros in Python is build an inline-facility
      which allows certain functions being expanded whenever they are called.
      This would hopefully increase speed at the sake of space efficiency.
      Historically, macros have been used for building Prolog-like languages,
      constrained-programming languages, lazy languages, very flexible object
      oriented languages, etc. on top of Lisp.

      In newer days, Design Patterns can be coded into the language via macros.
      This enables you to program on a higher level of abstraction than with
      classes. You can express your patterns more clearly and much shorter than
      without them.

      Indeed, the C++ community, which does not have macros, uses (some would say:
      misuses) their template facility to do metaprogramming . They implement
      design patterns, inline numerical code, etc. The resulting template code
      is ugly. Compiler messages unreadable. Programming painful. But
      developers feel it is worth to do because the abstractions they build are
      powerful and run fast.

      Having said that, I totally agree with earlier posters who said that macros
      in the hand of bad programmers are catastophic. Where I don't agree is
      that therefore the language should be more limited than necessary.

      Matthias

      Comment

      • Andrew Dalke

        Re: What's better about Ruby than Python?

        Alex Martell:[color=blue]
        > ... def __get__(self, obj, cls):
        > ... self.obj = obj
        > ... return self.cached_cal l[/color]

        That's the part where I still lack understanding.

        class Spam:
        def f(self):
        pass
        f = CachedCall(f)

        obj = Spam()
        obj.f()

        Under old-style Python
        obj.f is the same as getattr(obj, "f")
        which fails to find 'f' in the instance __dict__
        so looks for 'f' in the class, and finds it
        This is not a Python function, so it does not
        get bound to self. It's simply returned.

        obj.f() takes that object and calls it. In my original
        code (not shown) I tried implementing a __call__
        which did get called, but without the instance self.


        Under new-style Python
        obj.f is the same as getattr(obj, "f")
        which fails to find 'f' in the instance __dict__ so
        looks for 'f' in the class, and finds the CachedCall.

        Python checks if the object implements __get__,
        in which case it's called a descriptor. If so, it's
        called with the 'obj' as the first parameter. The
        return value of this call is used as the value for
        the attribute.

        Is that right?
        [color=blue]
        > should closely mimic your semantics, including ignoring
        > what I call obj and you call self in determining whether
        > a certain set of argumens is cached.[/color]

        Why should obj make a difference? There's only
        one CachedCall per method per .... Ahh, because it's
        in the class def, not the instance. Adding support for
        that using a weak dict is easy.

        Yeah, and my approach won't work with kwargs nor any
        other unhashable element. Since I didn't know what the
        Lisp code did nor how Lisp handles unhashable elements,
        I decided just to implement the essential idea.

        Andrew
        dalke@dalkescie ntific.com


        Comment

        • Aahz

          Re: What's better about Ruby than Python?

          In article <ql_0b.1664$Ej6 .614@newsread4. news.pas.earthl ink.net>,
          Andrew Dalke <adalke@mindspr ing.com> wrote:[color=blue]
          >Alex:[color=green]
          >>
          >> Even GvR
          >> historically did some of that, leading to what are now his mild
          >> regrets (lambda, map, filter, ...).[/color]
          >
          >and != vs. <>
          >
          >Can we have a deprecation warning for that? I've never
          >seen it in any code I've reviewed.[/color]

          We will, probably 2.4 or 2.5. (Whenever 3.0 starts getting off the
          ground.)
          --
          Aahz (aahz@pythoncra ft.com) <*> http://www.pythoncraft.com/

          This is Python. We don't care much about theory, except where it intersects
          with useful practice. --Aahz

          Comment

          • Alex Martelli

            Re: What's better about Ruby than Python?

            Andrew Dalke wrote:
            [color=blue]
            > Alex Martell:[color=green]
            >> ... def __get__(self, obj, cls):
            >> ... self.obj = obj
            >> ... return self.cached_cal l[/color]
            >
            > That's the part where I still lack understanding.
            >
            > class Spam:
            > def f(self):
            > pass
            > f = CachedCall(f)[/color]

            That's an oldstyle class -- use a newstyle one for smoothest
            and most reliable behavior of descriptors
            [color=blue]
            >
            > obj = Spam()
            > obj.f()
            >
            > Under old-style Python
            > obj.f is the same as getattr(obj, "f")[/color]

            This equivalence holds today as well -- the getattr
            builtin has identical semantics to direct member access.
            [color=blue]
            > which fails to find 'f' in the instance __dict__
            > so looks for 'f' in the class, and finds it
            > This is not a Python function, so it does not
            > get bound to self. It's simply returned.
            >
            > obj.f() takes that object and calls it. In my original
            > code (not shown) I tried implementing a __call__
            > which did get called, but without the instance self.[/color]

            Sure.
            [color=blue]
            > Under new-style Python
            > obj.f is the same as getattr(obj, "f")[/color]

            Yes.
            [color=blue]
            > which fails to find 'f' in the instance __dict__ so
            > looks for 'f' in the class, and finds the CachedCall.[/color]

            Sure.
            [color=blue]
            > Python checks if the object implements __get__,
            > in which case it's called a descriptor. If so, it's[/color]

            Exactly.
            [color=blue]
            > called with the 'obj' as the first parameter. The
            > return value of this call is used as the value for
            > the attribute.
            >
            > Is that right?[/color]

            Yes! So what is it that you say you don't get?

            [color=blue][color=green]
            >> should closely mimic your semantics, including ignoring
            >> what I call obj and you call self in determining whether
            >> a certain set of argumens is cached.[/color]
            >
            > Why should obj make a difference? There's only
            > one CachedCall per method per .... Ahh, because it's
            > in the class def, not the instance. Adding support for
            > that using a weak dict is easy.[/color]

            If obj is such that it can be used as a key into a dict
            (weak or otherwise), sure. Many class instances of some
            interest can't -- and if they can you may not like the
            result. COnsider e.g.

            class Justanyclass:
            def __init__(self, x): self.x = x
            def compute(self, y): return self.x + y

            pretty dangerous to cache THIS compute method -- because,
            as a good instance method should!, it depends crucially
            on the STATE of the specific instance you call it on.

            [color=blue]
            > Yeah, and my approach won't work with kwargs nor any
            > other unhashable element. Since I didn't know what the
            > Lisp code did nor how Lisp handles unhashable elements,
            > I decided just to implement the essential idea.[/color]

            An automatically cachable method on general objects is
            quite tricky. I don't think the Lisp code did anything
            to deal with that trickiness, though, so you're right
            that your code is equivalent. Anyway, I just wanted to
            show how the descriptor concept lets you use a class,
            rather than a function, when you want to -- indeed any
            function now has a __get__ method, replacing (while
            keeping the semantics of) the old black magic.


            Alex

            Comment

            • Anton Vredegoor

              Re: What's better about Ruby than Python?

              "Andrew Dalke" <adalke@mindspr ing.com> wrote:

              [defines cognitive macro called Speech]
              [color=blue]
              >I've created a new language, called Speech. It's based on the core
              >primitives found in the International Phonetic Alphabet. I've made some
              >demos using Speech. One is English and another is Xhosa. This just
              >goes to show how powerful Speech is because it can handle so many
              >domains. And it's extensible! Anything you say can be expressed in
              >Speech![/color]

              [snip lots of examples using it, trying to make macros look bad?]
              [color=blue]
              >In short, no one is denying that the ability to create new macros is
              >a powerful tool, just like no one denies that creating new words is
              >a powerful tool. But both require extra training and thought for
              >proper use, and while they are easy to write, it puts more effort
              >for others to understand you. If I stick to Python/English then
              >more people can understand me than if I mixed in a bit of Erlang/
              >Danish, *even* *if* the latter makes a more precise description
              >of the solution.[/color]

              You have found a wonderful analogy, however you seem to assume that
              your prejudices are so self explanatory that the conclusion that
              macros are bad is natural.

              I am not a native English speaker, and so my expressiveness in this
              language is severely handicapped, while I consider myself a person
              with good linguistic abilities.

              Obviously there are people from other linguistic backgrounds
              participating in discussions in this newsgroup who have the same
              problems. Maybe they are greater speakers than me and yet have still
              more problems using English.

              However this does not in the least cause this newsgroup to deviate
              substantially (or maybe it does but as a non-native speaker I can not
              discern the difference) from English. Rather we all strive to speak
              the same language in order to make as much people as possible
              understand what we are saying.

              While using Python as a programming language we strive for Pythonicity
              and for combining elegance with concisiveness and readability. We are
              using docstrings to comment our code and answer questions about it in
              the newsgroup. Helpful people debug our code and assist in formulating
              our algorithms in Python.

              IMO there is a strong tendency towards unification and standardization
              among the readers of this newsgroup and the need to conform and the
              rewards this brings are well understood.

              Seeing all this it would be a missed chance not to give the community
              the freedom of redefining the language to its advantage.

              Of course there are risks that the community would dissolve in
              mutually incompatible factions and it would be wise to slow down the
              process according to the amount of responsibility the group can be
              trusted with.

              The rewards would be incomparably great however, even to the amount
              that I would be ready to sacrifice Python only to give this thing a
              tiny chance. Suppose you could make a bet for a dollar with an
              expected reward of a thousand dollars? Statistically it doesn't matter
              whether you get a .999 chance of getting a thousand dollars or a
              ..00999 chance of getting a million dollars.

              Therefore, the only thing pertinent to this question seems to be the
              risk and gain assessments.
              [color=blue]
              >By this analogy, Guido is someone who can come up with words
              >that a lot of people find useful, while I am someone who can come
              >up withs words appropriate to my specialization, while most
              >people come up with words which are never used by anything
              >other than close friend. Like, totally tubular dude.[/color]

              Another relevant meme that is running around in this newsgroup is the
              assumption that some people are naturally smarter than other people.
              While I can certainly see the advantage for certain people for keeping
              this illusion going (it's a great way to make money, the market
              doesn't pay for what it gets but for what it thinks it gets) there is
              not a lot of credibility in this argument.

              The "hardware" that peoples minds are running on doesn't come in
              enough varieties to warrant such assumptions. For sure, computer
              equipment can vary a lot, but we as people all have more or less the
              same brain.

              Of course there is a lot of variation between people in the way they
              are educated and some of them have come to be experts at certain
              fields. However no one is an island and one persons thinking process
              is interconnected with a lot of other persons thinking processes. The
              idea that some kind of "genius" is solely responsible for all this
              progress is absurd and a shameful deviation to the kind of
              "leadership " philosophical atrocities that have caused many wars.

              To come back to linguistic issues, there's a lot of variation in the
              way people use their brain to solve linguistic problems. There are
              those that first read all the prescriptions before uttering a word and
              there are those that first leap and then look. It's fascinating to see
              "look before you leap" being deprecated in favor of "easier to ask
              forgiveness than permission" by the same people that would think twice
              to start programming before being sure to know all the syntax.

              In my case for example studying old latin during high school there was
              a guy sitting next to me who always knew the different conjugations
              the latin words where in and as a result he managed to get high grades
              with exact but uninteresting translations. My way of translating latin
              was a bit different, instead of translating word for word and looking
              up each form of each separate word (is it a genitivus, ablativus
              absolutus, imperativus, etcetera) I just read each word and going from
              the approximative meaning of all words put in a sequence of sentences
              I ended up with a translation that was seventy percent correct and
              that had a lot of internal consistency and elegance. It was usually
              enough to get a high enough grade and also some appraisal: "si non e
              vero, e ben trovato" or something like that.

              What this all should lead to I am not really sure, but I *am* sure
              that breaking out of formal mathematical and linguistic and
              programmatic rules is the only way to come to designs that have great
              internal consistency and that can accommodate for new data and
              procedures.

              It is sometimes impossible for a language designer to exactly pinpoint
              the reasons for a certain decision, while at the same time being sure
              that it is the right one.

              The ability to maintain internal consistency and the tendency of other
              people to fill in the gaps so that the final product seems coherent is
              IMO the main reason for this strange time-travel-like ability of
              making the right decisions even before all the facts are available.

              Well, maybe I have made the same mistake as you by providing arguments
              to the contrary of my intention of advocating the emancipation of the
              average Python user to the level of language designer.

              However if I have done so, rest assured that my intuition "knows" from
              before knowing all the facts that this is the way to go, and the
              rewards are infinitely more appealing than the risks of breaking up
              the Python community are threatening.

              One way or the other this is the way programming will be in the
              future, and the only question is: Will Python -and the Python
              community- be up to the task of freeing the programmers expressiveness
              and at the same time provide a home and starting point to come back
              to, or will it be left behind as so many other valiant effort's fate
              has been?

              Anton




              Comment

              • Borcis

                Re: What's better about Ruby than Python?

                Anton Vredegoor wrote:[color=blue]
                >
                > The ability to maintain internal consistency and the tendency of other
                > people to fill in the gaps so that the final product seems coherent is
                > IMO the main reason for this strange time-travel-like ability of
                > making the right decisions even before all the facts are available.[/color]

                Wow :)

                Comment

                • Jacek Generowicz

                  Re: What's better about Ruby than Python?

                  "Andrew Dalke" <adalke@mindspr ing.com> writes:
                  [color=blue]
                  > As a consultant, I don't have the luxury of staying inside a singular
                  > code base. By your logic, I would need to learn each different
                  > high level abstraction done at my clients' sites.[/color]

                  The alternative is to understand (and subsequently recognize) the
                  chunks of source code implementing a given patten for which no
                  abstraction was provided (often implemented slightly differently in
                  different parts of the code, sometimes with bugs), each time that it
                  occurs.

                  I'd rather use multimethods that implement the visitor pattern.

                  I'd rather look at multimethods, than at code infested with
                  implementations of the visitor pattern.

                  (The above comments are _not_ about the visitor pattern per se.)
                  [color=blue]
                  > The inference is that programming language abstractions should not
                  > be more attractive than sex.[/color]

                  Why ever not? Don't you want to put the joy back into programming :-)
                  [color=blue]
                  > Functions and modules and objects, based on experience, promote
                  > code sharing. Macros, with their implicit encouragement of domain
                  > specific dialect creation, do not.[/color]

                  I don't believe you can reasonably draw a rigid and well-defined
                  boundary between functions, modules and objects on one side, and
                  macros on the other. They all offer means of abstraction. All are open
                  to abuse. All can be put to good use.

                  In all four cases, I'd rather have the opportunity to create
                  abstractions, rather than not.

                  I find your suggestion that macros are in some way more "domain
                  specific" than modules, or objects or functions, bogus.
                  [color=blue]
                  > A language which allows very smart people the flexibility to
                  > customize the language, means there will be many different flavors,
                  > which don't all taste well together.[/color]
                  [color=blue]
                  > A few years ago I tested out a Lisp library. It didn't work
                  > on the Lisp system I had handy, because the package system
                  > was different. There was a comment in the code which said
                  > "change this if you are using XYZ Lisp", which I did, but that
                  > that's a barrier to use if I ever saw one.[/color]

                  You are confusing the issues of

                  - extensibility,
                  - standard non conformance,
                  - not starting from a common base,
                  - languages defined my their (single) implementation.

                  A few days ago I tested out a C++ library. It didn't work on the C++
                  system I had handy because the STL implementation was
                  different/template support was different. etc. etc.

                  A few days ago I tested out a Python library. It didn't work on the
                  implementation I had handy because it was Jython.
                  [color=blue]
                  > 4) a small change in a language to better fit my needs has
                  > subtle and far-reaching consequences down the line. Instead,
                  > when I do need a language variation, I write a new one
                  > designed for that domain, and not tweak Python.[/color]

                  So, what you are saying is that faced with the alternatives of

                  a) Tweaking an existing, feature rich, mature, proven language, to
                  move it "closer" to your domain.

                  b) Implementing a new language from scratch, for use in a single
                  domain

                  you would choose the latter?

                  If so, you are choosing the path which pretty much guarantees that
                  your software will take much longer to write, and that it will be a
                  lot buggier.

                  It's an extreme form of Greenspunning.

                  How do you reconcile
                  [color=blue]
                  > when I do need a language variation, I write a new one designed for
                  > that domain, and not tweak Python.[/color]

                  with
                  [color=blue]
                  > Functions and modules and objects, based on experience, promote
                  > code sharing. Macros, with their implicit encouragement of domain
                  > specific dialect creation, do not.[/color]

                  ?

                  You criticize macros for not encouraging code sharing (they do, by
                  encouraging you to share the (vast) underlying language while reaching
                  out towards a specific domain), while your preferred solution seems to
                  be the ultimate code non-sharing, by throwing away the underlying
                  language, and re-doing it.

                  Comment

                  • Borcis

                    Re: What's better about Ruby than Python?

                    Jacek Generowicz wrote:[color=blue]
                    >
                    > You criticize macros for not encouraging code sharing (they do, by
                    > encouraging you to share the (vast) underlying language while reaching
                    > out towards a specific domain), while your preferred solution seems to
                    > be the ultimate code non-sharing, by throwing away the underlying
                    > language, and re-doing it.[/color]

                    This criticism can't help looking frivolous, imho. You appear to be confusing
                    "language" with "speech". But I do believe there *must* exist a sane niche for
                    (perhaps mutated) macros (in some lisp-like sense).

                    Cheers, B.

                    Comment

                    • Kenny Tilton

                      Re: What's better about Ruby than Python?



                      Andrew Dalke wrote:[color=blue]
                      > Kenny Tilton:
                      >[color=green]
                      >>This macro:
                      >>
                      >>(defmacro c? (&body code)
                      >> `(let ((cache :unbound))
                      >> (lambda (self)
                      >> (declare (ignorable self))
                      >> (if (eq cache :unbound)
                      >> (setf cache (progn ,@code))
                      >>cache))))[/color]
                      >
                      >
                      > I have about no idea of what that means. Could you explain
                      > without using syntax? My guess is that it caches function calls,
                      > based only on the variable names. Why is a macro needed
                      > for that?[/color]

                      C? does something similar to what you think, but at with an order of
                      magnitude more power. Estimated. :) Here is how C? can be used:

                      (make-instance 'box
                      :left (c? (+ 2 (right a)))
                      :right (c? (+ 10 (left self))))

                      So I do not have to drop out of the work at hand to put /somewhere else/
                      a top-level function which also caches, and then come back to use it in
                      make-instance. That's a nuisance, and it scatters the semantics of this
                      particular box all over the source. Note, btw:

                      (defun test ()
                      (let* ((a (make-instance 'box
                      :left 0
                      :right (c? (random 30))))
                      (b (make-instance 'box
                      :left (c? (+ 2 (right a)))
                      :right (c? (+ 10 (left self))))))
                      (print (list :a a (left a) (right a)))
                      (print (list :b b (left b) (right b)))))

                      ....that different instances of the same class can have different rules
                      for the same slot. Note also that other plumbing is necessary to make
                      slot access transparent:

                      (defun get-cell (self slotname) ;; this fn does not need duplicating
                      (let ((sv (slot-value self slotname)))
                      (typecase sv
                      (function (funcall sv self))
                      (otherwise sv))))

                      (defmethod right ((self box)) ;; this needs duplicating for each slot
                      (get-cell box right))

                      But I just hide it all (and much more) in:

                      (defmodel box ()
                      ((left :initarg :left :accessor left)
                      (right :initarg :right :accessor right)))

                      ....using another macro:

                      (defmacro defmodel (class superclasses (&rest slots))
                      `(progn
                      (defclass ,class ,superclasses
                      ,slots)
                      ,@(mapcar (lambda (slot)
                      (destructuring-bind
                      (slotname &key initarg accessor)
                      slot
                      (declare (ignore slotname initarg))
                      `(defmethod ,accessor ((self ,class))
                      (get-cell self ',slotname))))
                      slots)))

                      [color=blue]
                      >
                      >[color=green][color=darkred]
                      >>>>import time
                      >>>>def CachedCall(f):
                      >>>[/color][/color]
                      > ... cache = {}
                      > ... def cached_call(sel f, *args):
                      > ... if args in cache:
                      > ... return cache[args]
                      > ... x = f(self, *args)
                      > ... cache[args] = x
                      > ... return x
                      > ... return cached_call
                      > ...
                      >[color=green][color=darkred]
                      >>>>class LongWait:
                      >>>[/color][/color]
                      > ... def compute(self, i):
                      > ... time.sleep(i)
                      > ... return i*2
                      > ... compute = CachedCall(comp ute)
                      > ...
                      >[color=green][color=darkred]
                      >>>>t1=time.tim e();LongWait(). compute(3);prin t time.time()-t1
                      >>>[/color][/color]
                      > 6
                      > 3.01400005817
                      >[color=green][color=darkred]
                      >>>>t1=time.tim e();LongWait(). compute(3);prin t time.time()-t1
                      >>>[/color][/color]
                      > 6
                      > 0.0099999904632 6
                      >
                      >[/color]

                      Cool. But call cachedCall "memoize". :) Maybe the difference is that you
                      are cacheing a specific computation of 3, while my macro in a sense
                      caches the computation of arbitrary code by writing the necessary
                      plumbing at compile time, so I do not have to drop my train of thought
                      (and scatter my code all over the place).

                      That is where Lisp macros step up--they are just one way code is treated
                      as data, albeit at compile time instead of the usual runtime consideration.



                      --

                      kenny tilton
                      clinisys, inc

                      ---------------------------------------------------------------
                      "Career highlights? I had two. I got an intentional walk from
                      Sandy Koufax and I got out of a rundown against the Mets."
                      -- Bob Uecker

                      Comment

                      • Jacek Generowicz

                        Re: What's better about Ruby than Python?

                        "Andrew Dalke" <adalke@mindspr ing.com> writes:
                        [color=blue]
                        > Ndiya kulala. -- I am going for the purpose of sleeping.
                        >
                        > And here's an example of Swedish with a translation into
                        > English, which lack some of the geneaological terms
                        >
                        > min mormor -- my maternal grandmother
                        >
                        > I can combine those and say
                        >
                        > Umormor uya kulala -- my maternal grandmother is going
                        > for the purpose of sleeping.
                        >
                        > See how much more precise that is because I can select
                        > words from different Dialects of Speech?[/color]

                        You are absolutely right. "Umormor uya kulala" is less readable than
                        "My maternal grandmother is going for the purpose of sleeping", to
                        someone who is familiar with English, but unfamiliar with Xhosa and
                        Swedish.

                        Now explain the Mor/Far concept and the "going for a purpouse"
                        concept" to said English speaker, and present him with text it which
                        combinations of the concepts are user repeatedly.

                        _Now_ ask yourself which is more readable.

                        For this reason it is rarely a good idea to define a macro for a
                        single use. However, it becomes an excellent idea if the idea the
                        macro expresses must be expressed repeatedly. The same is true of
                        functions, classes, modules ...

                        Comment

                        • Kenny Tilton

                          Re: What's better about Ruby than Python?



                          Andrew Dalke wrote:[color=blue]
                          > Olivier Drolet:
                          >[color=green]
                          >>Macros don't cause Common Lisp to fork
                          >>anymore than function or class abstractions do.[/color]
                          >
                          >
                          > Making new words don't cause Speech to fork any more than
                          > making new sentences does.[/color]

                          Hunh? This one doesn't work, and this is the one you have to answer.

                          Forget argument by analogy: How is a macro different than an API or
                          class, which hide details and do wonderful things but still have to be
                          mastered. Here's an analogy <g>: I could learn Java syntax in a week,
                          but does that mean I can keep up with someone who has been using the
                          class libraries for years? Nope.

                          And Java doesn't even have macros.

                          [color=blue]
                          > In short, no one is denying that the ability to create new macros is
                          > a powerful tool, just like no one denies that creating new words is
                          > a powerful tool. But both require extra training and thought for
                          > proper use, and while they are easy to write, it puts more effort
                          > for others to understand you. If I stick to Python/English then
                          > more people can understand me than if I mixed in a bit of Erlang/
                          > Danish, *even* *if* the latter makes a more precise description
                          > of the solution.[/color]

                          One of the guys working under me had no respect for readability, he just
                          got code to work, which was nice. I once had to work on his code. In
                          about half an hour, with the help of a few macros, a great honking mass
                          of text which completely obfuscated the action had been distilled to its
                          essense. One could actually read it.

                          Of course every once in a while you would notice something like "Ndiya",
                          but if you went to the macrolet at the top of the function you would
                          just think "oh, right" and get back to the code.

                          Maybe sometimes these macros could be functions, but then I'd just
                          call the function Ndiya.

                          So what is the difference?

                          btw, I am on your side in one regard: the LOOP macro in Lisp has
                          phenomenally un-Lispy syntax, so I have never used it. I am slowly
                          coming around to it being more useful than irritating, but I did not
                          like having a new /syntax/ invented. (LOOP /can/ be used with
                          conventional syntax, but I have seen such code only once and I think I
                          know why they broke the syntax. <g>). So I get that point, but normally
                          macros do not deviate from standard Lisp synatx.

                          Ndiya kulala.


                          --

                          kenny tilton
                          clinisys, inc

                          ---------------------------------------------------------------
                          "Career highlights? I had two. I got an intentional walk from
                          Sandy Koufax and I got out of a rundown against the Mets."
                          -- Bob Uecker

                          Comment

                          • Jacek Generowicz

                            Re: What's better about Ruby than Python?

                            Borcis <borcis@users.c h> writes:
                            [color=blue]
                            > Jacek Generowicz wrote:
                            >[color=green]
                            > > You criticize macros for not encouraging code sharing (they do, by
                            > > encouraging you to share the (vast) underlying language while reaching
                            > > out towards a specific domain), while your preferred solution seems to
                            > > be the ultimate code non-sharing, by throwing away the underlying
                            > > language, and re-doing it.[/color]
                            >
                            > This criticism can't help looking frivolous,[/color]

                            Only in so far as the original thesis is frivolous.
                            [color=blue]
                            > You appear to be confusing "language" with "speech".[/color]

                            I'm not sure what you mean by this.

                            Are you saying that macros are "language" because you've heard the
                            buzz-phrase that "macros allow you to modify the language", while
                            functions, classes and modules are "speech", because no such
                            buzz-phrases about them abound ?

                            If so, then you are erecting artificial boundaries between different
                            abstraction mechanisms. (All IMHO, of course.)

                            Comment

                            • Kenny Tilton

                              Re: What's better about Ruby than Python?



                              Alex Martelli wrote:[color=blue]
                              > Andrew Dalke wrote:
                              >
                              >[color=green]
                              >>Alex Martell:
                              >>[color=darkred]
                              >>>... def __get__(self, obj, cls):
                              >>>... self.obj = obj
                              >>>... return self.cached_cal l[/color]
                              >>
                              >>That's the part where I still lack understanding.
                              >>
                              >>class Spam:
                              >> def f(self):
                              >> pass
                              >> f = CachedCall(f)[/color]
                              >
                              >
                              > That's an oldstyle class -- use a newstyle one for smoothest
                              > and most reliable behavior of descriptors
                              >
                              >[color=green]
                              >>obj = Spam()
                              >>obj.f()
                              >>
                              >>Under old-style Python
                              >> obj.f is the same as getattr(obj, "f")[/color]
                              >
                              >
                              > This equivalence holds today as well -- the getattr
                              > builtin has identical semantics to direct member access.
                              >
                              >[color=green]
                              >> which fails to find 'f' in the instance __dict__
                              >> so looks for 'f' in the class, and finds it
                              >> This is not a Python function, so it does not
                              >> get bound to self. It's simply returned.
                              >>
                              >> obj.f() takes that object and calls it. In my original
                              >> code (not shown) I tried implementing a __call__
                              >> which did get called, but without the instance self.[/color]
                              >
                              >
                              > Sure.
                              >
                              >[color=green]
                              >>Under new-style Python
                              >> obj.f is the same as getattr(obj, "f")[/color]
                              >
                              >
                              > Yes.
                              >
                              >[color=green]
                              >> which fails to find 'f' in the instance __dict__ so
                              >> looks for 'f' in the class, and finds the CachedCall.[/color]
                              >
                              >
                              > Sure.
                              >
                              >[color=green]
                              >> Python checks if the object implements __get__,
                              >> in which case it's called a descriptor. If so, it's[/color]
                              >
                              >
                              > Exactly.
                              >
                              >[color=green]
                              >> called with the 'obj' as the first parameter. The
                              >> return value of this call is used as the value for
                              >> the attribute.
                              >>
                              >>Is that right?[/color]
                              >
                              >
                              > Yes! So what is it that you say you don't get?
                              >
                              >
                              >[color=green][color=darkred]
                              >>>should closely mimic your semantics, including ignoring
                              >>>what I call obj and you call self in determining whether
                              >>>a certain set of argumens is cached.[/color]
                              >>
                              >>Why should obj make a difference? There's only
                              >>one CachedCall per method per .... Ahh, because it's
                              >>in the class def, not the instance. Adding support for
                              >>that using a weak dict is easy.[/color]
                              >
                              >
                              > If obj is such that it can be used as a key into a dict
                              > (weak or otherwise), sure. Many class instances of some
                              > interest can't -- and if they can you may not like the
                              > result. COnsider e.g.
                              >
                              > class Justanyclass:
                              > def __init__(self, x): self.x = x
                              > def compute(self, y): return self.x + y
                              >
                              > pretty dangerous to cache THIS compute method -- because,
                              > as a good instance method should!, it depends crucially
                              > on the STATE of the specific instance you call it on.
                              >
                              >
                              >[color=green]
                              >>Yeah, and my approach won't work with kwargs nor any
                              >>other unhashable element. Since I didn't know what the
                              >>Lisp code did nor how Lisp handles unhashable elements,
                              >>I decided just to implement the essential idea.[/color]
                              >
                              >
                              > An automatically cachable method on general objects is
                              > quite tricky.[/color]

                              Lisp hashtables can key off any Lisp datum, but...
                              [color=blue]
                              > I don't think the Lisp code did anything
                              > to deal with that trickiness,[/color]

                              No, it did not. That snippet was from a toy (and incomplete)
                              implementation of my more elaborate Cells package. the toy was developed
                              over the keyboard during a talk I gave on Sunday. The next step would
                              have been to determine when the closure had best re-execute the code
                              body to see if the world had changed in interesting ways, but that is a
                              big step and requires dependency tracking between cells.

                              Once a Cell is told an input has changed, it re-runs its body to see if
                              it comes up with a different result, in which case it caches that and
                              tells other dependents to rethink their caches.

                              So what is shown in my example is fun but halfbaked. I was just trying
                              to show how a macro could hide the plumbing of an interesting mechanism
                              so the reader can focus on the essence.




                              --

                              kenny tilton
                              clinisys, inc

                              ---------------------------------------------------------------
                              "Career highlights? I had two. I got an intentional walk from
                              Sandy Koufax and I got out of a rundown against the Mets."
                              -- Bob Uecker

                              Comment

                              • Alex Martelli

                                Re: What's better about Ruby than Python?

                                Anton Vredegoor wrote:
                                ...[color=blue]
                                > tiny chance. Suppose you could make a bet for a dollar with an
                                > expected reward of a thousand dollars? Statistically it doesn't matter
                                > whether you get a .999 chance of getting a thousand dollars or a
                                > .00999 chance of getting a million dollars.[/color]

                                This assertion is false and absurd. "Statistically" , of course,
                                expected-value is NOT the ONLY thing about any experiment. And
                                obviously the utility of different sums need not be linear -- it
                                depends on the individual's target-function, typically influenced
                                by other non-random sources of income or wealth.

                                Case 1: with whatever sum you win you must buy food &c for a
                                month; if you have no money you die. The "million dollars chance"
                                sees you dead 99.9901 times out of 100, which to most individuals
                                means huge negative utility; the "thousand dollars chance" gives
                                you a 99.9% chance of surviving. Rational individuals in this
                                situation would always choose the 1000-dollars chance unless the
                                utility to them of the unlikely million was incredibly huge (which
                                generally means there is some goal enormously dear to their heart
                                which they could only possibly achieve with that million).

                                Case 2: the sum you win is in addition to your steady income of
                                100,000 $/month. Then, it may well be that $1000 is peanuts of
                                no discernible use to you, while a cool million would let you
                                take 6 months' vacation with no lifestyle reduction and thus has
                                good utility to you. In this case a rational individual would
                                prefer the million-dollars chance.

                                [color=blue]
                                > Therefore, the only thing pertinent to this question seems to be the
                                > risk and gain assessments.[/color]

                                Your use of 'therefore' is inapproprite because it suggests the
                                following assertion (which _is_ mathematically speaking correct)
                                "follows" from the previous paragraph (which is bunkum). The
                                set of (probability, outcome) pairs DOES mathematically form "the
                                only thing pertinent" to a choice (together with a utility function
                                of course -- but you can finesse that by expressing outcome as
                                utility directly) -- the absurdity that multiplying probability
                                times outcome (giving an "expected value") is the ONLY relevant
                                consideration is not necessary to establish that.

                                [color=blue]
                                > Another relevant meme that is running around in this newsgroup is the
                                > assumption that some people are naturally smarter than other people.
                                > While I can certainly see the advantage for certain people for keeping
                                > this illusion going (it's a great way to make money, the market
                                > doesn't pay for what it gets but for what it thinks it gets) there is
                                > not a lot of credibility in this argument.[/color]

                                *FOR A GIVEN TASK* there can be little doubt that different people
                                do show hugely different levels of ability. Mozart could write
                                far better music than I ever could -- I can write Python programs
                                far better than Silvio Berlusconi can. That does not translate into
                                "naturally smarter" because the "given tasks" are innumerable and
                                there's no way to measure them all into a single number: it's quite
                                possible that I'm far more effective than Mozart at the important
                                task of making and keeping true friends, and/or that Mr Berlusconi
                                is far more effective than me at the important tasks of embezzling
                                huge sums of money and avoiding going to jail in consequence (and
                                THAT is a great way to make money, if you have no scruples).

                                Note that for this purpose it does not matter whether the difference
                                in effectiveness at given tasks comes from nature or nurture, for
                                example -- just that it exists and that it's huge, and of that, only
                                a madman could doubt. If you have the choice whom to get music
                                from, whom to get Python programs from, whom to get as an accomplice
                                in a multi-billion scam, you should consider the potential candidates'
                                proven effectiveness at these widely different tasks.

                                In particular, effectiveness at design of programming languages can
                                be easily shown to vary all over the place by examining the results.

                                [color=blue]
                                > Of course there is a lot of variation between people in the way they
                                > are educated and some of them have come to be experts at certain
                                > fields. However no one is an island and one persons thinking process
                                > is interconnected with a lot of other persons thinking processes. The[/color]

                                Of course Mozart would have been a different person -- writing
                                different kinds of music, or perhaps doing some other job, maybe
                                mediocrely -- had he not been born when and where he was, the son
                                of a music teacher and semi-competent musician, and so on. And
                                yet huge numbers of other people were born in perfectly similar
                                circumstances.. . but only one of them wrote *HIS* "Requiem".. .

                                [color=blue]
                                > there are those that first leap and then look. It's fascinating to see
                                > "look before you leap" being deprecated in favor of "easier to ask
                                > forgiveness than permission" by the same people that would think twice
                                > to start programming before being sure to know all the syntax.[/color]

                                Since I'm the person who intensely used those two monickers to
                                describe different kinds of error-handling strategies, let me note
                                that they're NOT intended to generalize. When I court a girl I
                                make EXTREMELY sure that she's interested in my advances before I
                                push those advances beyond certain thresholds -- in other words in
                                such contexts I *DEFINITELY* "look before I leap" rather than choosing
                                to make inappropriate and unwelcome advances and then have to "ask
                                forgiveness" if/when rebuffed (and I despise the men who chose the
                                latter strategy -- a prime cause of "date rape", IMHO).

                                And there's nothing "fascinatin g" in this contrast. The amount of
                                damage you can infert by putting your hands or mouth where they
                                SHOULDN'T be just doesn't compare to the (zero) amount of "damage"
                                which is produced by e.g. an attempted access to x.y raising an
                                AttributeError which you catch with a try/except.



                                Alex

                                Comment

                                Working...