Hacker News new | comments | show | ask | jobs | submit login

Whenever I need to write a tiny script that tests the bounds of what is easily done with just awk and Bourne shell, the tool that I next reach for nowadays is Python. A few years back it was Perl5.

I'm not exactly sure why I started reaching for Python instead. It's so much easier with perl to do things like backticks to call some utility, or to use system() and easily deal with its stdout and stdin, and I never have to do a Google search to figure out how to use a regular expression to process the output (whereas I almost always need to bring up the doc page for Python's re).

I think what it ultimately comes down to is tooling and the availability of good libraries. I call "python3 -m venv venv", do an I'm Feeling Lucky google search for "XXX library inurl:pypi", and the sky is the limit with how easily I can make a script that does something relatively complicated. Comparing this with perl5 isn't even fair. You might find a cpan module that does what you want, and it might still be maintained, and you maybe can be bothered to figure out cpanminus, but anyone who has used perl in the last 5 years will agree, it's nowhere near as easy as it is with python.

Something that makes me optimistic about newer languages is that tooling is improving a great deal. It also makes me somewhat pessimistic about newer languages, though, if tooling is the primary aspect of a language that makes it popular.

I've never seriously tried perl6 but I've seen enough of the language features to know that I was really excited about it, at least at one point. I hope that some derivative of perl can rise from the ashes, because I'm too stupid to write actual lisp programs, but perl allows me to emulate what I imagine lisp programmers must feel.




I have two experiences telling with Perl and Python. Way back in the day, I had job doing web development in Perl. I had no say in the matter, it was the only choice available. And I actually used Perl enough to actually like it! I mean I understand why people who like Perl really like Perl.

But just a few years after that and I could hardly even read Perl code let alone try and code in it again.

Python was is opposite; I never coded in Python but I ported a Python product SDK from Linux to Windows in a few weeks. I could read it. I could write it. I made more mistakes with indenting than anything else. Even to this day, I don't know Python but I can muddle my way through and be reasonably productive.


Tangentially...

My organization maintains a couple of Perl web apps for internal purposes (one that dates back starting in 1997). We do some occasional work/improvements/modernizations on these. Mentally switching into "perl" mode to work on these projects requires tons more effort then switching between our other Bash/PHP/Puppet/Python codebases. And there are several sections of the code I've shied away from modernizing because they use esoteric perl operators that I don't use and don't really understand.

Not to mention that only a few members of our organization are really "fluent" in perl, and teaching it to the newbies feels almost like a waste of resources when they can be more productive faster using python which has ample modern documentation and simpler syntax/conventions and well defined coding standards.


> Mentally switching into "perl" mode to work on these projects requires tons more effort then switching between our other Bash/PHP/Puppet/Python

That's surprising to me. Bash, PHP and perl seem to be closer to each other than any of them are to python. For example, the use of sigils ($var) for variable names in Bash/PHP/perl.


Bash / PHP / Perl superficially look like each other. Python code looks different.

But Perl has many strange operators and conventions that do not do as expected, or are foreign to the point of being unreadable to those who don't use Perl regularly. Additionally, Perl can be made concise (one-liner) to the point of being unreadable. It's been said that Perl is a write-only language for a reason.

Contrast with Python, which I've had six-year-olds tell me what a program does after only a few minutes' introduction to Python syntax. Though to be fair, Python's List Comprehensions are in fact just as unreadable as Perl is.


I always make a point of documenting any of the more arcane parts of perl with a reference.


Both Bash and PHP use a single sigil ($) to denote variables. But in Perl, sigils also kind of denote the type of the variable (Scalar, array, hash, subroutine, typeglob). I say kind of because it's not quite that simple.

PHP is actually closer to compiled languages like Java and C# than it is to Perl, Bash, or Python. It's mostly a static language with dynamic typing.


How sigils are used in Perl 6, and how that compares to Perl 5: https://opensource.com/article/18/9/using-sigils-perl-6


I would agree. Maybe it's more because of what people are used to than the objective "distance" between them.


Though

1 does python have the same breadth of exiting codes as CPAN ? 2 the whole tab vs spaces thing that creates a lot of hard to see syntactical errors if I wanted to program in language like that id use FORTAN IV/66


> But just a few years after that and I could hardly even read Perl code let alone try and code in it again.

Precisely this.

The Perl Cookbook (and Perl Book cookbook section) was an absolute godsend in the time before the web.

However, the fact that my Perl Book and Perl Cookbook fell apart from so much usage shows how the language never really stuck in my brain in spite of continuous low-level usage.


I lost my copies of those books because I rarely needed them. Once I wrote it once, it stuck in my mind.

Everyone has a language or two that really "clicks" with them. For me, one of them is Perl. Python, on the other hand, is one of those languages that won't ever stick in my mind. I don't know why. I just can't do Python.

I picked up Golang in about a day.

I've tried Python about 4 times over about as many years and it has gone from something I wanted to learn to something I wish never existed.


There are 2 things to grok that people rarely explain to Python newbies, and which probably prevent some from building good intuition of things:

1. EVERYTHING is a DICTIONARY (including objects, despite some magic happening behind, objects are just dicts of data and functions, that are just values)

2. VARIABLES are just LABELS for things, and they only exist and can be movable around in one scope (`x = smth` inside a local scope will either create a new local label x, or move the local label x that already existed; there is no way to "move"/"create" a label outside the current scope, you can just use it to access what it's pointing to, except ugly hackery that falls back to manipulating interpreter's guts as if they are just dicts and that nobody does in real code)

Once you grok this the language is quite nice and intuitive. The next step is grokking:

A. operator overloading - this is something people like to avoid, but any math/physics code would easily become unreadable without this sprinkled around libraries like NumPy

B. the fact that the `=` operator can be overloaded - this can really f up your mental models of things, but again, it can make math/sciency code more readable when used carefully and the people in this field (ab)use it a lot (imho it should have never existed in the language, but we all have opinions)

C. everything can behave like function (which btw are first class things in Python) by just implementing __call__, another apparent trivia but it changes the shape of APIs a lot (eg. "have class instance also behave like a function and have it passable as an argument to something that expects a callback")

D. multiple inheritance - yeah, it exists in Python and it's maybe a bit ugly, but in fact it's what allows you to implement Mixins and other sugared-compositional patterns, actually reducing your total use of inheritance and the length of inheritance chains a lot (IMO multiple inheritance is the only things that saves inheritance from itself, and you shouldn't ever have I. without MI. but people seldom agree with me on this :P)

To be honest I still profoundly dislike Python as a language, but when most of your job is reading other people's code... you come to appreciate it more than other dynamic langs :)


In perl (almost) everything is a dictionary too. Except when you need it not to be. Great source of getting things done, or footguns. Here's an implementation of something vaguely useful in perl that is mostly not a dictionary (except where it is for state management purposes) - https://metacpan.org/source/ZARQUON/Array-Circular-0.002/lib...


A. reminds me of JS objects.

B. is to expected, and I think it might be useful; e.g. we prevent accidental copying of singletons in C++ via operator= (T &other) = delete;. I'd guess you could do something similar in python.

To top that: Yesterday I learned that you can legally overload the unary operator & in C++. Smuggling that into a large code base seems like a good way to mess with your colleagues ;)


> everything in Python is a dictionary

This is new to me, but probably will be useful.

Everything in R is a vector (or if you like, array). This is what makes R fast if your objective is not program development, but dissemination of information.

I wonder what should be said of Perl, but the only thing I can think of is every input should rather be a string.


The assignment (=) operator cannot be overloaded. Thus the PEP 572 controversy. https://www.python.org/dev/peps/pep-0572/


I was referring to __setitem__: you end up with expressions like `m[...] = ...` where practically speaking the meaning of `=` is no longer obvious. In some contexts it can end up meaning pretty unintuitive things (think pandas view into dataframes etc.). But, yeah, most languages have something like this since it's pretty useful, and only way to get away from these ambiguities is using purely immutable data which can be a no-go performance wise when you're working with references to multi-gigabyte structures...


I think the big insight there is that some libraries are popular despite unintuitive design.


I had the same experience. Perl clicked for me, but not Python. A few years ago, I switched to Go for performance and it has clicked as well. Go is a rather sparse language relative to Perl (and TIMTOWTDI), so I'm a bit surprised that it was a natural switch.


Perhaps you would benefit from a good teacher. I've found that some topics I find confusing when taught by one person are obvious when taught by another.


I had a 3 days Perl formation with an excellent teacher (17 years ago). I do not code much in perl, but when someone in the buildong has a bug in a perl script, he comes to see me. I think the perl books are not very good for a beginner because they do not focus on the most usefull parts. The ideas behind the syntax makes it easy to remember (your whole life) once you have passed the first steps of learning.


everything in python is a dictionary. That is what i needed told to start to grok it.


More or less the same as Perl and JavaScript.


Having used both languages for maybe 7 years each, you can write unreadable code in both. I have seen some absolute disasters in Python, its really about the skill and motivation of the developer to produce readable code.

Perl has a lot more syntax which makes it harder for people who don't know Perl, but if you know the language I don't think its inherently worse.


In response to your last sentence.

Just wanted to mention that Ruby was highly inspired by Perl, particularly its regular expressions and it has a variety of perlisms. Kind of surprised you went to python and not ruby.

Your lisp mention reminds me of this: http://www.randomhacks.net/2005/12/03/why-ruby-is-an-accepta...


I just wish ruby had the same quality of scoping and OO that perl5 has, but it ended up with the same "variables magically pop into existence for the entire function" footgun as python and a horribly restrictive OO that also requires me to repeat myself (accessor/constructor etc.) in a way that after about an hour sends me screaming back to perl

Edit: Look, this is a genuine opinion, I've chatted to ruby core devs about this and they couldn't find ways to achieve the same things I do with perl5 as elegantly in ruby (Steve Klabnik and I have an open conversation about how to find a kata where we can compare this stuff properly), I'm 100% happy to discuss this but blindly downvoting because you disagree is depressing - tell me why you think I'm wrong instead and I'll do my best to reply constructively


Not sure who downvoted you, sounds like you have good points.

Do you have some links/examples on that scoping & how you can avoid accessor/constructor in perl?


Scoping - 'my' is lexical/block scoping, same as javascript's 'let' (thank you! steal more things please!) so

  use feature 'say';
  use strict;
  use warnings;
  my $code = do {
    my $count = 0;
    sub { ++$count }
  };
  say $code->(); # 1
  say $code->(); # 2
and note that if I e.g. typoed $count inside the subroutine I'd get a compile time error (and it goes out of scope at the end of the 'do { ... }' block). Note that the 'state' keyword provides an easier way to do this, but it's the easiest demo of closures I can think of, though also there's fun to be had with methods:

  my $method = sub ($self, @args) { $self->foo(3, @args) };
  $object->$method(1, 2); # same as $object->foo(3, 1, 2);
Constructor/accessor wise:

  package MyClass;
  use Moo;
  has foo => (is => 'ro', required => 1);
  has bar => (is => 'rw');
  has baz => (is => 'lazy', builder => sub { expensive_default() });
then means that

  MyClass->new
will throw an exception telling you foo is required

  MyClass->new(foo => 1);
will work fine,

  $obj->foo; # returns the value of foo
  $obj->foo(3); # throws an exception - foo is ro
  $obj->bar; # returns the value of bar is any
  $obj->bar(26); # sets bar
and (if you didn't pass a value for it to the constructor)

  $obj->baz; # runs expensive_default() once and then retains the value
Hopefully that's a start, this is all typed off the top of my head on my first post-9am pint of coffee so my apologies for any omissions and/or errors.


Also, in languages like Java, C++, or C#, you can use bare braces to define a new scope, no keyword necessary. It's not done so much anymore because modern coding standards tend to favor shorter functions for clarity and unit testability, but it's always still an option.


You can do bare braces in perl5 too, I used the 'do { ... }' block because that's an expression rather than a statement so I could return the subroutine -

  my $code;
  {
    my $count = 0;
    $code = sub { ++$count };
  }
would've been equivalent but I always try and do assign-once-at-declaration-time where possible because mutable state is my mortal enemy.


what's the js equivalent to your example?

   let code = () => {
     let count = 0;
     return ++count 
   }
doesn't do the trick


JS doesn't have the do {} expression form so

  let code;
  {
    let count = 0;
    code = () => ++count;
  }
or let-over-lambda it and

  let code = (() => {
    let count = 0;
    return () => ++count;
  })();


Oh man, you responded the same as me at the same time.


> I'm not exactly sure why I started reaching for Python instead. It's so much easier with perl to do things like backticks to call some utility, or to use system() and easily deal with its stdout and stdin, and I never have to do a Google search to figure out how to use a regular expression to process the output (whereas I almost always need to bring up the doc page for Python's re).

The thing I find easier in Perl than in the other languages I might reach for when doing a lot of quick scripting tasks is declaring nested data structures. It's easy in Perl because often you don't have to declare them--you just use them. And that means that you can often make major changes to how your data structures work with just small source changes.

For tasks where you need to process data from logs or text files or similar, but don't actually quite know what it is you need to be doing with the data so need a good bit of exploring/flailing to get your bearings, and then maybe a few iterations trying different approaches to figure out what structures you need, and you don't have a lot of time to think about it up front--in other words, data analysis improvisation, Perl shines.


Same here. I do mainly Python development - Django docs made things way easier then the Perl frameworks that I tried.

But for quick and dirty scripting tasks I still pull out Perl as the extra sysntax makes thing so much easier - backticks and built in regular expressions for example.

And I have still never seen anything as intuitive to use as a Perl hash tied to a berkley db file for simple persistence to disk.


I agree that Perl's autovivification is a timesaver, although I can usually hack together what I want with Python's defaultdict.

For "data analysis improvisation" though, I don't know. A good REPL is a key part of that, and I'm not sure that Perl has anything as good as the ipython cli or jupyter notebook.


I'm exactly the same way about Perl vs Python. After years of using Perl 5 and due to what I also think is the simplicity of the language, I know I could do most small tasks more easily in Perl.

But Python feels more like "the future". When I need to write a script-like solution, I reach for Python because I need to practice with it and because I figure that the modules will be better maintained. You're right, though. I always need to look up simple things like system calls and often have to remind myself of exactly how the re module works.

But I slog through it. Don't get me started on the Python 2 -> 3 glacial migration, though. That almost makes me want to switch back to writing my scripts in Ruby.


> I'm not exactly sure why I started reaching for Python instead.

Oh, I am quite sure. Looks like Perl6 changed that, but it's because I was never sure that data structure should be a reference to a dictionary of references to scalars, or a dictionary of scalars, or a dictionary of reference to scalars, or a reference to a dictionary of scalars.

Anyway, next time I go for a quick script, I should go for Haskell, not Python, nor Perl (5 or 6, whatever). But I will probably go for Python, because it's painless enough and I don't know Haskell's shell integration by hearth. Anyway I will go for Haskell before I try Perl6, what is a nice measure of the problem they have to get mainstream again, because the language varies, but I'm far from the only person thinking this way.


> Anyway, next time I go for a quick script, I should go for Haskell, not Python, nor Perl (5 or 6, whatever). But I will probably go for Python, because it's painless enough and I don't know Haskell's shell integration by hearth.

I've started using rust for short scripting tasks, helps me get acquainted with the stdlib & ecosystem, and `cargo script` works really neatly, seamlessly allowing adding dependencies to a single-file script with not issue. Plus if you want to scale the script out to a proper project you can just take and promote the generated cargo project.


Yeah, I've had a similar experience in Scala-land. Spinning up a JVM to run a small script feels icky, but it's actually well worth it for the sake of not switching languages.


The kind of quick scripts I use Perl for involve picking interesting bits out of text files. Honest question: Would you use Haskell for that? If so, why? And how?


I'm with you here. It's not that Haskell isn't a good language, but that scripting languages are really good at scripting :)

Haskell does have a good REPL and being able to distribute a binary when finished is really nice.


You can also run Haskell in interpreted mode, so it is actually a viable choice for scripting.


It's viable, but certainly not designed for that sort of thing like Perl, Python, Powershell, Awk, & Bash. Many of those languages have built in niceties for scripting such as Perl's myriad of command line switches and well, everything about Powershell. They're optimized for shorter programs where Haskell is optimized for helping you write higher quality code.


Try the turtle library, after using it it would certainly feel for you like it was designed for scripting, it’s such a joy to use!


Are you kidding? Haskell is the language for picking stuff out of text files. Unless Perl got a complete transformation on the 5 to 6 change, it isn't even on the same league.


Could you be a bit more specific about what makes Haskell the language for this? I'm not sure it's going to be more comprehensible than Perl, for those who don't write Haskell full-time. I'm not sure it's going to be easier to read through the lines of an input file than it is in Perl, and I'm not sure it's going to be easier to apply regexes to lines than it is in Perl.

Is one of those assumptions wrong? Can you state why it's wrong?

Or do I need to adjust my sarcasm detector?


You could argue that Perl 6's grammars are a complete transformation. Please see https://docs.perl6.org/language/grammar_tutorial for more information. Note that Perl 6's grammars are used to parse Perl 6 code itself, so it's powerful enough to build complete language compilers out of.


Cool, Perl6 gained a native context-free parser. Yeah, that gets it in the league, I would have to compare it with Python parser libraries to decide what's better.

But not, Haskell and Prolog are still leaders here, with Haskell currently having the lead.


If it's not already on your radar, you should have a look at the Shelly library on Hackage.


Oh, I know about it. And it looks great.

It's basically the reason the next language I'll try on the shell is Haskell. But it takes looking at the documentation, so I'll leave it to try when I'm not in a rush. For shell scripting, that may take a long time.


> I hope that some derivative of perl can rise from the ashes, because I'm too stupid to write actual lisp programs, but perl allows me to emulate what I imagine lisp programmers must feel.

Well, there is Clojure. You can script it with `clj` and https://github.com/l3nz/cli-matic, and/or one of the ClojureScript interpreters. It has sane library management, so there is no PITA installing anything. You have JVM libraries, so you have all you need. We find it pretty handy.


Ruby has all of those perl features you mention, without a lot of the strange quirks from perl.


> without a lot of the strange quirks of perl

And instead with a lot of the strange quirks of Ruby!

\s, only kind of, I love Ruby but it does have a few quirks that I see confuse some people coming from other languages when they start writing non-trivial Ruby code (literally everything is an object being a big one — “what do you mean a class is an object?! modules too?!”).

However, these quirks are much, much easier to learn, understand, and possibly eventually come to like, rather than some (many) of the quirks that exist in Perl.


> what do you mean a class is an object

I think that's pretty standard for object orientated languages. I can't find of any where it isn't the case off the top of my head. Is it not the case in Perl's object orientated support?

And why wouldn't it be an object? Seems more surprising for classes to be an exception.


It means they lack a metaobject protocol.


People coming from Javaville or C#land definitely don't have that kind of abstraction (and yes, the usual rebuttal is that they're procedural, not OO).


Classes are objects in Java. You can even create new classes at runtime in Java or use java.lang.reflect.Proxy to make existing objects implement different interfaces.

I once did this in a class project, including even manually creating the bytecode at runtime. Ironically, it's probably the most understandable and maintainable of the crazy metaclass-style reflection I've done (although that's probably mostly due to the fact that the scope was much more limited: I was only mirroring a set of interfaces into a different namespace to work around some stupid limitation in a different library).


You can, yes, but not nearly in the same way.


> what do you mean a class is an object

> People coming from Javaville or C#land definitely don't have that kind of abstraction

What do you mean? A class is an object in both Java and C#.


Not exactly.

What you see as the Class type in Java, at least, is simply a representation of a class. It can tell you about a class, but it doesn't represent an actual thing you can manipulate, change, or use. I can't add a method to that class, or add a field, or manipulate its instances beyond basic method lookup and dispatch.

In something like Ruby or Smalltalk, a Class is an object. It can be changed live, altered, adapted, cloned, or otherwise used just like another object; and the application will change its behavior accordingly, right there on the spot.

I'd recommend reading up on prototype inheritance, as that is the model generally used in the latter languages.


You’re telling me that class objects in Java are immutable while they’re mutable in Ruby. That’s orthogonal to whether they’re objects.

> I'd recommend reading up on prototype inheritance

Thanks but I’ve already literally got my PhD in metaprogramming in Ruby and object model implementation in Java. Ruby doesn’t use anything like prototype inheritance.


Its more then that... It's not even inmutable, not really. There are some things, like privaCy of access, that can be mutated by manipulating Java class objects.

That said, maybe the difference here is how often the janky metaprogramming of classes interferes with day to day peogramming; a java programmer might have never seen this stuff, moreso then a ruby one?


Yeah, the correction re: prototype inheritance is a good one.

That said, there is a qualitative difference in what we call 'classes' in those two environments, which is part of why I think there's confusion. Class in Java is a fairly different concept than a Class in Smalltalk, Ruby, or JS.


Java has Class which is an Object.


Honest question: Can you write

    Class foo = String;
in Java? If so I guess classes really are objects, if not I'd say "there are some objects that represent (or wrap) some classes somehow."


I think what you mean is that classes are referenced by a separate namespace in Java and aren’t in Ruby.

That’s completely orthogonal to whether they’re objects or not.

You can keep fiction and non-fiction in separate bookshelves if you want but when you get either off the shelf it’s still a book.


I guess I'm not sure what "object" means in Java, then.

In languages I'm used to, an object is a type of value, and values are things that you can store in (or refer to with) variables.

The only vaguely object-like feature of Java classes I can think of is that you can look up (static) methods/attributes on them with a dot.

Or is there more? You can't call `String.toString()`, so `String` isn't an instance of something that inherits from `Object`. I'm at a bit of a loss here... There obviously exist "class objects", but they're not normally what people refer to when they talk about classes. I'd say Java classes are almost purely lexical constructs (though I could be wrong there -- again, I don't know much about Java...)


> In languages I'm used to, an object is a type of value, and values are things that you can store in (or refer to with) variables.

Class theStringClass = String.class;

Class[] myArrayOfClasses = new Class[1];

myArrayOfClasses[0] = theStringClass;

callSomeOtherMethod(theStringClass);

> You can't call `String.toString()`

String.class.toString() => "class java.lang.String"

theStringClass.toString() => "class java.lang.String"

myArrayOfClasses[0].toString() => "class java.lang.String"

somethingThatReturnsAClass().toString() => "class java.lang.String"

> `String` isn't an instance of something that inherits from `Object`

Class theObjectClass = Object.class;

theObjectClass.isAssignableFrom(theStringClass) => true

> I'd say Java classes are almost purely lexical constructs

They aren't - here's the source code for the Class class.

https://github.com/Project-Skara/jdk/blob/c2105ced865fba11fb...

Here's the source code for the toString method we were calling

https://github.com/Project-Skara/jdk/blob/c2105ced865fba11fb...


    Class foo = String.class;
(Though `Class` is actually a generic type, so you'd want to include the type parameter in actual code.)


Sure, I'd say that fits my second suggested wording -- `String.class` is an object that represents or wraps the `String` class.


How do you tell the difference between an object that is the String class, and an object that represents the String class? If you can call .toString on it, and you can compare it to other classes, and you can call .newInstance, then how is it more of a representation than being the actual thing?


> How do you tell the difference between an object that is the String class, and an object that represents the String class?

Hah, I think "an object that is the String class" begs the question :-). I think that `String.class` is an object because you can do objecty things with it (call methods, assign it to a variable etc) and `String` is not an object because you can't do any of those things with it.

To me they're not the same kind of thing, though they're intimately, inseparably and exclusively related. I personally would say even if

  new String()
was just syntactic sugar for

  String.class.newInstance()
, and all other "bare" uses of `String` were similarly shorthands for operations on `String.class`, I'd still hesitate to say that `String` itself was an object.

My logic is probably less useful than yours, though. I'd say "`A` is a `class`, but `a` is an instance of `Class`" and in your system where `A` and `a` are "the same thing" there's no difference between being a `class` and being an instance of `Class`. Because the things appear in different namespaces (as you say), and are related one-to-one, we could as well say they are two ways to refer to "the same thing", with different operations possible "depending on the phrasing."

Shrugs, it doesn't come naturally to me, but it's at least a self-consistent system.


In java you have to call the special and awkward .newInstance rather than being able to use standard "new". Whereas in e.g. Python I can equally well do

    >>> str("foo")
    'foo'
    >>> x = str
    >>> x("foo")
    'foo'
and the "builtin" str and "userspace" x are equally first-class.


Sure, the ergonomics are different. One is a statically compiled language and one is dynamic. But it's still an object.


If I write

    new String("foo");
in Java, how do I get an object that can take the place of String in that expression? String.class has some relationship with the "String" in the code I quoted, but it's not the same thing; the thing that I apply new to is not a thing I can call methods on, and the thing that I can call methods on is not a thing I can apply new to.


Not to mention the nightmare of ruby versions and packages.

I quite like the language by my biggest drawback to using ruby for anything is versioning and packages.


Honestly curious: can you give an example of what kind of issues you run into? Asking because I basically never have versioning or package issues with Ruby. And on the rare occasions when I do, there's usually a good Stack Overflow answer or Github issue.


Huh, with Bundler, Ruby was one of the first language ecosystems that actually got it's act together on those points. It is so much more mature than python in this regard, for example.


I would agree, however bundler & rvm are incredibly easier to setup and use when comparing to Python’s virtualenv (and the few other alternatives frequently brought up). I’m not sure there is even an equivalent for the Perl ecosystem, as I gave learning Perl an actual effort a while ago (no idea why) and all it’s quirks and weird syntax immediately turned me away and I’ve never looked back.


Really?

I haven't used it much or in a while thought Ruby had their package story down.

Python packaging is pretty bad requirements.txt is a pretty adhoc list and pipenv doesn't seem ready for prime time(haven't tried poetry yet)


> \s, only kind of, I love Ruby but it does have a few quirks that I see confuse some people coming from other languages when they start writing non-trivial Ruby code (literally everything is an object being a big one — “what do you mean a class is an object?! modules too?!”).

That's also true in python

---| type(enum)

    <class 'module'>
Also ruby Procs aren't objects

And unlike Smalltalk &&/and ||/or are not methods


It's also slower, which is quite a pity because I really like the syntax compared to Python. It has proper end statements for example.

We still use Perl5 heavily for web and backend services development (Mojolicious). If you keep your code tidy it's maintainable, so it all boils down to how you write your code. Needless to say, my tiny scripts are written in Perl. I simetimes even use it from command line to calculate dates in the future or do something that is too complicated with sed and awk.


> because I'm too stupid to write actual lisp programs

Even PG admits that Lisp (in particular CL) is an "atrocious"[0] scripting language for Unix, in part because the text-processing applications that you speak of aren't its forte. It's not that you're "too stupid", it's that it's harder than it needs to be to write scripts that do useful things on filesystems and text files using Lisp in a way that is compatible with multiple CL implementations. You'd still be Googling plenty and Lisp sure doesn't have the wealth of libraries that Python or Perl does.

On the other hand, I'd recommend you learn some form of lisp anyway for the aha moment when you implement a domain specific language with macros and scratches some itch of yours. Try Ruby, too, for the lispiest of those three scripting languages.

[0]: http://www.paulgraham.com/popular.html


That may be true in CL, but there is a scripting dialect of Lisp called TXR Lisp. It's documented in one big manual page (just like GNU Awk, Bash, and other classic programs). If you can't find what you're looking for there, either it doesn't exist, or you need help from StackOverflow or the TXR Mailing list.

TXR has decent capabilities for text processing, plenty of POSIX functions built right in, and such.

There is a decent port of TXR to Windows, which uses a fork of the Cygwin DLL called Cygnal. Cygnal provides more Windows-like behaviors in areas where stock Cygwin is too assertive with POSIX conventions in ways that make Cygwin programs confusing to Windows users.


How about Guile? I've only seen it used as an embedded language (in C) or using the repl.


For me, also with quite a bit of experience with Perl and Python, the main reason to use Python over Perl is readability. Especially when it comes to code written or modified by less experience engineers.

Programmers tend to think that writability is the most important when it comes to coding, while readability is actually far more important.

I agree that using Python's re module is harder to write for than regexps in Perl or Ruby. But honestly it's not that much harder, and usually using it leads to clearer, more explicit and more readable code.


I lean to Python when writing anything more than a few lines that I can see extending, but Perl (perl -pe '<code here>') still rules for command line pipes where I need a bit more power than what the standard Unix utilities provide.


Perl is no longer my first choice for scripting. Once upon a time perl was preinstalled on almost every Linux box and was a default package on most distributions, now you can't assume that. Also it is a bit difficult to use cpan - often the c code for a module does not compile for some reason during installation and you have to go and figure; on the other hand I never had any problems with pip. (Though I still don't quite like Python)

On the other hand bash has maps so it is possible to use that more for scripting.


Bash has a horrible syntax. Beyond a simple for loop I would reach for Perl.


But it has set -x ; really helps to see what the script is doing step by step. I don't know how to do that easily with other languages.


Put "how to trace a X script" (where X is a language name) into the search engine of your choice.


Shell scripts have so many footguns. Python is almost as terse, takes less time to write (for me anyway), and is way more maintainable.


What Linux distros don't include Perl by default? I certainly haven't come across any...


Well I did not do a lot of research for this post, but many installations that I have to deal with come from some image where perl is not been installed.


I just use perl5. Python is too hard to use for perl tasks. Separate venv for a script is horrible overkill. I also use Fedora Linux, where everything is integrated and just works.


> Separate venv for a script is horrible overkill

...and god help you when you write code/use a library that depends on language features not available by default, without pragmas, on the system Perl (5).


There is local lib and if you don't use RHEL or some other OS with ancient Perl it works just fine. Or just install what you need from the OS if you have root. Or use plenv and cpanm and whichever Perl version you want to create a local environment.


> Or just install what you need from the OS if you have root.

The availability of libraries is not the problem. The availability of language features is. Manually replacing the OS version of a ubiquitously-depended-on language as root seems like a very poor idea. The last time I tried that with Perl, I broke GNU Parallel (whose Perl code is a fascinating read, by the way!).

> Or use plenv and cpanm and whichever Perl version you want to create a local environment.

I agree; that's the right approach (or Perlbrew or any other portable-Perl installer). GP was responding to someone who argued against using venv, which is the equivalent of plenv.


I was arguing about installing Perl modules from the distribution's repository as root, not replacing the system interpreter. The other solution is system wide module install with cpanm. Perl5 has plugin "language features" available via modules such as Moo, Role::Tiny, MOP, autobox, Clone etc.


Whenever I need to write a tiny script that tests the bounds of what is easily done with just awk and Bourne shell, the tool that I next reach for nowadays is TXR or TXR Lisp.

I made it myself.

One of the conscious goals of TXR is to have a scripting language in the POSIX environment (without forgetting about MS Windows too) that is acceptable for people who would rather be coding in Lisp. (Speaking of awk: TXR has it: it's a Lisp macro.)

TXR saves coders from Python, Perl, Ruby, Tcl, Lua and whatever else.

TXR has no ecosystem or libraries; everything comes with the program. If it's not described in the manual, it doesn't exist; stop looking and write it yourself.

This kind of thing is forbidden in the TXR project: https://xkcd.com/1987/




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: