One of the things that I find fascinating about "modern" scripting languages
such as Perl and (gasp) Python is their support for things that you usually
only find in "functional" languages. (I'm not a formal student of programming
languages, I'm more like an armchair QB in the language leagues, so I hope
you'll forgive me if my terminology is off at certain points) By this, I mean
things like closures, the map() function, and so on. Not that they are by
any means restricted to functional languages, just that that's where they
tend to be, since the "type of thinking" that encourages their use tends to
be centered in the functional world.
So for example, even though any perl hacker can say:
sub make_adder {
my $add_this_much = shift;
return sub { return(shift(@_) + $add_this_much); }
} # End make_adder
my $function = make_adder(10);
print &$function(10),"\n";
You hardly ever see that kind of code outside of lisp, ML, and
those types of languages. (Simple example, anybody whose ever coded
lisp knows that it can get much hairier)
My question for other hackers out there is, do you ever find
yourself using this style of programming? Sure, the adventurous
of us have on occasion used map, but most people just stick to
foreach loops and so on. From most code I've read by other perl
programmers, they either studiously avoid it for some unknown reason,
or simply don't know about it at all.
Another question is: lisp and other similar languages have had a
whole lot of compiler research put into them to optimize the hell
out of functional programming constructs. The simplest example is
optimization of tail-recursive calls, which is quite easy and can
save ungodly amounts of time. Does perl do any of these optimizations?
If not, it makes me wonder why perl would support this "type" of
programming without exploiting the tricks. I'm definately glad that
it's there, but using it may not be a great idea if using it costs
a 5-fold increase in the running time of programs. :)
As a final observation in this random post, I was thumbing through
my well-worn copy of the Camel the other day, and I came across
a statement on map() that said something to the effect that foreach
and map were equivalent in most situations, the only difference being
that map() is for when you care about the list of results, and foreach
is mostly for when you don't care about the list of results. How
many newbies out there do you think are writing things like:
foreach $item (@list) {
# Do something complicated to $item
push(@results, $item);
}
--
David Allen
http://opop.nols.com/
> OK, call me a weirdo, but one of my interests of late has been functional
> programming and Perl.
> You hardly ever see that kind of code outside of lisp, ML, and
> those types of languages... My question for other hackers out there
> is, do you ever find yourself using this style of programming?
If you're into this kind of madness (;-), you might like to check out the
proposed addition to Perl 6 of generalized higher order functions:
http://tmtowtdi.perl.org/rfc/23.html
Damian
I use both. If it really is something complicated, then foreach is perhaps
more readable and easier to debug or modify. Where I frequently use map is
for things like "vector" operations :
@funcs = map {s/\^/**/;$_} @funcs; # convert ^ to **
or for initializing an array
@array = map {$vw[$_]**2*$rw[$_]} (0..$#vw);
--
Alan K. Jackson - BTC - Quantitative AVO Team
Shell E&P Technology and Research
voice :(713)245-7355 fax :(713)245-7492 snail :Box 481,Houston,Tx 77001
UUCP: ...!{uupsi}!shellus!ajackson INTERNET: ajac...@shellus.com
>OK, call me a weirdo,
You weirdo.
>but one of my interests of late has been functional
>programming and Perl.
>
>One of the things that I find fascinating about "modern" scripting languages
>such as Perl and (gasp) Python is their support for things that you usually
>only find in "functional" languages. (I'm not a formal student of programming
>languages, I'm more like an armchair QB in the language leagues, so I hope
>you'll forgive me if my terminology is off at certain points) By this, I mean
>things like closures, the map() function, and so on.
I would also classify "return values from functions serving as
arguments to another function" as a form of "functional programming".
>My question for other hackers out there is, do you ever find
>yourself using this style of programming?
Using the above as a valid form of "functional programming", you see
things like this all of the time:
foreach ( reverse sort @array ) {
"array name in list context" function returns list used as args to sort().
sort() returns list used as args to reverse().
Look Ma, no temp variables!
>How
>many newbies out there do you think are writing things like:
>
>foreach $item (@list) {
> # Do something complicated to $item
> push(@results, $item);
>}
All of them.
--
Tad McClellan SGML consulting
ta...@metronet.com Perl programming
Fort Worth, Texas
Of course. All the time. Besides being really cool as an
alternative form of OO, closures can be viewed as a kind of
macro capability for perl.
my @r; # result vector
my $loop = sub { ...
push @r, ...
return $bool;
};
for ( @inputs ) {
$loop->( $_ ) or last;
}
...
This is particularly nice when the closure code is very nasty,
and yet needs to access lexicals in the enclosing scope.
(Otherwise we'd just make a normal sub.)
And for callbacks, closures are virtually indispensable.
Compare with java and c++, which want "functional objects"
whose sole purpose in life is to contain a reference to a
function.
> a 5-fold increase in the running time of programs. :)
I don't think you'll see that. But you *will* see a significant
overhead for using OO fully in perl. Method lookups are costly.
--
John Porter
Aus des Weltalls ferne funken Radiosterne.
>OK, call me a weirdo, but one of my interests of late has been
>functional programming and Perl.
I don't normally conjure up anonymous functions and use them later on
(like your make_adder() example). But I do tend to write Perl
programs in a 'functional style' where most subroutines have no side
effects. This means you can then use the Memoize module to make your
program go a hundred times faster with very little effort - at least
for the type of stuff I write. (Memoize is a very handy module BTW -
IMHO it should be included in the standard perl distribution.)
>How many newbies out there do you think are writing things like:
>
>foreach $item (@list) {
> # Do something complicated to $item
> push(@results, $item);
>}
I know I am, because often the equivalent 'map' would look scary if
the subroutine is bigger than a couple of lines.
--
Ed Avis
ep...@doc.ic.ac.uk
I think you're right, and I don't think these powerful techniques are
as well-known or widespread as they should be.
There is an old joke that a dedicated Fortran programmer can write
Fortran programs in *any* language. Most programmers come to Perl
>From a unixy C-sh-awk sort of background, or are indoctrinated into
this mindset once they arrive. But Perl has features like closures
that are unavailable in C and which enable all sorts of approaches to
problems that are impossible in C. Consequently, most Perl
programmers are going around writing C programs in Perl, unaware that
it's possible to do much better.
In the past when I've written about some of these techniques the
response has been enthusiastic. Memoization is a good example. (See
http://www.plover.com/~mjd/perl/MiniMemoize/ for my TPJ article about
this.)
Right now I'm writing a book, possibly to be titled "Perl Advanced
Techniques Handbook", which will address these topics and techniques.
It will be published by Morgan Kaufmann next year and will also be
available on my web site. If you're interested, please visit
http://www.plover.com/~mjd/perl/book/