I was wondering if you know of any programming language in which we can pass parameters inside method name. I'm guessing this could improve the code readability. I.e.
Lets say I want to multiply to integers in a method. Normally my method declaration would be something like:
function multiply(int a, int b){
return a*b;
}
However, it may be nice to be able to define it this way also:
function multiply (int a) times (int b){
return a*b;
}
This way, we could make a more explicit call in the code by calling:
var c = multiply(4)times(2);
This could have a greater impact on more complicated code and programming syntax.
Do you know if something like this exists?
Of course, there is Smalltalk which is really expressive with its keyword messages...
n := collection size // 2.
head := collection copyFrom: 1 to: n.
Other than that, you will find that in ADA or Python, and probably some others you can prefix each argument with a key (which should match the function parameter names)...
Related
I know that there is a similar question here: Binding a function with std::initializer_list argument using pybind11 but because I cannot comment (not enough reputation) I ask my question here: Do the results from the above-linked question also apply to constructors: I.e. if I have a constructor which takes std::initializer_list<T> is there no way to bind it?
There's no simple way to bind it, at least. Basically, as mentioned in the other post (and my original response in the pybind11 issue tracker), we can't dynamically construct a std::initializer_list: it's a compile-time construct. Constructor vs method vs function doesn't matter here: we cannot convert a set of dynamic arguments into the compile-time initializer_list construct.
But let me give you a way that you could, partially, wrap it if you're really stuck with a C++ design that requires it. You first have to decide how many arguments you're going to support. For example, let's say you want to support 1, 2, or 3 int arguments passed via initializer_list<int> in the bound constructor for a MyType. You could write:
#include <stl.h>
py::class_<MyType>(m, "MyClass")
.def(py::init([](int a) { return new MyClass({ a }); }))
.def(py::init([](int a, int b) { return new MyClass({ a, b }); }))
.def(py::init([](int a, int b, int c) { return new MyClass({ a, b, c }); }))
.def(py::init([](std::vector<int> v) {
if (vals.size() == 1) return new MyClass({ v[0] });
elsif (vals.size() == 2) return new MyClass({ v[0], v[1] });
elsif (vals.size() == 3) return new MyClass({ v[0], v[1], v[2] });
else throw std::runtime_error("Wrong number of ints for a MyClass");
});
where the first three overloads take integer values as arguments and the last one takes a list. (There's no reason you'd have to use both approaches--I'm just doing it for the sake of example).
Both of these are rather gross, and don't scale well, but they exhibit the fundamental issue: each size of an initializer_list needs to be compiled from a different piece of C++ code. And that's why pybind11 can't support it: we'd have to compile different versions of the conversion code for each possible initializer_list argument length--and so either the binary size explodes for any number of arguments that might be used, or there's an arbitrary argument size cut-off beyond which you start getting a fatal error. Neither of those are nice options.
Edit: As for your question specifically about constructors: there's no difference here. The issue is that we can't convert arguments into the required type, and argument conversion is identical whether for a constructor, method, or function.
I have a pointer to a parent class and I want to assign a new child object to that pointer conditionally. Right now, the syntax I have is rather lengthly:
std::unique_ptr<ParentClass> parentPtr;
if (...) {
parentPtr = std::unique_ptr<ParentClass>(new ChildClass1());
} else {
parentPtr = std::unique_ptr<ParentClass>(new ChildClass2());
}
Is there a good way of making this more readable / less lengthly?
Two possibilities would be:
std::unique_ptr<ParentClass> parentPtr(condition ?
(ParentClass*)new ChildClass1() :
(ParentClass*)new ChildClass2());
If condition is complicated, just assign a boolean to it and then write the construction. This solution only works for a binary condition though.
Another is to embrace C++14, and use
parentPtr = std::make_unique<ChildClass>();
First off, the "obvious" solution C ? new X : new Y does not work, since even if X and Y have a common base class A, the types X * and Y * have no common type. This is actually not so surprising after all if you consider that a class can have many bases (direct or indirect) and a given type may appear as a base multiple times.
You could make the conditional operator work by inserting a cast:
A * = C ? static_cast<A *>(new X) : static_cast<A *>(new Y);
But this would quickly get long and tedious to read when you try to apply this to your real situation.
However, as for std::unique_ptr, it offers the reset function which can be used to good effect here:
std::unique_ptr<A> p;
if (C)
{
p.reset(new X);
}
else
{
p.reset(new Y);
}
Now even if the actual new expressions are long, this is still nicely readable.
I have a package containing a number of packed-struct typedefs and I am trying to write a CONSTANT function to tell me the maximum bit width of these structs. Each struct has an explicit message_type which is enumerated. I believe the below function I have written should be interpreted by the compiler as constant, but I am getting the error "(vlog-2118) The function 'get_max_message_length' is not a valid constant function" (this is in ModelSim).
Can anyone tell me why this function is not constant? After debugging I have determined that it is the enum method 'next()' that is causing it to be interpreted wrong. Any possible alternate solutions? Thank you in advance!
typedef enum logic [7:0]
{
MESSAGE_TYPE_0=0,
MESSAGE_TYPE_1=1,
MESSAGE_TYPE_2=2
} _MSGTYPE;
function integer get_message_length (_MSGTYPE message_type);
case (message_type)
MESSAGE_TYPE_0: return ($bits(message_0));
MESSAGE_TYPE_1: return ($bits(message_1));
MESSAGE_TYPE_2: return ($bits(message_2));
default: return 0;
endcase
endfunction
function integer get_max_message_length ();
automatic _MSGTYPE largest = largest.first();
automatic _MSGTYPE next = next.first();
next = next.next();
while (next != next.first()) begin
largest = get_message_length(largest) > get_message_length(next) ? largest : next;
next = next.next();
end
return get_message_length(largest);
endfunction
A constant function has certain restrictions - it must be a pure function (i.e. have no side effects and return the same value if called with the same arguments).
This restriction propagates, so your constant function can only call other functions that are also pure functions. The problem you have is that next.next() is not a pure function - it does not return the same value every time you call it.
Sadly the SystemVerilog LRM doesn't appear to define any pure mechanism for accessing enumerated values - for example this would work if it were possible: for (int i=0; i<enum.num(); i++) size=get_message_length(enum.item(i));
Off the top of my head I can't think of a neat way to do this. You could create a localparam which was an array of enum values and iterate over that but you'd have to write out the enum values again.
I have my function that needs changing to iteration, because of very slow executing of it.
There are two recursive calls, depends which condition is true.
It's something like this:
(I have static array of classes outside function, let's say data)
void func(int a, int b, int c, int d) {
//something
//non-recursive
//here..
for (i=0; i<data.length; i++) {
if (!data[i].x) {
data[i].x = 1;
if (a == data[i].value1)
func(data[i].value2,b,c,d);
else if (a == data[i].value2)
func(data[i].value1,b,c,d);
data[i].x = 0;
}
}
}
!!
EDIT: Here is my algorithm: http://pastebin.com/F7UfzfHv
Function searches for every paths from one point to another in graph, but returns (to an array) only one path in which are only unique vertices.
!!
And I know that good way to manage that is to use stack... But I don't know how. Could someone give me a hint about it?
There is a good possibility that your function might be computing the same thing again and again, which in technical terms is called as overlapping sub-problems(if you are familiar with the dynamic programming then you might know). First try to identify whether that is the case or not. Since you haven't told anything about what function do and I can't tell the exact problem.
Also the thing you are talking about using a stack is not of great use since recursion uses a stack internally. Using external stack instead of internal is more error prone is not of great use.
I am very new to TDD. I am reading TDD By Example and it says "never try to use the same constant to mean more than one thing" and it show an example of Plus() method.
In my opinion, there is no difference between Plus(1, 1) which uses same constant value and Plus(1, 2). I want to know what are pros and cons of using same constant value in test method?
I think you misinterprete that statement. What the author (imho) is trying to convey is that following code is a recipe for disaster.
const SomeRandomValue = 32;
...
// Plus testcase
Plus(SomeRandomValue, SomeRandomValue)
...
// Divide testcase
Divide(SomeRandomValue, SomeRandomValue)
You have two testcases reusing a none descriptive constant. There is no way to know that by changing SomeRandomValue to 0 your testsuite will fail.
A better naming would be something like
const AdditionValue = 32;
const DivisorValue = 32;
...
// Plus testcase
Plus(AdditionValue, AdditionValue)
...
// Divide testcase
Divide(DivisorValue, DivisorValue)
where it should be obvious as to what the constants are used for.You should not get to hung up on the idea of code reuse when creating testcases.
Or to put it in other words:
I don't see anything wrong with reusing the DivisorValue constant in multiple testcases > but there is definitly something wrong trying to shoehorn one value into a none descriptive variable just in the name of code reuse.
If you use the same value in your test - as in Plus(1, 1) - your code could work for the wrong reason. Here is an implementation of Plus that will pass such a test, but fail a test with different values.
public int Plus (int a, int b) {
return a + a;
}
A test that avoids this risk is a better test than one which lets errors like these slip through.