Perl: the super-convenient pseudo-functional language
I work at a place where we show adult models online. I was building our monthly newsletter and realized that of the 30 models who I could choose for the newsletter, not all of them had all 4 required pictures.
So I needed to hit our content server and see if a model had all 4 pictures. My knowledge of functional programming came in handy, but look how easy this was to code in Perl:
#!/usr/bin/perl
use LWP::Simple;
my @stream = qw(
uexitexy
pitoiaLden
lopdfits
ricknoverY
and_so_on_for_35_models
);
# type ModelName = String
# type ImageNumber = Int
# type URLString = String
# img :: ModelName -> ImageNumber -> URLString
sub img {
my $s = shift;
my $i = shift;
my $prefix = substr $s, 0, 1 ;
$prefix = uc $prefix;
"http://free.content.ourwebsite.com/fcs/$prefix/$s/${i}_th_.jpg";
}
# does a model have all 4 images?
# good_imgs :: [ URLString ] -> Bool
sub good_imgs {
my $s = shift;
for my $i (1..4) {
my $img = img($s, $i), $/;
return undef unless get($img) ;
}
return 1;
}
# grep is like Haskell's filter
my @ok = grep { good_imgs($_) } @stream ;
# print the models with all 4 images
print join "\n", @ok ;
This is my first time seeing how great _Haskell_ really is. Those type signatures make my Perl self-documenting. But the thing is, there is nothing close to libwww-perl for Haskell. It not only makes HTTP requests but comes with a pragmatic parser for everyday HTML.
Another thing is look how I could list the model names without bothering with quotes around the strings. The qw() operator in Perl allows one to input a list of strings without quotes by simply separating them with whitespace.
- metaperl's blog
- Login to post comments
import List import Char import Monad type URL = String models = words "uexitexy pitoiaLden lopdfits etc" modelUrl :: String -> Int -> URL modelUrl name num = joinPath [baseurl, prefix, name, show num] ++ "_th_.jpg" where baseurl = "http://free.content.ourwebsite.com/fcs" prefix = [toUpper (head name)] joinPath = foldr1 (\a b -> a ++ '/' : b) -- return True if URL exists. testHTTP :: URL -> IO Bool testHTTP url = ... -- needs a library -- like "all" but within a monad. allM :: (a -> IO Bool) -> [a] -> IO Bool allM pred [] = return True allM pred (a:as) = do ok <- pred a if ok then allM pred as else return False main = do okModels <- filterM modelOk models putStrLn (unlines okModels) where modelOk model = allM testHTTP (map (modelUrl model) [1..4])(I think Perl is a better language for these sorts of one-off scripts.)