How to use pure in D 2.0 - d

While playing around with D 2.0 I found the following problem:
Example 1:
pure string[] run1()
{
string[] msg;
msg ~= "Test";
msg ~= "this.";
return msg;
}
This compiles and works as expected.
When I try to wrap the string array in a class I find I can not get this to work:
class TestPure
{
string[] msg;
void addMsg( string s )
{
msg ~= s;
}
};
pure TestPure run2()
{
TestPure t = new TestPure();
t.addMsg("Test");
t.addMsg("this.");
return t;
}
This code will not compile because the addMsg function is impure. I can not make that function pure since it alters the TestPure object.
Am i missing something? Or is this a limitation?
The following does compile:
pure TestPure run3()
{
TestPure t = new TestPure();
t.msg ~= "Test";
t.msg ~= "this.";
return t;
}
Would the ~= operator not been implemented as a impure function of the msg array? How come the compiler does not complain about that in the run1 function?

Since v2.050, D relaxed the definition of pure to accept the so called "weakly pure" functions too. This refers to functions that "do not read or write any global mutable state". Weakly pure functions are not the same as pure functions in the functional language sense. The only relation is that they makes real pure functions, a.k.a. "strongly pure" functions able call the weak ones, like OP's example.
With this, addMsg can be marked as (weakly) pure, since only the local variable this.msg is altered:
class TestPure
{
string[] msg;
pure void addMsg( string s )
{
msg ~= s;
}
};
and of course, now you can use the (strongly) pure function run2 with no modification.
pure TestPure run2()
{
TestPure t = new TestPure();
t.addMsg("Test");
t.addMsg("this.");
return t;
}

Others have already pointed out that addMsg is not pure and cannot be pure because it mutates the state of the object.
The only way to make it pure is to encapsulate the changes you're making. The easiest way to do this is via return mutation, and there are two ways to implement this.
Firstly, you could do it like this:
class TestPure
{
string[] msg;
pure TestPure addMsg(string s)
{
auto r = new TestPure;
r.msg = this.msg.dup;
r.msg ~= s;
return r;
}
}
You need to copy the previous array because inside a pure function, the this reference is actually const. Note that you could do the copy better by allocating a new array of the final size and then copying the elements in yourself. You would use this function like so:
pure TestPure run3()
{
auto t = new TestPure;
t = t.addMsg("Test");
t = t.addMsg("this.");
return t;
}
This way, the mutation is confined to each pure function with changes passed out via return values.
An alternate way of writing TestPure would be to make the members const and do all the mutation before passing it to the constructor:
class TestPure
{
const(string[]) msg;
this()
{
msg = null;
}
this(const(string[]) msg)
{
this.msg = msg;
}
pure TestPure addMsg(string s)
{
return new TestPure(this.msg ~ s);
}
}
Hope that helps.

Please review the definition of pure functions:
http://en.wikipedia.org/wiki/Pure_function
http://www.digitalmars.com/d/2.0/function.html#pure-functions
Pure functions are functions that produce the same result for the same arguments. To that end, a pure function:
has parameters that are all invariant or are implicitly convertible to invariant
does not read or write any global mutable state
One of the effects of using pure functions is that they can be safely parallelized. However, it's not safe to execute several instances of your function in parallel, because they could both modify the class instance simultaneously, causing a synchronization problem.

I think that your code is conceptually correct. However you may have found case where the compiler's semantic analysis is not as good as your brain's.
Consider the case where the class's source is not available. In that cases the compiler would have no way of telling that addMsg only modifies member variable so it can't allow you to call it from a pure function.
To allow it in your case, it would have to have special case handling for this type of usage. Every special case rule added makes the language more complicated (or, if left undocumented, makes it less portable)

Just a hunch, but this function doesn't always return the same result.
See, it returns a reference to some object, and while the object will always contain the same data, the objects returned by several calls to the same functions are not identical; that is, they don't have the same memory address.
When you return a reference to the object, you're essentially returning a memory address, which is going to be different across several calls.
Another way to think of it, part of the return value is the memory address of an object, which is dependent on some global state(s), and if the output of a function depends on global state, then it's not pure. Hell, it doesn't even have to depend on it; as long as a function reads a global state, then it's not pure. By calling "new", you are reading global state.

Related

How to use a template to create two very similar member functions in C++

I am coding a C++ library and one class has two member functions that only differ in one function call:
int MyClass::member_func_1(int a) {
// ...
int b = some_function();
// ...
}
int MyClass::member_func_2(int a) {
// ...
int b = some_other_function();
// ...
}
Is there a way of not having to duplicate the code of these two functions, while still keeping the two member functions with the same function signatures?
Since it is a library all code must be generated when the library is compiled.
I have ruled out the option of having only one member function with an extra boolean argument to choose between some_function and some_other_function for performance reasons.
I know how to use a macro to do it, but could a template be used, or is there another better way?
A template solution is only a good solution if the call to either of the member functions is executed in a tight loop, where the overhead of testing a boolean or making an indirect function call would be too costly.
In this case, if C++17 standard is an option, the if constexpr syntax is probably the simplest way. Like in:
class MyClass
{
template<bool other> int member_func(int a)
{
//...
int b;
if constexpr (other)
b = some_other_function();
else
b = some_function();
//...
}
};
Since the only difference in the implementation of your two member functions is the calls to different member functions, that's what you should abstract out of those functions. You can do that by writing a single member function that takes a pointer to member function as an additional argument:
int common_member_func(int a, int (MyClass::*func)())
{
// ...
int b = (this->*func)();
// ...
}
and now the implementation of your two member functions would be:
int member_func_1(int a)
{
return common_member_func(a, &MyClass::some_function);
}
int member_func_2(int a)
{
return common_member_func(a, &MyClass::some_other_function);
}
Here's a demo.
You may use a boolean for switching the internal method to be called or pass a function pointer / std::function and call that one directly. the performance penalty will be ridiculously negligible.
If you really want to make your code less readable because of that virtually non-existant "performance reason", you can implement the common method templated, with a boolean template parameter. The if() clause referring the template parameter can then be a constexpr (realised during compilation).
However note that this will also lead to the method being effectively doubled in your applications code, and when you have many alternating calls, this might have an adverse effect on your performance similar to the original if() clause, i.e. not noticable at all.

Static initialization of function pointers

I'm having a class that contains a function pointer. I would like to initialize various instances of the class statically but I can't figure out the correct syntax for this.
Let's say, this is my class
class fooClass
{
int theToken;
string theOutput;
bool (*theDefault)( void );
};
I now would like to create a static instance of this, like this…
fooClass test
{
1,
"Welcome",
(){ return (theToken & 1 ) ? true : false; }
};
As I said, I can't figure out the proper syntax for the function pointer line. Or is it even possible like this? I'd really like not having to break out every function I create this way into its own function declaration.
What I'm trying to do is, allow each instance to have a unique default function because each instance represents a unique data-driven building block of a bigger system. The code I put in there is just for illustrative purposes. This default function will access certain global variables as well as some of the member variables and if need be I could pass this into the function.
Could someone point me in the right direction how I'd have to write the initialization for it to work under C++14?
If you want to refer to struct members inside the function, you cannot do with just a plain function pointer not receiving any argument, as it doesn't receive the this pointer.
My advice is to at very least change it to a pointer to a function taking the instance as an argument, then in initialization you can pass a capture-less lambda (which can be converted to a plain function pointer):
class fooClass
{
int theToken;
string theOutput;
bool (*theDefault)( fooClass *that);
// you may provide a helper for ease of use
bool Default() { return theDefault(this);}
};
fooClass test
{
1,
"Welcome",
[] (fooClass *that){ return (that->theToken & 1 ) ? true : false; }
};
You can also use an std::function<bool(fooClass*)> to allow even functors, lambdas with captures & co. if you are ok with the increased overhead.
You may be tempted to use a plain std::function<bool()> instead, and use a lambda capturing the instance by reference, such as
fooClass test
{
1,
"Welcome",
[&test] (){ return (test->theToken & 1 ) ? true : false; }
};
This does work, but is extremely dangerous if test happens to be copied, as theDefault will still refer to test even in the copy (and even after the original will have been destroyed).
(incidentally, this is how OOP is often done in languages such as Lua, but there (1) objects are not copied and (2) automatic memory management makes sure that closures "keep alive" the objects they capture)

Is there a portable way of defining replaceable function/variable/constant?

By replaceable function I mean something like the new and delete operators in C++ which are replaced if a user-provided definition is supplied.
Is there a reasonably portable way of achieving this in a library for other cases than operator new and delete (in C/C++)? Or would one need to solve this separately for each implementation?
For a concrete example let's assume that the library contains:
int the_answer(void) {
return 42;
}
and then a program using that would want to override this:
int the_answer(void) {
return 43;
}
int main() {
printf("The answer is %d\n", the_answer());
}
it should result in it printing "The answer is 43" (but if commenting out the last definition of the_answer it would write "The answer is 42").
The actual use case is to be able to customize the behavior of the library by overriding data for default behavior.
In C++ you can use the fact that a template has a lower priority than an implementation that does not require implicit casts/construction of arguments.
// library function
template <class = void>
int the_answer() { return 42; }
// optional override
int the_answer() { return 43; }
Note that the definition order is not important, the template always loses.
Sure, for anything except operators. Note that C does not have operator overloading, so your question is mis-tagged.
For functions/variables/constants, you could define a macro to perform the intended operation. When overloading (or, rather, replacing), #undef the macro and define a new one. Works for either C or C++, although incredibly dangerous.
In C, overloading or replacing functions is not an option. Either you would have to use the preprocessor, as mentioned above, or actually edit the resulting binary to use your functions.
In C++, you could make a polymorphic class that uses virtual functions, overriding the definition that was previously there. This would be the easiest solution to override the operation of the library itself.
In either language, it would be extremely difficult to change the type of a variable or value of a constant without recompiling.
Global function pointer ?
Functor overload ?
Global function pointer
Let say your library defines a doCoffee() function this way:
void doCoffee_impl() { /* ... */ }
void (doCoffee*)(void) = doCoffee_impl;
Your library users can then replace the behaviour of doCoffee by reaffecting the global variable.
Functor overload
But, hey! you're coding C++. Why not use a virtual operator() ?
struct Brewer
{
virtual operator()() { /* ... */ }
} brewer;
brewer *doCoffee = &brewer;
Your users may overload this:
struct UserBrewer : public Brewer
{
virtual operator()() { /* ... */ }
} userBrewer;
doCoffee = &userBrewer;
Let to the reader: either declare variables static in the source header or define it extern and define the variable in a provided compilation unit.

Using class member function pointers in C++ for Arduino

I need to make a list of function pointers to member objects and then execute them as need be in an InterruptSubRoutine. I created a class with a virtual function to wrap all classes that need interrupts, and they will use to execute their interrupt.
I can pass these and put them in the Array, but I get an error on the line where I try to execute them saying
expression must have a (pointer-to-) function type.
Header
typedef bool (InterruptSubRoutine::*function_pointer)();
void initializeTI();
void enableTI();
void disableTI();
void procInterrupt();
void addInterrupt(bool (InterruptSubRoutine::*interrupt)());
TimerThree timerInt;
function_pointer activeInterrupts[INTERRUPT_POINTER_SIZE];
Cpp
void ::initializeTI()
{
timerInt.initialize(TIMER_INTERRUPT_PERIOD);
}
void ::procInterrupt()
{
bool empty = true;
for(int i = 0; i<INTERRUPT_POINTER_SIZE; i++)
{
if (activeInterrupts[i] != nullptr)
{
empty = false;
bool returnV = activeInterrupts[i](); //this is where i get the problem, with the error stating "expression must have a (pointer-to-) function type"
if (!returnV)
{
activeInterrupts[i] = nullptr;
}
}
}
if (empty)
{
disableTI();
}
}
void ::addInterrupt(bool (InterruptSubRoutine::*function)())
{
for(int i = 0; i<INTERRUPT_POINTER_SIZE; i++)
{
if (activeInterrupts[i] == nullptr)
{
activeInterrupts[i] = function;
break;
}
}
}
void ::enableTI()
{
void (*interrupt)(void);
interrupt = &procInterrupt;
timerInt.attachInterrupt(interrupt, TIMER_INTERRUPT_PERIOD);
}
void ::disableTI()
{
timerInt.detachInterrupt();
}
here's something to get you started:
activeInterrupts is an array of function pointers
function_pointer activeInterrupts[INTERRUPT_POINTER_SIZE]; hence activeInterrupts[i] will be a function pointer.
you can't assign a integer-type variable, a function pointer: bool returnV = activeInterrupts[i](), they are incompatible types
Your problem starts with the wording of the question:
I need to make a list of function pointers to member objects...
No! You have pointer to member functions! And member functions need a object in which they are executed.
I created a class with a virtual function to wrap all classes that need interrupts
No! You create a base class where instances from derived classes ( which are called objects ) can use the given member functions. Please remember: The methods are part of the class but they are running in the context of the object.
Instead of that you also can have static class functions which are related to the class and work without objects! This is also possible but a total different approach.
From your wording I believe you did not really understand what is class,method,object and the relations between them. So I would advice you to read a OOP beginners book.
The simple problem as result of your wrong coding is, that you need an object in which context you can call the member function ( method ) which is addressed via a member function pointer.
If you want to store a object and a pointer, simply use a struct to fill the pointer and the object in and do the call. You are also free to bind the method pointer to the object with std::bind if you are using a modern c++11 version. As std::bind is header only code from c++ it works also for avr.
In general:
I think it is a bad design for small embedded systems to create, register, and store objects and in addition pointers to functions in runtime! this all can be done during compile time which makes the code much faster, smaller and less error prone. Think about memory allocation ( new/malloc) on a small embedded device! And if you are already use static allocation and global objects ( which is also bad design in bigger projects ) you also can resolve your call tree to all objects during compile time.
As a simple fix for your first problem you should:
bool returnV = (object.*activeInterrupts[i])();
where object is an instance of InterruptSubRoutine class or any derived class from that.
As an additional remark to your question itself:
It would be nice to shrink down all code snippets to the minimum we need to analyze the problem. On the other hand it would be nice if it could be used to compile it directly without adding all the missing stuff. Thanks!

Why do I "need opCmp" for an anonymous class?

I'm not exactly sure how to explain this, so please ask me to clarify anything that doesn't make sense. I have an interface and a template function which returns functions which return anonymous inner classes based on the compile time argument:
interface MyInterface {
void getName();
}
MyInterface function() getMyInterfaceFactory(string name)() {
return function() {
return new class MyInterface {
void getName() { //Do something involving name here }
};
};
}
Now, getMyInterfaceFactory() used to be getMyInterface() and it used to return the anonymous object directly. Everything worked fine. When I added the the factory functions, I started getting an exception during startup from Object:
object.Exception.....(102): need opCmp for class mymodule.getMyInterfaceFactory!("someargument").getMyInterfaceFactory.__funcliteral14.__anonclass13
So, I looked at the throwing line in the druntime source, and it looks like the default implementation of opCmp for Object just throws. I am not comparing factory functions or MyInterfaces anywhere. I am storing factories as the values of a string indexed associative array, but opCmp was not required when I was storing the anonymous classes directly in that array, only when I started storing the functions. If I insert an opCmp (using memory address), everything seems to work normally, but MyInterface is not really comparable so I'd prefer not to do that unless I have to.
If possible, I'd like to know why/where opCmp is being invoked on the anonymous classes, and how I can prevent or work around it.
Note: The default implementation of opCmp in Object includes a comment vaguely referencing a bug, a commented out memory address comparison, and then the throwing version.
Thanks!
Edit: I should mention, I tried both windbg and ddbg to track down exactly where opCmp was being called, but failed in both cases. Windbg gave no useful information, because it stubbornly refused to load any symbols, ddbg loaded symbols, but the exception occurs during initialization (after static module constructors but before main) and presumably ddbg didn't have access to the druntime symbols?
Update: I'm having trouble reproducing the opCmp error specifically in toy examples, but I think I have figured out what is happening.
It seems that creating anonymous inner classes which inherit interfaces inside of anonymous functions is buggy (go figure). Specifically, the anonymous classes and are not well behaved with respect to virtual functions. Even with opCmp defined, I've had errors with toString and the default constructors, and had members that simply do nothing (but don't throw or error when called). __traits(allMembers, MyInterface) returns the expected information, as does __traits(allMembers, typeof(anonInstance)) but calling the members listed frequently does not work. Weird.
But, if I change the interface to a class with abstract methods, the opCmp error is resolved, the anonymous class behaves as expected, etc. I don't know much about compilers, but I think that during compilation a symbol table is built which maps virtual function names to the memory addresses stored in vtbl. I think what is happening is that the map generated varies when returning an anonymous class derived from an interface. This is possible because interfaces support multiple inheritance, and so can't prescribe an absolute vtbl mapping. Classes, however, could require that all inheritors stick to the same mapping scheme (I don't know if they do, but they could) and so the anonymous classes can't end up with a different mapping.
Again, I'm really not certain, but it seems to fit the symptom, opCmp being called even though I haven't used it anywhere. I don't think it is specifically opCmp that was the problem, I think all the virtual functions defined in Object are vulnerable. I was able to support this with the following:
testopcmphelper.d
interface TestInterface {
string helloWorld();
}
class TestClass {
abstract string helloWorld();
}
testopcmp.d
import testopcmphelper;
import std.stdio;
void invokeFn(TestInterface function() f) {
auto t = f();
auto s = t.helloWorld();
writeln(s);
}
unittest {
auto f = function() {
return new class TestInterface {
string helloWorld() {
return "Hello World!";
}
};
};
invokeFn(f);
}
void invokeFn(TestClass function() f) {
auto t = f();
auto s = t.helloWorld();
writeln(s);
}
unittest {
auto f = function() {
return new class TestClass {
string helloWorld() {
return "Goodbye World!";
}
};
};
invokeFn(f);
}
Which prints:
src.utilities.testopcmp.__unittest2.__funcliteral1.__anonclass10
Goodbye World!
Indicating that invokeFn(TestInterface) is calling Object.toString instead of TestInterface.helloWorld.
I am going to leave the question open for another day, in case I've made a mistake. I will probably then report this as a bug in DMD. I will work around the problem by using only abstract classes for anonymous factory function base types.
TL;DR Seems to be a bug.