Unnamed Constructors In dart - dart

I have the following code in dart:
class Complex {
num real;
num imaginary;
Complex(this.real, this.imaginary);
Complex.real(num real) {
Complex(real, 0);
print('function constructed!!!');
}
}
void main() {
var a = Complex.real(1);
}
Therefore, I would like to know here what is wrong in the constructor: Complex.real... I had this question after watching tensor programming tutorial on dart on youtube #14:40.
And why is the initializer operator used instead Complex.real(num real) : this(real, 0); ?

Complex.real(num real) {
Complex(real, 0);
print('function constructed!!!');
}
invokes the unnamed constructor (Complex(real, 0)) to construct a different Complex instance and then discards the result. Your Complex.real constructor therefore produces an uninitialized object. You can observe this:
Complex.real(num real) {
Complex(real, 0);
print('${this.real}'); // Prints: null
}
The syntax for making one constructor leverage another is to use this in an initializer list:
Complex.real(num real) : this(real, 0);
As #lrn pointed out, redirecting constructors can't have a body, so to have the print line you'd need to use a factory constructor (or a static method):
factory Complex.real(num real) {
final complex = Complex(real, 0);
print('function constructed!!!');
return complex;
}

Related

Dafny "call might violate context's modifies clause"

I'm new to Dafny. I'm getting the error: call might violate context's modifies clause on the line where Seek() calls Step() in the following code:
class Tape {
var val : int;
constructor() {
this.val := 0;
}
method Write(x : int)
modifies this
{
this.val := x;
}
}
class Simulator {
var tape : Tape;
var step_num : nat;
constructor() {
this.tape := new Tape();
this.step_num := 0;
}
method Step()
modifies this, this.tape
ensures this.step_num > old(this.step_num)
{
this.tape.Write(1);
this.step_num := this.step_num + 1;
}
method Seek(target_step_num : int)
modifies this, this.tape
{
while this.step_num < target_step_num {
this.Step();
}
}
}
I don't understand what's going on here because I explicitly annotated Seek() with modifies this, this.tape.
Looking around online I see some talk about "freshness" and I get the impression that this has to do with ensuring that I have permission to access this.tape, but I don't understand how to fix it. Thanks!
You need invariant that this.tape is not reassigned to something else in methods. Adding ensures this.tape == old(this.tape) post condition in Seek and Step and also adding invariant this.tape == old(this.tape) fixes it.
FWIW, in addition to Divyanshu's excellent answer, I also discovered that I could fix this issue by defining tape as a const:
class Simulator {
const tape : Tape;
var step_num : nat;
...
In this case, it appears that const means that the pointer/reference will never be modified (that it will never point to a different Tape object), not that the Tape object itself will be unmodified.

C++ set with customized comparator crashes on insert

STL set can have customized comparator. It can be implemented in several ways, such as define an operator(), use decltype on lambda, etc. I was trying to use a static method of a class and encountered a weird crash. The crash can be demonstrated by the following code
#include <string>
#include <set>
struct Foo {
static bool Compare(std::string const& s1, std::string const& s2)
{
return s1 < s2;
}
};
std::set<std::string, decltype(&Foo::Compare)> S;
int main()
{
S.insert("hello");
S.insert("world");
return 0;
}
The crash happened on the second insert. Thank you.
You have to pass pointer to compare function to set constructor, otherwise it is null and it is why the code fails.
std::set<std::string, decltype(&Foo::Compare)> S{&Foo::Compare};
By decltype(&Foo::Compare) you only specify the type of comparator, it has to be provided because its default value is null.
Change your code to below will solve the problem.
struct Foo {
bool operator()(std::string const& s1, std::string const& s2)
{
return s1 < s2;
}
};
std::set<std::string, Foo> S;
The original program crushes because the constructor of set will try to call the constructor of decltype(&Foo::Compare) which is actually not constructible.

Instantiating a subclass in a superclass?

abstract class A {
A(this.x, this.y);
// error: abstract classes cannot be instantiated
//
// another issue: even if you used a base concrete class
// to perform this operation, it would lose type information.
A copy({int? x, int? y}) => A(x ?? this.x, y ?? this.y);
final int x;
final int y;
}
class B extends A {
// Forced to implement copy and similar
// methods on all classes that extend A,
// which is problematic when that number
// is large or changes are necessary.
}
Is there a way to solve this problem or do I have to essentially rewrite the same code for all classes that extend A?
You can, but it requires you to do quite a lot of the work
you are asking to avoid:
class A<T extends A<T>> {
final T Function(int, int) _constructor;
final int x;
final int y;
A._(this._constructor, this.x, this.y);
T copy({int? x, int? y}) => _constructor(x ?? this.x, y ?? this.y);
}
class B extends A<B> {
B(int x, int y) : super._((int x, int y) => B(x, y), x, y);
}
(The code will get shorter when Dart gets constructor tear-offs, then it's just, super._(B, x, y);.)
You cannot, currently, inherit constructors, and you can't create an instance of a type that you don't know yet (because constructors are not inherited, so you don't know if the constructor exists). The only way to abstract over actual behavior (which code to run) is to capture it in a closure and pass it as a function.

Dart argument definition test deprecated?

On Dart 1.0.0, I just tried:
class MyClass {
int x;
bool b;
MyClass(int x, [bool b = true]) {
if(?b) {
// ...
}
}
}
And am getting a compiler error on the ?b part:
The argument definition test ('?' operator) has been deprecated
So what's the "new" way of testing for whether or not an argument was supplied?
There is no way to test if an argument was provided or not. The main-reason for its removal was, that it was very complex to forward calls this way.
The generally preferred way is to use null as "not given". This doesn't always work (for example if null is a valid value), and won't catch bad arguments. If null is used, then the parameter must not have a default-value. Otherwise the parameter is not null but takes the default-value:
foo([x = true, y]) => print("$x, $y");
foo(); // prints "true, null"
So in your case you should probably do:
class MyClass {
int x;
bool b;
MyClass(int x, [bool b]) {
if(b == null) { // treat as if not given.
// ...
}
}
}
This makes new MyClass(5, null) and new MyClass(5) identical. If you really need to catch the first case, you have to work around the type-system:
class _Sentinel { const _Sentinel(); }
...
MyClass(int x, [b = const _Sentinel()]) {
if (b == const _Sentinel()) b = true;
...
}
This way you can check if an argument has been provided. In return you lose the type on b.
The argument definition test operator was deprecated because it was redundant with checking for null; an optional parameter that was omitted would get the value null, and the caller could've passed null explicitly anyway. So instead use == null:
class MyClass {
int x;
bool b;
MyClass(int x, [bool b]) {
if (b == null) {
// throw exception or assign default value for b
}
}
}

Assign function/method to variable in Dart

Does Dart support the concept of variable functions/methods? So to call a method by its name stored in a variable.
For example in PHP this can be done not only for methods:
// With functions...
function foo()
{
echo 'Running foo...';
}
$function = 'foo';
$function();
// With classes...
public static function factory($view)
{
$class = 'View_' . ucfirst($view);
return new $class();
}
I did not found it in the language tour or API. Are others ways to do something like this?
To store the name of a function in variable and call it later you will have to wait until reflection arrives in Dart (or get creative with noSuchMethod). You can however store functions directly in variables like in JavaScript
main() {
var f = (String s) => print(s);
f("hello world");
}
and even inline them, which come in handy if you are doing recusion:
main() {
g(int i) {
if(i > 0) {
print("$i is larger than zero");
g(i-1);
} else {
print("zero or negative");
}
}
g(10);
}
The functions stored can then be passed around to other functions
main() {
var function;
function = (String s) => print(s);
doWork(function);
}
doWork(f(String s)) {
f("hello world");
}
I may not be the best explainer but you may consider this example to have a wider scope of the assigning functions to a variable and also using a closure function as a parameter of a function.
void main() {
// a closure function assigned to a variable.
var fun = (int) => (int * 2);
// a variable which is assigned with the function which is written below
var newFuncResult = newFunc(9, fun);
print(x); // Output: 27
}
//Below is a function with two parameter (1st one as int) (2nd as a closure function)
int newFunc(int a, fun) {
int x = a;
int y = fun(x);
return x + y;
}

Resources