Took about 30 minutes, far less time than messing about with why pip has broken on my desktop yet again:
Traceback (most recent call last):
File "/usr/local/bin/pip", line 11, in <module>
sys.exit(main())
File "/usr/local/lib/python3.5/dist-packages/pip/_internal/cli/main.py", line 73, in main
command = create_command(cmd_name, isolated=("--isolated" in cmd_args))
File "/usr/local/lib/python3.5/dist-packages/pip/_internal/commands/__init__.py", line 96, in create_command
module = importlib.import_module(module_path)
File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 665, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "/usr/local/lib/python3.5/dist-packages/pip/_internal/commands/search.py", line 18, in <module> b5n:~/venv_dir$ python3 -m venv im_a_venv
b5n:~/venv_dir$ . im_a_venv/bin/activate
(im_a_venv)b5n:~/venv_dir$ pip install requests
(im_a_venv)b5n:~/venv_dir$ pip freeze > requirements.txt
(im_a_venv)b5n:~/venv_dir$ deactivate
b5n:~/venv_dir$ python3 -m venv another_venv
b5n:~/venv_dir$ . another_venv/bin/activate
(another_venv)b@b5n:~/venv_dir$ pip install -r requirements.txtI don't write software as an end goal, I write software to accomplish my end goal.
My personal experience: at one of my previous jobs we've had the need to find a support ticket system (preferably free) that was flexible enough to handle a few hundred email accounts with different signatures, headers, reply templates, queues, filters, and more for each individual account. At the time the "winner" was OTRS [0] [1], a system in Perl that is super flexible and had a free version (more recently renamed to community edition since it detached a bit from their enterprise version).
It served us well enough that I have deployed it again on my current job when a similar but smaller need arose (both jobs in tourism industry). It's a pretty big and complex thing but does it's job well once configured correctly which does take a bit of work.
> The only times I see it is for legacy stuff, and then only because the script is too much of a hassle to be rewritten.
That can possibly be the case here since it is "old" (changelog lists the first public beta at 2002) but has had pretty much continuous development until this day. Any company trying to develop something like this these days would probably choose something else but I guess they're a Perl shop now.
[0] - https://github.com/OTRS/otrs
[1] - https://otrs.com/
Yes, you can call them open core now. But still many companies are using the community edition and are served well by it.
I worked closely with the technical founder and he started the pre-decessor of OTRS in the 90s while working at SUSE, and yeah of course it was in Perl!
I must say that working on the quite significant OTRS code base, with proper code conventions, 'modern' perl5 is not so bad. But when using third party libraries sometimes you'd see arcane language usage and there seems lots of magic involved...
Also, the technical founder started https://zammad.org -- the same idea but started in 2012 or so. So now it's Ruby!
Modern perl5 is ok. But the ecosystem is slowly deteriorating.
You’re an expert, and a rewrite is going to expose you to a lot of scrutiny. You are going to break things, when maybe you haven’t broken things in a long time and people like it that way.
So when some day arrives where a new fad is hot and it’s hard to impossible to find Perl programmers, the will create a new team to rewrite it badly because now they have no other choice. And of course the new folks are going to screw up, but that’s just expected.
Which I'm finding harder to understand as I learn more languages. Yeah, every language has its differences and idiosyncrasies, but as long as you have access to docs (if not third-party resources like expert blogs or Stack Overflow) it's pretty straightforward to figure those out and be reasonably productive relatively soon.
That is: a senior programmer should have enough background knowledge to be able to be productive on any language ("polyglot" shouldn't be a big deal), and a junior programmer won't typically have enough experience in any particular language to be definitively a "$LANGUAGE programmer". In either case, whether or not a programmer already knows the language before being hired is kind of a moot point.
My current dayjob was the first time I had written any non-trivial amounts of Python, Javascript, or C# in a professional capacity in my whole career. Being productive on them wasn't terribly hard - it's just different syntax around a lot of the same concepts (and sure, there were also some new concepts - took a good while for me to wrap my head around async/await, for example, coming from a background of message passing between threads or processes or actors - but those can be learned).
Usually the choice of programming language is far less significant as a barrier to one's understanding of a codebase than, say, the actual problem domain. Writing software for, say, a warehouse tends to necessitate knowing an awful lot about how warehouses work; whether or not you happen to know a given programming language is entirely secondary to whether or not you know the difference between a picker and a packer, or between a replenishment and a cycle count. Similar deal in medicine, or education, or manufacturing, or sales, or finance, or what have you.
New people make idiomatic mistakes, and if the language isn't cool they expect more money. Recruiting people is harder, so you tend to get stuck with the people you have, and managers tend to bristle at that. Eventually a new language full of people who look like cogs is going to win out. I hate that this is true, but it is.
I maintained a Python test harness for a while. No prior experience with Python. I mostly stayed out of trouble, in part because I set low expectations, tried nothing fancy. But it wasn't what I wanted to be doing, and not what I wanted the team to be doing. When I left they finally canned the entire thing.
Those are all pretty basic Algol-family languages (at least if we're talking vaguely modern Javascript). If you were thrown in to J or Forth or Erlang you might have a different experience.
I don't know if I'd necessarily call the JS in question "modern", though. It's running on RhinoScript, which needless to say ain't exactly the latest hotness. Still, the platform in question does happen to support/encourage AMD modules (with some special comments for certain components), so I guess it could be worse.
Demand in this case, will likely create its own supply.
We shouldn't really be treating software differently. The liability for a mission critical system that works but cannot be repaired climbs over time.
Just because it works doesn't mean it isn't broken.
Evolution/flux is not the natural state of all software. I've seen plenty of business/enterprise software which has continued to provide business value for decades without structural or architectural changes.
And as we've seen with old video games, there are lots of timing problems that you simply never encounter on the original hardware but are impossible to ignore on recent vintage hardware.
Now that I think about it, that's actually a decent hiring test:
Tell the candidate part of their job will be maintaining a small Perl codebase. If they can't deal with that without throwing a fit, I have no interest in working with them.
It's a sharp tool, if you're not careful someone might get hurt. But professionals deal with sharp tools all the time, especially when it's the best tool for the job.
Given Perl’s legendary code-opacity and maintenance challenges, this kind of seems inevitable. After all, if you could at least read and decipher the old code, maybe you could reproduce it!
Many orgs ship perl based tools as current, up-to-date products. Mellanox OFED is one I was using earlier today.
My own github[1] has a plethora of perl projects.
I'd imagine a bigger rewrite effort would have led to a more slick iteration on the UI, and it seems the legacy HTML templates are still baked in.
IMDB seems plenty fast to me. UI isn't great, but that's more of a presentation layer design thing than a language thing.
Anecdote: I found this Perl image-hosting package a couple years ago as a self-hosted alternative to sites like Imgur, and I think it's great: https://framagit.org/fiat-tux/hat-softwares/lutim/tree/maste...
https://metacpan.org/pod/Mason (if you're not familiar with Mason)
Perl is everywhere, it's just not widely publicised because of the stigma attached to the language.
Most of the ad network backend sites are perl, including a lot of Yahoo.
The codebase was millions of lines long, modules (pm files) with like 1000 methods and 10,000 lines, a total mess and it had 0 unit tests too. Almost beyond salvageable. Left a bit of a sour taste.
They're trying to migrate to AWS but AWS don't even natively support Perl in their libraries. There's a few third party libraries in CPAN but nothing as comprehensive as what's available with official libraries for other languages.
Nothing against the language but I don't know why you wouldn't use literally anything else nowadays. Python or PHP, JavaScript or even Ruby if you're looking for a dynamically typed language. AWS don't even support Perl.
Also, CPAN had better libraries than pip did all the way up until I last used Perl in 2015. Ofc, it depends on what you're doing. My point is, there was a reason to use Perl once upon a time ago.
The alternatives back then were PHP, C, C++ (the old bad kind), BASIC, assembly, FORTRAN, and others like Smalltalk. Seeing this, it's understandable why Java took the world by storm the same way Perl did.
Since Perl code is often very compact, it probably needs a higher comment to code ratio than most other languages, but you don't see that either.
To quote myself from a recent discussion:
I think some languages do make it easy to write convoluted code, but through judicious use of coding standards (including a helping of common sense [don't be clever where you can at all avoid it, which IME is ~~almost~~ all the time], code linters, and so on) I think how you use a language plays a huge part in code maintainability.
For instance, I've heard PHP get shit on pretty badly all around the web, but I've worked at PHP shops that had nice, clean codebases, and my current Perl codebase is, in many ways, nicely structured. That's not to say there aren't some hairy codepaths that could use refactoring, but I really think that kind of thing, again, can happen in almost any language.
1. You can use virtually any language to write clean code
Not sure if I agree with this, though it may well be true. I just know there are some things like Brainfuck where it's designed to be impossible. I realize that language is created specifically for the purpose of making a coder say "WTF", but perhaps there are other languages that are not designed to be so that are really nearly impossible to write good code in.
2. Perl lends itself to unreadable code
If you stick to Modern Perl you still might end up with things like `wantarray` in your code so I guess this is kind of true. You need to be judicious in your use of code.
Some languages lend themselves more easily to writing clean code, like I feel about Go or if you hate the Go type system, Ruby. Even in Ruby I feel like metaprogramming is ripe for misuse.
It's a tough thing to talk about. I don't feel like I wholeheartedly disagree with your sentiment which seems to be "some languages lend themselves to bad code" and subsequently that Perl lends itself to bad code but there is plenty of ambiguity in these thoughts.
I used it for automation of my calculations in grad school. For data analysis. For monitoring.
In my subsequent day jobs, I used it to develop shipping products. No one really should care what language something is written in, if it does the job well.
Most recently (a few weeks ago), I used it as the driver for creating and submitted 10's of thousands of jobs for COVID19 research the team I am working with[1][2].
For the above project, I had to forward port 12 year old C++ code to make use of modern C++ based boost libraries. Took a bit of time to fix this. But the perl code, ran perfectly, and quickly[3].
Anyone trying to portray things otherwise, likely has a longstanding axe they like to grind. Language advocacy can be done without attempting to tear down other languages. Though those who argue against perl often bring up the same, old, tired, and incorrect points.
I'll keep using perl thank you. And Julia. And C. Each has their domain of applicability. Most people know and understand this.
[1] https://community.hpe.com/t5/advantage-ex/how-my-supercomput...
[2] https://community.hpe.com/t5/advantage-ex/the-story-of-how-i...
[3] https://scalability.org/2020/04/fun-and-topical-hpc-project-...
The system is from like 2013 and still going, but I really wish I could rewrite it in a language I can actually train people on in a reasonable amount of time. It took the one junior I have about 6 months to get to the point where he could read the syntax without tearing his hair out. It's not really built to create maintainable structures.
The libraries and stuff are full of opinionated little "gotchas." As an example, the Test::Simple module will throw errors if you use a number to title a test which is infuriating when you're writing a test which tests all the numbers in the space of acceptable or possible inputs.
Especially for example how variables have symbols for different types ($ for scalars, % for hashes, @ for arrays). And if you want to for example pass an array to a function you have to send it manually referenced with like method(\@myArray) which then inside the method is contained in a $scalar.
Compared to Python for example where you'd literally just pass the array to the method like method(array).
The values in @_ are aliased to the values in the subroutine call.
Most of the time, you want pass by value semantics, so you unpack the array and copy the values into function variables. If you want to modify an argument, it's typically passed in as a reference, and you can mess with it that way.
However, there are times when it would be horribly inefficient to make those copies, or when you need to do some magic (generally best avoided in 99.999% of your code), that this makes possible.
Also, since Perl functions are always variadic, it means that it's easy to work with a variable list of arguments in a function. For example, if you are expecting a list of key value pairs for your function, you can simply write:
my %args = @_
Making signatures default will be a big improvement, but the power of the simple abstraction @_ provides should not be underestimated. It's actually an elegant solution to a complex problem. sub method {
my ($self, $a, $b, $c) = @_;
}
$self being a reference to the current module (ala Javascript's 'this')How does one tell Python to pass the contents of said array as distinct parameters to the function, instead of as a lone array parameter?
In Perl, that's the difference between foo(@bar) and foo(\@bar) or foo(1, 2, 3) vs foo([1, 2, 3]).
With an asterisk: method(*array)
How is that more understandable than @ vs \@ without knowing the language? My guess is it isn't.
a, *, b = [1,2,3,4]
def foo(*args):
bar(*[1,2,3])
all do "what you'd expect" from the single concept that "* is sort of pattern-matchy for an array".But the more important bit is just that you don't have to prefix variables with @ and $. Python is optimized for writing code that acts on variables, while perl is optimized for code that acts on strings. While strings are certainly a common data type, most code isn't modifying strings directly. So optimizing for that case doesn't make a lot of sense.
def f(b):
print(b)
f(a)f(*a)
That is true. This alone might be a good reason to look elsewhere for new projects.
However, for existing Perl codebases, PAWS is comprehensive and popular library, and is generated from the official botocore: https://github.com/pplu/aws-sdk-perl
There's 194,000 modules, which is probably the most of any language:
> Nothing against the language but I don't know why you wouldn't use literally anything else nowadays.
Gee, let me see:
- Perl's Mojolicious web framework is probably the most powerful today.
- Perl has moderate static typing with use strict;
- Perl allows forward references, unlike Javascript or Python.
The question is why would I use anything but Perl?
I still think Perl is a much better tool for what some bash and python scripts are doing. Maybe Perl7 will remove some stigma and allow for people to use the tool instead of it being instantly dismissed.
Ariba isn't a household name, but it has deep and widespread connections to thousands of the largest companies in the world.
I considered Perl, since it was the only scripting language interpreter, but the good enough (on paper) date handling libraries I found on CPAN turned out to require a far newer Perl 5 version that was available.
I'm afraid that the best-case Perl solution would have been more difficult to write than the roundabout but reliable and easy to understand final solution (Oracle SQL functions executed through the command-line SQL*Plus client).
Perl is not bad but no new codebases should ever be written in it imo. It's to easy to shoot yourself in the foot unless you know perl REALLY well. Moose is ok but a far-cry from any modern OOP system.
Efficient, cheap and stable. Ported to about everywhere.
https://benchmarksgame-team.pages.debian.net/benchmarksgame/...
For instance, the page you linked has “pidigits” at the top, and says node is faster, 2.58s vs 3.61.
2.58s is the slowest run of the fastest pidigits on the node page, but one of its runs took 1.04 seconds.
The perl page lists a 1.24 second run for “pidigits 2”.
The reported numbers in the language comparisons don’t seem to be averages.
All the pidigits programs list the same output, so presumably, they’re running with the same ‘N’.
Between the variance and inexplicable stats being applied to the results, I’m not sure what to conclude from these numbers.
No, there really isn't.
> 2.58s is the slowest run of the fastest pidigits on the node page, but one of its runs took 1.04 seconds.
Notice column N — 2,000 6,000 10,000.
That's a command line argument passed to each program, controlling how many digits of pi are generated — the workload.
So, 2.58s for 10,000 digits and 1.04s for 6,000.
(And as it says, there can be a cold caches effect on the first measurements.)
Perl fares somewhat favorably against Python, Ruby and PHP though. Those are what I would consider equivalent languages to compare against to get a general idea of its speed.
I can pretty much assure you the accumulated dollars invested over the years in making JS fast is likely to be closer to multiple billions combined.
It's also worth noting that three of the examples (pidigits, reverse-complement, fasta) don't seem to do any multiprocessing in Perl whereas they do in Node.js. At least for reverse-complement and fasta, it should be possible to rewrite those to use multithreading (like the Node.js versions do).
Until someone does…
Also, how is Perl any less stable than other languages? Are you saying the language doesn't change much or that it doesn't crash?
time ./startup_time.pl 0.016s
time ./startup_time.py 0.295s
Parsing a 20Mb log file with a regex: time ./parse_log.pl 0.683s
time ./parse_log.py 1.534s
For which metric are you claiming Perl is slower than Python? #!/usr/bin/env perl
use 5.026;
open my $fh, '<', 'logs1.txt';
while (<$fh>) {
chomp;
say if /\b\w{15}\b/;
}
close $fh;
Python 3.8 #!/usr/bin/env python
import re
with open('logs1.txt', 'r') as fh:
for line in fh:
if re.search(r'\b\w{15}\b', line): print(line, end='')
Why isn't it a fair comparison? The startup time is generic and string parsing is a major feature of, say, web development. I didn't say Perl5 numerics match Python's but even there Python relies on external libs. #!/usr/bin/env python3
import re
with open('logs1.txt', 'r') as fh:
regex = re.compile(r'\b\w{15}\b')
for line in fh:
if regex.search(line): print(line, end='')
Perl almost certainly does this by default for regex literals, and that's a fair advantage for the "kitchen sink" style of language design versus orthogonal features (regex library, raw strings) that Python uses. time ./index.pl 0.258s
time ./index.py 0.609s
If you factor-in that Python startup time is 0.279s slower than Perl the processing differential comes down to 0.072s.The issue here is that pythons regex engine has overhead, and with lots of sequential calls with small strings like that the overhead adds up.
If you batch lines together in chunks you’ll see a huge improvement in speed, but the point is that it’s not “Python vs Perl” it’s “pythons regex engine vs Perl’s regex engine”. Which is about a contrived Perl-biased benchmark if ever there was one.
[admin@localhost ~]$ time ./test.py
real 0m0.295s
user 0m0.158s
sys 0m0.138s
[admin@localhost ~]$ time ./test.pl
real 0m0.164s
user 0m0.158s
sys 0m0.006s
#!/usr/bin/env perl
use 5.16.3;
open my $fh, '<', 'logs1.txt';
while (<$fh>) {
chomp;
if (/\b\w{15}\b/) {}
}
close $fh;
#!/usr/bin/env python
import re
regex = re.compile(r'\b\w{15}\b')
with open('logs1.txt', 'r') as fh:
for line in fh:
if regex.search(line):
continueEdit: perl is still faster, to be clear
Perl5 won the dec2bin benchmark.
The other thing I learned was that PHP's binary/decimal functions are two orders of magnitude slower, despite its core interpreter performance being best-in-class.
It has even less backcompat problems than the native regex.
It's faster at some things and slower at others. It's fairly similar in speed profile to Python in my eyes.
> Are you saying the language doesn't change much or that it doesn't crash?
Both is probably what was meant. They are literally changing the major version so they can change some backwards compatibility, as Perl has made strong backwards compatibility a goal and selling point for decades. You can take a script written in 2000, and it will likely run without problem if you run it on a Perl 5.30, released last year.
- Cheap: it does not cost much to hire someone to write perl. If they don't know how yet, the choice in style let them be efficient quickly. The code to be deployed is very lightweight, both in CPU and RAM usage.
- Stable: no API break. No new module that reinvent the wheel and breaks your codebase. Unit testing is about everywhere in cpan. Code written 20 years ago still run fine.
That's debatable for single-threaded workloads (they're typically pretty comparable in my observation), and highly unlikely for multi-threaded workloads (Python has a global interpreter lock whereas Perl does not AFAICT; you can work around that in Python, but it typically involves spawning entirely separate processes, thus introducing IPC overhead that wouldn't be present in a Perl equivalent).
Looking at some comparative benchmarks (https://benchmarksgame-team.pages.debian.net/benchmarksgame/...), Perl seems to be faster in a slight majority of cases, and in nearly all cases has a lower memory overhead. Not that benchmarks really matter anyway, given that they're usually a poor indicator of real-world performance, but still.
> Perl 7 is v5.32 with different settings. Your code should work if it’s not a mess. Expect a user release within a year.
Are there actually people that are still deploying new things in Perl? The only times I see it is for legacy stuff, and then only because the script is too much of a hassle to be rewritten.