Inspired a little by: https://stackoverflow.com/questions/30977789/why-is-c-not-a-functional-programming-language
I found: Higher Order Perl
It made me wonder about the assertion that Perl is a functional programming language. Now, I appreciate that functional programming is a technique (much like object oriented).
However I've found a list of what makes a functional programming language:
- First Class functions
- Higher Order Functions
- Lexical Closures
- Pattern Matching
- Single Assignment
- Lazy Evaluation
- Garbage Collection
- Type Inference
- Tail Call Optimization
- List Comprehensions
- Monadic effects
Now some of these I'm quite familiar with:
Garbage collection, for example, is Perl reference counting and releasing memory when no longer required.
Lexical closures are even part of the FAQ: What is a closure? - there's probably a better article here: http://www.perl.com/pub/2002/05/29/closure.html
But I start to get a bit fuzzy on some of these - List Comprehensions, for example - I think that's referring to map
/grep
(List::Util
and reduce
?)
I anyone able to help me fill in the blanks here? Which of the above can Perl do easily (and is there an easy example) and are there examples where it falls down?
Useful things that are relevant:
Perl monks rant about functional programming
Higher Order Perl
C2.com functional programming definitions
First Class functions
In computer science, a programming language is said to have first-class functions if it treats functions as first-class citizens. Specifically, this means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures.
So in Perl:
Verdict: Natively supported
Higher Order Functions
With reference to this post on perlmonks:
Verdict: Natively supported
Lexical Closures
Within the perl FAQ we have questions regarding
What is a closure?
:This is explained perhaps a little more clearly in the article: Achieving Closure
Verdict: Natively supported
Pattern Matching
Dispatch tables are the closest approximation - essentially a hash of either anonymous subs or code refs.
Because it's
just
a hash, you can add code references and anonymous subroutines too. (Note - not entirely dissimilar to Object Oriented programming)Verdict: Workaround
Single Assignment
I'm not sure
perl
really does this. The closest approximation might be references/anonymous subs or perhapsconstant
.Verdict: Not Supported
Lazy Evaluation
Examples of lazy evaluation techniques in Perl 5?
And again, coming back to Higher Order Perl (I'm not affiliated with this book, honest - it just seems to be one of the key texts on the subject).
The core concept here seems to be - create a 'linked list' in perl (using object oriented techniques) but embed a code reference at your 'end marker' that evaluates if you ever get that far.
Verdict: Workaround
Garbage Collection
Perl does this via reference counting, and releasing things when they are no longer referenced. Note that this can have implications for certain things that you're (probably!) more likely to encounter when functional programming.
Specifically - circular references which are covered in
perldoc perlref
Verdict: Native support
Type Inference
Perl does implicitly cast values back and forth as it needs to. Usually this works well enough that you don't need to mess with it. Occasionally you need to 'force' the process, by making an explicit numeric or string operation. Canonically, this is either by adding 0, or concatenating an empty string.
You can overload a scalar to do different things in by using
dualvars
Verdict: Native support
Tail Call Optimization
Why is Perl so afraid of "deep recursion"?
It'll work, but it'll warn if your recursion depth is >100. You can disable this by adding:
But obviously - you need to be slightly cautious about recursion depth and memory footprint.
As far as I can tell, there isn't any particular optimisation and if you want to do something like this in an efficient fashion, you may need to (effectively) unroll your recursives and iterate instead.
Verdict: Native
List Comprehensions
Perl has
map
,grep
,reduce
.It also copes with expansion of ranges and repetitions:
So you can:
Verdict: Native (
List::Utils
is a core module)Monadic effects
... nope, still having trouble with these. It's either much simpler or much more complex than I can grok.
If anyone's got anything more, please chip in or edit this post or ... something. I'm still a sketchy on some of the concepts involved, so this post is more a starting point.
Really nice topic, I wanted to write an article titled something link "the camel is functional". Let me contribute with some code.
Perl also support this anonymous functions like