Prev: Searching some references
Next: Comparing Lisp to Python, what you consider more important:speed or macros.
From: Xah Lee on 29 Apr 2010 05:03 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 29 Apr 2010 09:02 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 29 Apr 2010 09:55 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 29 Apr 2010 10:21 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 29 Apr 2010 10:36
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 |