Control-Flow structures
The control flow of Jacy is mostly inspired by Rust.
We've got if/if let as an expression, loop as an expression, while/while let and for.
while/while let and for are statements, because:
- Why we need to use them as expressions if they return
()(unit) - I'm trying to solve the problem above, and it will be solved they'll become expression which returns an any-type value
- If I made them expressions then it would break backward compatibility:
- You could put them in expression place, but they returned
(), and in the new version, they started returning some non-()value
- You could put them in expression place, but they returned
if/if let
if is an expression, works the same as in other languages, here's nothing to say about except that I need to note that
Jacy does not support implicit bool conversion even through operator overloading like C++ does.
if let
if let is a way to check if some value matches a specific pattern. Also, as this is a pattern matching we able to
destruct our value.
Syntax is following.
ifLetExpression: 'if let' pattern '=' expr block
while/while let
while is a statement that works the same as while in other c-like languages
while let is the same as while except that its condition behaves like if let.
while/while let are expressions
Here are some thoughts about possible solutions.
while myval {
// Do something if `myval` is true
} else {
// Do something if `myval` is false (at first)
}
It is an obvious solution, but has some problems:
As far as
whilecan return some value it must explicitlybreakwith value. We cannot just use the last statement of thewhileblock as the result value, becausewhileis possibly multiple-times iterable.If we don't
breakwith value, then what would be the result? - It cannot be simply written in asm-like code with jumps, because we don't know when ourwhile"does not break".
Problem example.
let a = while myval {
if somethingElse => break true
} else {
false
}
- What is the type of this
whileexpression? -bool | (), but we don't support inferred union types.
For now, I cannot come up with any good solution, so while is a statement. Anyway, let's try something:
IDEA #1 This one requires static-analysis (maybe complex).
let a = while myval {
if somethingElse => break true
break false
} else {
false
}
We can analyze this code and say that each break-value is bool, so we allow this.
What about this?.
let a = while myval {
if somethingElse => break true
} else {
false
}
Each break-value is of type bool, so we allow it because the alternative workflow is an infinite loop.
We required some static-analysis on while, which is, as I see, is not really complex and not differs much from the
if expression value inference. The only problem is that the use cases of while-else are not common, especially when
we cover only this use case.
let a = if myval {
let mut result = false
while myval {
// ...
if somethingElse {
result = true
break
}
}
return result
} else {
false
}
for loop
for-loop is a statement, not an expression, here, problems with making it an expression are the same as for while
(read above) but even more complex. for-loop in Jacy has only one syntax (for ... in ...) same as Rust, which
covers all usages (almost) of for-loop from C++.
The syntax is the following.
forLoop: 'for' pattern 'in' expression block
Examples.
// In C++ we write
for (int i = 0; i < something; i++) {
// ...
}
```jc
// In Jacy:
for i in 0..=something {
// ...
}
// In C++
for (const auto & x : vec) {
// ...
}
// In Jacy
for x in &vec {
// ...
}