I am strugging a bit to implement a nested if else expressions in SML. Can anyone highlight its syntax. Suppose there are three conditions C1, C2, C3 I need equivalent of following in C code.
if (C1) {
return true;
}
else {
if(C2) {
return true;
}
else {
if (C3) {
return true;
}
else {
return false;
}
}
}
I tried the following, but its treated as "if, else if, and else" cases
if C1 then true
else if C2 then true
else if C3 then true
else false
You're correct. Two code fragments are equivalent.
With a bit of indentation, your SML example looks more like using nested if/else:
if C1 then true
else
if C2 then true
else
if C3 then true
else false
You could also use parentheses so that SML example looks almost the same as C example but it isn't necessary.
Of course, the most idiomatic way in SML is to write
C1 orelse C2 orelse C3
You could use the same trick for your C code. Remember that returning true/false in if/else blocks is code smell.
I agree that using orelse is the right way to go here, but just as an alternative to situations where you want to act on more complex combinations, pattern matching would be able to help you.
fun funtrue (false,false,false) = false
| funtrue _ = true
or as a case statement
case (C1,C2,C3) of
(false,false,false) => false
| _ => true
Related
In the book The Practice of Programming, there's a short snippet of C code that implements a regex matcher. Brian W Kernighan has expanded on that chapter and published it online at https://www.cs.princeton.edu/courses/archive/spr09/cos333/beautiful.html
Robs C code relies on the '\0' sentinels for length matching, but that won't work in Rust. So my port of the code ends up with lots of length checks.
I use slices to byte arrays to simplify the task a bit, instead of supporting utf-8 encoded strings.
The implementation consists of three functions re_match, match_here and match_star. I use ranges for iterating over the slices.
// Search for regex anywhere in the text.
fn re_match(regex: &[u8], text: &[u8]) -> bool {
if regex.len() > 0 && regex[0] == b'^' {
return match_here(®ex[1..], &text);
}
// We need to check even if text is empty
if match_here(regex, text) {
return true
}
for i in 0..text.len() {
if match_here(regex, &text[i..]) {
return true
}
}
false
}
// Search for regex at beginning of text
fn match_here(regex: &[u8], text: &[u8]) -> bool {
if regex.len() == 0 {
return true;
}
if regex.len() > 1 && regex[1] == b'*' {
return match_star(regex[0], ®ex[2..], text);
}
if regex.len() == 1 && regex[0] == b'$' {
return text.len() == 0;
}
if text.len() > 0 && (regex[0] == b'.' || regex[0] == text[0]) {
return match_here(®ex[1..], &text[1..]);
}
false
}
// Search for c* regex at beginning of text.
fn match_star(c: u8, regex: &[u8], text: &[u8]) -> bool {
if match_here(regex, text) {
return true;
}
let mut i = 0;
while i < text.len() && (text[i] == c || c == b'.') {
if match_here(regex, &text[i..]) {
return true;
}
i += 1;
}
false
}
Question
How can I rewrite these kind of functions to not need so many length checks?
META: Should I use iterators instead of slices as parameters? When choose one over the other?
For the match_here I would use match with the underappreciated slice-pattern syntax. That would avoid most len() uses. Using is_empty() is nicer than len() == 0:
fn match_here(regex: &[u8], text: &[u8]) -> bool {
match regex {
&[] => true,
&[b'$'] => {
text.is_empty()
}
&[z, b'*', ref tail # ..] => {
match_star(z, tail, text)
}
&[z, ref tail # ..] if if !text.is_empty() && (z == b'.' || z == text[0]) => {
match_here(tail, &text[1..])
}
_ => false,
}
}
Or if you feel fancy you can do a double match:
fn match_here(regex: &[u8], text: &[u8]) -> bool {
match (regex, text) {
(&[], _) => true,
(&[b'$'], &[]) => true,
(&[b'$'], _) => false,
(&[z, b'*', ref tail # ..], txt) => {
match_star(z, tail, txt)
}
(&[z, ref tail # ..], &[]) => false,
(&[z, ref tail # ..], &[tz, ref ttail # ..]) => if z == b'.' || z == tz => {
match_here(tail, ttail)
}
_ => false,
}
}
The cool thing about this latter option is that since you are never using the index operator [x] you are sure you will never go out of bounds, without ever checking the len() of your slices.
The len() of the other functions, I don't particularly see them as non-idiomatic. They may be rewritten in a more rusty way, but then the equivalence to the C code would not be so obvious. You would need to stop and think!
About using iterators or slices, I personally prefer slices for this kind of things. The problem with iterators is the backbuffer, for example, to check for the x* you need to take two bytes from the iterator, but then, if the second one is not a * you have to put it back... Naturally you can use Iterator::peek but that will only give you one element. If at any time you need to look ahead two bytes, you have a problem.
So unless you need to parse a very big input (> hundreds of MBs) I would stick to the plain slices.
Having the equals ignore case option
if (bookType.equals(Type.BABY.name, true))
Is there an option to do contain similar with ignore case?
val validTypes = listOf("Kids", "Baby")
if (validTypes.contains(bookType)))
I see there is an option of doing :
if (bookType.equals(Type.BABY.name, true) || bookType.equals(Type.KIDS.name, true))
But I want more elegant way
Could use the is operator with a when expression, and directly with book rather than bookType:
val safetyLevel = when (book) {
is Type.BABY, is Type.KIDS -> "babies and kids"
is Type.CHILD -> "okay for children"
else -> "danger!"
}
See Type checks and casts.
Perhaps you could make the valid types list all uppercase then you can do the following:
You could use map to convert the case for all items in the list e.g.
validTypes.contains(bookType.uppercase())
Or you could use any (https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/any.html)
validTypes.any { bookType.uppercase() == it }
If you want to keep the casing of your original list you could do:
validTypes.any { bookType.replaceFirstChar { it.uppercaseChar() } == it }
Why is the else statement is not allowed to have a then or other conditions?
Is it because it is the final condition within the else-if conditions it represents?
I am struggling to understand this concept since I'm a beginner who just learned about variables.
I'm asking this because I received an error with my else statement in the code:
message = 0
condition = 30
if condition <=10
message = “try harder”
elseif
condition <=20 then
message = "Almost learning"
else
condition = <=30 **—This is the line where I get the error message**
message = "Now you’re getting it"
end
print(message)
Would appreciate someone breaking down in laymen terms, why else is not allowed to have < or > or then or other conditions.
else condition = <= 30
(which is the way your code was originally formatted) would be a very unusual feature in a language.
The whole point of else on its own is to execute if none of the other conditions were true. So a condition on the else is absolutely useless.
The Programming in Lua book if statement shows the normal usage:
if op == "+" then
r = a + b
elseif op == "-" then
r = a - b
elseif op == "*" then
r = a*b
elseif op == "/" then
r = a/b
else
error("invalid operation")
end
However, your actual code (when formatted correctly) ends up looking like:
else
condition = <=30
which is correct in terms of the else but unfortunately makes the next line a statement. And this statement is very much incorrect syntax.
Now it may be that you meant to assign 30 to condition but, based on your other lines (that sort of match this as a condition), I suspect not. So it's probably best just to remove that line totally.
if (Condition1)
{
dothis;
}
else if (Condition1)
{
dothat;
}
Out of curiosity, when I invoke the same condition for the else if, will the dothat part of the code still execute when Condition1 is satisfied? Does this vary from programming language to programming language?
What you wrote is basically equivalent to
if(Condition1)
{
dothis;
}
else
{
if(Condition1)
{
dothat;
}
}
So no, it will never be called.
No, the second condition will never be executed in any language. Here is a basic flowchart of your logic.
However, if Condition1 somehow evaluates to false in the first condition and true in the second, then the second will be called. Example:
<?php
$var = true;
function condition() {
global $var;
$var = !$var;
return $var;
}
if(condition()) {
echo "Conditional 1";
} elseif(condition()) {
echo "Conditional 2";
}
In this case, "Conditional 2" will be printed because condition() first evaluates to false, and then to true.
While at most one branch is executed1 per if-else-statement, in cases where the "condition" contains a a side-effect, it might not always be the if branch that is executed.
For instance, consider this JavaScript code with a side-effect introduced by the "condition" expression.
y = -1;
if (++y) { // the "condition" is ++y
alert("1")
} else if (++y) {
alert("2")
}
Only one branch ("2") was executed, but the same "condition" was used in both cases. For such reasons it can be problematic to have side-effects in conditionals.
1 In all modern mainstream languages the conditions for an if-else are evaluated "on demand" and "in order". Thus the first branch for which the condition evaluates to true is executed, regardless of other side-effects, and it is the only branch executed.
The second if follows an else – consequently, it will only be executed if the first if does not succeed. So – no; the dothat will not be executed. All (sane) programming languages do this.
However, some programming languages have special constructs for an else if, and you have to write it as one statement, variously called elif, elsif or ElseIf, depending on the language.
Since Condition1 evaluated to True the if's "dothis" will be invoked and skip over the else if. If you wanted to invoke the dothis and dothat then you would have two if statements with the same Condition1 or just put both dothis and dothat under one if statement. This is what I have seen in computer programming languages I have used.
Python example.
b = 2
if b == 2:
print "Hello"
elif b == 2:
print "World"
...
Hello
so here is my code
a="yes"
b="no"
c=a[0].upper() + a[1:]
d=b[0].upper() + b[1:]
e=a.upper()
f=b.upper()
def shut_down(s):
if s == a or c or e:
return "Shutting down..."
if s == b or d or f:
return "Shutdown aborted"
else:
return"yeah"
so when i call up the function it doesn't execute properly(it doesn't run through all the if statement) i am new to python and don't know why is this but when i redo the work like the following it works as intended
a="yes"
b="no"
c=a[0].upper() + a[1:]
d=b[0].upper() + b[1:]
e=a.upper()
f=b.upper()
def shut_down(s):
if s == a:
return "Shutting down..."
if s== e:
return "Shutting down..."
if s ==c:
return "Shutting down..."
if s == b:
return "Shutdown aborted!"
if s == d:
return "Shutdown aborted!"
if s == f:
return "Shutdown aborted!"
else:
return "Sorry, I didn't understand you."
can anyone tell me why is this happening
The issue is with the expression s == a or c or e (and its variations) which doesn't do what you intend.
It is evaluated like this: (s == a) or bool(c) or bool(e). Since c and e are always "truthy" values (being non-empty strings), the or expression ends up always being true.
There are a few alternative solutions:
You could distribute out the equality test in your current version of the expression, resulting in s == a or s == c or s == e, but that's a lot of repeated text.
Another alternative is to use the in operator which tests if a value is in a container: s in (a, c, e). That's less typing, but it still does three tests.
A better solution would allow you to avoid the multiple tests completely. Instead, you can make a single test that is completely case-insensitive: s.lower() == a.
With the third solution, there's no need to calculate the variables c, d, e, or f (and you could even put the "yes" and "no" literals directly in the tests, allowing a and b to go away too!). It will match a few more input texts (e.g. "yEs"), but that's probably a feature, rather than a bug.
This is an issue commonly experienced by new programmers; the computer does not behave how one would expect it to, but rather how it is told to.
The equality comparison is not distributed across all or terms, but rather is only performed on only the first. You must provide it in all terms yourself:
if s == a or s == c or s == e:
Python also has an alternate syntax for this (although operation is not quite the same), based on containment checking:
if s in (a, c, e):
In this case we have only two operands for in, and distribution across the tuple elements is not required.