[Python-il] Perl Vs. Python on Various Points

Beni Cherniavsky cben at users.sf.net
Mon Jul 13 16:57:39 IDT 2009


On Mon, Jul 13, 2009 at 11:10, Shlomi Fish<shlomif at iglu.org.il> wrote:
>
> 1. Syntax as an Indicative of What the Language is Doing:
> ---------------------------------------------------------
>
> He said he didn't like Perl syntax like "push @$array_ref, $val;" because
> of the sigils. I said I happen to like it because the extra characters
> convey meaning. By looking at this code I know that $array_ref is an array
> reference, that it is being treated as an array and that one appends a
> single ("scalar") value to it. On the other if I see code like this:
>
> <<<<<
> s.add(h)
>>>>>>
>
> It's harder for me to know what's going on without running the program. For
> all I know s and h could be almost anything. The sigils convey meaning.
>
If sigils just conveyed variable types, you could achieve the same
effect with Hungarian notation:

listS.add(scalarH)

No, sigils have a deeper function - they (together with other parts of
perl syntax) assign types to the whole syntax tree - not just the
leaves but all nodes!

1. They convey the type of operators: "$listref1 = $listref2" is 0-deep copy
   while "@list1 = @list2" is 1-deep-copy.

2. They imply coercion operators on type boundaries: "$listlen = @list".

So it's not about adding extra characters for readability.  Adding
characters in one place increases information densitiy in other
places.

As others mentioned, the downside is that sigils don't scale to custom
types - all references are syntactically the same.

> 2. Comparison Operators:
> ------------------------
>
> Later on the discussion diverted to comparison operators. Now python only
> has "==" and friends for comparison (at least as far as I know) while Perl 5
> has both ==/!=/>/etc. and eq/ne/gt/etc. The first ones are intended for
> numeric comparison and the latter ones for string comparison.
>
> I argued that by looking at code with such comparisons, I can tell what kind
> of comparison the programmmer intended the comparison to be. Part of the
> reason for the fact that Perl 5 has both types of comparison is that it
> does not have separate data types for strings and for numbers, but this is
> not the only reason.
>
Same about "($s1 . $s2) x 10" vs. "($n1 + $n2) * 10".
Again, it's not just about knowing the type from the look of the code.
In python, one should always coerce numbers/strings to their intended
type; given that, == always does the right thing.
What separate operators allow in perl, is to have the coercions
*implied*, thus increasing code density.

...
> So Python's == does a deep comparison of complex data structures and returned
> that x and y where equivalent despite the fact that they aren't the same
> physical reference.
...
> For deep comparison we have CPAN modules like
> http://search.cpan.org/dist/Test-Differences/ , or can use the more limited
> is_deeply() functionationality of Test::More.
>
That's very bad - basic features of nested structures like printing
(Data::Dumper) and comparison must be easily accesible.
That's why Perl now has the new ~~ "smart match" operator.
Not having nested data printing is *unspeakably* bad when using an
interactive prompt, which is why Perl's debugger does have an "x"
command.

> I personally feel that it's impossible to have "one-comparison-fits-all"
> because for two pieces of data, there may be several ways that we would like
> to compare them.
>
Some lisps have 4 (equal, eql, eq, =) or more.  But most of that cruft
is just optimization.
All modern languages concluded that you need just 2: deep by-value
comparison (overloadable by type), and shallow identity check.
And the shallow identity check is rare enough that maybe it doesn't
even deserve an operator.
(BTW, in lisp operators are cheap - the are regular functions - which
might explain why they felt OK with having so many.)

> 3. Circular References:
> -----------------------
> After the discussion on comparison, the conversation diverted to
> discussing circular references. My partner for the conversation was
> surprised to learn that Python has them:
...
Ha?  Every non-purely-functional language with references has them.
Or did you mean that Python detects them when dumping values?

It was important to not blow your terminal if you dumps one, and to
make garbage collection (mostly) work on them, but the rest of mess is
left for you to untangle.

> Now what happens if we try to compare two equivalent circular data strctures:
...
> So CPython is not very smart about it, and throws an ugly expection.
>
I've never heard of a single language that *is* very smart about them!
 There is no easy, or even single, way to compare circular structures.
 Nor is there much use.

> Obviously x[0] = x data structures are neither too common or useful, but
> circular references are useful for such data structures and OO patterns
> as trees with parent pointers, doubly-linked lists or graphs.
>
Back-references are a common cause of accidental circles, but
Sure, but these are not normally part of the object's "value" that
participates in comparison.
If they are, go back to the drawing board :).

Graphs are the only structure that is meaningfully symmetric.
There are many ways to define graphs, so it's left to libraries to handle them.

> I asked
> the people on Freenode #python about it and they told me that "python has had
> a cycle collector since 2.0" and I was told that this cycle collector does
> not make object destruction unpredictable.
>
Fine print: python collects cycles but not immediately; cycles that
contain objects with __del__ finalizers are not collected.

> perl 5 still doesn't have something like that and when I consulted #perl
> about it they said that http://xrl.us/be233e is a start towards a cycle
> collection for objects.
>
Note how many years Perl and Python lived without it.
=> "You Ain't Gonna Need It" until proven otherwise.
Rule of thumb: you do need it when you find yourself using weakrefs.

-- 
Beni <cben at users.sf.net>


More information about the Python-il mailing list