Subject: Re: [Israel.pm] Perl Vs. Python on Various Points

From: Gabor Szabo <[email-masked]>
Date: Mon, 13 Jul 2009 12:56:55 +0300

I don't understand you Shlomi.

By now you should know that any comparison between Perl and Python just
leads to some Python fan pulling out the "Perl is not readable" meme.
It is totally worthless to talk in public about this. There is always
the bad apple
to ruin any normal discussion.

Nevertheless let me comment on some of your points,

On Mon, Jul 13, 2009 at 11:10 AM, Shlomi Fish<[email-masked]> 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:

I like the sigils ($ @ %) indicating the data type but I dislike that
in Perl 5 we need to
dereference arrays writing @$aray_ref and there even more horrid constructs.
Luckily in Perl 6 it is cleaned up hence I prefer it over Perl 5.

Some people still add & in front of the function names even though
that requirement
was eliminated 15 years ago.

>
> 4. Hiding Code By Using .pyc's
> ------------------------------
>
> The python backend compiles the text-based Python code to bytecode, and
> caches the result in .pyc files. My partner to the conversation argued that
> he often uses these .pyc files to "hide" the source code from people he's
> distributing it to them, so they will be unable to reverse engineer it.
>
> I told him that with a symbolic language such as Python, such .pyc files
> do not provide adequate "protection" as they contain the names of identifiers
> and other detailed information on the code.

Let's go to the car analogy.

Locking your car does not stop someone from steeling it but it makes
it more difficult.
It might also be the difference between making you eligible or not to
receive payment from
the insurance company.

<story>
Actually I have a personal experience with this. A long time ago I had
a car that cost
only a few thousand shekels so I did not make the comprehensive insurance.
Unfortunately I have not installed Rav-bariach-lock either. One night
some kids stole it,
used it for a few weeks and crashed it. The police found it and I had
to handle the disposal
of what remand from the car. It clearly wasn't a professional car
stealer - did not take it for
the 'monetary value' of the car but for the fun value. They were
script kids. If the car had a
lock on it they would have moved to the next - easier - target.
</story>

Creating byte-code might not stop those who really want to steal your
code but it will make
it slightly more difficult and it might make the difference for the
legal department.

Talking about obfuscation and Perl on a Python list is just plain
silly as you could see
from the other comment. For some reason Python programmers -
especially those who
once used Perl - cannot stop themselves from such stupid derogative comments.

Technically you might be right that obfuscation and bytecode pose  the
same level of
difficulty for reverse engineering. I don't know. What I know is that
obfuscation is not an
accepted practice in the industry and compilation to byte-code is (see
Java, C#).

So the fact that Perl 5 cannot be compiled to bytecode is a major drawback in
every place where a company wants to distribute its code to customers.
Luckily this is too solved by Perl 6 so if you write in Perl 6 you can
already compile
it to Parrot byte-code.

regards
   Gabor

-- 
Gabor Szabo                     http://szabgab.com/blog.html
Test Automation Tips        http://szabgab.com/test_automation_tips.html
Perl 6 Tricks and Treats  http://szabgab.com/perl6_tricks_and_treats.html

---

From: Shlomi Fish <[email-masked]>
Date: Mon, 13 Jul 2009 13:45:44 +0300

> to ruin any normal discussion.

Yes, I guess I know that. It still doesn't prevent the rest of the discussion 
from being high-quality and interesting. It's sad that many Pythoneers need to 
state this meme, again and again, (despite the fact that they should know 
better by now) but it doesn't rule out an intelligent and insightful 
discussion.

> > 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:
>
> dereference arrays writing @$aray_ref and there even more horrid
> constructs. Luckily in Perl 6 it is cleaned up hence I prefer it over Perl
> 5.
>

Normally you need only one dereference of some arrow expression. I'm 
personally am not bothered by it too much. I haven't investigated too much of 
how Perl 6 handles the references' syntax (except for the leading digit be the 
same for every access), but it may be worthy of inspection.

> was eliminated 15 years ago.

And it's no longer recommended because it over-rides prototypes and does other 
shenanigans. 

> > caches the result in .pyc files. My partner to the conversation argued
> > that he often uses these .pyc files to "hide" the source code from people
> > he's distributing it to them, so they will be unable to reverse engineer
> > it.
> >
> > do not provide adequate "protection" as they contain the names of
> > identifiers and other detailed information on the code.
>

I think your analogy is more or less valid here, even though I may argue that 
a single car is not analogous to code that you distribute to customers at a 
lot of cost.

> it slightly more difficult and it might make the difference for the

Well, it's fig-leaf protection. It may be good enough for the legal 
department, but it won't really protect your code (which is how fig-leaf 
protection is defined).

Personally, I think more software companies should trust their customers (like 
FOSS developers trust their users), and realise that what matters is not how 
many people violate the licensing terms, but how many of them would have been 
paying customers:

http://better-scm.berlios.de/bk/what-bitmover-got-wrong.html

> accepted practice in the industry and compilation to byte-code is (see

Well, in Java and .NET compilation to byte-code may make more sense because 
they are not symbolic languages. However, as my link to the Slashdot 
discussion indicates, reverse engineer Java byte code may be substantially 
easier than reverse engineer real Assembly code.

In Python, the .pyc's are generated for optimisation and are not meant as a 
reliable way to obscure the code. So relying on it for protecting the source 
code, may be good for covering your ass, but it's not real protection.

> So the fact that Perl 5 cannot be compiled to bytecode is a major drawback
> in every place where a company wants to distribute its code to customers.

The perl 5 virtual machine uses its own internal bytecode, which is documented 
and accessible and can be utilised for such things. I recall that ActiveState 
used to distribute their PerlMx (Perl Mail Exchange - a now defunct spam 
filtering framework) as Perl bytecode. Again - not real protection, but 
possibly enough to satisfy their legal department. So the technology is there.

Again, I wouldn't recommend doing it, because it's not real protection, but 
neither are Python's .pyc files. 

> Luckily this is too solved by Perl 6 so if you write in Perl 6 you can

Well, there's still a long time until we will have a usable Perl 6 compiler. 
At the moment, Rakudo still has many bugs and omissions and reportedly runs 
600 times slower than perl 5. While I'm looking forward to it, it will be some 
time until we can use Perl 6 in production.

Compiling to Parrot bytecode may be somewhat better than python's or perl 5's 
bytecode, as far as "protection" is concerned, but I wouldn't count on it 
being hard to reverse engineer either.

Regards,

	Shlomi Fish

-- 
-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
What Makes Software Apps High Quality -  http://xrl.us/bkeuk

God gave us two eyes and ten fingers so we will type five times as much as we
read.

---

From: Gabor Szabo <[email-masked]>
Date: Mon, 13 Jul 2009 14:07:04 +0300

> many people violate the licensing terms, but how many of them would have been

I am sure companies are worried about someone using their code without paying
the license fee but I think they are a lot more worried about someone
taking their
code and selling a competitive product.

Again something that happened to me:

I published the content of one of my training courses so people can
read it and one
of the high-profile training companies copied it and uses it directly
competing against
me with a much better marketing department.

Interestingly I happen to know someone who was a manager in the parent
company of
that training company and he said something like
"copying others material is an industry standard in Israel".
as if that will make me happier.

Gabor

---

From: Shlomi Fish <[email-masked]>
Date: Mon, 13 Jul 2009 14:32:37 +0300

On Monday 13 July 2009 14:07:04 Gabor Szabo wrote:
> > I think your analogy is more or less valid here, even though I may argue
> > that a single car is not analogous to code that you distribute to
> > customers at a lot of cost.
> >
> >
> > Personally, I think more software companies should trust their customers
> > (like FOSS developers trust their users), and realise that what matters
> > is not how many people violate the licensing terms, but how many of them
> > would have been paying customers:
>
> I am sure companies are worried about someone using their code without
> paying the license fee but I think they are a lot more worried about
> someone taking their

Yes.

> as if that will make me happier.

I assume the licensing terms that the material was made available under did 
not allow commercial use. In that case, you have the right to press charges 
against this company, receive damages and/or prevent them from making further 
use of your material without permission. The law (and the common ethical 
conduct) are on your side.

Naturally, suing someone is very resource consuming, and so may not be an 
option for you.

Another option would be for you to make this fact public (with all the 
relevant facts and details) in hope that it will tarnish the other company's 
reputation. Again, this should be thoughtfully considered and may backfire.

I should note that I made my the material of my "Perl for Newbies" series ( 
see http://www.shlomifish.org/lecture/Perl/Newbies/ ) available under the 
Public Domain and I encourage people to make any use of them that they wish. I 
would still appreciate a monetary donation , attribution , or releasing 
derived works to the public too, but I don't necessitate them. But I agree 
with Gabor that he has been done an injustice because it is within his right 
to restrict commercial use of his material, and even some Creative Commons 
licences are doing that.

Regards,

	Shlomi Fish 

> Gabor
> _______________________________________________
> Python-il mailing list
> [email-masked]
> http://hamakor.org.il/cgi-bin/mailman/listinfo/python-il

-- 
-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
Stop Using MSIE - http://www.shlomifish.org/no-ie/

---

From: Shlomi Fish <[email-masked]>
Date: Mon, 13 Jul 2009 15:47:48 +0300

On Monday 13 July 2009 15:12:16 Tal Einat wrote:
> On Mon, Jul 13, 2009 at 12:57 PM, Shlomi Fish wrote:
> > On Monday 13 July 2009 12:00:23 Tal Einat wrote:
> >> > I said I happen to like it because the extra characters convey
> >> > meaning.
> >>
> >> Perl has very few built-in types; I recall numbers, strings, arrays,
> >> hashes and functions. When you need to use anything else you are
> >> forced to use references, which are indistinguishable from numbers and
> >> require "casting" their targets' values back to their actual type.
> >
> > References are not numbers. They are different types of scalars. You can
> > tell them apart using perldoc -f ref . You may be able to add a reference
> > to a number, without a lot of meaning, or perform other arithmetic
> > operations, but it's not encouraged.
>
> My point here was that because references are scalars like numbers and
> strings, and references are used quite often, knowing that something
> is a scalar means that it is either a "simple" scalar (number, string,
> undef) or a reference (which can point to anything), so it isn't
> obvious what type of underlying data it represents. My experience with
> Perl found me using references very often, which made the sigils less
> informative and more of a burden.

I see. Well, you can tell what a reference is by how it is used. ->[], ->{}, -
>(), ->method() , etc. are all different. It will be better in Perl 6, where 
one can pass non-scalar variables (@array, %hash, etc.) to functions by 
reference, as well as call methods on them directly. Hopefully, we'll see some 
of this in perl 5 too.

>
> >> In Python every class defines its own
> >> comparison methods (if relevant), which Python uses when evaluating
> >> "==" and friends. I can use "==" and ">=" and ">" to compare various
> >> types of containers, such as lists, sets, tuples and dicts, and these
> >> comparisons are simple and obvious. Besides making the code clean and
> >> readable, things like this make learning Python less tedious.
> >
> > Can I also overload the meaning of these for my own containers? This may
> > cause unexpected results. This is also the case for Perl with
> > overloading.
>
> Yes, you can. However, doing so for non-trivial comparisons is highly
> discouraged.
>
> The main point is that the comparison operators simply work for all of
> the built-in classes as well as those in the standard library.
> Normally you doesn't really have to think about such issues at all
> since the normal comparison operators just do what you would expect.
>

I see.

> >> > 4. Hiding Code
> >>
> >> Usually you just don't want someone to have your original version of
> >> the code, so they don't copy/paste and develop their own product based
> >> on your code.
> >
> > Well, Richard M. Stallman and other free software zealots will disagree
> > with you on this. ;-) Even Python itself is distributed along with the
> > original version of the code, so other people can copy/paste and develop
> > their own product based on the code. Its licence even permits changing
> > the licence of the code, including making it proprietary.
>
> I should have added "excluding open-source software" or something
> before that... :)
>

My point was that even if you are distributing non-FOSS software (which is 
within your rights), you should still not depend on hiding your source code 
(especially in language that don't easily allow it) as a way of protecting it. 
Like I said, it's fig-leaf protection at best.

> >> For this purpose obfuscation and/or compiling to
> >> byte-code are enough.
> >
> > You may be right. However, I was under the impression that my
> > conversation partner wanted even better protection.
>
> That is hard to achieve with any language! There are many decompilers
> for C/C++ which do a pretty good job even on highly optimized code,
> not just Java. 

Really? I'm surprised that the C/C++ decompilers are so advanced. I expected 
the current state of the art to be less than that.

> The only way to ensure someone doesn't know what your
> software is doing is to not have the software run on his computer.
>

Right.

> >> (Obligatory: Writing in Perl is all the obfuscation one would ever need
> >> ;)
> >
> > That's an old joke and was never particularly funny or true.
>
> Actually I was trying to have a serious conversation, and just
> mentioned the usual trolling with a wink to show that I'm not like
> that. No hard feelings I hope?
>

No, none. But next time try to be more explicit, or alternatively not throw 
oil into the fire at all.

Regards,

	Shlomi Fish

> - Tal

---

From: Beni Cherniavsky <[email-masked]>
Date: Mon, 13 Jul 2009 16:57:39 +0300

On Mon, Jul 13, 2009 at 11:10, Shlomi Fish<[email-masked]> wrote:
> <<<<<
> 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 <[email-masked]>

---

From: Beni Cherniavsky <[email-masked]>
Date: Mon, 13 Jul 2009 22:32:47 +0300

On Mon, Jul 13, 2009 at 13:45, Shlomi Fish<[email-masked]> wrote:
>> the bad apple to ruin any normal discussion.
>
I do want to address that meme productively.
If you catch me degenerating to a troll, feel free to apply sunlight
and I'll to freeze to stone ;-)

First, it's important to clarify that Python fans don't pull the
readability meme to be nasty (at least not initially).
For us, it is honestly the most important thing we can say about Perl
vs. Python.
You could show us a 100 perl features, and we'd still say "but Python
looks better"!
We feel the difference is very real, and very important.

You know Perl & Python and prefer Perl, so obvisouly it's not a
universal assement.
This might be a bit like Lisp parens - some people love them, some hate them.
Lispers fought the "Lisp is unreadable, it all looks the same" meme for decades.
But there is an undeniable reality to the problem: it scares a lot of people.

The second observation I have to make concerns the "semantic gap".
It's a notion I saw once in someone's defense of some esoteric
language, can't find it now.
"Semantic gap" is the distance between how you think about the
problem, and how your code looks.
Obvisously the smaller this gap is, the better - any distance adds
friction, distraction and bugs.

It seems to me that many of the intricacies of Perl's syntax increase
the semantic gap.
(Please read mitigating comments below before replying point-by-point.)

push @array, $val;
    I meant push, of course it's scalar into array, why did I have to
mention "@" and "$"?
$array_ref = [1, 2];
    I meant an array, the "$" is an outright lie!
$length = @array;
    I meant take length of array, but all I wrote was "$" and "@".
$length = scalar @array;
    Better style, but why did I say "scalar" when I meant "length"?
@a = @b;
%a = %b;
    1-deep-copy, but I never said "copy".
$a_ref = $b_ref;
    no copy, but looks similar.
$a = <>;
...
$total += $a;
    I meant convert string to number, why didn't I say it anywhere?
    Also, what does it do if it's not a valid number?
    Where did I say it should silently do that?
    Why didn't I write "<> || 0" if that's what I meant?
open ...;
     What does it do if it fails?  Continues?
     I wrote "open", I didn't mean "maybe open".
open ... || die;
     This ensures that open does its work.  Why do I have to say it?

     What I'm getting is that code should either do exactly what I
said, or crash.
     If I want to recover from errors, I should explicitly write the
recovery path.
     Silent defaults == execution paths invisible on casual reading.

$a > $b;
$a gt $b;
    I meant compare values, why do I mention the type?
    If it implies conversion, it's non-obvious (see above);
    if it doesn't imply conversion, why do I have to mention it?
%b2a = reverse %a2b;
    Happens to work neatly, but not because that's what "reverse" does.
    It's converted to a flat list, the list is reversed, and parsed into a hash.
    You have to think about the process.  (OK, this one is an idiom)
while (($key, $value) = each %hash)
    I meant "foreach", why did I write a while?
while(<>)
    I meant "foreach", why did I write a while?
sub s {
  my ($a, $b) = @_;
  ...
}
    I meant "sub s($a, $b) { ... }", why do I write it this ugly way?

[BTW, Perl 6 is much better!  It fixes all problems that were rooted
in historical accident rather than deliberate choice.
Eventually I gave up on it, but for lesser reasons...]

Of course, with experience these become second nature to you.
You write and read idioms, and you know exactly what they mean.

So it's not so much of a practical question as phylosophical - do you
care how your idioms look to the non-initiated?
How close is it to English?  How much brain cells do you need to
transparently read and write these idioms?
Note that these are ideological questions.  If a non-obvious syntax +
deeper training idioms give you more power, why not?

The Python answer is "because, period": we believe in "Readability counts".
The second answer is proof-by-example: if Python manages a cleaner
syntax with comparable power, it's a win.

On a deeper level of semantic gap, the above "petty" examples don't matter.
The real semantic gap is in domain-specific things.
The question is not how you manipula lists, it's how you manipulate FooFrobs.
So the real question is - does the language allow writing a great
FooFrobs library?

This depends on syntax like function definition and calling, class
definition and use,
namespace mechanics, higher-order facilities, control abstractions, etc.
These are harder to evaluate, so I won't even try to list examples.
I do think Python is very good on this scale too.

On this point,  http://greenokapi.net/talks/ReadablePerl.pdf is a great read.
Shows perl is not bad either.

-- 
Beni <[email-masked]>

---

From: Gabor Szabo <[email-masked]>
Date: Tue, 14 Jul 2009 17:36:49 +0300

Hi Beni,

> You know Perl & Python and prefer Perl, so obvisouly it's not a

There is a difference when you say:

"For me Python is more readable than Perl"
"Python is more readable than Perl"
"Perl is NOT readable" or "Perl is write only".

The first one is ok.
The second one is already crossing the line.
The third one is outright nasty. Don't even try to convince me otherwise.

Oh and when you try to say in all kinds of words like
"For us readability is important" is just plain sounds as FUD.
I could keep saying "For us working code is important" or I could
say "For us freedom is important".

> But there is an undeniable reality to the problem: it scares a lot of people.

Yeah, the unknown scares a lot of people.

> (Please read mitigating comments below before replying point-by-point.)

I don't feel myself competent to answer point-by-point nor do I think it is
relevant. There are cases where I agree that Perl isn't intuitive enough
but there are a lot of other cases where I think the same arguments could be
used just in the opposite direction.

I think it boils down a lot to how your brain works but more importantly
to what you are used to.

> Eventually I gave up on it, but for lesser reasons...]

It is hard to keep up with the development of Perl 6 but we are getting closer.
I am giving a training class next month in Lisbon and I believe in a year or two
we will see it getting in production. You can already write applications in it.

> Shows perl is not bad either.

Indeed. One of the biggest problems of Perl is that it was (and still
is) used by
many  people who don't know how to write code. They were copy pasting
bad code examples or code examples that are are only working to keep backword
compability for the last 22 years. Companies are hiring people with very little
experience and telling them to write production code without even the
involvement
of one experienced Perl programmer.

IMHO it happens a lot less in Python.

regards
  Gabor

---

From: Shlomi Fish <[email-masked]>
Date: Wed, 15 Jul 2009 09:34:57 +0300

On Monday 13 July 2009 16:57:39 Beni Cherniavsky wrote:
> > 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.
>
> 1. They convey the type of operators: "$listref1 = $listref2" is 0-deep
> copy while "@list1 = @list2" is 1-deep-copy.
>

I guess you're right. I still find that using sigils help me understand what 
the code does.

> > 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.
>
> > 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.
>
> ...
>
> > http://search.cpan.org/dist/Test-Differences/ , or can use the more
> > limited is_deeply() functionationality of Test::More.
>

Well, I haven't found deep comparison very useful so far, except in testing, 
where I have is_deeply() or the better Test::Differences. Personally, if I 
have a complex data structure and want to compare it to another complex data 
structure - how will this comparison be done and what can I learn from it in 
my code? 

Data::Dumper has been part of the Perl core for a long time (it can mostly 
implemented completely in user-land, though), and Perl programmers make 
extensive use of it. There are many other modules for handling nested data 
structures on CPAN and in the core, like Storable, which is useful for 
serialisation and deserialisation or http://search.cpan.org/dist/Data-DPath/ . 

> > because for two pieces of data, there may be several ways that we would
> > like to compare them.
>

Yes, it's hard for me to recall which is which. I think (=) is numeric and 
(eq) is if it's the same referent. Isn't (equal) a deep comparison?

> comparison (overloadable by type), and shallow identity check.

Well, arguably the Perl 5 distinction of == and eq is because strings and 
numbers are inter-changeable.

> might explain why they felt OK with having so many.)

Not all Lisp operators can be implemented as regular functions. Examples for 
this are (or) and (and). These might still be able to be implemented as 
macros.

> Or did you mean that Python detects them when dumping values?

No, that they exist in the first place. He was surprised to learn that they 
are at all possible in Python, as he didn't use them.

Yes.

>  There is no easy, or even single, way to compare circular structures.

Well, one option I can think of is to detect a cycle within the nesting path 
of each variable being compared, and if so, see if it's equivalent to the one 
in the other side, and deal with it. In any case, throwing an exception in 
this case is not very desirable because saying a_ref == b_ref is innocent 
enough. But I suppose the edge case of a circular reference is not critical 
enough to warrant special treatment.

> There are many ways to define graphs, so it's left to libraries to handle

I don't understand these two paragraphs.

>
> > 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.
>

Ah.

Regards,

	Shlomi Fish

-- 
-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
My Aphorisms - http://www.shlomifish.org/humour.html

---

From: Beni Cherniavsky <[email-masked]>
Date: Wed, 15 Jul 2009 12:47:58 +0300

On Mon, Jul 13, 2009 at 16:19, Roman Gaufman<[email-masked]> wrote:
> I didn't tell my "clients" anything - my employer said you can't use
> Perl because it doesn't have compiled bytecode, I asked what about
> python, it does -  they came back to me saying to use it.
>
If you are satisfied with this outcome, more power to you ;-)
If want ammunition in favor of Perl:
1. Python bytecode is really easy to decompile, waaay easier than C.
  Details below.
  Be careful with stressing this, lest your employer demands C :-\
2. Perl also uses bytecode, it just doesn't spew it into files by default.
  But it's easy to do - see below.

> There are disassemblers and decompilers for just about all compiled
> bytecode out there - they show you the virtual machine instructions
> used and some reference identifiers. There are also disassemblers and
> decompilers for compiled C code, that also show you the machine
> instructions being used.

Bytecodes tend to use higher-level operations, with well-defined
function frames on stack, debug information, and no ugly C-style
optimizations (inlining, unrolling, order-changing scheduling, etc.)

Also, dynamic languages like Python have almost no information
that can be thrown out after compilation (e.g. types).  Everything
you write is needed for running.

> pyc is compiled bytecode - so while you can reverse engineer compiled
> bytecode (as you can reverse engineer just about everything) -- you
> don't have nesting depths, scope, type - all you have is numeric
> codes, numeric addresses and some visible references. It's a little
> more than fig-leaf protection.
>
Wrong!  Python bytecode retains scopes, variable names, etc.
Decompiled python code is really almost identical to original!
About the only thing you lost are comments:
http://sourceforge.net/projects/decompyle/
http://www.crazy-compilers.com/decompyle/

You can achieve a bit more protection by obfuscating names:
http://pawsense.com/python..obfuscator/
http://www.lysator.liu.se/~astrand/projects/pyobfuscate/
but these only work on single-module projects and aren't 100% safe.

At the very least, use python -OO to produce .pyo without docstrings.
Note that -O also discards assert statements
(lesson: never use assert for input validation in Python).

Perl bytecode
-----------------
See:
http://www.developertutorials.com/tutorials/cgi-perl/optimize-perl-050409/page10.html
http://perldoc.perl.org/B/Bytecode.html
http://www.perlmonks.org/?node_id=62936
(I never used any of those, just shooting relevant google results.)

I don't know how much information Perl bytecode retains;
from the little I know about Perl internals, I suspect it loses more
details and does more transformations than Python,
so decompiled code should looks less like the source.
If even more armor is needed, there are obfuscators for Perl too.

--
Beni <[email-masked]>

---

From: Shlomi Fish <[email-masked]>
Date: Wed, 22 Jul 2009 12:53:40 +0300

>   But it's easy to do - see below.

Hi Beni!

Just wanted to thank you for this great post of yours. You've confirmed my 
intuition.

Regards,

	Shlomi Fish

> http://www.developertutorials.com/tutorials/cgi-perl/optimize-perl-050409/p
>age10.html http://perldoc.perl.org/B/Bytecode.html

-- 
-----------------------------------------------------------------
Shlomi Fish       http://www.shlomifish.org/
Parody on "The Fountainhead" - http://xrl.us/bjria