From: Xah Lee on
On Apr 28, 4:19 am, Zadirion <zadir...(a)gmail.com> wrote:
> I'm new to functional programming, just barely getting the hang of it,
> I hope.
> So from what I understand, side-effects are not desirable when writing
> functional code. This means setq and variables in general should be
> avoided.
>
> But suppose I have a list and I need its length not once, but twice or
> more inside my function. If i'm not supposed to use a variable to
> store the length of the list, how am I supposed to reuse the result of
> that computation (the length determining)?
>
> (setq len (length mylist))
> (concatenate 'list (subseq 0 (/ len 2)) (subseq (+ (/ len 2) 1) len))
>
> How am i supposed to achieve this without using the len variable? Or
> am I incorrectly understanding what functional programming is all
> about? (I come from a c++ background so imperative programming is all
> I know for now) I could call length each time where needed, but that
> is obviously very inefficient and unnecessary.
>
> Many thanks,
> Gabriel

using local variable is fine. In lisp, it's like this:

(let (var1 var2 ...)
(setq var1 val1)
(setq var2 val2)
...
body
)

the key to remember about functional programing, is that the behavior
of your function should only depends on input, and that usually means
just the argument it receives. Using local variable is still
functional programing, as long as those variables don't leak, such as
global variables, and they shouldn't keep a state (such as in OOP).

However, the quest to avoid using variables is of theoretical interest
as well as a interesting programing program of a given language.

there are, academic language that does not have variables at all.
(though, off hand i don't know any. Web search for the word
“cominator” and you'll find examples.)

without a pure functional lang such as Haskell, avoiding variable is
difficult or impossible.

Even Haskell, for practical reasons, have local variables, just that
you can't change a variable's value. (effectively, they are local
“constants”)

In a less strict functional lang OCaml/F#, you can have variables that
changes value.

Lisp, as a functional lang, is even less strict than the above ones.
Also, it is IMPOSSIBLE to write any non-trivial function without using
variables, mutable or not.

In Mathematica, which i've coded for over 10 years, am among the
world's say top 100 expert, i often avoid using ANY variables at all.
It is not difficult to do. Basically, any function is all just a
sequence of application of functions. Though, the code get complicated
for average programers to understand, but simple if you understand the
function application paradigm.

Mathematica can be considered as a lisp variant. However, lisps
(Common Lisp, Scheme Lisp, Emacs Lisp, Arc lisp, NewLisp, all can not
avoid variables. I'm pretty sure this includes Clojure lisp, Qi lisp,
or, that these two still would cost far more effort or un-natural code
to avoid vars than Mathematica)

Part of the reason why it is impossible to avoid using variables in
lisp,
i'v detailed in the past, in these essays:

• The Concepts and Confusions of Prefix, Infix, Postfix and Fully
Nested Notations
http://xahlee.org/UnixResource_dir/writ/notations.html

• Fundamental Problems of Lisp
http://xahlee.org/UnixResource_dir/writ/lisp_problems.html

In fact, trying code code in no-variable functional style is part of
the reason i discovered these lisp problems.

Look for the sections that discuss the nesting problem. The nesting
syntax is part of the problem, but there are other reasons that i
haven't discussed in the above essays. Maybe i'll write a detailed
essay about this topic in the future, but now just from the top of my
head ... (was going to write perhaps a one sentence description of
what i thought are the other reasons other than the nesting syntax,
because the problem cannot theoretically be just syntax... but am
tired, and i think the issue is more complex then i can think now...
will need to think about this another time)

Xah
∑ http://xahlee.org/

☄
From: Tim Bradshaw on
On 2010-04-29 02:28:59 +0100, RG said:

> Lisp is not considered functional because every form returns a value.
> First, it is clearly not true that every form returns a value. You
> don't even need to introduce the ambiguous case of (values). There are
> many forms in CL that don't return anything, notably GO, THROW, and
> ERROR.

Even this is a red herring. The important thing (not about
being-a-functional-language but about being-a-Lisp) is that it's an
*expression language*: There are no statements in Lisp. What that
means is that if you can say x, you can say, for instance, (let ((y x)
....) freely (and this is true even for things like GO: Y will never
actually be bound to anything because control will have been
transferred, but it is syntactically a valid expression. What people
actually mean when they say "everything returns a value" (which is
false) is "everything is an expression".

This is quite distinct from C, say: I can say "if (x) then; else;", but
that's a *statement* not an expression, so I can't say "int foo = (if
(x) then; else;);" for instnace: indeed there is a whole construct in C
just for this: I have to say "int foo = (x? then : else);".

What this buys you is syntactic composabilty: you can freely compose
expressions with the result being another expression. In the above
case, I can take x and make (let ((y x)) ...), and I can quite happily
then have (let ((z (let ((y x)) ...))) ...), and so on.

And what *that* gets you turns out to be macros. People often wonder
if you could have a language "like C but with macros" and assume that
the thing that makes this difficult is syntax: it's not, it's the lack
of syntactic composability. It's not very difficult to write a front
end which has an s-expression syntax but the semantics of C:

(define-function (foo int) ((a int))
(if (bar a)
(return (+ a 1))
(return (- 1 a))))

and now you can use macros easily. Or you think you can until you find
that things like this are not valid:

(define-function (foo int) ((a int))
(return (+ a
(if (bar a) 1 -1))))

So you now need a whole bunch of idiosyncratic
this-is-a-statement/this-is-an-expression rules which are just endless
pain and make writing robust macros very hard.

Note in the above that I grounded everything on some undefined "x"
which was an expression. Expressions can have parts which are not
expressions: for instance in (let ((x 1)) ...) ((x 1)) is not an
expression, and neither is "FOR" in (loop for x from 1 below n ...).

From: RG on
In article <4bd929bb$0$273$14726298(a)news.sunsite.dk>,
"Captain Obvious" <udodenko(a)users.sourceforge.net> wrote:

> R> The reason Lisp is considered a functional language is that it has
> R> lexical closures as first-class data structures.
>
> A bit of problem here is that most modern programming languages have them.
> Python and JavaScript always had them.

Actually, Python didn't get them until version 2.2:

http://www.python.org/dev/peps/pep-0227/

> They were added relatively recently into C#, PHP, Delphi.
> There are proposals to add them into Java and C++.
>
> Should we consider all these languages functional? I don't think so. That
> would be totally meaningless.

I disagree. It depends on how you define functional language. There
are two reasonable definitions:

1. A functional language is one that supports programming in a
functional style. On this definition, being a functional language is
not a dichotomy, it's a continuum, and all of these languages are to
some extent functional.

2. A functional language is one that forces you to program in a
functional style. On this definition, none of these languages are
functional, including Lisp.

I personally prefer definition 1, though I don't really care to quibble
over terminology. But there is no reasonable way that you can say that
Lisp is definitively a functional language while Python and Javascript
are definitively not. The best you can do is argue that Lisp's support
for functional programming is better than the others.

> R> That's really all you need to do functional programming.
>
> Well, ok, you can do functional programming in all those languages I've
> listed above.
> But another question is -- do you want to? Is that a preferred style?

Sure. Why not? I write functional code in Python all the time. It's
annoying, but no more so than any of the zillion other annoyances that
coders have to face on a daily basis. And Python has some built-in
features (notably iterators and list comprehensions) that make
functional programming easier than in Lisp.

rg
From: Didier Verna on
RG <rNOSPAMon(a)flownet.com> wrote:

> I disagree. It depends on how you define functional language. There
> are two reasonable definitions:
>
> 1. A functional language is one that supports programming in a
> functional style. On this definition, being a functional language is
> not a dichotomy, it's a continuum, and all of these languages are to
> some extent functional.
>
> I personally prefer definition 1

Yup. The only definition that /should/ stand is: functional = supports
functions as first class citizens, as per Christopher Strachey's
definition. And support for any paradigm is indeed a continuum.

I also find particularly annoying when people assume that functional =
purely functional. That's the kind of vocabulary fuzziness that leads to
comments I've heard too often like:

<C guy>:
Lisp? Ah yeah, that's this weird functional language with lots of parens...

<Haskell guy>:
Lisp? Ah yeah, that's this weird imperative language with lots of parens...

--
Resistance is futile. You will be jazzimilated.

Scientific site: http://www.lrde.epita.fr/~didier
Music (Jazz) site: http://www.didierverna.com
From: Tamas K Papp on
On Thu, 29 Apr 2010 06:55:24 -0700, RG wrote:

> coders have to face on a daily basis. And Python has some built-in
> features (notably iterators and list comprehensions) that make
> functional programming easier than in Lisp.

I don't know Python that well. Could you please give an example? I
am curious whether those constructs give something extra, and if so,
whether one could implement them in CL.

Thanks,

Tamas