Problem with NOT operator in Swift clauses - swift

I'm programming in Swift 5.0 an app to move my character around a world and I've some problems with the NOT (!) operator in the if condition body.
I wrote:
if character.!isBlocked {
character.moveForward()
}
but the compiler say: Error: ".!" it's not a binary operator
Instead, if I wrote
if character.isBlocked {
character.turnBack()
}
it works perfectly. Its possible to use a negative clause as if condition clause?

If you are aiming to validate as "if not", then you should implement it as:
if !character.isBlocked {
character.moveForward()
}
The logical NOT ! operator is a unary prefix operator:
Unary: it is for a single target.
Prefix: it should be before the target.
So, why it should be before character.isBlocked but not isBlocked?
Because character.isBlocked is the boolean to evaluate, isBlocked is the property name. The correct syntax is to use ! to evaluate the whole thing (Boolean value).

Related

In Flutter/Dart, what is the difference between using "==" vs "is" in a conditional if statement [duplicate]

This question already has answers here:
What is the difference between 'is' and '==' in Dart?
(2 answers)
Closed 2 years ago.
I am doing a tutorial on BLoC in Flutter and the tutor uses the keyword "is" in his conditional if statement, which he said "smartcasts" the state. Can anyone help me understand how the "is" operator gives me access to the bloc's state in the code below?
BlocBuilder<WeatherBloc, WeatherState>(
builder: (context, state) {
if (state is WeatherLoaded) {
return buildColumnWithData(context,state.weather);
}
When I tried the same code with if (state == WeatherLoaded), I'm not able to pass the state.weather into the buildColumnWithData function. Why is this?
'==' is an equality operator.
To test whether two objects x and y represent the same thing, use the == operator. (In the rare case where you need to know whether two objects are the exact same object, use the identical() function instead.) Here’s how the == operator works:
If x or y is null, return true if both are null, and false if only one is null.
Return the result of the method invocation x.==(y). (That’s right, operators such as == are methods that are invoked on their first operand. For details, see Operators.)
'is' is a type test operator
The result of obj is T is true if obj implements the interface specified by T. For example, obj is Object is always true.
In your code:
is checks if state is instance of WeatherLoaded class.
On top of that, you don't need to make a cast to WeatherLoaded if the check was successful - in the scope of the if statement state variable is downcast to WeatherLoaded ("is smartcasts the state").
With == operator, you can compare 2 instances of a class.

Overloading operators for a class

Let's say I have the following class:
class A {
has $.val;
method Str { $!val ~ 'µ' }
}
# Is this the right way of doing it?
multi infix:<~>(A:D $lhs, A:D $rhs) {
('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}
How would I overload an operator (e.g., +) for a class in the same manner as Str in the previous class?
I guess this only works for methods that are invoked on an instance object and using the multi operator-type:<OP>(T $lhs, T $rhs) { } syntax for operators is the right way to go about it but I'm unsure.
For instance, in Python there seems to be a correspondence between special methods named after the operators (e.g., operator.__add__) and the operators (e.g., +). Furthermore, any operator overloading for a custom class is done inside the class.
In Perl 6, operators are considered part of the current language. All things that relate to the current language are defined lexically (that is, my-scoped). Therefore, a multi sub is the correct thing to use.
If putting this code in a module, you would probably also want to mark the multi for the operator with is export:
multi infix:<~>(A:D $lhs, A:D $rhs) is export {
('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}
So that it will be available to users who use or import the module (use is in fact defined in terms of import, and import imports symbols into the lexical scope).
While there are some operators that by default delegate to methods (for example, prefix:<+> calls Numeric), there's no 1:1 relation between the two, and for most operators their implementation is directly in the operator sub (or spread over many multi subs).
Further, the set of operators is open, so one is not restricted to overloading existing operators, but can also introduce new ones. This is encouraged when the new meaning for the operator is not clearly related to the normal semantics of the symbol used; for example, overloading + to do matrix addition would be sensible, but for something that couldn't possibly be considered a kind of addition, a new operator would be a better choice.
class A {
has $.val;
method Str { $!val ~ 'µ' }
}
multi infix:<~>(A:D $lhs, A:D $rhs) {
('(', $lhs.val, ',', $rhs.val, ')', 'µ').join;
}
dd A.new(val => "A") ~ A.new(val => "B"); # "(A,B)µ"
So yes, that is the correct way. If you want to override +, then the name of the sub to create is infix:<+>.
You can also provide the case for type objects by using the :U "type smiley", e.g.:
multi infix:<~>(A:U $lhs, A:U $rhs) {
'µ'
}
Hope this answers your question.

Xtext, Xbase: infer questions

I'm going to write an inferrer for my dsl and I have some questions that I could not solve with only the help of documentation.
First one:
I need to create static void main() from a feature: how can I add static with .toMethod()?
Second one:
Suppose I have a rule in my dsl like this:
Sequence:
'SEQ' name=ID '{'
statements+=Statement*
'}'
;
Where Statement:
Statement:
Sequence | others...
;
Sequence must be mapped to a void method and the body of that method is composed from the traslation of statements.
But the problem is this: when inside a Sequence I'll find another Sequence I have to create a method for the new sequence and add a call in super sequence.
For example:
SEQ first {
instructions...
SEQ second {
other instructions....
}
instructions...
}
Must generate:
void first(){
instructions(translated)...
second();
instructions(translated)...
}
void second(){
other instructions(translated)...
}
Is it possible to realize it?
First question:
ctx.toMethod('main', ctx.newTypeRef(Void.Type)) [
static = true
….
]
Second question:
Implying that with 'instructions' you mean instances of 'XExpression', you need to trick a bit, as it is currently not possible to compose new expressions during inference.
What you coudl basically do is to make your Sequence a subtype of XExpression. Then during JvmModelInference you need to walk over your expression tree (Statement) and create methods for Sequences. you need to override the XbaseTypeComputer as well as the XbaseCompiler and add type computation and compile strategies for your expressions. The latter would be a call to the method created during inference.

ternary in postlude?

Can I do ternary in the postlude(s) the same way that I do them int he prelude? In other words have it fire off different calls depending on the say something was evaluated in the prelude?
Yes. You can include a guard condition on a postlude expression. This works for both explicit event raising and persistant variable modification. The expression following if can be any valid expression, including functions.
Example:
fired {
raise explicit event "foo" if cheese == 5;
}

; expected but <place your favourite keyword here> found

I'm trying to write a class for a scala project and I get this error in multiple places with keywords such as class, def, while.
It happens in places like this:
var continue = true
while (continue) {
[..]
}
And I'm sure the error is not there since when I isolate that code in another class it doesn't give me any error.
Could you please give me a rule of thumb for such errors? Where should I find them? are there some common syntactic errors elsewhere when this happens?
It sounds like you're using reserved keywords as variable names. "Continue", for instance, is a Java keyword.
You probably don't have parentheses or braces matched somewhere, and the compiler can't tell until it hits a structure that looks like the one you showed.
The other possibility is that Scala sometimes has trouble distinguishing between the end of a statement with a new one on the next line, and a multi-line statement. In that case, just drop the ; at the end of the first line and see if the compiler's happy. (This doesn't seem like it fits your case, as Scala should be able to tell that nothing should come after true, and that you're done assigning a variable.)
Can you let us know what this code is inside? Scala expects "expressions" i.e. things that resolve to a particular value/type. In the case of "var continue = true", this does not evaluate to a value, so it cannot be at the end of an expression (i.e. inside an if-expression or match-expression or function block).
i.e.
def foo() = {
var continue = true
while (continue) {
[..]
}
}
This is a problem, as the function block is an expression and needs to have an (ignored?) return value, i.e.
def foo() = {
var continue = true
while (continue) {
[..]
}
()
}
() => a value representing the "Unit" type.
I get this error when I forget to put an = sign after a function definition:
def function(val: String):Boolean {
// Some stuff
}