SlideShare a Scribd company logo
Is Haskell an
Acceptable Perl?
@osfameron
LambdaLounge MadLab 18 April 2016
https://github.com/osfameron/haskell-perl
Overview
Perl:
https://www.perl.org/
Perl 5 is a highly
capable, feature-rich
programming language
with over 27 years of
development
Haskell:
https://www.haskell.org/
An advanced purely-
functional programming
language
An open source community
effort for over 20 years
Received Wisdom?
Perl:
dynamic
messy
simple
flexible
Haskell:
static
clean
hard
mathsy
Received Wisdom?
Perl:
dynamic
messy
simple
flexible
$?=~s/(?:[%^]+)/a/gsmx;
Haskell:
static
clean
hard
mathsy
a>>=(c@(_ _)->b’$c:[d])
Comparison
Perl:
Imperative
OO
Functional
“Weakly typed”
Real World
Haskell:
- (or best?)
-
Purely Functional
Strongly typed
?
Comparison
Perl:
Imperative
OO
Functional
“Weakly typed”
Real World
“whipuptitude”
Haskell:
- (or best?)
-
Purely Functional
Strongly typed
?
“manipulexity”
“Around 1993 I
started reading
books about Lisp,
and I discovered
something important:
Perl is much more
like Lisp than it is
like C.”
What Makes Lisp
Different?
“…describes seven
features of Lisp.
Perl shares six of
these features; C
shares none of them.
These are big,
important features,
features like first-
class functions,
dynamic access to the
symbol table, and
automatic storage
management.”
-- mjd
Perl6:
1st implementation
(Pugs) written in
Haskell!
Many Haskell ideas
influenced design
of Perl6.
GHC:
Used Perl to
prototype early
versions of key
components
(the Evil Mangler,
etc.)
still required for
“boot” script to
build ghc from
source
Is Haskell an acceptable Perl?
Example:
??? (“Annie”, “Bob”, “Chandra”)
=> (5, 3, 7)
Example:
map ??? (“Annie”, “Bob”, “Chandra”)
=> (5, 3, 7)
Example:
map length, (“Annie”, “Bob”, “Chandra”)
=> (5, 3, 7)
Perl vs Haskell?
??? map length,
(“Annie”, “Bob”, “Chandra”)
Map
map length,
(“Annie”, “Bob”, “Chandra”)
map length
[“Annie”, “Bob”, “Chandra”]
Map
map length,
(“Annie”, “Bob”, “Chandra”)
map length
[“Annie”, “Bob”, “Chandra”]
length :: String -> Int
length “Annie” => 5
map length :: [String]->[Int]
map :: (a -> b) -> [a] -> [b]
Map
map length,
(“Annie”, “Bob”, “Chandra”)
# map EXPR, LIST
# map BLOCK LIST
map { length } (…)
map length
[“Annie”, “Bob”, “Chandra”]
Map
map length,
(“Annie”, “Bob”, “Chandra”)
# map EXPR, LIST
# map BLOCK LIST
map { length } (…)
map length
[“Annie”, “Bob”, “Chandra”]
Map
map length,
(“Annie”, “Bob”, “Chandra”)
# map EXPR, LIST
# map BLOCK LIST
map { length } (…)
# length EXPR
# length
# If EXPR is omitted, returns
the length of $_
map length
[“Annie”, “Bob”, “Chandra”]
Map
map length,
(“Annie”, “Bob”, “Chandra”)
• expression
• $_ (“it”)
• optional parameters
map length
[“Annie”, “Bob”, “Chandra”]
• function
• currying
• “lifting”
Doubling
map $_ * 2, (1..5)
=> (2,4,6,8,10)
map (*2) [1..5]
=> [2,4,6,8,10]
Doubling
map double($_), (1..5)
use experimental ‘signatures’;
sub double ($x) { $x * 2 }
map double [1..5]
double x = x * 2
-- or
double = (*2)
Define our own ‘fmap’
fmap &double, (1..5)
sub double ($x) { $x * 2 }
sub fmap ???
map double [1..5]
double x = x * 2
-- or
double = (*2)
Define our own ‘fmap’
fmap &double, (1..5)
sub double ($x) { $x * 2 }
sub fmap ($fn, @list) {
map $fn->($_), @list
}
map double [1..5]
double x = x * 2
-- or
double = (*2)
Prototypes...
map _&double, (1..5)
sub double ($x) { $x * 2 }
{
no experimental 'signatures';
sub _ ($) { shift->($_) }
}
map double [1..5]
double x = x * 2
-- or
double = (*2)
Reverse...
??? map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
Reverse...
map reverse,
(“foo”, “bar”)
=> ...
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
Reverse...
map reverse,
(“foo”, “bar”)
=> () # wtf?
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
Reverse...
map reverse,
(“foo”, “bar”)
=> ()
# reverse LIST
reverse (“foo”, “bar”)
=> (“bar”, “foo”)
reverse () => ()
# reverse STRING
reverse “foo” => “oof”
# reverse ($_)
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
Reverse...
map scalar reverse,
(“foo”, “bar”)
=> (“oof”, “rab”)
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
Reverse...
map scalar reverse,
(“foo”, “bar”)
=> (“oof”, “rab”)
• map is really concatMap!
map reverse
[“foo”, “bar”]
=> [“oof”, “rab”
concatMap vs map
map {$_,$_} (1..3)
=> (1,1,2,2,3,3)
map (x->[x,x]) [1..3]
=> [[1,1],[2,2],[3,3]]
concatMap vs map
map {$_,$_} (1..3)
=> (1,1,2,2,3,3)
concatMap (x->[x,x]) [1..3]
=> [1,1,2,2,3,3]
Reverse with concatMap
map scalar reverse,
(“foo”, “bar”)
=> (“oof”, “rab”)
concatMap reverse
[“foo”, “bar”]
=> [“oofrab”] -- eeek!
Reverse with concatMap
map scalar reverse,
(“foo”, “bar”)
=> (“oof”, “rab”)
• scalar vs list context
concatMap (return . reverse)
[“foo”, “bar”]
=> [“oof”, “rab”]
• map vs concatMap
• return (to wrap value
in e.g. list)
Length of lists of lists:
??? ([1,2,3], [5,4,3,2,1])
=> (3, 5)
Length of LoL
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map length, @l
=> (16, 16) # wtf
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map length, @l
=> (16, 16)
# length STRING
[1,2,3] => “ARRAY(0x293a1d8)”
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map length, @l
=> (16, 16)
# length STRING
[1,2,3] => “ARRAY(0x293a1d8)”
# scalar @array
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map scalar, @l
=> ([1,2,3], [5,4,3,2,1])
# [1,2,3] is already scalar!
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
Length of LoL
my @l = ([1,2,3], [5,4,3,2,1]);
map scalar @$_, @l
=> (3, 5)
l = [[1,2,3], [5,4,3,2,1]]
map length l
=> [3, 5]
length :: [a] -> Int
Tails
??? map tail l
=> [[2,3], [4,3,2,1]]
Tails
map [ @$_[1..$#$_] ], @l
=> ([2,3], [4,3,2,1])
map tail l
=> [[2,3], [4,3,2,1]]
Tails
map [ @$_[1..$#$_] ], @l
=> ([2,3], [4,3,2,1])
• Yes, I know
map tail l
=> [[2,3], [4,3,2,1]]
Tails
map tail($_), @l
=> () # bah!
sub tail ($head, @tail) {
@tail
}
map tail l
=> [[2,3], [4,3,2,1]]
Tails
map __&tail, @l
=> ([2,3], [4,3,2,1])
sub tail ($head, @tail) {
@tail
}
{
no experimental 'signatures';
sub _ ($) { shift->($_) }
sub __ ($) { [shift->(@$_)] }
}
map tail l
=> [[2,3], [4,3,2,1]]
A thought...
Scalar/list context
Sigils ($, @, %)
implicit $_
Optional parameters
References and
dereferencing
Automatic type coercions
Subroutine prototypes
Type system
Example
Scalar/list context Monads (Maybe, List)
Example:
-- https://prime.haskell.org/wiki/Libraries/Proposals/MonadFail
import qualified Data.Map as M
en2it = M.fromList [
("hello","ciao"),
("goodbye","ciao"),
("pasta","pasta") ]
translate db k =
let v = M.lookup k db
in case v of
Nothing -> fail "No translation"
Just v' -> return v'
Example:
*Main> translate en2it "hello"
"ciao"
*Main> translate en2it "hello" :: Maybe String
Just "ciao"
*Main> translate en2it "hello" :: [String]
["ciao"]
*Main> translate en2it "whipuptitude"
*** Exception: user error (No translation)
*Main> translate en2it "whipuptitude" :: Maybe String
Nothing
*Main> translate en2it "whipuptitude" :: [String]
[]
To be fair...
Perl:
• Larry Wall: linguist,
missionary
• + jobbing programmers
• pragmatic
• magpie-like
Haskell:
• Decades of Comp Sci
professors and PhD
students
• purity
• experimentation
Why are we* so terrified of types?
en2it :: M.Map [Char] [Char]
en2it = M.fromList [
("hello","ciao"),
("goodbye","ciao"),
("pasta","pasta") ]
translate :: (Monad m, Ord k) => M.Map k a -> k -> m a
translate db k =
let v = M.lookup k db
in case v of
Nothing -> fail "No translation"
Just v' -> return v'
Why are we* so terrified of types?
en2it :: M.Map [Char] [Char]
en2it = M.fromList [
("hello","ciao"),
("goodbye","ciao"),
("pasta","pasta") ]
translate :: (Monad m, Ord k) => M.Map k a -> k -> m a
translate db k =
let v = M.lookup k db
in case v of
Nothing -> fail "No translation"
Just v' -> return v'
Why are we* so terrified of types?
“Programming in ML is very pleasant. More than
almost any other language I know, you can just
write down the definitions of the functions as
they come into your head. You don't need to bother
with declarations; everything is just figured out
for you automatically.
And you do get a lot of type errors, both actual
failures and also places where the type emitted by
the compiler is not what you thought it should be.
But unlike in C or Pascal, every one of those
errors indicates a real, serious problem in your
program, not merely something you have to groan
over and try to work around the compiler's
stupidity yet again.”
-- mjd http://perl.plover.com/classes/typing/notes.html
Why are we* so terrified of types?
[4, 8, 15, 16, 23, 42] :: [Int]
Type terror: undefined values
[4, 8, 15, undef, 16, 23, 42] :: [Panic!]
Type terror: undefined values
my %en2it = (
hello => “ciao”,
goodbye => “ciao”,
pasta => “pasta”
);
my @l = map $en2it{$_},
(“hello", “monad", “pasta”);
my @c = grep defined, @l;
# (“ciao”, “pasta”)
Type terror: undefined values
-- data Maybe a = Just a | Nothing
l = map (flip Map.lookup h)
[“hello", “monad", “pasta”]
-- [Just “ciao”, Nothing, Just “pasta”]
c = catMaybes l
-- [“ciao”, “pasta”]
Type terror: signal values
[1, undef, 2, “X”, 3, -5]
# positive number: record
# undef: no record found
# “string”: processing instruction
# negative number: record flagged for
deletion
Type terror: signal values
records :: [Maybe Record]
records = [
Just Record (Left 1),
Nothing,
Just Record (Left 2),
Just Instruction “X”
Just Record (Left 2),
Just Record (Right 5)]
data Record =
Record (Either Int Int) | Instruction String
Type terror: but! but! but!
serialization (show)
objects of a particular class (typeclasses)
GADTs
existential types
dynamic introspection
...
Bonus section #1
practical oneliners
april.txt
There is shadow under this red rock,
(Come in under the shadow of this red rock),
And I will show you something different from either
Your shadow at morning striding behind you
Or your shadow at evening rising to meet you;
I will show you fear in a handful of dust.
Grep for a string
$ perl -ne ‘print if /shadow/’ < april.txt
???
Grep for a string
$ perl -ne ‘print if /shadow/’ < april.txt
notaoneliner.hs:
import Data.List
main = interact (
unlines .
(filter (a -> "shadow" `isInfixOf` a))
. lines )
$ runghc notaoneliner.hs < april.txt
april.txt | grep shadow
There is shadow under this red rock,
(Come in under the shadow of this red rock),
Your shadow at morning striding behind you
Or your shadow at evening rising to meet you;
Grep for a string
$ perl -ne ‘print if /shadow/’ < april.txt
hask.bash:
if which ghc > /dev/null
then
function h { ghc -e "interact ($*)" Ust.hs ; }
function hl { h "bylines ($*)" ; }
function hw { h "bywords ($*)" ; }
fi
$ hl ‘filter (regexBool “shadow”)’ < april.txt
Ust.hs
https://wiki.haskell.org/Simple_Unix_tools
https://ulissesaraujo.wordpress.com/tag/command/
{-# LANGUAGE NoMonomorphismRestriction #-}
module Ust(
bylines, bywords, showln, regexBool, uniq, rpt, take', drop',
head', tail', tail10, tac, rev, rev_w, wc_c, wc_l, wc_w, space,
unspace, remove, upper, clean, clean', clean'', blank, join, tr,
tr_d, grep, grep_v, cksum
) where
import Control.Monad.Instances; import Data.List; import Data.Char;
import Data.Maybe; import Text.Printf; import System.Environment;
import Text.Regex.Posix
-- First, three helpers
bylines f = (unlines . f . lines)
bywords f = (unwords . f . words)
showln = (++ "n") . show
-- simple boolean regex matching
regexBool r l = l =~ r :: Bool
...
Uppercase
$ perl -pe ‘$_ = uc’ < april.txt
$ h upper < april.txt
Ust.hs:
upper = map toUpper
april.txt | upper
THERE IS SHADOW UNDER THIS RED ROCK,
(COME IN UNDER THE SHADOW OF THIS RED ROCK),
AND I WILL SHOW YOU SOMETHING DIFFERENT FROM EITHER
YOUR SHADOW AT MORNING STRIDING BEHIND YOU
OR YOUR SHADOW AT EVENING RISING TO MEET YOU;
I WILL SHOW YOU FEAR IN A HANDFUL OF DUST.
Sort
$ perl -e 'print sort <>' < april.txt
$ hl sort < april.txt
april.txt | sort
(Come in under the shadow of this red rock),
And I will show you something different from either
I will show you fear in a handful of dust.
Or your shadow at evening rising to meet you;
There is shadow under this red rock,
Your shadow at morning striding behind you
Sorted words
$ perl -e 'print join " ",
sort map { chomp; split } <>' < april.txt
$ hw sort < april.txt
april.txt | sort-words
(Come And I I Or There Your a at at behind different
dust. either evening fear from handful in in is meet
morning of of red red rising rock), rock, shadow shadow
shadow shadow show show something striding the this
this to under under will will you you you you; your
Bonus section #2
real world(ish) code
Modelling TV programmes
Brand:
“Have I
Got News
For You?”
Series:
“3”
Episode:
“1” /
HIGNFY123
Modelling TV programmes
Brand:
“Have I
Got News
For You?”
Series:
“3”
Episode:
“1” /
HIGNFY123
Brand:
“Have I
Got OLD
News For
You?”
Series:
“1”
Episode:
“5” /
HIGNFY123
Data modelling
package Programme;
use Moo;
use Types::Standard
qw/ Maybe Str /;
has id => ( is => 'ro',
isa => Maybe[Str] );
has id2 => ( is => 'ro',
isa => Maybe[Str] );
package Brand;
use Moo;
extends 'Programme';
# ditto Series, Episode...
type PrimaryId = Maybe String
type AlternateId = Maybe String
data Prog = Prog
ProgType
PrimaryId AlternateId
deriving (Eq, Ord, Show)
data ProgType =
Brand |
Series |
Episode
deriving (Eq, Ord, Show)
The “Database”
package Database;
use Moo;
use Types::Standard
qw/ArrayRef HashRef InstanceOf/;
has list => (
is => 'ro',
isa => ArrayRef[InstanceOf["Programme"]],
...
);
has graph => (
is => 'ro',
isa => HashRef[InstanceOf["Programme"]],
...
);
data Database = Database {
list :: [Prog],
graph :: M.Map Prog Prog
}
Get Hierarchy
use experimental ‘signatures’;
sub getHierarchy($self, $prog) {
if (my $parent = $self->lookup($prog->id)) {
return ($prog, $self->getHierarchy($parent))
}
else { return $prog }
}
getHierarchy :: Database -> Prog -> [Prog]
getHierarchy db p =
let l = M.lookup p (graph db)
in case l of
Nothing -> [p]
Just (parent) -> p : (getHierarchy db parent)
Get Hierarchy
use experimental ‘signatures’;
use MooX::HandlesVia;
has graph => (
is => 'ro',
isa => HashRef[InstanceOf["Programme"]],
handles_via => 'Hash',
handles => { lookup => ‘get’ }
);
sub getHierarchy($self, $prog) {
if (my $parent = $self->lookup($prog->id)) {
return ($prog, $self->getHierarchy($parent))
}
else { return $prog }
}
Search for a programme
sub search ($self, $prog1) {
my sub match ($prog2) {
return unless ref $prog1 eq ref $prog2;
return unless $prog1->id or $prog1->id2;
return unless $prog2->id or $prog2->id2;
return unless $prog1->id or $prog2->id2;
return unless $prog1->id2 or $prog2->id;
return if $prog1->id and $prog2->id and $prog1->id ne $prog2->id;
return if $prog1->id2 and $prog2->id2 and $prog1->id2 ne $prog2->id2;
return 1;
}
return $self->filter(&match);
}
Search for a programme
use experimental 'lexical_subs';
has list => (
is => 'ro',
isa => ArrayRef[InstanceOf["Programme"]],
handles_via => 'Array',
handles => { filter => 'grep'}
);
Search for a programme
search db p =
filter (match p) (list db)
where
match (Prog t1 _ _) (Prog t2 _ _) | t1 /= t2 = False
match (Prog _ Nothing Nothing) _ = False
match _ (Prog _ Nothing Nothing) = False
match (Prog _ Nothing _) (Prog _ _ Nothing) = False
match (Prog _ _ Nothing) (Prog _ Nothing _) = False
match (Prog _ (Just p1) _) (Prog _ (Just p2) _) | p1 /= p2 = False
match (Prog _ _ (Just a1)) (Prog _ _ (Just a2)) | a1 /= a2 = False
match _ _ = True
Thanks!
@osfameron
https://github.com/osfameron/haskell-perl
Ad

More Related Content

What's hot (20)

Wx::Perl::Smart
Wx::Perl::SmartWx::Perl::Smart
Wx::Perl::Smart
lichtkind
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
Simon Proctor
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
Simon Proctor
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
Vic Metcalfe
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
Lin Yo-An
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門
Hiromi Ishii
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
garux
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
진성 오
 
Perl 6 in Context
Perl 6 in ContextPerl 6 in Context
Perl 6 in Context
lichtkind
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
Sanketkumar Biswas
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
Nikita Popov
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type System
abrummett
 
groovy & grails - lecture 3
groovy & grails - lecture 3groovy & grails - lecture 3
groovy & grails - lecture 3
Alexandre Masselot
 
EcmaScript 6
EcmaScript 6 EcmaScript 6
EcmaScript 6
Manoj Kumar
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
garux
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
Naïveté vs. Experience
Naïveté vs. ExperienceNaïveté vs. Experience
Naïveté vs. Experience
Mike Fogus
 
Template Haskell とか
Template Haskell とかTemplate Haskell とか
Template Haskell とか
Hiromi Ishii
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language
Ashal aka JOKER
 
Wx::Perl::Smart
Wx::Perl::SmartWx::Perl::Smart
Wx::Perl::Smart
lichtkind
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
Simon Proctor
 
Perl6 a whistle stop tour
Perl6 a whistle stop tourPerl6 a whistle stop tour
Perl6 a whistle stop tour
Simon Proctor
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
Vic Metcalfe
 
Perl.Hacks.On.Vim
Perl.Hacks.On.VimPerl.Hacks.On.Vim
Perl.Hacks.On.Vim
Lin Yo-An
 
Invertible-syntax 入門
Invertible-syntax 入門Invertible-syntax 入門
Invertible-syntax 入門
Hiromi Ishii
 
Descobrindo a linguagem Perl
Descobrindo a linguagem PerlDescobrindo a linguagem Perl
Descobrindo a linguagem Perl
garux
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
진성 오
 
Perl 6 in Context
Perl 6 in ContextPerl 6 in Context
Perl 6 in Context
lichtkind
 
Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)Static Optimization of PHP bytecode (PHPSC 2017)
Static Optimization of PHP bytecode (PHPSC 2017)
Nikita Popov
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type System
abrummett
 
Introdução ao Perl 6
Introdução ao Perl 6Introdução ao Perl 6
Introdução ao Perl 6
garux
 
Desarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutosDesarrollando aplicaciones web en minutos
Desarrollando aplicaciones web en minutos
Edgar Suarez
 
Naïveté vs. Experience
Naïveté vs. ExperienceNaïveté vs. Experience
Naïveté vs. Experience
Mike Fogus
 
Template Haskell とか
Template Haskell とかTemplate Haskell とか
Template Haskell とか
Hiromi Ishii
 
Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)Good Evils In Perl (Yapc Asia)
Good Evils In Perl (Yapc Asia)
Kang-min Liu
 
여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language여자개발자모임터 6주년 개발 세미나 - Scala Language
여자개발자모임터 6주년 개발 세미나 - Scala Language
Ashal aka JOKER
 

Similar to Is Haskell an acceptable Perl? (20)

Introduction to Perl
Introduction to PerlIntroduction to Perl
Introduction to Perl
Sway Wang
 
Five Languages in a Moment
Five Languages in a MomentFive Languages in a Moment
Five Languages in a Moment
Sergio Gil
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slide
jonycse
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
Michael Pirnat
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014
Konrad Malawski
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
Ígor Bonadio
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
Utkarsh Sengar
 
An introduction to Ruby
An introduction to RubyAn introduction to Ruby
An introduction to Ruby
Wes Oldenbeuving
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
Howard Lewis Ship
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 
PERL for QA - Important Commands and applications
PERL for QA - Important Commands and applicationsPERL for QA - Important Commands and applications
PERL for QA - Important Commands and applications
Sunil Kumar Gunasekaran
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go Programming
Lin Yo-An
 
Functional perl
Functional perlFunctional perl
Functional perl
Errorific
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
Matt Stine
 
学生向けScalaハンズオンテキスト
学生向けScalaハンズオンテキスト学生向けScalaハンズオンテキスト
学生向けScalaハンズオンテキスト
Opt Technologies
 
C to perl binding
C to perl bindingC to perl binding
C to perl binding
Shmuel Fomberg
 
ES6 is Nigh
ES6 is NighES6 is Nigh
ES6 is Nigh
Domenic Denicola
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
FITC
 
Ruby 1.9
Ruby 1.9Ruby 1.9
Ruby 1.9
guestaef7ea
 
Introduction to Perl
Introduction to PerlIntroduction to Perl
Introduction to Perl
Sway Wang
 
Five Languages in a Moment
Five Languages in a MomentFive Languages in a Moment
Five Languages in a Moment
Sergio Gil
 
python beginner talk slide
python beginner talk slidepython beginner talk slide
python beginner talk slide
jonycse
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
Michael Pirnat
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014Scalding - the not-so-basics @ ScalaDays 2014
Scalding - the not-so-basics @ ScalaDays 2014
Konrad Malawski
 
Ruby - Uma Introdução
Ruby - Uma IntroduçãoRuby - Uma Introdução
Ruby - Uma Introdução
Ígor Bonadio
 
Python Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard WayPython Workshop - Learn Python the Hard Way
Python Workshop - Learn Python the Hard Way
Utkarsh Sengar
 
Modern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter BootstrapModern Application Foundations: Underscore and Twitter Bootstrap
Modern Application Foundations: Underscore and Twitter Bootstrap
Howard Lewis Ship
 
Scala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar ProkopecScala presentation by Aleksandar Prokopec
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 
PERL for QA - Important Commands and applications
PERL for QA - Important Commands and applicationsPERL for QA - Important Commands and applications
PERL for QA - Important Commands and applications
Sunil Kumar Gunasekaran
 
Happy Go Programming
Happy Go ProgrammingHappy Go Programming
Happy Go Programming
Lin Yo-An
 
Functional perl
Functional perlFunctional perl
Functional perl
Errorific
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
Matt Stine
 
学生向けScalaハンズオンテキスト
学生向けScalaハンズオンテキスト学生向けScalaハンズオンテキスト
学生向けScalaハンズオンテキスト
Opt Technologies
 
An Intro To ES6
An Intro To ES6An Intro To ES6
An Intro To ES6
FITC
 
Ad

More from osfameron (12)

Writing a Tile-Matching Game - FP Style
Writing a Tile-Matching Game - FP StyleWriting a Tile-Matching Game - FP Style
Writing a Tile-Matching Game - FP Style
osfameron
 
Data Structures for Text Editors
Data Structures for Text EditorsData Structures for Text Editors
Data Structures for Text Editors
osfameron
 
Rewriting the Apocalypse
Rewriting the ApocalypseRewriting the Apocalypse
Rewriting the Apocalypse
osfameron
 
Global Civic Hacking 101 (lightning talk)
Global Civic Hacking 101 (lightning talk)Global Civic Hacking 101 (lightning talk)
Global Civic Hacking 101 (lightning talk)
osfameron
 
Adventures in civic hacking
Adventures in civic hackingAdventures in civic hacking
Adventures in civic hacking
osfameron
 
Haskell in the Real World
Haskell in the Real WorldHaskell in the Real World
Haskell in the Real World
osfameron
 
Oyster: an incubator for perls in the cloud
Oyster: an incubator for perls in the cloudOyster: an incubator for perls in the cloud
Oyster: an incubator for perls in the cloud
osfameron
 
Semantic Pipes (London Perl Workshop 2009)
Semantic Pipes (London Perl Workshop 2009)Semantic Pipes (London Perl Workshop 2009)
Semantic Pipes (London Perl Workshop 2009)
osfameron
 
Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)
osfameron
 
Functional Pe(a)rls
Functional Pe(a)rlsFunctional Pe(a)rls
Functional Pe(a)rls
osfameron
 
Readable Perl
Readable PerlReadable Perl
Readable Perl
osfameron
 
Bigbadwolf
BigbadwolfBigbadwolf
Bigbadwolf
osfameron
 
Writing a Tile-Matching Game - FP Style
Writing a Tile-Matching Game - FP StyleWriting a Tile-Matching Game - FP Style
Writing a Tile-Matching Game - FP Style
osfameron
 
Data Structures for Text Editors
Data Structures for Text EditorsData Structures for Text Editors
Data Structures for Text Editors
osfameron
 
Rewriting the Apocalypse
Rewriting the ApocalypseRewriting the Apocalypse
Rewriting the Apocalypse
osfameron
 
Global Civic Hacking 101 (lightning talk)
Global Civic Hacking 101 (lightning talk)Global Civic Hacking 101 (lightning talk)
Global Civic Hacking 101 (lightning talk)
osfameron
 
Adventures in civic hacking
Adventures in civic hackingAdventures in civic hacking
Adventures in civic hacking
osfameron
 
Haskell in the Real World
Haskell in the Real WorldHaskell in the Real World
Haskell in the Real World
osfameron
 
Oyster: an incubator for perls in the cloud
Oyster: an incubator for perls in the cloudOyster: an incubator for perls in the cloud
Oyster: an incubator for perls in the cloud
osfameron
 
Semantic Pipes (London Perl Workshop 2009)
Semantic Pipes (London Perl Workshop 2009)Semantic Pipes (London Perl Workshop 2009)
Semantic Pipes (London Perl Workshop 2009)
osfameron
 
Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)Functional Pearls 4 (YAPC::EU::2009 remix)
Functional Pearls 4 (YAPC::EU::2009 remix)
osfameron
 
Functional Pe(a)rls
Functional Pe(a)rlsFunctional Pe(a)rls
Functional Pe(a)rls
osfameron
 
Readable Perl
Readable PerlReadable Perl
Readable Perl
osfameron
 
Ad

Recently uploaded (20)

Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]
saniaaftab72555
 
FL Studio Producer Edition Crack 2025 Full Version
FL Studio Producer Edition Crack 2025 Full VersionFL Studio Producer Edition Crack 2025 Full Version
FL Studio Producer Edition Crack 2025 Full Version
tahirabibi60507
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
ssuserb14185
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
Not So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java WebinarNot So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
Maxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINKMaxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINK
younisnoman75
 
Top 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docxTop 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docx
Portli
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 
Automation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath CertificateAutomation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath Certificate
VICTOR MAESTRE RAMIREZ
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
Andre Hora
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Download YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full ActivatedDownload YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full Activated
saniamalik72555
 
Download Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With LatestDownload Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With Latest
tahirabibi60507
 
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRYLEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
NidaFarooq10
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 
Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]Get & Download Wondershare Filmora Crack Latest [2025]
Get & Download Wondershare Filmora Crack Latest [2025]
saniaaftab72555
 
FL Studio Producer Edition Crack 2025 Full Version
FL Studio Producer Edition Crack 2025 Full VersionFL Studio Producer Edition Crack 2025 Full Version
FL Studio Producer Edition Crack 2025 Full Version
tahirabibi60507
 
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
How to Batch Export Lotus Notes NSF Emails to Outlook PST Easily?
steaveroggers
 
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...Explaining GitHub Actions Failures with Large Language Models Challenges, In...
Explaining GitHub Actions Failures with Large Language Models Challenges, In...
ssuserb14185
 
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025Why Orangescrum Is a Game Changer for Construction Companies in 2025
Why Orangescrum Is a Game Changer for Construction Companies in 2025
Orangescrum
 
Not So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java WebinarNot So Common Memory Leaks in Java Webinar
Not So Common Memory Leaks in Java Webinar
Tier1 app
 
Maxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINKMaxon CINEMA 4D 2025 Crack FREE Download LINK
Maxon CINEMA 4D 2025 Crack FREE Download LINK
younisnoman75
 
Top 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docxTop 10 Client Portal Software Solutions for 2025.docx
Top 10 Client Portal Software Solutions for 2025.docx
Portli
 
Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025Adobe Master Collection CC Crack Advance Version 2025
Adobe Master Collection CC Crack Advance Version 2025
kashifyounis067
 
Automation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath CertificateAutomation Techniques in RPA - UiPath Certificate
Automation Techniques in RPA - UiPath Certificate
VICTOR MAESTRE RAMIREZ
 
Adobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest VersionAdobe Illustrator Crack FREE Download 2025 Latest Version
Adobe Illustrator Crack FREE Download 2025 Latest Version
kashifyounis067
 
WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)WinRAR Crack for Windows (100% Working 2025)
WinRAR Crack for Windows (100% Working 2025)
sh607827
 
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software DevelopmentSecure Test Infrastructure: The Backbone of Trustworthy Software Development
Secure Test Infrastructure: The Backbone of Trustworthy Software Development
Shubham Joshi
 
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
What Do Contribution Guidelines Say About Software Testing? (MSR 2025)
Andre Hora
 
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Requirements in Engineering AI- Enabled Systems: Open Problems and Safe AI Sy...
Lionel Briand
 
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New VersionPixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
Pixologic ZBrush Crack Plus Activation Key [Latest 2025] New Version
saimabibi60507
 
Download YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full ActivatedDownload YouTube By Click 2025 Free Full Activated
Download YouTube By Click 2025 Free Full Activated
saniamalik72555
 
Download Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With LatestDownload Wondershare Filmora Crack [2025] With Latest
Download Wondershare Filmora Crack [2025] With Latest
tahirabibi60507
 
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRYLEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
LEARN SEO AND INCREASE YOUR KNOWLDGE IN SOFTWARE INDUSTRY
NidaFarooq10
 
PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025PDF Reader Pro Crack Latest Version FREE Download 2025
PDF Reader Pro Crack Latest Version FREE Download 2025
mu394968
 

Is Haskell an acceptable Perl?

  • 1. Is Haskell an Acceptable Perl? @osfameron LambdaLounge MadLab 18 April 2016 https://github.com/osfameron/haskell-perl
  • 2. Overview Perl: https://www.perl.org/ Perl 5 is a highly capable, feature-rich programming language with over 27 years of development Haskell: https://www.haskell.org/ An advanced purely- functional programming language An open source community effort for over 20 years
  • 6. Comparison Perl: Imperative OO Functional “Weakly typed” Real World “whipuptitude” Haskell: - (or best?) - Purely Functional Strongly typed ? “manipulexity”
  • 7. “Around 1993 I started reading books about Lisp, and I discovered something important: Perl is much more like Lisp than it is like C.”
  • 8. What Makes Lisp Different? “…describes seven features of Lisp. Perl shares six of these features; C shares none of them. These are big, important features, features like first- class functions, dynamic access to the symbol table, and automatic storage management.” -- mjd
  • 9. Perl6: 1st implementation (Pugs) written in Haskell! Many Haskell ideas influenced design of Perl6.
  • 10. GHC: Used Perl to prototype early versions of key components (the Evil Mangler, etc.) still required for “boot” script to build ghc from source
  • 12. Example: ??? (“Annie”, “Bob”, “Chandra”) => (5, 3, 7)
  • 13. Example: map ??? (“Annie”, “Bob”, “Chandra”) => (5, 3, 7)
  • 14. Example: map length, (“Annie”, “Bob”, “Chandra”) => (5, 3, 7)
  • 15. Perl vs Haskell? ??? map length, (“Annie”, “Bob”, “Chandra”)
  • 16. Map map length, (“Annie”, “Bob”, “Chandra”) map length [“Annie”, “Bob”, “Chandra”]
  • 17. Map map length, (“Annie”, “Bob”, “Chandra”) map length [“Annie”, “Bob”, “Chandra”] length :: String -> Int length “Annie” => 5 map length :: [String]->[Int] map :: (a -> b) -> [a] -> [b]
  • 18. Map map length, (“Annie”, “Bob”, “Chandra”) # map EXPR, LIST # map BLOCK LIST map { length } (…) map length [“Annie”, “Bob”, “Chandra”]
  • 19. Map map length, (“Annie”, “Bob”, “Chandra”) # map EXPR, LIST # map BLOCK LIST map { length } (…) map length [“Annie”, “Bob”, “Chandra”]
  • 20. Map map length, (“Annie”, “Bob”, “Chandra”) # map EXPR, LIST # map BLOCK LIST map { length } (…) # length EXPR # length # If EXPR is omitted, returns the length of $_ map length [“Annie”, “Bob”, “Chandra”]
  • 21. Map map length, (“Annie”, “Bob”, “Chandra”) • expression • $_ (“it”) • optional parameters map length [“Annie”, “Bob”, “Chandra”] • function • currying • “lifting”
  • 22. Doubling map $_ * 2, (1..5) => (2,4,6,8,10) map (*2) [1..5] => [2,4,6,8,10]
  • 23. Doubling map double($_), (1..5) use experimental ‘signatures’; sub double ($x) { $x * 2 } map double [1..5] double x = x * 2 -- or double = (*2)
  • 24. Define our own ‘fmap’ fmap &double, (1..5) sub double ($x) { $x * 2 } sub fmap ??? map double [1..5] double x = x * 2 -- or double = (*2)
  • 25. Define our own ‘fmap’ fmap &double, (1..5) sub double ($x) { $x * 2 } sub fmap ($fn, @list) { map $fn->($_), @list } map double [1..5] double x = x * 2 -- or double = (*2)
  • 26. Prototypes... map _&double, (1..5) sub double ($x) { $x * 2 } { no experimental 'signatures'; sub _ ($) { shift->($_) } } map double [1..5] double x = x * 2 -- or double = (*2)
  • 27. Reverse... ??? map reverse [“foo”, “bar”] => [“oof”, “rab”
  • 28. Reverse... map reverse, (“foo”, “bar”) => ... map reverse [“foo”, “bar”] => [“oof”, “rab”
  • 29. Reverse... map reverse, (“foo”, “bar”) => () # wtf? map reverse [“foo”, “bar”] => [“oof”, “rab”
  • 30. Reverse... map reverse, (“foo”, “bar”) => () # reverse LIST reverse (“foo”, “bar”) => (“bar”, “foo”) reverse () => () # reverse STRING reverse “foo” => “oof” # reverse ($_) map reverse [“foo”, “bar”] => [“oof”, “rab”
  • 31. Reverse... map scalar reverse, (“foo”, “bar”) => (“oof”, “rab”) map reverse [“foo”, “bar”] => [“oof”, “rab”
  • 32. Reverse... map scalar reverse, (“foo”, “bar”) => (“oof”, “rab”) • map is really concatMap! map reverse [“foo”, “bar”] => [“oof”, “rab”
  • 33. concatMap vs map map {$_,$_} (1..3) => (1,1,2,2,3,3) map (x->[x,x]) [1..3] => [[1,1],[2,2],[3,3]]
  • 34. concatMap vs map map {$_,$_} (1..3) => (1,1,2,2,3,3) concatMap (x->[x,x]) [1..3] => [1,1,2,2,3,3]
  • 35. Reverse with concatMap map scalar reverse, (“foo”, “bar”) => (“oof”, “rab”) concatMap reverse [“foo”, “bar”] => [“oofrab”] -- eeek!
  • 36. Reverse with concatMap map scalar reverse, (“foo”, “bar”) => (“oof”, “rab”) • scalar vs list context concatMap (return . reverse) [“foo”, “bar”] => [“oof”, “rab”] • map vs concatMap • return (to wrap value in e.g. list)
  • 37. Length of lists of lists: ??? ([1,2,3], [5,4,3,2,1]) => (3, 5)
  • 38. Length of LoL l = [[1,2,3], [5,4,3,2,1]] map length l => [3, 5] length :: [a] -> Int
  • 39. Length of LoL my @l = ([1,2,3], [5,4,3,2,1]); map length, @l => (16, 16) # wtf l = [[1,2,3], [5,4,3,2,1]] map length l => [3, 5] length :: [a] -> Int
  • 40. Length of LoL my @l = ([1,2,3], [5,4,3,2,1]); map length, @l => (16, 16) # length STRING [1,2,3] => “ARRAY(0x293a1d8)” l = [[1,2,3], [5,4,3,2,1]] map length l => [3, 5] length :: [a] -> Int
  • 41. Length of LoL my @l = ([1,2,3], [5,4,3,2,1]); map length, @l => (16, 16) # length STRING [1,2,3] => “ARRAY(0x293a1d8)” # scalar @array l = [[1,2,3], [5,4,3,2,1]] map length l => [3, 5] length :: [a] -> Int
  • 42. Length of LoL my @l = ([1,2,3], [5,4,3,2,1]); map scalar, @l => ([1,2,3], [5,4,3,2,1]) # [1,2,3] is already scalar! l = [[1,2,3], [5,4,3,2,1]] map length l => [3, 5] length :: [a] -> Int
  • 43. Length of LoL my @l = ([1,2,3], [5,4,3,2,1]); map scalar @$_, @l => (3, 5) l = [[1,2,3], [5,4,3,2,1]] map length l => [3, 5] length :: [a] -> Int
  • 44. Tails ??? map tail l => [[2,3], [4,3,2,1]]
  • 45. Tails map [ @$_[1..$#$_] ], @l => ([2,3], [4,3,2,1]) map tail l => [[2,3], [4,3,2,1]]
  • 46. Tails map [ @$_[1..$#$_] ], @l => ([2,3], [4,3,2,1]) • Yes, I know map tail l => [[2,3], [4,3,2,1]]
  • 47. Tails map tail($_), @l => () # bah! sub tail ($head, @tail) { @tail } map tail l => [[2,3], [4,3,2,1]]
  • 48. Tails map __&tail, @l => ([2,3], [4,3,2,1]) sub tail ($head, @tail) { @tail } { no experimental 'signatures'; sub _ ($) { shift->($_) } sub __ ($) { [shift->(@$_)] } } map tail l => [[2,3], [4,3,2,1]]
  • 49. A thought... Scalar/list context Sigils ($, @, %) implicit $_ Optional parameters References and dereferencing Automatic type coercions Subroutine prototypes Type system
  • 51. Example: -- https://prime.haskell.org/wiki/Libraries/Proposals/MonadFail import qualified Data.Map as M en2it = M.fromList [ ("hello","ciao"), ("goodbye","ciao"), ("pasta","pasta") ] translate db k = let v = M.lookup k db in case v of Nothing -> fail "No translation" Just v' -> return v'
  • 52. Example: *Main> translate en2it "hello" "ciao" *Main> translate en2it "hello" :: Maybe String Just "ciao" *Main> translate en2it "hello" :: [String] ["ciao"] *Main> translate en2it "whipuptitude" *** Exception: user error (No translation) *Main> translate en2it "whipuptitude" :: Maybe String Nothing *Main> translate en2it "whipuptitude" :: [String] []
  • 53. To be fair... Perl: • Larry Wall: linguist, missionary • + jobbing programmers • pragmatic • magpie-like Haskell: • Decades of Comp Sci professors and PhD students • purity • experimentation
  • 54. Why are we* so terrified of types? en2it :: M.Map [Char] [Char] en2it = M.fromList [ ("hello","ciao"), ("goodbye","ciao"), ("pasta","pasta") ] translate :: (Monad m, Ord k) => M.Map k a -> k -> m a translate db k = let v = M.lookup k db in case v of Nothing -> fail "No translation" Just v' -> return v'
  • 55. Why are we* so terrified of types? en2it :: M.Map [Char] [Char] en2it = M.fromList [ ("hello","ciao"), ("goodbye","ciao"), ("pasta","pasta") ] translate :: (Monad m, Ord k) => M.Map k a -> k -> m a translate db k = let v = M.lookup k db in case v of Nothing -> fail "No translation" Just v' -> return v'
  • 56. Why are we* so terrified of types? “Programming in ML is very pleasant. More than almost any other language I know, you can just write down the definitions of the functions as they come into your head. You don't need to bother with declarations; everything is just figured out for you automatically. And you do get a lot of type errors, both actual failures and also places where the type emitted by the compiler is not what you thought it should be. But unlike in C or Pascal, every one of those errors indicates a real, serious problem in your program, not merely something you have to groan over and try to work around the compiler's stupidity yet again.” -- mjd http://perl.plover.com/classes/typing/notes.html
  • 57. Why are we* so terrified of types? [4, 8, 15, 16, 23, 42] :: [Int]
  • 58. Type terror: undefined values [4, 8, 15, undef, 16, 23, 42] :: [Panic!]
  • 59. Type terror: undefined values my %en2it = ( hello => “ciao”, goodbye => “ciao”, pasta => “pasta” ); my @l = map $en2it{$_}, (“hello", “monad", “pasta”); my @c = grep defined, @l; # (“ciao”, “pasta”)
  • 60. Type terror: undefined values -- data Maybe a = Just a | Nothing l = map (flip Map.lookup h) [“hello", “monad", “pasta”] -- [Just “ciao”, Nothing, Just “pasta”] c = catMaybes l -- [“ciao”, “pasta”]
  • 61. Type terror: signal values [1, undef, 2, “X”, 3, -5] # positive number: record # undef: no record found # “string”: processing instruction # negative number: record flagged for deletion
  • 62. Type terror: signal values records :: [Maybe Record] records = [ Just Record (Left 1), Nothing, Just Record (Left 2), Just Instruction “X” Just Record (Left 2), Just Record (Right 5)] data Record = Record (Either Int Int) | Instruction String
  • 63. Type terror: but! but! but! serialization (show) objects of a particular class (typeclasses) GADTs existential types dynamic introspection ...
  • 65. april.txt There is shadow under this red rock, (Come in under the shadow of this red rock), And I will show you something different from either Your shadow at morning striding behind you Or your shadow at evening rising to meet you; I will show you fear in a handful of dust.
  • 66. Grep for a string $ perl -ne ‘print if /shadow/’ < april.txt ???
  • 67. Grep for a string $ perl -ne ‘print if /shadow/’ < april.txt notaoneliner.hs: import Data.List main = interact ( unlines . (filter (a -> "shadow" `isInfixOf` a)) . lines ) $ runghc notaoneliner.hs < april.txt
  • 68. april.txt | grep shadow There is shadow under this red rock, (Come in under the shadow of this red rock), Your shadow at morning striding behind you Or your shadow at evening rising to meet you;
  • 69. Grep for a string $ perl -ne ‘print if /shadow/’ < april.txt hask.bash: if which ghc > /dev/null then function h { ghc -e "interact ($*)" Ust.hs ; } function hl { h "bylines ($*)" ; } function hw { h "bywords ($*)" ; } fi $ hl ‘filter (regexBool “shadow”)’ < april.txt
  • 70. Ust.hs https://wiki.haskell.org/Simple_Unix_tools https://ulissesaraujo.wordpress.com/tag/command/ {-# LANGUAGE NoMonomorphismRestriction #-} module Ust( bylines, bywords, showln, regexBool, uniq, rpt, take', drop', head', tail', tail10, tac, rev, rev_w, wc_c, wc_l, wc_w, space, unspace, remove, upper, clean, clean', clean'', blank, join, tr, tr_d, grep, grep_v, cksum ) where import Control.Monad.Instances; import Data.List; import Data.Char; import Data.Maybe; import Text.Printf; import System.Environment; import Text.Regex.Posix -- First, three helpers bylines f = (unlines . f . lines) bywords f = (unwords . f . words) showln = (++ "n") . show -- simple boolean regex matching regexBool r l = l =~ r :: Bool ...
  • 71. Uppercase $ perl -pe ‘$_ = uc’ < april.txt $ h upper < april.txt Ust.hs: upper = map toUpper
  • 72. april.txt | upper THERE IS SHADOW UNDER THIS RED ROCK, (COME IN UNDER THE SHADOW OF THIS RED ROCK), AND I WILL SHOW YOU SOMETHING DIFFERENT FROM EITHER YOUR SHADOW AT MORNING STRIDING BEHIND YOU OR YOUR SHADOW AT EVENING RISING TO MEET YOU; I WILL SHOW YOU FEAR IN A HANDFUL OF DUST.
  • 73. Sort $ perl -e 'print sort <>' < april.txt $ hl sort < april.txt
  • 74. april.txt | sort (Come in under the shadow of this red rock), And I will show you something different from either I will show you fear in a handful of dust. Or your shadow at evening rising to meet you; There is shadow under this red rock, Your shadow at morning striding behind you
  • 75. Sorted words $ perl -e 'print join " ", sort map { chomp; split } <>' < april.txt $ hw sort < april.txt
  • 76. april.txt | sort-words (Come And I I Or There Your a at at behind different dust. either evening fear from handful in in is meet morning of of red red rising rock), rock, shadow shadow shadow shadow show show something striding the this this to under under will will you you you you; your
  • 77. Bonus section #2 real world(ish) code
  • 78. Modelling TV programmes Brand: “Have I Got News For You?” Series: “3” Episode: “1” / HIGNFY123
  • 79. Modelling TV programmes Brand: “Have I Got News For You?” Series: “3” Episode: “1” / HIGNFY123 Brand: “Have I Got OLD News For You?” Series: “1” Episode: “5” / HIGNFY123
  • 80. Data modelling package Programme; use Moo; use Types::Standard qw/ Maybe Str /; has id => ( is => 'ro', isa => Maybe[Str] ); has id2 => ( is => 'ro', isa => Maybe[Str] ); package Brand; use Moo; extends 'Programme'; # ditto Series, Episode... type PrimaryId = Maybe String type AlternateId = Maybe String data Prog = Prog ProgType PrimaryId AlternateId deriving (Eq, Ord, Show) data ProgType = Brand | Series | Episode deriving (Eq, Ord, Show)
  • 81. The “Database” package Database; use Moo; use Types::Standard qw/ArrayRef HashRef InstanceOf/; has list => ( is => 'ro', isa => ArrayRef[InstanceOf["Programme"]], ... ); has graph => ( is => 'ro', isa => HashRef[InstanceOf["Programme"]], ... ); data Database = Database { list :: [Prog], graph :: M.Map Prog Prog }
  • 82. Get Hierarchy use experimental ‘signatures’; sub getHierarchy($self, $prog) { if (my $parent = $self->lookup($prog->id)) { return ($prog, $self->getHierarchy($parent)) } else { return $prog } } getHierarchy :: Database -> Prog -> [Prog] getHierarchy db p = let l = M.lookup p (graph db) in case l of Nothing -> [p] Just (parent) -> p : (getHierarchy db parent)
  • 83. Get Hierarchy use experimental ‘signatures’; use MooX::HandlesVia; has graph => ( is => 'ro', isa => HashRef[InstanceOf["Programme"]], handles_via => 'Hash', handles => { lookup => ‘get’ } ); sub getHierarchy($self, $prog) { if (my $parent = $self->lookup($prog->id)) { return ($prog, $self->getHierarchy($parent)) } else { return $prog } }
  • 84. Search for a programme sub search ($self, $prog1) { my sub match ($prog2) { return unless ref $prog1 eq ref $prog2; return unless $prog1->id or $prog1->id2; return unless $prog2->id or $prog2->id2; return unless $prog1->id or $prog2->id2; return unless $prog1->id2 or $prog2->id; return if $prog1->id and $prog2->id and $prog1->id ne $prog2->id; return if $prog1->id2 and $prog2->id2 and $prog1->id2 ne $prog2->id2; return 1; } return $self->filter(&match); }
  • 85. Search for a programme use experimental 'lexical_subs'; has list => ( is => 'ro', isa => ArrayRef[InstanceOf["Programme"]], handles_via => 'Array', handles => { filter => 'grep'} );
  • 86. Search for a programme search db p = filter (match p) (list db) where match (Prog t1 _ _) (Prog t2 _ _) | t1 /= t2 = False match (Prog _ Nothing Nothing) _ = False match _ (Prog _ Nothing Nothing) = False match (Prog _ Nothing _) (Prog _ _ Nothing) = False match (Prog _ _ Nothing) (Prog _ Nothing _) = False match (Prog _ (Just p1) _) (Prog _ (Just p2) _) | p1 /= p2 = False match (Prog _ _ (Just a1)) (Prog _ _ (Just a2)) | a1 /= a2 = False match _ _ = True