Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot assign an if statement to a variable

Tags:

raku

The problem here is that I do not understand well the difference between statements and blocks in control flow.

Looking the ternary operator I can use it to assign a variable. But this is an operator, so it is like applying a function--isn't it?

> my $variable = True ?? 34 !! 42;
34 

since in the raku documentation says:

if documentation

if

To conditionally run a block of code, use an if followed by a condition. The condition, an expression, will be evaluated immediately after the statement before the if finishes. The block attached to the condition will only be evaluated if the condition means True when coerced to Bool. Unlike some languages the condition does not have to be parenthesized, instead the { and } around the block are mandatory:

do documentation

do

The simplest way to run a block where it cannot be a stand-alone statement is by writing do before it:

so this should work in both cases:

> my $variable = do {34};
34

> my $variable = if True {34;} else {43;} 
===SORRY!===
Word 'if' interpreted as a listop; please use 'do if' to introduce the statement control word
------> my $variable = if⏏ True {34;} else {43;} 
Unexpected block in infix position (two terms in a row)
------> my $variable = if True⏏ {34;} else {43;} 

as said in the error I need to add the do:

> my $variable = do if True {34;} else {43;} 
34

So the if really does not run the block...or what is the real problem here?

like image 410
anquegi Avatar asked Oct 20 '20 05:10

anquegi


People also ask

Can you assign an IF statement to a variable?

Yes, you can assign the value of variable inside if.

Can you assign a variable in an if statement Python?

For example, assignment expressions using the := syntax allow variables to be assigned inside of if statements, which can often produce shorter and more compact sections of Python code by eliminating variable assignments in lines preceding or following the if statement.

Can we use assignment operator in if condition?

Using the assignment operator in conditional expressions frequently indicates programmer error and can result in unexpected behavior. The assignment operator should not be used in the following contexts: if (controlling expression)

Can you assign a value to a function?

No, you can't assign values to functions.


Video Answer


1 Answers

TL;DR: The actual difference is between statement and expression, not statement and block. do is a statement prefix that creates expressions.


if actually creates a statement (anything that is run in Raku is), however, what it's not is an expression. do is a statement prefix, and what it does is turn statements into expressions.

However, if is not really a first-class function that you can assign to a variable or handle around. Whenever you find pieces of syntax such as that one (or for, for instance), you need to prefix them with do to "expressionify" them.

say &say.^name;# OUTPUT: «Sub␤»                                                                                                 say &do.^name; # OUTPUT: «===SORRY!=== Error while compiling <tmp>␤Undeclared  routine:␤...
say &if.^name; # OUTPUT: «===SORRY!=== Error while compiling <tmp>␤Undeclared routine:␤    if used at line 1␤␤»

So if, by itself, does not create a block, it does not create an expression, it simply creates a statement. You need to precede it with do if you want it to actually turn it into a expression. It does run the block that's behind it, however.

Let's go back to the original question, statements and blocks. Blocks are objects, first-class citizens. You can use them, apply them, pass them around.

my &ifs = { if $_ {34} else {43}};
ifs(True).say; # OUTPUT: «34␤»

Statements are throwaway blocks you simply run. In some cases, they are also expressions: they yield a result which, then, you can assign.

my &ifs = { if $_ {34} else {43}};
my $result = ifs(True).say; # OUTPUT: «34␤»
say $result;                # OUTPUT: «True␤»

The ifs(True).say statement prints to output, it also produces a result that can be assigned. All three lines are also statements, and as a matter of fact, expressions too.

Some control structures, however, do not create expressions.

Some others do; for creates a expression; while does not.

if is an example of this. They don't produce a result. You use them for the side effects: running a statement (if true) or another (if not). You might turn them into a block, as above, and pass them around. Or you can just precede them with do and make them produce a throwaway result, which you can then use.

So it will very much depend on your actual use case. You can surround the if statement with curly braces and create a block; or you can simply use the result creating an expression. Or you might want to use it just for the side effects, doing nothing.

like image 164
jjmerelo Avatar answered Sep 29 '22 13:09

jjmerelo