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 theif
finishes. The block attached to the condition will only be evaluated if the condition meansTrue
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?
Yes, you can assign the value of variable inside if.
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.
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)
No, you can't assign values to functions.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With