Is Python a functional programming language?
Is this a paradigm that is well supported by both the language syntax and the general programming APIs?
I heard that lambdas were limited to a single expression, and that other functional features were slated for removal in Python 3... is this the case or have I been misinformed?
Finally, even if Python supports functional features, is this a model that is used often in client/application code?
Kind regards,
Samuel
No. Python is a multi-paradigm language. But it does have functions (and
methods) as first-class objects.
> Is this a paradigm that is well supported by both the language syntax
> and the general programming APIs?
I'd say so, but it certainly depends on what functional language features
you desire.
> I heard that lambdas were limited to a single expression
... which is a good thing. An expression in Python can do pretty complex
things already. Not allowing more puts a limit to code readability degradation.
> and that other
> functional features were slated for removal in Python 3... is this the
> case or have I been misinformed?
No such functionality has been removed in Py3, and in fact, several core
language features were adapted to make functional programming easier and
more efficient.
> Finally, even if Python supports functional features, is this a model
> that is used often in client/application code?
From my point of view, yes. But the beauty is that Python is
multi-paradigm, so you're not restricted to functional language features.
Stefan
Depends on your definition of "functional programming language", but
well, not really. It's mostly an imperative, object-oriented (but not
pure-object) language. It has some restricted support for some
functional idioms but trying to use it a true FPL would be a waste of
time (both developper's and computer's).
> Is this a paradigm that is well supported by both the language syntax and the general programming APIs?
No.
> I heard that lambdas were limited to a single expression,
True.
> and that other functional features were slated for removal in Python 3...
False.
Some FP-inspired functions and types are moving from builtins to a
dedicated module, but they are still available.
> is this the case or have I been misinformed?
>
> Finally, even if Python supports functional features, is this a model that is used often in client/application code?
Once again, depends on your definitions of what's "functional". Some
FP-inspired idioms and features are definitly idiomatic, but that
doesn't make for true functional programming. Once again, trying to do
pure FP in Python would be fighting against the language.
It supports some aspects of functional programming but I wouldn't go as
far as to call it an FPL.
> Is this a paradigm that is well supported by both the language syntax
> and the general programming APIs?
I'd say "somewhat supported" rather than "well supported".
> I heard that lambdas were limited to a single expression, and that
> other functional features were slated for removal in Python 3... is
> this the case or have I been misinformed?
I think, some features were slated for removal, but after some
discussion they were moved to libraries instead of eliminated
completely.
> Finally, even if Python supports functional features, is this a model
> that is used often in client/application code?
That's more a question of the programmers than the programs. If you're
comfortable programming in functional style, that will tend to show
up in your python code. There are some contortions you have to do though.
If your goal is to engage in functional programming, you're better off
using a language designed for that purpose. Python is a pragmatic
language from an imperative tradition, that has some functional features
tacked on. Python is pleasant for imperative programming while letting
you make some use of functional style.
While your first sentence is spot-on, saying that functional features
are "tacked on" understates the case. Consider how frequently people
reach for list comps and gen exps. Function dispatch through dicts is
the standard replacement for a switch statement. Lambda callbacks are
common. Etc, etc, etc
--
Aahz (aa...@pythoncraft.com) <*> http://www.pythoncraft.com/
f u cn rd ths, u cn gt a gd jb n nx prgrmmng.
> Is Python a functional programming language?
Not in any meaningful sense of the term.
> Is this a paradigm that is well supported by both the language syntax and
> the general programming APIs?
No.
> I heard that lambdas were limited to a single expression,
Yes. In a functional language that wouldn't be a problem, as there's no
limit to the complexity of an expression. Python's expressions are far
more limited, which restricts what can be done with a lambda.
> and that other
> functional features were slated for removal in Python 3... is this the
> case or have I been misinformed?
I don't know about this.
> Finally, even if Python supports functional features, is this a model that
> is used often in client/application code?
Not really. List comprehensions are probably the most common example of
functional idioms, but again they're limited by Python's rather limited
concept of an expression.
I'm no expert of functional programming at all, but I read many times
(from famous programmers) that Python is very lisp-like, but with a
more conventional syntax.
For example, Paul Graham and others have some interesting views on
this subject: http://www.prescod.net/python/IsPythonLisp.html
That doesn't mean python can compete with other purely functional
languages, but it's probably as functional as it can be for a more
conventional, multiparadigm language.
Luis
Kind regards,
Samuel
Ben Lippmeier made the interesting claim that one of the defining
characteristics of functional programming is type systems based on the
Curry-Howard correspondence. By that standard I think even Scheme
(perhaps the grandaddy of functional languages) wouldn't qualify.
I do think of Scheme as a functional language, but of Python and Lisp as
imperative languages with functional aspects.
I like learnyouahaskell.com if you want to get some exposure to Haskell,
probably the archetypal functional language these days. I've been
fooling with it on and off for the past couple years. I'm still not
convinced that it's that good a vehicle for practical general purpose
software development, but there are some specific areas where it works
out just beautifully. And in terms of the challenges it presents and
the amount I've learned from it, it's one of the most interesting things
I've done as a programmer in as long as I can remember. It really is
mind altering.
> Python is a pragmatic language from an imperative tradition ...
I thought the opposite of “functional” was “procedural”, not “imperative”.
The opposite to the latter is “declarative”. But (nearly) all procedural
languages also have declarative constructs, not just imperative ones
(certainly Python does). Presumably an “imperative” language would not.
> But the beauty is that Python is multi-paradigm ...
The trouble with “multi-paradigm” is that it offends the zealots on all
sides. It’s like saying that, to effect a compromise among multiple
conflicting monotheistic religions, we should create a polytheistic amalgam
of them.
The Romans were pretty successful in doing so, for several hundred years.
Let's see if Python will conquer and rule for that long.
Stefan
Offhand I can't tell that imperative and procedural mean something
different. Both basically mean that the programmer specifies a series
of steps for the computer to carry out. Functional languages are mostly
declarative; for example, an expression like
x = 3
is called an "equation" rather than an "assignment". It declares "x is
equal to 3", rather than directing x to be set to 3. If someplace else
in the program you say "x = 4", that is an error, normally caught by
the compiler, since x cannot be equal to both 3 and 4.
Just to play devil's advocate, I will notice that list comps and gen
exps are not really
functional (a generator has a state that changes at each call of
next). A functional language
would use streams instead. Function dispatch through dicts is very
lame compared to pattern matching. Lambdas are restricted. There is no
tail call optimization. Definitively Python functional features are
"tacked on" with respect to a language defined to be functional.
Having said that, the functional features are still usable and one can
use a functional style
in Python if she wants to (module a few caveats).
Python has only two: 'global' and now 'nonlocal'.
There are also two meta-declarations: the coding cookie (which
would/will go away in an entirely unicode world) and future imports
(which are effectively temporarily gone in 3.x until needed again).
Newbies sometimes trip over def and class being imperative (executable)
statments rather than declarations.
Terry Jan Reedy
Er, declarative programming has nothing to do with variable declarations.
http://en.wikipedia.org/wiki/Declarative_programming
Cheers,
Chris
--
http://blog.rebertia.com
I found it hard to get much from the vague description. I will leave it
to Lawrence to list what *he* thinks are 'declarative constructs' in Python.
> Offhand I can't tell that imperative and procedural mean something
> different. Both basically mean that the programmer specifies a series of
> steps for the computer to carry out. Functional languages are mostly
> declarative; for example, an expression like
> x = 3
> is called an "equation" rather than an "assignment". It declares "x is
> equal to 3", rather than directing x to be set to 3. If someplace else in
> the program you say "x = 4", that is an error, normally caught by the
> compiler, since x cannot be equal to both 3 and 4.
In both ML and Haskell, bindings are explicitly scoped, i.e.
let x = 3 in ... end (ML)
let x = 3 in ... (Haskell)
If you bind a variable which is already bound, it introduces a new binding
which "overrides" the existing binding. It won't generate an error.
The key point is that a variable has a fixed (constant) value at any
specific point in the program. The value depends upon which bindings are
in scope at that point, and not on the "state" of the variable at a
particular point in time.
E.g. (Haskell):
test y = let x = 3
in let f y = x + y
in let x = 5
in f y
test 5
8
x has the value 3 at the point that f is defined, so that's the value
which is used when f is used.
Variable declarations have everything to do with declarative programming.
An imperative way to create a variable is to allocate the memory
yourself and instead of "variables" you have just registers and the
memory; fortunately all popular imperative languages (wisely) picks up
declarative syntax from the declarative paradigm. In Python, the regular
def/class is a pseudo-declaration, but it is also possible to
*imperatively/procedurally* create a class by calling type() and a
function by passing a __call__() to type()'s __dict__ argument.
A fully declarative language just turn everything into declarations
including the "business logic" of the application (and of course,
variable declaration).
>> But the beauty is that Python is multi-paradigm ...
>
> The trouble with “multi-paradigm” is that it offends the zealots on
> all sides.
Is that how you view people who like languages to exhibit a degree of
consistency? Some people would prefer to have a manageable set of rules
rather than having to remember the results of all of the possible
combinations of interactions between language features.
I'm not talking about nested bindings. I'm talking about two different
bindings of the same symbol in the same scope:
$ cat meow.hs
x = 3
x = 4
$ ghc meow.hs
meow.hs:2:0:
Multiple declarations of `Main.x'
Declared at: meow.hs:1:0
meow.hs:2:0
> I like learnyouahaskell.com if you want to get some exposure to Haskell,
> probably the archetypal functional language these days. I've been
> fooling with it on and off for the past couple years. I'm still not
> convinced that it's that good a vehicle for practical general purpose
> software development, but there are some specific areas where it works
> out just beautifully. And in terms of the challenges it presents and
> the amount I've learned from it, it's one of the most interesting things
> I've done as a programmer in as long as I can remember. It really is
> mind altering.
Completely agree with you. Learnyouahaskell.com is as good as it gets
to learn haskell: haven't had so much fun learning a language since I
picked up python :-)
For similarly mind-altering pleasure, have a look at pure-lang [http://
code.google.com/p/pure-lang/] which describes itself as:
"Pure is a modern-style functional programming language based on term
rewriting. It offers equational definitions with pattern matching,
full symbolic rewriting capabilities, dynamic typing, eager and lazy
evaluation, lexical closures, built-in list and matrix support and an
easy-to-use C interface. The interpreter uses LLVM as a backend to JIT-
compile Pure programs to fast native code."
Enjoy!
AK
> On Tue, 11 May 2010 23:13:10 +1200, Lawrence D'Oliveiro wrote:
>
>>> But the beauty is that Python is multi-paradigm ...
>>
>> The trouble with “multi-paradigm” is that it offends the zealots on
>> all sides.
>
> Is that how you view people who like languages to exhibit a degree of
> consistency?
Interesting, I never knew “consistency” was a synonym for “faith”...
> Some people would prefer to have a manageable set of rules
> rather than having to remember the results of all of the possible
> combinations of interactions between language features.
What are you accusing Python of, exactly?
It may be worth noting the interactive behaviour:
$ ghci
GHCi, version 6.8.2: http://www.haskell.org/ghc/ :? for help
Loading package base ... linking ... done.
Prelude> let x = 7
Prelude> let f y = x + y
Prelude> f 3
10
Prelude> let x = 5
Prelude> f 3
10
The main point is that variables aren't mutable state.
An important secondary point is that, unlike Python, free (global)
variables in a function body are substituted when the function is defined,
not when it's called.
Ahem (emphasis mine):
"""
==This syntax is *ghci-specific*==
The syntax for 'let' that ghci accepts is not the same as we would use
at the “top level” of a normal Haskell program.
"""
-- http://book.realworldhaskell.org/read/getting-started.html
>> Some people would prefer to have a manageable set of rules rather than
>> having to remember the results of all of the possible combinations of
>> interactions between language features.
>
> What are you accusing Python of, exactly?
I'm not accusing it of anything, exactly. I'm just pointing out that there
are entirely pragmatic reasons for disliking "multi-paradigm" languages.
LOL
> > I heard that lambdas were limited to a single expression,
>
> Yes. In a functional language that wouldn't be a problem, as there's no
> limit to the complexity of an expression. Python's expressions are far
> more limited, which restricts what can be done with a lambda.
One very annoying thing in Python is the distinction between
statements and expressions.
Ever since learning LISP (well, Scheme) in S&ICP I find myself
frequently annoyed by this pointless distinction, started by
C (or earlier), and propogated without much thought.
Often I'll want to write a lamda that, say, prints something, or
modifies a global variable, and find that, well, it's either
impossible or beyond my interest in figuring it out.
It appears there is finally a ternary operator (for making if/else
into "expressions"):
http://en.wikipedia.org/wiki/Ternary_operation#Python
Maybe it will grow on me - it makes sense in English, but on
first glance I thought the programmer suffered from dyslexia.
To be fair, it appears that Python's whitespace-sensitive syntax sort
of precludes the "make a complex function on one line" that is typical
of languages which don't have statement/expression distinctions, but
I'm not convinced it couldn't be solved, perhaps by allowing anonymous
functions to span multiple lines, just like named functions.
> > Finally, even if Python supports functional features, is this a model that
> > is used often in client/application code?
>
> Not really. List comprehensions are probably the most common example of
> functional idioms, but again they're limited by Python's rather limited
> concept of an expression.
Map/reduce, lambda, apply, that kind of stuff... kinda similar to
functional languages.
But "statements lack any side effects"? No way.
In fact, a common distinction you'll see observed, but not always, is
that "statements may have side effects, expressions do not".
For some definitions of "functional language", there are no
side-effects, so there is no need for a statement which doesn't
evaluate to a value, so there is no need for a statement/expression
distinction, so everything is an expression.
You may have seen Paul Graham's other article about Python and LISP:
http://www.paulgraham.com/icad.html
Upon re-skimming it, I find myself wondering if I got the
expression/statement annoyance from his pages, or from my own
experience. I can't remember :-) Probably it was an annoyance that I
hadn't put my finger on until he spelled it out for me, like a
splinter in my mind :-)
He obliquely references my other pet peeve, the global/class/local
distinction, completely ignoring arbitrarily-nested lexical scoping.
From what I've read in this thread, there's a recent "nonlocal"
declaration that sounds like it might accomplish something useful in
this regard.
(I still haven't figured out how he managed to use lexical closures in
his web server to allow one web page to use another to allow the user
to select and return a value, like a color from a color wheel, unless
he implemented his own web server in LISP, since HTTP is stateless).
I really like Scheme's clean syntax (never learned Common LISP, sorry,
too much to remember) but frankly, I've never looked at a problem and
said, "you know, Scheme would be perfect for this". Maybe if I was
writing a program that did optimizing transformations on abstract
syntax trees, or something. And since Scheme has never come in handy,
I never bothered with Common LISP. I feel similarly about ML, OCAML
and Haskell... maybe one day when I'm bored, not today, not this
project.
So in the end, I find myself using python more than anything else,
fully acknowledging its warts. I used to admire its simplicity, but
now with decorators, iterators, generators, metaclasses, and the
proliferation of special method names, I have to wonder if that still
holds true... certainly I understand 90+% of python programs, but
do I understand that proportion of the constructs?
PS: Why do people call LISP object-oriented? Are they smoking crack?
No classes, no methods, no member variables... WTF?
--
A Weapon of Mass Construction
My emails do not have attachments; it's a digital signature that your mail
program doesn't understand. | http://www.subspacefield.org/~travis/
If you are a spammer, please email jo...@subspacefield.org to get blacklisted.
One extremely valuable thing in Python is the distinction between
statements and expressions.
In fact, given the semantic similarity between Python and Lisp, I would
argue that Python having the distinction is partly responsible for its
popularity.
> One very annoying thing in Python is the distinction between
> statements and expressions.
GvR regards it as a feature, claiming that research in the 1980s showed
that the syntactic heterogeneity aided comprehension. I believe this is
true for me.
> Ever since learning LISP (well, Scheme) in S&ICP I find myself
> frequently annoyed by this pointless distinction,
You have missed the very important distinction generally reflected in
the statement/expression divide. Some code is meant to be evaluated
immediately and some is meant to be quoted for later evaluation. In
general (yes, there are some exceptions), Python statements are either
restricted gotos or statements that implicitly quote part of the code in
the statement. And in general, with a few exceptions, including lambda,
expressions are completely and immediately evaluated. Changing print and
exec from statements to functions made Py3 more consistent in this
respect this distinction.
In List, one either quotes explicitly or must remember that certain
'functions' are not really functions but are 'special functions' or
'macros' that implicitly quote the code, just like Python statements do.
Simple statement example:
name = expression
The name is implicitely quoted. Behind the scenes, this is a function
call. At module level, one can write the call explictly, with explicit
quotes:
globals().__setitem__('name', expression)
If the statement form annoys you, use the expression equivalent. (Within
functions, however, you do not have this choice in CPython because, for
efficiency, function local namespaces are not Python objects and hence
there is no Python function to directly manipulate them.)
In Lisp, the expression would be something like
(set 'name expression)
Compound statement example:
def f(a, b=3);
'doc for a'
<several lines of body code>
The def keyword, default arg expression(s), and doc string are evaluated
immediately. The function name, parameter names, and body code must be
quoted somehow. In Python, this is done implicitly as signalled by def
being a statement keyword rather than a function name. Behind the
scenes, the def statement is implemented mainly by two function calls:
compile the (quoted) code and create a function object. I believe that
one could define functions with explicit calls rather than a statement,
but it would be much more work and require explicit quotes. Turning a
class statement into an exec() and type() call is easier, but still
extra work.
Terry Jan Reedy
Haskell has whitespace-based syntax like Python (you can alternatively
use curly braces). Their term for it is "layout". You can
alternatively use curly braces and semi-colons. I'd have to say that
Haskell's indentation rules are a bit harder to understand than Python's
at first.
> PS: Why do people call LISP object-oriented? Are they smoking crack?
> No classes, no methods, no member variables... WTF?
Maybe because Common Lisp has a strong support for object-oriented
programming.
Peter Seibel: Practical Common Lisp
Generic functions and methods (chapter 16)
http://www.gigamonkeys.com/book/object-reorientation-generic-functions.html
Classes (chapter 17)
http://www.gigamonkeys.com/book/object-reorientation-classes.html
Paul Graham: On Lisp
Object-Oriented Lisp (chapter 25)
http://www.bookshelf.jp/texi/onlisp/onlisp_26.html#SEC156
Wikipedia: Common Lisp Object System