I was just wondering what the principle feature of a FUNCTIONAL programming
language is????.
Thanks for any help.
If just one feature: computation proceeds by equational substitution?
But maybe that's defines 'declarative'.
Best regards,
Jon C.
--
Jonathan G Campbell BT48 7PG jg.ca...@ntlworld.com 028 7126 6125
http://homepage.ntlworld.com/jg.campbell/
I would suggest "no side-effects", but my knowledge is limited as I
have only recently started learning Haskell. My comments below are
probably too sweeping, and too simplistic, and so I hope someone more
learned in FP will correct the following for both our benefit!
What I mean by "no side-effects" is that a function will always
evaluate to the same result if it is given the same inputs. (And the
only way to pass data to a function is as a parameter). Because of
this guarantee, functions don't have to be evaluated until their
result is actually needed, and only as far as is necessary.
This also leads to treating functions as just another piece of data to
be passed around and combined at will, thereby enabling programmers to
think about solutions to problems at a "higher" level.
This is completely different way of thinking when compared to
IMPERATIVE programming languages, in which statements are executed
specifically for their side-effects, such as altering the value of a
variable held in some memory location.
In an imperative language, running the same function twice can result
in different values depending on changes that have taken place
elsewhere. This makes it harder to see that a program is correct.
Imperative languages do have the advantage that they are closer to the
way the hardware is programmed, although modern CPUs are so fast this
isn't really an issue any more.
Program Correctness is vital in our increasingly wired world. FP
languages make it substantially easier to reason about the program and
whether it is correct. Imperative languages on the whole do not,
(although one honourable exception to this is Eiffel, with its Design
by Contract philosophy).
I hope this helps, and look forward to any further comments...
> I would suggest "no side-effects", but my knowledge is limited as I
> have only recently started learning Haskell.
I use very often Clean, but I didn't really grasp the benefits of "side
effect free" so far. Without any ulterior-motive: Maybe someone can give
me an example which will enlightenment me.
What I more love (and maybe this is interwoved with side-effect-free):
g:: !Int !Real -> *{#Real}
g s d =...
Surely, it is not always required to give strictness (type) information
but giving strictness (type) information helps me a lot in reading
legacy Clean code. A quick look is enough and I know at least
superficial what the function is behaving like. This is one reason why I
moved to Clean for scientific calculations. Matlab or Yorick (or IDL...)
are good at graphics and therelike but it is really hard to read code,
when one does not know what is going on:
g(s,d)
There "a" could be an array or real or integer in Yorick. And even
commenting would not be of great help, because it is hard to have the
comments always up-to-date.
This is not specifically about functional programming, but I think there
is a great advantage in strongly-typed languages. This is a reason why I
do not really like Lisp (and the possibility to give type information in
Lisp is --in my opinion-- not as elegant as with Clean).
S. Gonzi
> David Basil Wildgoose wrote:
>
>
>>I would suggest "no side-effects", but my knowledge is limited as I
>>have only recently started learning Haskell.
>>
>
> I use very often Clean, but I didn't really grasp the benefits of "side
> effect free" so far. Without any ulterior-motive: Maybe someone can give
> me an example which will enlightenment me.
One benefit I can think of is that a compiler can do a lot of nice
optimizations. E.G. if you have this C++ code, like
int a[10000];
for (int i=1; i< 10000; i++)
a[i]=f();
If you know that there are no side effects you can write
int a[10000];
int r = f();
for (int i=1; i< 10000; i++)
a[i]=r;
C++ compilers can't do this, because they can't be sure that f() has no
side effects.
Coming from C++, these are the properties of functional languages which
got me interested in this paradigm.
Andreaa
I would be quite surprised if an optimizing C++ compiler couldn't figure
this out (and if the function f were in the same source file).
--
/Times-Bold 40 selectfont/n{moveto}def/m{gsave true charpath clip 72
400 n 300 -4 1{dup 160 300 3 -1 roll 0 360 arc 300 div 1 1 sethsbcolor
fill}for grestore 0 -60 rmoveto}def 72 500 n(This message has been)m
(brought to you by the)m(letter alpha and the number pi.)m(David Feuer)
m(David...@brown.edu)m showpage
David Feuer wrote:
>
> Andreas Schlapbach wrote:
> > One benefit I can think of is that a compiler can do a lot of nice
> > optimizations. E.G. if you have this C++ code, like
> >
> > int a[10000];
> > for (int i=1; i< 10000; i++)
> > a[i]=f();
> >
> > If you know that there are no side effects you can write
> >
> > int a[10000];
> > int r = f();
> > for (int i=1; i< 10000; i++)
> > a[i]=r;
> >
> > C++ compilers can't do this, because they can't be sure that f() has no
> > side effects.
> >
> > Coming from C++, these are the properties of functional languages which
> > got me interested in this paradigm.
>
> I would be quite surprised if an optimizing C++ compiler couldn't figure
> this out (and if the function f were in the same source file).
>
How?? It is undecidable...but even if you do it based on syntax
alone, it is very difficult, and probably most every function
would not qualify, even if it is not side effecting.
(By "based on syntax", i mean I check f and see
if the text contains any pointers/references, and then check if any
'primitive' IO functions are used, and then check recursively all
the functions f calls....)
>Andreas Schlapbach wrote:
>> One benefit I can think of is that a compiler can do a lot of nice
>> optimizations. E.G. if you have this C++ code, like
>>
>> int a[10000];
>> for (int i=1; i< 10000; i++)
>> a[i]=f();
>>
>> If you know that there are no side effects you can write
>>
>> int a[10000];
>> int r = f();
>> for (int i=1; i< 10000; i++)
>> a[i]=r;
>>
>> C++ compilers can't do this, because they can't be sure that f() has no
>> side effects.
>>
>> Coming from C++, these are the properties of functional languages which
>> got me interested in this paradigm.
>
>I would be quite surprised if an optimizing C++ compiler couldn't figure
>this out (and if the function f were in the same source file).
Most C++ compilers don't do this kind of analysis,
because doing it effectively for languages like C++ is very difficult.
Note that it's not enough just that the source code for f() be visible
to the compiler. The compiler also needs to know that none of the
functions that f() calls have any side effects. It also needs to know
that the result of f() doesn't depend on the value of variables which
are modified during the loop.
--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
> Most C++ compilers don't do this kind of analysis,
> because doing it effectively for languages like C++ is very difficult.
>
> Note that it's not enough just that the source code for f() be visible
> to the compiler. The compiler also needs to know that none of the
> functions that f() calls have any side effects. It also needs to know
> that the result of f() doesn't depend on the value of variables which
> are modified during the loop.
Ok. I was thinking about the really simple case of a function which
takes some arguments and does some (easily proved side-effect free)
stuff to them, and returns the answers, without depending on the values
of any global variables.
David Feuer <David...@brown.edu> writes:
>Ok. I was thinking about the really simple case of a function which
>takes some arguments and does some (easily proved side-effect free)
>stuff to them, and returns the answers, without depending on the values
>of any global variables.
If it's that simple (often called a "leaf" function), chances are the
C++ compiler implements it specially anyway. Most of the time, it can
avoid most of the overhead you would expect with a "normal" function
call, like setting up a stack frame. So the speedup won't be as great
as you might expect for a more complex function which just happens to
be pure.
Cheers,
Andrew Bromage
Ronald Legere wrote:
> How?? It is undecidable...but even if you do it based on syntax
> alone, it is very difficult, and probably most every function
> would not qualify, even if it is not side effecting.
> (By "based on syntax", i mean I check f and see
> if the text contains any pointers/references, and then check if any
> 'primitive' IO functions are used, and then check recursively all
> the functions f calls....)
On the other hand... this is not to say that this requires a functional
language. IT is quite possible (I think Eiffel does this) to have
two different kinds of functions (say 'Functions' and 'Procedures' or
something) and require that Functions have no side effects (guaranteed
only by the programmer, much as is the case with many eager functional
languages...). Or have some kind of annotation. Whatever.
> On the other hand... this is not to say that this requires a functional
> language. IT is quite possible (I think Eiffel does this) to have
> two different kinds of functions (say 'Functions' and 'Procedures' or
> something) and require that Functions have no side effects (guaranteed
> only by the programmer, much as is the case with many eager functional
> languages...). Or have some kind of annotation. Whatever.
In such a language, it should generally be possible to ensure that
"functions" do not have side effects: don't let them! Allow them only
to mutate local variables and call other functions! You could even put
on an additional restriction that they can only access their arguments
and local variables, for certain purposes.
> IT is quite possible (I think Eiffel does this) to have two different
> kinds of functions (say 'Functions' and 'Procedures' or something)
> and require that Functions have no side effects (guaranteed only
> by the programmer,
Eiffel's functions can depend on the state and return different values
in different times. The convention is only to not let them have side
effects, but it's not enough to make them referentially transparent
and hoist out of loops.
--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^
QRCZAK
> Eiffel's functions can depend on the state and return different values
> in different times. The convention is only to not let them have side
> effects, but it's not enough to make them referentially transparent
> and hoist out of loops.
>
I know nothing of Eiffel. I am just saying that it is possible for a
compiler to enforce these properties. You could have a language with
three or more classes of procedures with varying levels of "purity".
(first-class function would likely make things harder....)
> I know nothing of Eiffel. I am just saying that it is possible for a
> compiler to enforce these properties.
Eiffel doesn't try to enforce this - it's only a convention.
>Fergus Henderson wrote:
>
>> Most C++ compilers don't do this kind of analysis,
>> because doing it effectively for languages like C++ is very difficult.
>>
>> Note that it's not enough just that the source code for f() be visible
>> to the compiler. The compiler also needs to know that none of the
>> functions that f() calls have any side effects. It also needs to know
>> that the result of f() doesn't depend on the value of variables which
>> are modified during the loop.
>
>Ok. I was thinking about the really simple case of a function which
>takes some arguments and does some (easily proved side-effect free)
>stuff to them, and returns the answers, without depending on the values
>of any global variables.
There's very little in C++ that falls into the category of "easily
proved side-effect free". For example, anything involving dynamic
memory allocation can't easily be proved side-effect free, since the
user is allowed to replace the global `operator new' function with
one that has side effects, and this can only be determined at link time.
As David said - eagerly-evaluating languages don't enforce it as well.
No difference in language semantics.
Eiffel isn't designed for a functional programming style, but
enforcement of function purity is not part of the problem.
(Been there, done that. Including trying to port Chris Okasaki's Pure
Functional Datatypes library to Eiffel. It would have worked like a
charm if Eiffel didn't have the wrong syntactic sugar for functional
programming.)
Regards,
Joachim
--
This is not an official statement from my employer.
I would love to hear more of your thoughts on this matter. I take it
you have looked at the possibilities of the new "Agent" functionality
that is now provided with the ISE 5.0 version of Eiffel, (and probably
others)?