ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
...
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 ?
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.
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.
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'.
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."
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 " 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.
Last edited by sundialsvcs; 02-25-2013 at 12:20 PM.
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
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
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.
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.
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
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
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
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.