Hacker News new | past | comments | ask | show | jobs | submit login
Black Perl (wikipedia.org)
124 points by soundsop on Jan 30, 2010 | hide | past | favorite | 40 comments



Here's my favorite piece of perl:

#!/usr/bin/perl -s

                                                      @x=qw/e n d/;if(         
                               $kg){$e=13;$_="setrand(@{[int((rand)*90)]})     
                           ;K=vector(2,g,nextprime(random(10^$s)));e=$e;n=K[1]*
                               K[2];d=e^-1%((K[1]-1)*(K[2]-1));";s/\s//sg;for( 
                                `echo "$_ e\nn\nd\n"|gp -q`){print$x[$j++]     
                              ,"=",`echo "10i16o$_ p"|dc`}exit}$t=             
                             unpack'H*',join'',<>;$l=length$n;$y               
                          =$e?$l-2:$l;$i="16dio";while  (){$M=                 
                      ($e&&1+int(rand 8)).(substr     $t,$p                    
                   ,$y or last);$i.="\U$M $k        $n\E|                      
                pc";$p+=$y}for(reverse                                         
           `echo "$i"|dc`){chop                                                
   ;$d&&s/^(.)//||($_=                                                         
     sprintf"%0${l}s"                                                          
      ,$_); $f                                                                 
      .=$_}#                                                                   
      print                                                                    
      pack                                                                     
     'H*'                                                                      
   ,$f

http://ftp.uk.debian.org/munitions/documents/rsafin.html


In Perl, just like English, this poem parses but makes no sense. :P


I think it would make more sense to a member of the OTO. Kind of Crowleyesque.


I've always enjoyed the fun/weird bits of the Perl community and wrote a fair bit of (intentionally) obfuscated Perl a few years back.

My personal best was this "zombie" code: http://www.joelesko.com/cgi-bin/obfu.pl?obfuID=5


I love the "unpack" dripping off his arms.


This poem was the reason I learned Perl. Always makes me smile :)


That's why I liked Perl so much, the community & culture were (are) great.

Take a look at the first issues of The Perl Journal as well.


Funny, this is why I hate perl so much.

Fun to hack around, but then you have to maintain someone else's Perl, or write a large application in it, and the endless facepalming begins.


IMO, this argument is a red-herring: you can write bad code in any language.

Perl lit is awesome and erudite: the best idioms are described in the Cookbook. Programming Perl is a joy to read, Best Practices could be used as a standards guide.

I agree that v5 has some problematic constructs, but, all in all, what Larry Wall & Co did was awesome.


I've written a complex ruby library and then ported it to perl. Since both languages are basically the same in their capabilities the port was very straightforward. I know both languages fairly well, but if I go back to the ruby version I can read it just fine, while if I look at the perl version it looks like a morass of symbol soup. The language has so much unnecessary syntactic noise that even what I would consider well-written Perl code that I've personally designed and written is still too difficult to read.

Also, from my personal experience, in general the average quality of Perl code I've seen, whether it's CPAN libraries or code at I see at work, is much less than the average quality Python and Ruby code I see, which is more of a community problem than a language one, although Perl being the way it is seems to attract a certain class of developers I would rather not have to work with.


I ported a well-known Perl library to Ruby. It looked terrible and didn't work at all.

Turns out the problem is that I don't know Ruby.


I suppose I can't prove to you that I know Perl very well any more than you can prove to me that you actually tried to port a library over to a language without even bothering to learn the language. The latter sounds kind of stupid to me.


Who told you I wasn't stupid?


>IMO, this argument is a red-herring: you can write bad code in any language.

I would be delighted to see you cause a segfault in Haskell without taking advantage of an implementation bug.

The point isn't that you can or cannot write bad code in any language, it's not that simple. It's a matter of how difficult a language's semantics, type-checking, logical structures, and faculties make it to traverse the spectrum towards bad code.

Python has clean indentation baked in at the implementation. All major interpreted languages don't allow you to muck around with pointers.

Functional languages strongly discourage mutability. Object oriented languages are really just a foil for context scoping in various ways combined with somewhat sanitary code-reuse that is less likely to introduce type or memory sharing bugs.

It really bothers me when people say, "you can write bad code in any language". Of course you can, but that ejects the subtlety and reality of the matter into vacuum. You cannot disregard the effect of the programming environment on the code, and the supposed canard of Perl's write-once read-never is not false but rather, a tendency that it facilitates.

I mean, have you seen the number of operators in Perl?

http://tinyurl.com/badvbx (large 300 dpi jpg, Period Table of Operators in Perl)

While this makes Perl the king of golfing, the mental context it consumes to remember all the operators someone else may use in their code (but that you do not) makes reading their code a non-trivial task.

This is precisely the thing people complain about when comparing (unfavourably) C++ to C. There's just too much syntax and too many complicated interactions that make it nearly impossible to reason about what the code does, let alone any degree of referential transparency.

Potentially one of Lisp's most powerful attributes is as you may have heard, the lack of syntax. The one ever-present syntactic feature in Lisp (paren) is widely mocked as well by detractors!

Perl is awesome. It's erudite. It's a fantastic means of parsing and manipulating text (I vastly prefer Perl to awk/sed abuse except for in-line commands.) Perl documentation is really good too.

All the meta of what makes a languages pleasant to use, is mostly there for Perl, but the language itself is a syringe of heroin and rat poison, just begging you to abuse the power.

And don't mention CPAN. People who accuse Python libraries of being written by amateurs haven't seen the manifest horrors that exist in CPAN. Rubyists have it good by comparison.

Can we please drop the "you can write bad code in any language" line now?


> It's a matter of how difficult a language's semantics, type-checking, logical structures, and faculties make it to traverse the spectrum towards bad code.

You mean a different kind of "bad code" than the comment to which you replied.

Ruby, Python, Haskell, Prolog, ML, CL -- none of these languages prevent malicious or inexperienced coders from choosing poor identifiers, violating encapsulation, abusing or ignoring language-specific idioms, or designing a big ball of mud.

> I mean, have you seen the number of operators in Perl?

That's Perl 6, not Perl 5, and it's out of date.


I agree with you regarding Perl, but you're completely wrong regarding Haskell and Python. Both languages, though high-level, allow direct unchecked access to pointers.

> I would be delighted to see you cause a segfault in Haskell without taking advantage of an implementation bug.

  import Foreign
  main = peek nullPtr
Or, more complicated but less obvious:

  import Data.Typeable
  import Data.ByteString

  data Wrap a = Wrap a
  	deriving (Show)

  instance Typeable (Wrap a) where
  	typeOf _ = typeOf ()

  main = let Just (Wrap bad) = cast $ Wrap () in print (bad :: ByteString)

> Python has clean indentation baked in at the implementation. All major interpreted languages don't allow you to muck around with pointers.

  >>> import ctypes as c
  >>> c.string_at(0)
  Segmentation fault


This isn't really part of the usual work environment. Just because you can import a library and go nuts with it doesn't mean it's an everyday part of the language.

I mean really, kind of missing the point don't you think?

It's not even like Haskell makes it trivial to mutate the pointers in a natively Von Neumann-esque manner.

Monads don't count either.

Example: how often have you seen unsafe C# code (pointers) used in a production web app?

Counterpart to the above: How often do you see pointers used in C? All the time

Presenting the pathological case isn't refuting what I'm saying, it's just affirming it by showing how far you have to go out of your way to abuse your memory access, whereas in C, it's just a part of how you code. (Functors, for example.)


Pointers are absolutely part of the average Haskell and Python work environment -- it's impossible to get reasonable performance without them. Of course, Python programmers like to stick the important parts in an extension module (written in C, naturally), close their eyes, and pretend they're not doing anything "unsafe".

> It's not even like Haskell makes it trivial to mutate the pointers in a natively Von Neumann-esque manner.

Haskell has a module specifically for manipulating pointers[1]. There's no inherent safety in using Haskell rather than C for pointer based code.

> Monads don't count either.

This sentence makes no sense, and makes me think you've never (or seldom) used Haskell before.

> Example: how often have you seen unsafe C# code (pointers) used in a production web app?

Somewhat often -- pointers are used in database adapter, template engines, graphics rendering, and any code which needs to call into foreign libraries.

> Counterpart to the above: How often do you see pointers used in C? All the time

That's because C is used in code where performance is absolutely critical, which demands having control over memory layout and management. Pointers aren't a symptom of using C -- using C is a result of needing pointers.

[1] http://haskell.org/ghc/docs/latest/html/libraries/base-4.2.0...


>Pointers are absolutely part of the average Haskell and Python work environment -- it's impossible to get reasonable performance without them.

I think that making calls to functions implemented in C via the FFI would be more productive. I've never heard of anyone using pointers in Python for anything.

>This sentence makes no sense, and makes me think you've never (or seldom) used Haskell before.

Sure it does, performing an arbitrary mutation on an already known variable (location in memory) in Haskell is very intentionally non-trivial due to striving for purity as a functional language. (Copy rather than overwrite behavior as a default.)

>That's because C is used in code where performance is absolutely critical, which demands having control over memory layout and management. Pointers aren't a symptom of using C -- using C is a result of needing pointers.

Uh, the whole, "C only uses pointers for speed" thing is completely incorrect. All the experienced C programmers I know use pointers simply because they're the most direct and portable means of writing terse code that is still performant in spite of the brevity. I mentioned functors for a reason.

This is more pedantic than some of the conversations I've witnessed in ##C on Freenode, come on.

You're missing the point by a greater distance than Christopher Columbus missed the West Indies in the late 15th century.


> Sure it does, performing an arbitrary mutation on an already known variable (location in memory) in Haskell is very intentionally non-trivial due to striving for purity as a functional language. (Copy rather than overwrite behavior as a default.)

This paragraph 1) has nothing to do with monads and 2) is incorrect. Monads exist to enforce in which order computations are performed. And there's nothing difficult about mutating memory in Haskell; aside from a lack of built-in syntax, it's a close equivalent to C.

  import Foreign

  main = do
  	p <- malloc      -- p = malloc(sizeof(char))
  	poke p 'a'       -- *p = 'a'
  	peek p >>= print -- printf("'%c'\n", *p)
  	poke p 'b'       -- *p = 'b'
  	peek p >>= print -- printf("'%c'\n", *p)
  	free p           -- free(p)


Strictly, both of these are possible. Technically, it's well known that type systems cannot be perfect in the sense of consistency and finding all "good" programs. Therefore, socially, it's known that there are bad neighborhoods like Foreign, Typeable, and System.IO.Unsafe where one has to be extremely careful while playing around.

So, sure, you make a great, fun technical point, but at the same time Haskell as a language and a community has very, very carefully worked to make sure people don't make segfaults — actually, they tried to make sure people don't even write ugly code with polluted namespaces and odd global state.

Perl, C, Java just haven't (as much).


The overall point the post you replied to was trying to make, it seems to me, was that it's not about what bad things you can or can't do in a language, it's about whether the language encourages or facilitates bad habits. You can muck about with pointers in Haskell, but it's made very obvious - by the community, by the documentation, by the typesystem - that you're doing something potentially unsafe and risky. Similarly, though perhaps a little less so, with Python etc.

As has been said before, it's not important what a language makes possible, so much as what it makes easy -- and, I'd like to add, what it makes hard.


Why did you stop liking Perl? I am just curious.


Never stopped liking it, but at some point I got tired of waiting for v6 and moved on to Ruby (mostly because of Rails) and some FP.

v6 would fix everything that I find irksome on v5.


I hear you. I stopped waiting for Perl 6 a long time ago; that has freed me to enjoy Perl 5 more fully. Most of the stuff I do these days is Perl with the Catalyst web and DBIx::Class database frameworks, but I like Rails a lot too and I use it when it's a good fit.

I like the Ruby language a lot; the whole method_missing system beats AUTOLOAD hacks and I like Ruby's standard classes and core libraries. The Smalltalk influence is nice too; I like when an "OO language" feels object-oriented all the way down.


Can anyone enlighten a cuttlefish about what this means/does?


There are a few places where it seems to me the program would die, but they are surrounded by conditionals that are always false... so I am not sure.

I am downloading Perl 3 and am just going to run the thing.

Edit: OK, yacc is too new, make is too new, the C compiler can't understand 1989 C, etc... so I have lost interest.


This is a good demonstration of why, if you're saving/archiving/safeguarding important code, that you save the code, the toolchain, environment and hardware. Important enough to make all that effort, anyway. Like maybe climate research code, that kind of important and long-term relevant.


I work in an archives and for the reasons you mention many archives--with the exception of various national and large-scale archives--are failing in their efforts to preserve born digital records.

It's a thorny problem, really. In many cases, we have to preserve hardware required to decode information--think u-matic tape players, 5.25" floppies, Iomega zip drives, etc.--as well as software to decode the information on the files.


Could you store VMs?


I think this poem was present in Programming Perl, 1st edition, which covers Perl 4.


Perl 4 and the book's first edition were released simultaneously, and Perl 4 was merely a version of the Perl 3 interpreter.

Depending on who you ask, this decision was either for convenience ("this book teaches Perl 4" is easier to say than "this book teaches Perl 3.numbers.here") or marketing ("look--Perl 4 came out!"), the latter sort of like Slackware's increment of version numbers from 4 to 7.


> the latter sort of like Slackware's increment of version numbers from 4 to 7

That was done because all of the other distros at the time had higher version numbers and people were looking at Slackware with a, "Well, it's only version 4. RedHat/Mandrake/etc are already on version 7!" attitude. I remember there being a written (web) justification for it.


It's just a poem, written in Perl instead of English. perl (ver3 or 5 for the updated poem) can compile it but running the poem doesn't do anything useful.


Ah, okay, thanks! I guess I assumed that it was infamous because it did something terrible. Still pretty neat!


If I recall correctly, Perl poetry should parse, there's no need for it to do something useful.


I'm confused, are you a cuttlefish or a scuttlefish?


I'm an all-seeing cuttlefish. However, that was too long for an HN username. Despite seeing it all, I comprehend very little and require the help of my betters to understand. Hence the questions.


This is potentially the most adorable thing I've ever seen on this site.


You can never be sure on the internet. If I were Cthulhu, I'd claim to be a little cuttlefish too.




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

Search: