Dart - declare function as variable - function

In Dart - as in many other languages - there is more than one way to declare a function. The question is, are there any differences aka "when should I use which"?
void foo(int i) {
print('i = $i');
}
void main() {
void Function(int) bar = (int j) {
print('j = $j');
};
foo(1);
bar(2);
}
Is there any difference in the declaration of foo or bar other than the fact that bar can be overwritten?

Functions can be introduced by
function declarations
method decla-rations
getter declarations
setter declarations
constructor declarations
function literals
In terms of Dart specification there is 2 differences between function literals (aka anonymous function) and other declarations
it has no name - anonymous
we can't declare a return type (which only obtained by means of type inference)
If you prefer to keep type safety, you will have to write long declaration.
Consider this example:
String foo(int i, {bool b}) => '$b $i'; // return type declared
final bar = (int i, {bool b}) => '$b $i'; // return type could not be infered
final String Function(int i, {bool b}) bar = (i, {b}) => '$b $i'; // return type infered
From my perspective
bar isn't as readable as foo declaration
Let functions literals do their anonymous job =)
PS If I missed anything - please edit my answer or reach me in comments

Related

Reference to class method

I would like to pass to a function a reference to a class method.
For example:
#include <functional>
struct Foo
{
int f(const int& val) const
{
return val+2;
}
};
int caller(const std::function<int(const int&)>& f)
{
return f(1);
}
int main()
{
caller([](const int& val){return val+2;}); // OK
Foo foo;
caller(foo.f); // WRONG
return 0;
}
How can I fix the second call of caller() (NB: Foo:f() is not static)?
In your case, function f doesn't use any member of Foo so it can be declared static
static int f(const int& val)
and passed as:
caller(&Foo::f);
But suppose that f cannot be declared static and you want to pass "reference" to member function of particular object.
You can use lambda in that case:
Foo foo;
caller(
[&foo](const int& val){
return foo.f(val);
}
);
foo object is captured in square brackets (in this case by reference) so that you can call f member function on that particular object.
Although it is not part of your question, I should add that it is not really useful to pass int by const reference, as you will not gain any performance improvement that way. Actually, your code will run slower than if you pass int by value.

Static function variables in Swift

I'm trying to figure out how to declare a static variable scoped only locally to a function in Swift.
In C, this might look something like this:
int foo() {
static int timesCalled = 0;
++timesCalled;
return timesCalled;
}
In Objective-C, it's basically the same:
- (NSInteger)foo {
static NSInteger timesCalled = 0;
++timesCalled;
return timesCalled;
}
But I can't seem to do anything like this in Swift. I've tried declaring the variable in the following ways:
static var timesCalledA = 0
var static timesCalledB = 0
var timesCalledC: static Int = 0
var timesCalledD: Int static = 0
But these all result in errors.
The first complains "Static properties may only be declared on a type".
The second complains "Expected declaration" (where static is) and "Expected pattern" (where timesCalledB is)
The third complains "Consecutive statements on a line must be separated by ';'" (in the space between the colon and static) and "Expected Type" (where static is)
The fourth complains "Consecutive statements on a line must be separated by ';'" (in the space between Int and static) and "Expected declaration" (under the equals sign)
I don't think Swift supports static variable without having it attached to a class/struct. Try declaring a private struct with static variable.
func foo() -> Int {
struct Holder {
static var timesCalled = 0
}
Holder.timesCalled += 1
return Holder.timesCalled
}
7> foo()
$R0: Int = 1
8> foo()
$R1: Int = 2
9> foo()
$R2: Int = 3
Another solution
func makeIncrementerClosure() -> () -> Int {
var timesCalled = 0
func incrementer() -> Int {
timesCalled += 1
return timesCalled
}
return incrementer
}
let foo = makeIncrementerClosure()
foo() // returns 1
foo() // returns 2
Swift 1.2 with Xcode 6.3 now supports static as expected. From the Xcode 6.3 beta release notes:
“static” methods and properties are now allowed in classes (as an
alias for “class final”). You are now allowed to declare static stored
properties in classes, which have global storage and are lazily
initialized on first access (like global variables). Protocols now
declare type requirements as “static” requirements instead of
declaring them as “class” requirements. (17198298)
It appears that functions cannot contain static declarations (as asked in question). Instead, the declaration must be done at the class level.
Simple example showing a static property incremented inside a class (aka static) function, although a class function is not required:
class StaticThing
{
static var timesCalled = 0
class func doSomething()
{
timesCalled++
println(timesCalled)
}
}
StaticThing.doSomething()
StaticThing.doSomething()
StaticThing.doSomething()
Output:
1
2
3
Another solution
class Myclass {
static var timesCalled = 0
func foo() -> Int {
Myclass.timesCalled += 1
return Myclass.timesCalled
}
}

Test if a Dart value is actually a function?

Is it possible to test if a value is a function that can be called? I can test for null easily but after that I have no idea how to ensure the parameter passed in is actually a function?
void myMethod(funcParam)
{
if (funcParam != null)
{
/* How to test if funcParam is actually a function that can be called? */
funcParam();
}
}
void myMethod(funcParam) {
if(funcParam is Function) {
funcParam();
}
}
Of course, the call to funcParams() only works if the parameter list matches - is Function doesn't check for that. If there are parameters involved, one can use typedefs to ensure this.
typedef void MyExpectedFunction(int someInt, String someString);
void myMethod(MyExpectedFunction funcParam, int intParam, String stringParam) {
if(funcParam is MyExpectedFunction) {
funcParam(intParam, stringParam);
}
}
In your case, you want to check if the function can be called with zero arguments.
typedef NullaryFunction();
main () {
var f = null;
print(f is NullaryFunction); // false
f = () {};
print(f is NullaryFunction); // true
f = (x) {};
print(f is NullaryFunction); // false
}
If you just want to know that it is some function, you can test with ... is Function. All callable objects implement Function, but it is technically possible (though often not useful) to implement Function manually without actually being callable. It does make a kind of sense for objects that mock callability through noSuchMethod.
var f = () {};
print(f is Function); // 'true'
var x = (x){};
print(x is Function); // 'true'

In C++, how to use find_if on a map with a functor when keys are struct with strings?

I have a stl::map which key type is a custom struct. I want to know if this map already has a key with a specific string as component (noted as "id" below), whatever the value of its other components. Inspired by this answer and this one also, I try to use stl::find_if with a custom functor:
map<myStruct, vector<size_t> > myMap;
struct myStruct
{
string a, b, c, id;
};
struct checkId : unary_function<pair<myStruct, vector<size_t> >, bool>
{
private:
string _exp;
public:
checkId (myStruct x) : _exp(x.id) {}
bool operator() (const pair<myStruct, vector<size_t> > & p) const
{
return p.first.id.compare(_exp) == 0;
}
};
map<myStruct, vector<size_t> >::iterator it;
myStruct newS; // to be initialized, but not shown here
it_mP2P = find_if(myMap.begin(), myMap.end(), checkId(newS));
When I compile this, gcc returns me:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = myStruct]’:
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_map.h:347: instantiated from ‘_Tp& std::map<_Key,_Tp, _Compare, _Alloc>::operator[](const _Key&) [with _Key = myStruct, _Tp = std::vector<long unsigned int, std::allocator<long unsigned int> >, _Compare = std::less<myStruct>, _Alloc = std::allocator<std::pair<const myStruct, std::vector<long unsigned int, std::allocator<long unsigned int> > > >]’
myprogram.cpp:386: instantiated from here
/usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_function.h:227: error: no match for ‘operator<’ in ‘__x < __y’
Does this mean that I have to overload the operator "<" to work with my custom struct if I want to use my functor "checkId"? How can I do this? I am not a C++ expert,so thanks in advance for any piece of code.
http://codepad.org/VYNqdZeF
struct myStruct
{
std::string a, b, c, id;
bool operator<(const myStruct& rhs) const //HERES THE MAGIC
{return id < rhs.id;} //WHEEEEEEEEEEEE!
};
This is required to make std::map<myStruct, stuff> work, without passing a custom comparison functor.
It's got nothing to do with checkId. The following demonstrates the same problem:
map<myStruct, vector<size_t> > myMap;
struct myStruct
{
string a, b, c, id;
};
std::map is a sorted map (it's usually implemented as a binary search tree)... the key type (myStruct in this case) must have operator< implemented simply to construct the map.
If you don't need fast lookups, you can just use a vector< pair< myStruct, vector<size_t> > >; if you need fast lookups, you have to add some kind of structure to myStruct. For a std::map this must be a comparison operator; alternatively you can use a std::unordered_map (in C++11; this is usually implemented as a hash table) -- in this case you will need to implement a hash function.
See the documentation of std::map and std::unordered_map for more details.
This has nothing to do with your use of find_if.
For a type to be a key of a map, it needs to be comparable, either by implementing operator< or by providing a comparator as a template parameter of the map.
Mooing Duck's answer is the easiest to do, but not the most flexible
if you go and write
struct myStruct
{
std::string a, b, c, id;
bool operator<(const myStruct& rhs) const
{return id < rhs.id;}
};
then all your maps that have myStruct as a key, will have to be sorted
by id.
Suppose you have one map that needs to be compared by a, and another one by b. If you put operator<() inside your myStruct, then you will have coupled the struct with its users, tightly, which is not good programming practice.
Instead, you could set a compare function to each map:
struct myStruct
{
std::string a, b, c, id; // keep your struct unchanged, and independent of clients
};
bool Compare_by_a(const myStruct &s1, const myStruct& s2) {
return s1.a < s2.a;
}
bool Compare_by_b(const myStruct &s1, const myStruct& s2) {
return s1.b < s2.b;
}
bool Compare_by_id(const myStruct &s1, const myStruct& s2) {
return s1.id < s2.id;
}
map<myStruct, vector<size_t>, Compare_by_a > map1;
map<myStruct, vector<size_t>, Compare_by_b > map2;
map<myStruct, vector<size_t>, Compare_by_id > map3;

Custom STL Containers

I have written code that allows one to traverse mapped data in the order it was entered.
The solution I coded a couple of times was:
Given a keytype, K, and and data type, D,
std::map
std::vector
When one wanted to randomly find a data entry, use map.find(K). When one wanted to traverse the map in entry order, use std::vector::iterator (begin(), end()].
This was fine, but as an exercise, I wanted to write this 'OrderedMap' as an STL compliant container. I also have (stripped down to this discussion):
template <typename K, typename D>
class OrderedMapValue
{
private:
K first_ref;
std::map<K,size_t>& m;
std::vector<D>& v;
public:
const K& first
D& second
assignment operator=(const D& data)
{
std::map<K,size_t>::const_iterator iter = m.find(first_ref);
v[iter.second] = data; // error checking of iter stripped
}
};
Further assuming
template <typename K, typename D>
class OrderedMap
{
public:
typename OrderedMapValue<K,D>& OrderedMap<K,D>::operator[](const K&);
// snip...
};
class MyClass
{
public:
MyClass(std::string s) : _my_data(s) {}
private:
std::string _my_data;
};
The following code works:
OrderedMap<std::string,MyClass*> omap;
omap["MyKey"] = new MyClass("dummy");
However, this code does not:
OrderedMap::iterator iter = omap.find("MyKey");
MyClass * obj = iter->second;
delete obj;
iter->second = new MyClass("dummy");
Assuming I have done something
a) Structurally silly or
b) Unnecessarily complex, how should this be done?
I realize that I'm likely reinventing the wheel here, but again, this effort is mainly to increase my knowledge of STL containers, their design patterns and proper use.
Thanks in advance for any insights,
I don't have a compiler right now to test this, so there could be errors, but I think you want it more like:
template <typename K, typename D>
class OrderedMap
{
private:
std::map<K,size_t> &m;
std::vector<D> &v;
public:
typename pair<K,D> TYPE;
TYPE& operator[](const K &k)
{
return v[ m[ k ]];
}
TYPE& operator[](size_t idx)
{
return v[ idx ];
}
pair<iterator,bool> insert( const TYPE& pair )
{
map<K, size_t>::const_iterator iter;
iter = m.find( pair.first );
if( iter != m.end() )
return make_pair( v[ iter.second], false );
m.insert( make_pair( pair->first, v.size() ));
v.push_back( pair->second );
return make_pair( v.last() , inserted );
}
iterator &begin()
{
return v.begin();
}
// etc
};
In OrderedMapValue::operator=, you have:
std::map<K,size_t>::const_iterator iter = m.find(first_ref);
What is first_ref? The code doesn't reference it (no pun intended) elsewhere. It looks to me like it might be a vestige from an older implementation, replaced elsewhere by the public member
const K& first.
Could this be the problem?
EDIT from the comments: The code doesn't show that first_ref is initialized anywhere; so for all I can tell, the call to m.find(first_ref) is searching for an empty string, rather than the key for the OrderedMapValue.