Google
 
Webnews.only-4-geeks.com
Interesting places
news.only-4-geeks.com Forum Index » C++Goto page 1, 2, 3  Next

Functions without side-effects. Proposal

 
Jump to:  
 
Zara
PostPosted: Tue Sep 02, 2008 7:43 pm    Post subject: Functions without side-effects. Proposal
       
I would like to publish this proposal for enhancing C++ language. As
comp.std.c++ seems dead, I will post it in comp.lang.c++.moderated, as
I feel the intended audience reads this newsgroup usually.

Sorry for the length of the message, but I can't make it shorter.

Ruminations on a functional extension to C++
Juan Antonio Zaratiegui Vallecillo, a.k.a. Zara
zara@coit.es

Proposal for the adaptation of some ideas from functional programming
in order to improve C++ language.

** Rationale
Many problems of this language come from the existence of side-effects
in the 'functions', coming from the fact that the language is
'procedural' by definition. If we could guarantee that some functions
were such in a 'functional' way (that is, without side-effects) there
would be many cases in which:
testing the correctness of an algorithm would be easier. It would even
be possible.
the compiler would be able to optimize further, knowing when some
values/objects would be reusable as it could be sure they were not
affected by anything external.
there would be another compiler-time checking: the 'no-side-effects'
correctness, in the lines but stricter than 'const' correctness.
This is no syntactic sugar.
I hope that everything will become clearer in the following
paragraphs. Sorry for my english.

** Definition
A function or class-member function will be considered with no side
effects if:
- All parameters passed to it are passed as const value or by const
reference.
- It will return only an object of the type expressed by its
signature or an exception, and void return value is not valid. The
return value will never be a POD pointer, but it may be a smart
pointer.
- It will not modify any global object.
- It will not access any volatile value anywhere.
- Any object it creates, will also be destroyed unless it is the
return value.
- It will catch no exception, any exception generated within will
flow seamlessly to the caller.
- It will only create local objects or smart/scoped pointers, apart
form the return value. The objects will be created through
constructors with no side effects, and the destructors will have no
side effects. Allocating memory for the object data is not a
side-effect, and neither destroying it in the destructor. There should
be some kind of system to verify that the destructor rids these
allocated data, but I don´t know if it should be easy enough to force
the uses of smart/scoped pointers.
- It will only call another functions or member functions with no
side effects.
- Any time it is called with the same parameters it will return the
same value (apart form run time exceptions related with memory
exhaustion)

** Nomenclature
This is the hardest part. The best option seems to be to create a new
keyword to qualify this functions, for instance:

double sin ( double arc ) no_side_effects;

As this option may result too noisy for real programmers, an
abbreviation may be adopted:

double sin ( double arc ) nseff;

Thinking of the possibility of its availability being an option of the
compiler (but this may be unfeasible, as you may notice further on):

double sin ( double arc ) __nseff;

We may even try to reuse keywords, so as to maintain the keyword list
constant:

double sin ( double arc ) void;

This one would be a nice way to tell the compiler that the function is
void of side-effects! A draw-back: the quality of 'void' of a member
function would imply 'const', deviating from anythin seen otherwise on
the language.
I will use the qualifier no_side_effects from now on, but I am not
showing any special preference, it is just a matter of making it
easier for the reader to locate them on source samples.
Finally, there should be a special qualifier for templated functions
or templates or template member functions, which may have side effects
or not depending on the template parameters. Although I know it may
conflict with other propositions, I will use the keyword auto to
qualify these functions: the compiler will tag them as 'no side
effects' when functions accomplish all conditions listed above,
otherwise it will be tagged as normal (having side effects).

** Functions
Any function with no side effect should be tagged as that, letting the
compiler take advantage of it:

double sin ( double arc ) no_side_effects;
double sin_table[] = {
sin(0),
sin(M_PI/4),
sin(M_PI/2),
sin((3*M_PI)/4),
sin(M_PI),
sin((5*M_PI)/4),
sin((3*M_PI)/2),
sin((7*M_PI)/4)
};

In the usual C++ compiler (without no_side_effects), this structure
will be calculated at run time through eight calls to sin. The use of
the function tag may enable the compiler to use some compile time
library to evaluate sin, and fill the table without calling once the
function sin at run time.
This concept could be extended to no_side_effects functions defined
within the source code: the compiler may opt to evaluate them (if all
arguments are constant) and use the values calculated as constants
instead of living the calculations for run time.

** Classes
For an object to be used within a no side effect function, it should
constructed through an adequate constructor:
- All parameters passed to it are passed as const value or by const
reference.
- It will not modify any global, static object and/or mutable object.
- It will not access any volatile value anywhere.
- It will catch no exception, any exception generated within will
flow seamlessly to the caller.
- It will only create local objects or smart/scoped pointers. Any
data allocated by it, should be destroyed by the destructor. It should
be exception-safe, in the hardest way.
- It will only call another functions with no side effects.
- Any time it is called with the same parameters it will return the
same value (save for run time exceptions related with memory
exhaustion).
This constructors will be specifically qualified, i.e.:

class OneClass {
// this constructor has side-effects
OneClass( double& whatever );
// this constructor has no side-effects
OneClass( const int whatever ) no_side_effects;
};

** Member functions
A member function may be qualified as no_side_effects if it
accomplishes all conditions expressed for functions, plus:
the object passed to it (*this) is more than const: it behaves as a
const and no volatile or static members may be accessed.

** Function templates
A member function may be qualified as no_side_effects if it
accomplishes all conditions expressed for functions. When trying to
instantiate, the type of the parameters passed are critical. If the
instantiation renders valid, it will have more priority than all other
possibilities of the same characteristics.

template <class SOME_CLASS>
int calc_something() {
return SOME_CLASS::evaluate(22);
}
template <class SOME_CLASS>
static int calc_something() no_side_effects {
return SOME_CLASS::evaluate(42);
}
class SEclass {
private:
static int store_it;
public:
static int evaluate(int n) const {
return store_it=n;
}
};
class NSEclass {
public:
int evaluate(int n) no_side_effects {
return n;
}
};

It is evident that calc_something<SEclass> should return 22, while
calc_something<NSEclass> should return 42.
Function templates may inherit its quality of 'side-effect-ness' from
the template parameters, i.e.:

template <class SOME_CLASS>
int calc_other_thing() auto {
return SOME_CLASS::evaluate(6);
}

Thus, calc_other_thing<SEclass> is const, while
calc_other_thing<NSEclass> is no_side_effects.

** Template classes
All restrictions applicable to classes are of use, plus constructors
and member functions may be qualified as auto as in the case of
function templates.

** Template functions as members of classes and template classes
All restrictions applicable to member functions of classes and
template classes, they me qualified as auto.

** Future possiblities
Everything exposed above is only an skeleton, but I feel that the
existence of a functional paradigm aside with all the others already
living in C++, would made it a more expressive way of programming.
Maybe, someone at Boost may take advantage of it. What about
boost::has_no_side_effects?
On the other hand, codign guidelines suchs as MISRA-C++ may be
rewritten to rely on the existence of this model, as the necessity of
this functions withous side-effects is stated repeatedly in them.

** Final word
Everything expressed here is open to comments and criticism, of
course. I only beg for your forgiveness if it has already been
discussed (and maybe dismissed); if there are some inconsistencies
coming from a not deep enough knowledge of C++; or if anyone feels
hurt by anything said here; it is all my fault.

Juan Antonio Zaratiegui Vallecillo, a.k.a Zara
zara@coit.es


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Andrei Alexandrescu
PostPosted: Wed Sep 03, 2008 8:58 am    Post subject: Re: Functions without side-effects. Proposal
       
Alberto Ganesh Barbati wrote:
Quote:
Zara ha scritto:
Proposal for the adaptation of some ideas from functional programming
in order to improve C++ language.


I'm sorry to sound dismissive, but it seems to me that most of this
proposal can either be achieved with constexpr or be automatically
detected by the compiler. In the rest of the cases, your "no side
effect" concept is just an optimization hint that doesn't change the
language semantic, so it would be better handled using an attribute
rather than a new syntax. Or am I missing something?

Ganesh

I think the proposal does have merit. It essentially introduces pure
functions, so it would allow writing entire parts of programs in pure
functional style.

There are some issues with proving that a function is pure. Worst thing
is object construction by a pure function. The compiler would have to
prove that the constructor creates an independent value that does not
alias anything else. That's hard to do modularly with existing
constructor semantics. But it can be done.

By the way, a pure function doesn't need to take constant objects. As
long as its output only depends on its input and it has no side effects,
the function is pure all right. Const doesn't help any in this case
because it's only skin deep (intransitive).


Andrei

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
David Abrahams
PostPosted: Wed Sep 03, 2008 6:55 pm    Post subject: Re: Functions without side-effects. Proposal
       
on Wed Sep 03 2008, Andrei Alexandrescu <SeeWebsiteForEmail-AT-erdani.org> wrote:

Quote:
There are some issues with proving that a function is pure. Worst thing
is object construction by a pure function. The compiler would have to
prove that the constructor creates an independent value that does not
alias anything else.

IIUC that's true for some definition of "value," by the definition of
the language. I presume you mean to include data accessible through
pointers as part of the value?

Quote:
That's hard to do modularly with existing constructor semantics. But
it can be done.

I don't see how you could possibly do it. We don't have anything in the
language that allows us to annotate a pointer as denoting a relationship
to a different object as opposed to a referencing a dynamically
allocated part of the object's value.

Quote:
By the way, a pure function doesn't need to take constant objects. As
long as its output only depends on its input and it has no side effects,
the function is pure all right. Const doesn't help any in this case
because it's only skin deep (intransitive).

Doesn't help with what?

--
Dave Abrahams
BoostPro Computing
LINK

[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Zara
PostPosted: Wed Sep 03, 2008 7:01 pm    Post subject: Re: Functions without side-effects. Proposal
       
On Tue, 2 Sep 2008 23:44:03 CST, Alberto Ganesh Barbati
<AlbertoBarbati@libero.it> wrote:

Quote:
Zara ha scritto:

Proposal for the adaptation of some ideas from functional programming
in order to improve C++ language.


I'm sorry to sound dismissive, but it seems to me that most of this
proposal can either be achieved with constexpr or be automatically
detected by the compiler. In the rest of the cases, your "no side
effect" concept is just an optimization hint that doesn't change the
language semantic, so it would be better handled using an attribute
rather than a new syntax. Or am I missing something?


I didn´t know aboiut constexpr (I,ve just read n2235.pdf). As I see
it, constexpr are a subset of the no_side_effects functions I have
described.
I think that my proposal is more general, as it includes the
possibility of library functions to be tagged as no_side_effects,
complex functions to be tagged also.
In itself, it is as much an optimization hint as a set of restrictions
to be checked at compile-time. I don´t know (yet) if there is any
compiler with the possibility to check such a set of restrictions.
In fact, I am almost certain that these sets of restrictions (or at
least, part of them) do change language semantic.

Best regards,

Zara

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
restor
PostPosted: Wed Sep 03, 2008 8:58 pm    Post subject: Re: Functions without side-effects. Proposal
       
Quote:
** Definition
- It will not access any volatile value anywhere.

what about this function? Is it pure (side effect free)?

const int FACTOR = 2;

const int increase( const int i ) {
return FACTOR * i;
}

Does it side-effect-free-ness change if it is linked with another
library that executes:

extern int FACTOR;
int mutable_factor = const_cast<int>(FACTOR);
increase(4);
mutable_factor = 3;
increase(4);

Regards,
&rzej


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
RobThaBlob
PostPosted: Wed Sep 03, 2008 8:58 pm    Post subject: Re: Functions without side-effects. Proposal
       
On Sep 3, 9:58 am, Andrei Alexandrescu <SeeWebsiteForEm...@erdani.org>
wrote:
Quote:
Alberto Ganesh Barbati wrote:
Zara ha scritto:
Proposal for the adaptation of some ideas from functional programming
in order to improve C++ language.

I'm sorry to sound dismissive, but it seems to me that most of this
proposal can either be achieved with constexpr or be automatically
detected by the compiler. In the rest of the cases, your "no side
effect" concept is just an optimization hint that doesn't change the
language semantic, so it would be better handled using an attribute
rather than a new syntax. Or am I missing something?

Ganesh

I think the proposal does have merit. It essentially introduces pure
functions, so it would allow writing entire parts of programs in pure
functional style.

There are some issues with proving that a function is pure. Worst thing
is object construction by a pure function. The compiler would have to
prove that the constructor creates an independent value that does not
alias anything else. That's hard to do modularly with existing
constructor semantics. But it can be done.

By the way, a pure function doesn't need to take constant objects. As
long as its output only depends on its input and it has no side effects,
the function is pure all right. Const doesn't help any in this case
because it's only skin deep (intransitive).

{ Signature and banner removed; please don't quote unnecessary material.
-mod }

I'd have to agree, and would favour the use of the keyword 'pure' for
such purposes to indicate that it is a 'pure' functional-style
function.

The ability to have pure functions could, in turn, lead to many other
applications from FP style, such as currying (one or more parameter
being fixed, generating a new variant of the function at the
compiler's discretion).

However, it may be that such an approach may complicate the language
yet more, and be better pursued by using Foreign Function Interfaces
between a true FP language and procedural languages.

Rob Grainger


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Alberto Ganesh Barbati
PostPosted: Thu Sep 04, 2008 1:46 am    Post subject: Re: Functions without side-effects. Proposal
       
restor ha scritto:
Quote:
** Definition
- It will not access any volatile value anywhere.

what about this function? Is it pure (side effect free)?

const int FACTOR = 2;

const int increase( const int i ) {
return FACTOR * i;
}

Does it side-effect-free-ness change if it is linked with another
library that executes:

extern int FACTOR;
int mutable_factor = const_cast<int>(FACTOR);
increase(4);
mutable_factor = 3;
increase(4);


This code does not try to modify FACTOR, so why should it affect the
side-effect-ness of function increase()? Maybe you intended to write:

int& mutable_factor = const_cast<int&>(FACTOR);

In this case the behaviour is undefined, according to 7.1.5.1/4: "[...]
any attempt to modify a const object during its lifetime (3.Cool results
in undeï¬ned behavior", so the question is moot.

Ganesh


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Andrei Alexandrescu
PostPosted: Thu Sep 04, 2008 1:58 am    Post subject: Re: Functions without side-effects. Proposal
       
David Abrahams wrote:
Quote:
on Wed Sep 03 2008, Andrei Alexandrescu <SeeWebsiteForEmail-AT-erdani.org> wrote:

There are some issues with proving that a function is pure. Worst thing
is object construction by a pure function. The compiler would have to
prove that the constructor creates an independent value that does not
alias anything else.

IIUC that's true for some definition of "value," by the definition of
the language. I presume you mean to include data accessible through
pointers as part of the value?

Entities worth working with for purity purposes are entire access
graphs, e.g. any data reachable starting from a given object.

It all depends on how ambitious a purity subsystem wants to be. If no
private mutable data is allowed inside a pure function and no
user-defined object construction is allowed inside a pure function, then
it's easy to typecheck a pure function:

a) No mutation is allowed inside a pure function.

b) A pure function can only call other pure functions.

Assuming constructors cannot be pure, ensuring a and b is all that's
needed for ensuring a pure modular subsystem in C++.

Things get about an order of magnitude more interesting when pure
functions are allowed to mutate private state. Arguably, this is a pure
function:

unsigned factorial(unsigned n)
{
unsigned result = 1;
for (unsigned i = 1; i < n; ++i) result *= i;
return result;
}

It is pure because it output only depends on its input. However, by a
rigid definition of purity it's not pure because it mutates result and
i. But that's an implementation detail so factorial should typecheck as
pure. This is where the notion of private state and comes into play. If
allowing private user-defined objects is needed, disjoint object graphs
come into play too.

Quote:
That's hard to do modularly with existing constructor semantics. But
it can be done.

I don't see how you could possibly do it. We don't have anything in the
language that allows us to annotate a pointer as denoting a relationship
to a different object as opposed to a referencing a dynamically
allocated part of the object's value.

It can be done by annotating constructors and typechecking them in a
special way that makes those annotated constructor more restrictive. D
will do that. The story is not quite simple and I doubt there will be
extensive information on it until my book on D comes out.

Quote:
By the way, a pure function doesn't need to take constant objects. As
long as its output only depends on its input and it has no side effects,
the function is pure all right. Const doesn't help any in this case
because it's only skin deep (intransitive).

Doesn't help with what?

Typechecking pure constructors.


Andrei

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Alberto Ganesh Barbati
PostPosted: Thu Sep 04, 2008 9:28 pm    Post subject: Re: Functions without side-effects. Proposal
       
Zara ha scritto:
Quote:
In fact, I am almost certain that these sets of restrictions (or at
least, part of them) do change language semantic.

There's a quick test to discern that. Write a well-formed program with
the proposed decoration. Then, remove *all* decorations. If the program
is still well-formed and produces the same observable behaviour, then
the decoration did no affect the language semantic.

Ganesh

--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

 
Edward Rosten
PostPosted: Thu Sep 04, 2008 10:43 pm    Post subject: Re: Functions without side-effects. Proposal
       
On Sep 4, 3:28 pm, Alberto Ganesh Barbati <AlbertoBarb...@libero.it>
wrote:
Quote:
Zara ha scritto:

In fact, I am almost certain that these sets of restrictions (or at
least, part of them) do change language semantic.

There's a quick test to discern that. Write a well-formed program with
the proposed decoration. Then, remove *all* decorations. If the program
is still well-formed and produces the same observable behaviour, then
the decoration did no affect the language semantic.

It depends if overloading based on pureness is allowed (muck like
const). For instance, functions like acos() affect the global errno
variable. There you could have two prorotpyes:

double acos(double);
double acos(double) pure;

If you can only call pure functions from within pure functions (like
const methods), then the two can potentially produce different
retults:

double foo(double d) pure {return acos(d);}
acos(0);
foo(-10);
if(errno == EDOM)
...

Another point is that pure functions of compile-time constants could
result in compile time constants, which would be useful.

Finally, if it really helps correctness and optimization, then is it
worth it? With many programs, you could remove all consts, and still
get the same results, bit I find them useful. Likewise, inline should
not be necessary either.


-Ed


--
[ See LINK for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
 

Page 1 of 3 .:. Goto page 1, 2, 3  Next

Google
 
Webnews.only-4-geeks.com

Windows Update | C++ | C | PHP | JavaScript | Photoshop | Programming | Windows 2000 | Python | Windows XP | Object | Flash | Flash - ActionScript | Paint Shop Pro | Excel | PowerPoint | Access | Word | Windows 98 | Internet Explorer 6.0 | CorelDraw12 | Java | XML | asm x86 | Linux Mandrake | Linux RedHat | Outlook |  | news from newsgroups |_ | s

Web Templates

Awesome Website Templates ©

zabawki edukacyjne długopisy rowery Telewizory laserowe gry dla dzieci