LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Perl or Python (https://www.linuxquestions.org/questions/programming-9/perl-or-python-4175451226/)

dugan 02-23-2013 11:13 PM

Quote:

Originally Posted by Sergei Steshenko (Post 4898414)
b) I need to specify variables in 'format(n, f, s)' in correct order

Not strictly true.

Code:

>>> '{var}'.format(var='value')
'value'

And if you feel that even that sucks, I'm not going to tell you that your opinion is wrong.

Sergei Steshenko 02-23-2013 11:45 PM

Quote:

Originally Posted by dugan (Post 4898500)
Not strictly true.

Code:

>>> '{var}'.format(var='value')
'value'

And if you feel that even that sucks, I'm not going to tell you that your opinion is wrong.

Of course, it sucks. Because even in shell:

Code:

foo="bar"; echo "foo=$foo"
foo=bar

.

Simple.

The goal of Perl was to attract users of 'sed', 'awk', 'sh', and the goal of Python apparently was to be different from Perl.

sundialsvcs 02-24-2013 10:21 AM

This is all nonsense. :)

The languages are different, as are their respective designers. Perl shows its original influences as an extension of Awk, designed to excel at solving file- and text-manipulation problems. Python, despite its odd indentation-driven syntax, is much more LISP-like.

These are both: tools for a job. Your job. Therefore, it would behoove you to learn a great deal about both languages (as well as others).

Each programming language or tool has a certain mind-set that it champions: a certain class of problems that it solves well, and a certain methodology for solving such problems. Today, each language also is accompanied by a large and rich tool-set of contributed software, which in many pragmatic ways are more-important than the core language itself.

So, the middle word in the question should not be "Or." It should be, "And."

A carpenter never chooses between a hammer "or" a chisel, but selects the most-appropriate tool for the task at hand, and allocates a certain amount of his professional-development time learning about more tools.

dugan 02-24-2013 10:45 AM

Quote:

Originally Posted by sundialsvcs (Post 4898709)
Python, despite its odd indentation-driven syntax, is much more LISP-like.

Interesting, I've never seen Python described as more LISP-like than Perl. Could you please say more about that?

Sergei Steshenko 02-24-2013 04:58 PM

[QUOTE=sundialsvcs;4898709]... Python, despite its odd indentation-driven syntax, is much more LISP-like. .../QUOTE]

I'd say it's quite the opposite, especially for the earlier Python versions.

But both Perl and Python are influenced by LISP.

devUnix 02-25-2013 05:35 AM

Quote:

Originally Posted by sundialsvcs (Post 4898709)
A carpenter never chooses between a hammer "or" a chisel, but selects the most-appropriate tool for the task at hand, and allocates a certain amount of his professional-development time learning about more tools.

Well said, sir!

Sergei Steshenko 02-25-2013 05:42 AM

Quote:

Originally Posted by sundialsvcs (Post 4898709)
...
A carpenter never chooses between a hammer "or" a chisel, but selects the most-appropriate tool for the task at hand, and allocates a certain amount of his professional-development time learning about more tools.

Now, tell me, what is it that Python can do and Perl can't ?

mina86 02-25-2013 09:08 AM

Quote:

Originally Posted by Sergei Steshenko (Post 4899173)
Now, tell me, what is it that Python can do and Perl can't ?

Now, tell me, what is it that Perl can do and Python can't?

Your argument is silly, since both languages have similar set of features and they can do similar things. They have different syntax for various things but on functional level they do the same. And some of the differences are a matter of taste. Like I've said for instance, I don't like having to typo $, @ and % since I have to reach my fingers far away from home row. I also don't like Perl object model, and I'm sorry, but if you tell my that it's better then Python's than you are crazy.

And string formatting thing? "string: $s, number: $n, float: $f" is very hard to internationalize whereas "string: %(string)s, number: %(number)d, float: %(float)f" is very easy to internationalize.

Sergei Steshenko 02-25-2013 10:56 AM

Quote:

Originally Posted by mina86 (Post 4899295)
Now, tell me, what is it that Perl can do and Python can't?

Your argument is silly, since both languages have similar set of features and they can do similar things. They have different syntax for various things but on functional level they do the same. And some of the differences are a matter of taste. Like I've said for instance, I don't like having to typo $, @ and % since I have to reach my fingers far away from home row. I also don't like Perl object model, and I'm sorry, but if you tell my that it's better then Python's than you are crazy.

And string formatting thing? "string: $s, number: $n, float: $f" is very hard to internationalize whereas "string: %(string)s, number: %(number)d, float: %(float)f" is very easy to internationalize.



Quote:

I also don't like Perl object model
- it was stolen from Python. http://www.perl.com/pub/2007/12/soto-11.html :

Quote:

Python

After Tcl came Python, which in Guido's mind was inspired positively by ABC, but in the Python community's mind was inspired negatively by Perl. I'm not terribly qualified to talk about Python however. I don't really know much about Python. I only stole its object system for Perl 5. I have since repented.
.

By the way, I suggest to read the whole article - quite an interesting review of a number of programming languages.

So, since you dislike Perl object model which in fact is the one of Python, your defending Python looks silly :).

Quote:

Now, tell me, what is it that Perl can do and Python can't?
- it can't start catching up with Python - because Python finally started catching up with Perl since Python 3.

If you want a practical example, translate this:

Code:

sergei@amdam2:~/junk/closures_demo> cat -n main.pl
    1  #!/usr/bin/perl
    2
    3  ###############################
    4  # written by Sergei Steshenko #
    5  ###############################
    6
    7  use strict;
    8  use warnings;
    9
    10  $|=1;
    11
    12  my $_car_creator_sub=require './car_creator.prl';
    13
    14  my $_fancy_car_hash_ref=
    15  $_car_creator_sub->
    16    (
    17    'silver', # $color,
    18    300      # $engine_power
    19    );
    20
    21  ${$_fancy_car_hash_ref}{set_driver_sub}->('long legged blond');
    22
    23
    24
    25  my $_humble_car_hash_ref=
    26  $_car_creator_sub->
    27    (
    28    'dark green', # $color,
    29    150          # $engine_power
    30    );
    31
    32  ${$_humble_car_hash_ref}{set_driver_sub}->('poor unemployed');
    33
    34  my $_color;
    35  my $_engine_power;
    36  my $_driver;
    37
    38  $_color=${$_fancy_car_hash_ref}{report_color_sub}->('what a fancy car !');
    39  warn "fancy car color is: $_color";
    40
    41  $_engine_power=
    42  ${$_fancy_car_hash_ref}{report_engine_power_sub}->('what a powerful car !');
    43  warn "fancy car engine power is: $_engine_power";
    44
    45  $_driver=${$_fancy_car_hash_ref}{get_driver_sub}->();
    46  warn "in fancy car the driver is: $_driver";
    47
    48
    49  $_color=${$_humble_car_hash_ref}{report_color_sub}->('what a modest person');
    50  warn "humble car color is: $_color";
    51
    52  $_engine_power=
    53  ${$_humble_car_hash_ref}{report_engine_power_sub}->('what an economical car');
    54  warn "fancy car engine power is: $_engine_power";
    55
    56  $_driver=${$_humble_car_hash_ref}{get_driver_sub}->();
    57  warn "in humble car the driver is: $_driver";
sergei@amdam2:~/junk/closures_demo> cat -n car_creator.prl
    1  ###############################
    2  # written by Sergei Steshenko #
    3  ###############################
    4
    5  use strict;
    6  use warnings;
    7
    8  my $_lame_replacement_of_warn=
    9  sub # the subroutine is anonymous in order not to pollute
    10      # 'main' package namespace; $_lame_replacement_of_warn
    11      # variable won't polluted namespace too, that's because
    12      # Perl 'require' implicitly creates scope, so the variable
    13      # will be in that scope.
    14      # Perl 'require' is NOT like C/C++ '#include' - '#include'
    15      # effectively concatenates files, i.e. no additional scopes
    16      # are created; Perl 'require' DOES create additiobal scope
    17    {
    18    my ($file, $line_number, @stuff_to_print) = @_;
    19
    20    print "#!#!#!# @stuff_to_print at line number ",
    21          $line_number,
    22          " in ",
    23          $file,
    24          " file\n";
    25    };
    26
    27  # the above subroutine is not functionally necessary, it simply shows that
    28  # one can create subroutines necessary for functionality of constructor,
    29  # and being at the same scope as the contructor, still not polluting namespace.
    30
    31
    32  # the anonymous code reference to be returned follows - since it is
    33  # anonymous, it can NOT clash with any name in whatever package the
    34  # file is going to be require'd into
    35  sub
    36    {
    37    my
    38    (
    39    $color,
    40    $engine_power
    41    ) = @_;
    42
    43    my %self; # the hash to be exported anonymously
    44
    45    $_lame_replacement_of_warn->
    46      (
    47      __FILE__, # $file,
    48      __LINE__, # $line_number,
    49        (
    50        "creating car instance with \$color=$color \$engine_power=$engine_power ",
    51        "\\%self=", \%self
    52        )      # @stuff_to_print
    53      );
    54
    55
    56    $self{report_color_sub} =
    57    sub
    58      {
    59      my ($aux_message) = @_;
    60
    61      $_lame_replacement_of_warn->
    62        (
    63        __FILE__, # $file,
    64        __LINE__, # $line_number,
    65          (
    66          "in ",
    67          "\\%self=", \%self,
    68          " \$color=$color \$aux_message=$aux_message"
    69          )      # @stuff_to_print
    70        );
    71
    72      $color; # the returned value
    73      };
    74
    75    $self{report_engine_power_sub} =
    76    sub
    77      {
    78      my ($aux_message) = @_;
    79
    80      $_lame_replacement_of_warn->
    81      (
    82      __FILE__, # $file,
    83      __LINE__, # $line_number,
    84        (
    85        "in ",
    86        "\\%self=", \%self,
    87        " \$engine_power=$engine_power \$aux_message=$aux_message"
    88        )      # @stuff_to_print
    89      );
    90
    91      $engine_power; # the returned value
    92      };
    93
    94    my $driver;
    95
    96    $self{set_driver_sub} =
    97    sub
    98      {
    99      $driver=$_[0];
  100      };
  101
  102    $self{get_driver_sub} =
  103    sub
  104      {
  105      $driver; # the returned value
  106      };
  107
  108    \%self; # the returned hash reference;
  109    };
sergei@amdam2:~/junk/closures_demo> ./main.pl
#!#!#!# creating car instance with $color=silver $engine_power=300  \%self= HASH(0x82d4bc4) at line number 48 in ./car_creator.prl file
#!#!#!# creating car instance with $color=dark green $engine_power=150  \%self= HASH(0x82d47d4) at line number 48 in ./car_creator.prl file
#!#!#!# in  \%self= HASH(0x82d4bc4)  $color=silver $aux_message=what a fancy car ! at line number 64 in ./car_creator.prl file
fancy car color is: silver at ./main.pl line 39.
#!#!#!# in  \%self= HASH(0x82d4bc4)  $engine_power=300 $aux_message=what a powerful car ! at line number 83 in ./car_creator.prl file
fancy car engine power is: 300 at ./main.pl line 43.
in fancy car the driver is: long legged blond at ./main.pl line 46.
#!#!#!# in  \%self= HASH(0x82d47d4)  $color=dark green $aux_message=what a modest person at line number 64 in ./car_creator.prl file
humble car color is: dark green at ./main.pl line 50.
#!#!#!# in  \%self= HASH(0x82d47d4)  $engine_power=150 $aux_message=what an economical car at line number 83 in ./car_creator.prl file
fancy car engine power is: 150 at ./main.pl line 54.
in humble car the driver is: poor unemployed at ./main.pl line 57.
sergei@amdam2:~/junk/closures_demo>

- pay special attention to anonymity and to non-pollutions of namespace.

Pay attention that you can not by mistake or intentionally change variables (e.g. $_lame_replacement_of_warn ) at top level of 'car_creator.prl' from 'main.pl'.

jheengut 02-25-2013 12:06 PM

philosophy of Perl == write less code

philosophy of Python == write readable code

sundialsvcs 02-25-2013 12:15 PM

Personally, I use Perl and Python (and... and...) pretty much interchangeably in my line of work, so I honestly don't think too much about them and certainly don't try to debate philosophies or to suggest that one is "better than" another. It also simply isn't the point of "what can one do that the other cannot."

There are various articles such as http://www.norvig.com/python-lisp.html and http://openbookproject.net/py4fun/lisp/lisp.html which are much better than I am at discussing the etymology of the various programming languages (and, mind you, they definitely do each have one).

In my view, you can definitely see a Lisp influence in Python, with its use of tail-recursion, S-expressions and a bunch of other funky ideas. Not so much in Perl, which was inspired by Awk.

There are always multiple "levels of :jawa:" in every programming language. There's a friendly, approachable front-room that you can spend a lot of time in, perhaps an entire career in. But, over there in the corner, not drawing attention to itself in any particular way, there is a little Door. If you choose to open that door, a strange and intoxicating odor will waft out. You can follow it, exploring the first Hall of Mysteries. At the far end of that room, also not drawing attention to itself, is another little Door ...

You will generally not find the differences between various languages in that friendly, approachable front room.

Every programming language, without exception, started in the mind of some person (or, eecch! committee) who had a problem to solve and who envisioned an "–er" tool to solve that problem and others like it. Then, a whole bunch of other people whacked on it over the years, and wrote a lot of code in it which paid for their research-grants and salaries. And, so it goes.

Sergei Steshenko 02-25-2013 12:43 PM

Quote:

Originally Posted by jheengut (Post 4899413)
philosophy of Perl == write less code

philosophy of Python == write readable code

"philosophy of Perl == write less code" - where did you take this idea from ?

"philosophy of Python == write readable code" - OK, write a regular expression in Perl and Python, and let's compare readability.

mina86 02-25-2013 01:10 PM

Quote:

Originally Posted by Sergei Steshenko (Post 4899380)
So, since you dislike Perl object model which in fact is the one of Python, your defending Python looks silly :).

All right than, let me rephrase: I don't like Perl's syntax for class definition and object creation. Python's is much more readable.


- it can't start catching up with Python - because Python finally started catching up with Perl since Python 3.

If you want a practical example, translate this:

Quote:

Originally Posted by Sergei Steshenko (Post 4899380)
Pay attention that you can not by mistake or intentionally change variables (e.g. $_lame_replacement_of_warn ) at top level of 'car_creator.prl' from 'main.pl'.

Yes, I agree that Python's lack of variable declaration (which can be enforced in Perl by using warnings) is a big flaw.

I can also agree that it would be nice if Python had full-blown lambda where you can put any amount of code, but I really don't see the argument of not polluting namespaces here. And frankly, I find equivalent Python code more readable (mostly because Python has sane syntax for objects):
Code:

$ cat main.py
import inspect

class Car(object):
    @classmethod
    def _warn(cls, msg, *args):
        frameinfo = inspect.getframeinfo(inspect.currentframe().f_back)
        filename = frameinfo.filename
        line_number = frameinfo.lineno
        if len(args) == 1:
            msg = msg % (args,)
        elif args:
            msg = msg % args
        print "#!#!#!# %s at line number %d in %s file" % (
            msg, line_number, filename)

    def __init__(self, color, power):
        self._color = color
        self._power = power
        self._driver = None
        self._warn('creating car instance with color=%s engine_power=%g, '
                  'self=%r', color, power, self)

    def __repr__(self):
        return repr({
            'color': self._color,
            'power': self._power
        });

    def getColor(self, aux_msg):
        self._warn('in %r, color=%s, msg=%s', self, self._color, aux_msg)
        return self._color

    def getPower(self, aux_msg):
        self._warn('in %r, power=%s, msg=%s', self, self._power, aux_msg)
        return self._power

    def setDriver(self, driver):
        self._driver = driver

    def getDriver(self):
        return self._driver


fancy_car = Car('silver', 300)
fancy_car.setDriver('long legged blond')

color = fancy_car.getColor('what a fancy car !')
print "fancy car color is %s" % color

power = fancy_car.getPower('what a powerful car !');
print "fancy car engine power is: %g" % power

driver = fancy_car.getDriver();
print "in fancy car the driver is: %s" % driver;
$ python main.py
#!#!#!# creating car instance with color=silver engine_power=300, self={'color': 'silver', 'power': 300} at line number 21 in main.py file
#!#!#!# in {'color': 'silver', 'power': 300}, color=silver, msg=what a fancy car ! at line number 30 in main.py file
fancy car color is silver
#!#!#!# in {'color': 'silver', 'power': 300}, power=300, msg=what a powerful car ! at line number 34 in main.py file
fancy car engine power is: 300
in fancy car the driver is: long legged blond

Quote:

Originally Posted by Sergei Steshenko (Post 4899441)
OK, write a regular expression in Perl and Python, and let's compare readability.

Both use the same regex syntax so I fail to see your point.


UPDATE: In case you'll try to pursue your namespace pollution argument:
Code:

$ cat main.py
import inspect


def createCar(color, power):
    _driver = [None]

    def _warn(msg, *args):
        frameinfo = inspect.getframeinfo(inspect.currentframe().f_back)
        filename = frameinfo.filename
        line_number = frameinfo.lineno
        if len(args) == 1:
            msg = msg % (args,)
        elif args:
            msg = msg % args
        print "#!#!#!# %s at line number %d in %s file" % (
            msg, line_number, filename)

    class Car(object):
        def __repr__(self):
            return repr({
                'color': color,
                'power': power
            });

        def getColor(self, aux_msg):
            _warn('in %r, color=%s, msg=%s', self, color, aux_msg)
            return color

        def getPower(self, aux_msg):
            _warn('in %r, power=%s, msg=%s', self, power, aux_msg)
            return power

        def setDriver(self, driver):
            _driver[0] = driver

        def getDriver(self):
            return _driver[0]

    return Car()


fancy_car = createCar('silver', 300)
fancy_car.setDriver('long legged blond')

humble_car = createCar('dark green', 150)
humble_car.setDriver('poor unemployed')

color = fancy_car.getColor('what a fancy car !')
print "fancy car color is %s" % color

power = fancy_car.getPower('what a powerful car !');
print "fancy car engine power is: %g" % power

driver = fancy_car.getDriver();
print "in fancy car the driver is: %s" % driver;


color = humble_car.getColor('what a modest person')
print "fancy car color is %s" % color

power = humble_car.getPower('what an economical car');
print "fancy car engine power is: %g" % power

driver = humble_car.getDriver();
print "in humble car the driver is: %s" % driver;
$ python main.py
#!#!#!# in {'color': 'silver', 'power': 300}, color=silver, msg=what a fancy car ! at line number 26 in main.py file
fancy car color is silver
#!#!#!# in {'color': 'silver', 'power': 300}, power=300, msg=what a powerful car ! at line number 30 in main.py file
fancy car engine power is: 300
in fancy car the driver is: long legged blond
#!#!#!# in {'color': 'dark green', 'power': 150}, color=dark green, msg=what a modest person at line number 26 in main.py file
fancy car color is dark green
#!#!#!# in {'color': 'dark green', 'power': 150}, power=150, msg=what an economical car at line number 30 in main.py file
fancy car engine power is: 150
in humble car the driver is: poor unemployed

_driver is an array only because Python 2.7 (which I have installed) does not have nonlocal keywoard.

Sergei Steshenko 02-25-2013 01:47 PM

Quote:

Originally Posted by mina86 (Post 4899460)
All right than, let me rephrase: I don't like Perl's syntax for class definition and object creation. Python's is much more readable.


- it can't start catching up with Python - because Python finally started catching up with Perl since Python 3.

If you want a practical example, translate this:


Yes, I agree that Python's lack of variable declaration (which can be enforced in Perl by using warnings) is a big flaw.

I can also agree that it would be nice if Python had full-blown lambda where you can put any amount of code, but I really don't see the argument of not polluting namespaces here. And frankly, I find equivalent Python code more readable (mostly because Python has sane syntax for objects):
Code:

$ cat main.py
import inspect

class Car(object):
    @classmethod
    def _warn(cls, msg, *args):
        frameinfo = inspect.getframeinfo(inspect.currentframe().f_back)
        filename = frameinfo.filename
        line_number = frameinfo.lineno
        if len(args) == 1:
            msg = msg % (args,)
        elif args:
            msg = msg % args
        print "#!#!#!# %s at line number %d in %s file" % (
            msg, line_number, filename)

    def __init__(self, color, power):
        self._color = color
        self._power = power
        self._driver = None
        self._warn('creating car instance with color=%s engine_power=%g, '
                  'self=%r', color, power, self)

    def __repr__(self):
        return repr({
            'color': self._color,
            'power': self._power
        });

    def getColor(self, aux_msg):
        self._warn('in %r, color=%s, msg=%s', self, self._color, aux_msg)
        return self._color

    def getPower(self, aux_msg):
        self._warn('in %r, power=%s, msg=%s', self, self._power, aux_msg)
        return self._power

    def setDriver(self, driver):
        self._driver = driver

    def getDriver(self):
        return self._driver


fancy_car = Car('silver', 300)
fancy_car.setDriver('long legged blond')

color = fancy_car.getColor('what a fancy car !')
print "fancy car color is %s" % color

power = fancy_car.getPower('what a powerful car !');
print "fancy car engine power is: %g" % power

driver = fancy_car.getDriver();
print "in fancy car the driver is: %s" % driver;
$ python main.py
#!#!#!# creating car instance with color=silver engine_power=300, self={'color': 'silver', 'power': 300} at line number 21 in main.py file
#!#!#!# in {'color': 'silver', 'power': 300}, color=silver, msg=what a fancy car ! at line number 30 in main.py file
fancy car color is silver
#!#!#!# in {'color': 'silver', 'power': 300}, power=300, msg=what a powerful car ! at line number 34 in main.py file
fancy car engine power is: 300
in fancy car the driver is: long legged blond


Both use the same regex syntax so I fail to see your point.


"Yes, I agree that Python's lack of variable declaration (which can be enforced in Perl by using warnings) is a big flaw." - I think you are missing the point. I said that from 'main.pl you can not change variables in 'car_creator.prl' - by construction of the language. I.e. the variables in question are invisible.

In your translation you completely missed the point. My 'main.pl' imports (using Perl 'require' statement) another file: 'car_creator.prl'. Even though I myself wrote both file the point is that in real life such files are written by different developers, and protection from unauthorized use of resources is important - you know, all that private/protected stuff ?

So, if you want to understand what Python can't do while Perl can, try to translate my code preserving separation into two files, and preserving functionality of the files.

By the way, pay attention that I have not used Perl OO model at all. And closures which I'm using exist for a reason - closures are a classical mecahnism to implement state.

Also, I export only methods through $self, while you, if I understand correctly, in stuff like self._color export data. I.e. if my understanding is correct, you do not have data encapsulation while I have it.

If you can't adequately (i.e. using equivalent mechanisms) translate what I've written, you have a vivid example of what can be done in Perl, but not in Python.


Not polluting namespaces means less mess when several developers work on a project - they do not have to agree on names. Perl is a production language.

mina86 02-25-2013 07:50 PM

Quote:

Originally Posted by Sergei Steshenko (Post 4899485)
So, if you want to understand what Python can't do while Perl can, try to translate my code preserving separation into two files, and preserving functionality of the files.

My second translation does what you want. Not that I agree with your argument at all. The practice is that you can “hide” elements just by prefixing the name with an underscore. It's not as ideal as C++'s protected and private, but it works reasonably well.

Quote:

Originally Posted by Sergei Steshenko (Post 4899485)
By the way, pay attention that I have not used Perl OO model at all. And closures which I'm using exist for a reason - closures are a classical mecahnism to implement state.

You're reason makes the code less readable though.

Quote:

Originally Posted by Sergei Steshenko (Post 4899485)
If you can't adequately (i.e. using equivalent mechanisms) translate what I've written, you have a vivid example of what can be done in Perl, but not in Python.

My updated translation does what Perl code does except for being put in one file. Separating it to two files. You can use

Quote:

Originally Posted by Sergei Steshenko (Post 4899485)
Not polluting namespaces means less mess when several developers work on a project - they do not have to agree on names. Perl is a production language.

As long as two developers work on different files, there's no namespace clash in Python either. If they work on the same file, I would expect them to work together and agree on names anyway.


All times are GMT -5. The time now is 02:44 PM.