Type specification for if/else braces in dart - flutter

I'm beginner in dart language and Flutter SDK.
I try to make clear code by using analysis_option.yml from official flutter project.
I get stuck on this warning :
It seems that adding <dynamic> before the brace removes the warning, but it makes no sense for me.
Someone can explain why this is necessary ? And how a scope can return a type ?

It's because you put => <dynamic> at the beginning of the anonymous function:
// vv vvvvvvvvv
.then((dynamic currentUser) => <dynamic> {
By doing this, instead of an anonymous function with a body, you have declared a lambda function that returns a Set<dynamic>. Moving on:
if (currentUser == null)
<dynamic> {...}
Dart is now thinking you are defining elements of a Set. Dart also supports collection conditionals, so your if/else are being interpreted as conditionals in a Set literal.
(If you don't know what collection conditionals are, it's similar to Python compositions and basically means that [ 1, if (false) 2 else 3 ] will produce the list [1, 3].)
And so because you also provided a body for the if statement but didn't have a semicolon at the end of its single statement, Dart is once again thinking you are specifying a Set. Because the Dart auto-formatter is so helpful, it is helpfully suggesting that you add an explicit type annotation to your Set literal that you've "defined" under the else statement.
else
{...}
// Dart formatter: "It looks like you are trying to create
// a `Set<dynamic>`. Do you need some help
// with that?"
Essentially, the root cause is because of the =>. In Dart, you only use => if you are defining a lambda, a.k.a. a single line anonymous function. (Compared to Javascript, which uses => for all of its anonymous functions, lambda or not. Isn't being a multi-lingual programmer the greatest?)
If you take out the => <dynamic> it should fix all the "errors".

Related

Is there way to use ternary expression with a continue statement inside a loop in Dart

I'm trying to use a ternary expression along with a continue or break construct inside a do-while loop in Dart but I get a compilation error.
do
{
expr ? print('Conditionally print something') : continue;
}while(expr == true);
The above code fails at compile-time but if I use a pair of if-else decision structure, the code works. So, the question to the community is why the ternary expression is not working along with continue or break construct?
The ternary operator takes 3 expressions in the form of (expr1) ? (expr2) : (expr3).
You can't execute statements in ternary operator, nor only in dart but in other languages also. Since break and continue are not expressions but statements they cant be used here
No, you can't do it.
continue is a Dart Statement (read below), and print is a function
First
In the Dart Language Specification section 17.23 explains how it works.
https://dart.dev/guides/language/specifications/DartLangSpec-v2.10.pdf
Search the original document, because the copy/paste doesn't seems to work well.
17.23 Conditional conditional
A conditional expression evaluates one of two expressions based on a boolean
condition.
{conditionalExpression} ::= {ifNullExpression}
(‘?’ {expressionWithoutCascade} ‘:’ {expressionWithoutCascade})?
Evaluation of a conditional expression c of the form e1?e2 : e3 proceeds as
follows:
First, e1 is evaluated to an object o1. It is a dynamic error if the runtime type of o1 is not bool. If r is true, then the value of c is the result of
evaluating the expression e2. Otherwise the value of c is the result of evaluating
the expression e3.
Second
As you can see the ternary operator requires expressions, but continue, in the same PDF of language specification is defined as an statement, a reserved word, as:
18 Statements statements
A statement is a fragment of Dart code that can be executed at run time.
Statements, unlike expressions, do not evaluate to an object, but are instead
executed for their effect on the program state and control flow
Third
in the case of print, it's taken as a function I guess, didn't find the specification. Perhaps it returns void.
We can still ask ourselves, why can't we put continue in a function, even in a lambda like () => { continue; } or similar. The short answer is that as said in the specification for the continue statement, if it's not inside a while, etc. is gonna give a compile error. And if it's inside a function, it will prevent that function to reach the return statement, and again, the ternary will expect a return value.
We can still research a little more, many things are inside the specification.
When something like this happens, you can also search without specifying the language, to get information on JAVA or C# that may help you.
Java: Ternary with no return. (For method calling)
It seems that Swift language would allow continue and break inside the ternary, as per this article - https://forums.swift.org/t/bringing-control-flow-keywords-to-the-ternary-operator/13878
Because a ternary operator is returning a value. With the following syntax:
condition ? expresion1 : expression2
which means:
If condition is true, it return expression1. If it is not it return expression2.
So, you can't use statement like this:
print('Conditionally print something')
or
continue
An expression evaluates to a value. A statement does something.

Understanding Safe.Coerce in Purescript

I've been looking at the compiled version of some code snippets to dig into how my code is represented at runtime.
I'm not surprised to see that safe coerce and unsafe coerce are the same in the compiled JavaScript. There's a dictionary passed into safe coerce that's unused/undefined in the code I've looked at so far.
It seems like if the runtime representation of two types is the same, then there shouldn't be any runtime overhead for having/using such a type. This isn't true and I'm curious to understand why.
Coercing two types requires a function call at runtime. What I'm not understanding is that this function call appears to do nothing.
exports.unsafeCoerce = function (x) {
return x;
};
If I declare a newtype
newtype Selection = Selection Int
I see something similar in JavaScript:
var Selection = function (x) {
return x;
};
Which means I might see something like this in JavaScript:
return Selection(Data_Int.pow(2)(Safe_Coerce.coerce()(n) - 1 | 0));
which should be identical to this:
return Data_Int.pow(2)(n - 1 | 0);
In this case, both Selection and coerce only ever return what they're given. Once the type checking has been done, I'm not sure what purpose they continue to serve.
The reason the code is generated like it is, and not in a more efficient form like you suggest, is because the purs compiler has only a simplistic optimiser.
Why unsafeCoerce is defined as it is is because it is a PureScript function and must match the runtime representation of PureScript functions. Same goes for Selection.
Constraints are represented as functions on dictionaries. Some time ago there was an optimisation added such that empty dictionaries do not have to be constructed as empty JavaScript objects, and instead can be represented by undefined. That is why there is no argument passed to coerce.

Matching against the enclosing function's return type

Is it possible for a Rust macro to match against the enclosing function's return type?
An example is something like a logging and assert macro which also returns Err in functions returning Result and panics in functions not returning Result. To implement this the macro should somehow know about the enclosing function's return type.
I suppose this is not possible with declarative macros (macro_rules!) because they have a limited set of matching types (as described in The Rust Reference, chapter Macros By Example): items, blocks, statements, patterns, expressions, types, identifiers, and so on, but not the enclosing function's return type.
But perhaps with procedural macros?
Summary: No, it's not easily possible, even with procedural macros. And I actually think you shouldn't write such a thing, even if it's possible. Just let your macro evaluate to a Result and let the user deal with it.
Function-like macro
Rust macros, procedural and declarative, only have access to their input stream: just a list of tokens. For function-like macros (the ones you invoke via foo!(...)), the input is just what you pass to them. So you could manually pass the return type:
macro_rules! foo {
(Result $($stuff:tt)*) => { return Err(()); };
($($stuff:tt)*) => { panic!(); };
}
fn returns_result() -> Result<String, ()> {
foo!(Result<(), ()>); // will return `Err`
Ok("hi".into())
}
fn returns_string() -> String {
foo!(String); // will panic
"hi".into()
}
But I guess that is not what you want: the user would have to manually specify the return type for each macro invocation.
The same goes for procedural macros that are invoked this way.
Procedural macro attribute
Can we define a procedural macro where the return type of the function is in the input token stream? Yes, preferably via a proc-macro attribute. If you define such an attribute bar, you could write this:
#[bar]
fn returns_result() -> Result<String, ()> { ... }
And your procedural macro would receive the whole function definition as input, including the return type. But what are you going to do with that information?
You can change the whole function as you like, so one idea would be to search for all foo!() macro invocations in the function and replace them with return Err or panic!() depending on the return type. That is: do the macro invocation step for your own macros via a procedural macro.
But I think this is a bad idea for several reasons. Most importantly, I don't think it's well defined when the compiler calls the procedural macro. So the compiler could attempt to invoke your foo!() macros before calling the procedural macro.
So it could work via procedural macro, but not in a way that is typical. So it's rather hacky.
What I think is the best solution
Lastly, how would I do it? Let your macro evaluate to a Result. Then the user can easily decide themselves what to do with it. If they return a Result, they just need to add ?. If they don't, they have the freedom to choose between .unwrap(), expect() and other ways to panic.
I understand why you are trying to do what you want to do (it's easier for the user and comfortable), but I think it's not a good idea. It probably comes down to "spooky action at a distance": what a macro in your function does suddenly depends on the return type of that function. That means when you change that, the whole semantics of the function change. This sounds like something you could shoot yourself in the foot with very easily. That's also probably the reason why it's not easy in Rust.

Spread syntax in function call in Reason

In Javascript you can use the spread syntax in a function call like this:
console.log(...[1,2,3]);
Is there an equivalent in Reason? I tried the following:
let bound = (number, lower, upper) => {
max(lower, min(upper, number));
};
let parameters = (1,0,20);
bound(...parameters) |> Js.log;
But this gives an unknown syntax error:
Try reason snippet
There's not. Reason is a statically typed language, and lists are dynamically-sized and homogenous. It would be of very limited use, and not at all obvious how it would deal with too few or too many arguments. If you want to pass a list, you should just accept a list and deal with it appropriately, as a separate function if desired.
You could of course use a tuple instead, which is fixed-size and heterogenous, but I don't see a use-case for that either, since you might as well just call the function directly then.
For JavaScript FFI there is however the bs.splice attribute, which will allow you to apply a variable number of arguments to a js function using an array. But it needs to be called with an array literal, not just any array.

How to use Javascript's for (attr in this) with Coffeescript

In Javascript, the "for (attr in this)" is often dangerous to use... I agree. That's one reason I like Coffeescript. However, I'm programming in Coffeescript and have a case where I need Javascript's "for (attr in this)". Is there a good way to do this in Coffeescript?
What I am doing now is writing a bunch of logic in embedded raw Javascript, such as:
...coffeescript here...
for (attr in this) {
if (stuff here) {
etc
}
}
It'd be nice to use as little Javascript as possible... any suggestions for how I can achieve this and maximize my use of Coffeescript?
Instead of for item in items which iterates through arrays, you can use for attr, value of object, which works more like for in from JS.
for own attr, value of this
if attr == 'foo' && value == 'bar'
console.log 'Found a foobar!'
Compiled: https://gist.github.com/62860f0c07d60320151c
It accepts both the key and the value in the loop, which is very handy. And you can insert the own keyword right after the for in order to enforce an if object.hasOwnProperty(attr) check which should filter out anything from the prototype that you don't want in there.
Squeegy's answer is correct. Let me just amend it by adding that the usual solution to JavaScript's for...in being "dangerous" (by including prototype properties) is to add a hasOwnProperty check. CoffeeScript can do this automatically using the special own keyword:
for own attr of this
...
is equivalent to the JavaScript
for (attr in this) {
if (!Object.prototype.hasOwnProperty(this, attr)) continue;
...
}
When in doubt about whether you should use for...of or for own...of, it's generally safer to use own.
You can use for x in y or for x of y depending on how you want to interpret a list of elements. The newest version of CoffeeScript aims to solve this problem, and you can read about its new use with an issue (that has since been implemented and closed) here on GitHub