Trying to understand if statements in Scala - scala

I am trying to understand why my code doesn't work! I am trying to solve the classic balance parentheses problem and Im getting a no such element on my third if statement which doesn't make sense to me because I thought my second if statement would avoid that case but I dont think my second if statement is returning?
def balance(chars: List[Char]): Boolean = {
def check(left: Int,right: List[Char]): Boolean = {
if (left < 0) false
if (right.isEmpty) left == 0
if (right.head == ')') check(left + 1, right.tail)
else check(left - 1, right.tail)
}
check(0,chars.filter(x => (x == ')') || (x == '(')))
}

Following up on my comment. I don't believe that you are actually getting a Null Pointer exception. Scala doesn't encourage the use of nulls and I don't know of any case where the standard library will return a null. Nulls are encapsulated by Option.None in Scala (or see upcoming explicit nulls in Scala 3) and even when you are integrating with a Java library, it is recommended that you wrap the null behavior in an option.
That being said, under the assumption that you are getting a No Such Element Exception in reality, let's look at you code.
Understanding the return behavior in Scala
A Scala function will take the last value in it's body as it's return value. In your case it is this block
if (right.head == ')') check(left + 1, right.tail)
else check(left - 1, right.tail)
Since the previous if blocks are not conditionally linked together all 3 of them will be evaluated. Even if one of the first two evaluates the true, Scala will NOT return and continue to evaluate because it sees more code in the function body it has not computed yet.
So in this case even if the second condition is true, the third one still gets evaluated.
Use the full ternary syntax and add else
if (left < 0) false else
if (right.isEmpty) left == 0 else
if (right.head == ')') check(left + 1, right.tail)
else check(left - 1, right.tail)
More on ternary syntax here

Let us desugar check definition a little bit:
def check(...) =
{
if (left < 0) false else (); // expression 1
if (right.isEmpty) left == 0 else (); // expression 2
return if (right.head == ')') check(...) else check(...); // expression 3 (last expression)
}
Note how the semicolons ; make it clear we have three separate expressions in the expression block, and only the last one is passed to return. Now the two key concepts to understand are
conditional expressions if (š¯‘’1) š¯‘’2 else š¯‘’3 are first-class values (and not control statements)
the "returned" value of the whole block expression is only the value of the last expression in the block
Hence to fix the issue, as suggested by others, we need to connect the three separate expressions into a single expression of the form if...else if ... else if ... else.

Related

isdigit function for BCPL

I am currently programming in BCPL for an OS course and wanted to write a simple is_digit() function for validation in a program of mine.
A code snippet of my current code follows:
let is_digit(n) be {
if ((n >= '0') /\ (n <= '9')) then
resultis true;
}
I am aware that BCPL has no notion of types, but how would I be able to accomplish this sort of thing in the language?
Passing in a number yields a false result instead of the expected true.
is_digit() is a function returning a value, rather than a routine, so should use = VALOF rather than BE. Otherwise, the code is OK.
let is_digit(n) = valof {
.....
resultis true
}
Functions that return values should be using valof rather than be, the latter (a routine rather than a function) can be called as a function but the return value you get back from it will be undefined(a).
In addition, you should ensure you return a valid value for every code path. At the moment, a non-digit will not execute a RESULTIS statement, and I'm not entirely certain what happens in that case (so best to be safe).
That means something like this is what you're after, keeping in mind there can be implementation variations, such as & and /\ for and, or {...} and $(...$) for the block delimiters - I've used the ones documented in Martin's latest manual:
LET is_digit(n) = VALOF {
RESULTIS (n >= '0') & (n <= '9')
}
(a) Since Martin Richards is still doing stuff with BCPL, this manual may help in any future questions (or see his home page for a large selection of goodies).

How to avoid return statement and escape from for loop?

I've been told to avoid use of return in Scala, although I'm not sure why.
I've got the following code, and it doesn't seem to return the proper thing unless I put the return keyword in there. Why do I need to put return?
def nextParen(chars: List[Char]): List[Char] =
for(i <- 0 to chars.size - 1) {
if(chars(i) == '(' || chars(i) == ')') {
return chars.slice(i, chars.size) // return HERE!
}
}
List.empty
}
The argument for avoiding return is that it leads to code that is less readable, and not refactor-safe. It's not an absolute rule, if you find an algorithm that's best expressed that way, but usually code can be made clearer by writing it as an expression.
This particular code looks to be equivalent to:
def nextParen(chars: List[Char]) =
chars.dropWhile{c => c != '(' && c != ')'}
In general, try to focus on writing expressions rather than procedures; rather than telling the compiler what steps it should take, tell it what the value is. Even if you didn't know about dropWhile, you could write the loop as a fold (e.g. foldLeft) that says what to do at each element of the list, and then the case where the list is empty at the end would fall out naturally, rather than needing two different branches for where there is a match and where there isn't.
There's nothing wrong with using return when it clearly expresses your intent in a good algorithm. However, you should be cautious about using it because it isn't necessary, and most things you want to do already have decent implementations in the collections library.
So, for example, your code works but is O(n^2) in the size of the list because you're indexing into a linear data structure. It's much better to use
chars.dropWhile(c => c != '(' && c != ')')
or if you don't know about that, any of a huge number of alternatives:
val i = chars.indexWhere(c => c == '(' || c == ')')
if (i < 0) chars take 0 else chars drop i
var found = false
chars.filter(c => found || { found = (c == '(' || c == ')'); found })
You can probably come up with half a dozen more without trying too hard. (Fold with an indicator, for/yield with an if clause, span, etc.)
So the best reason to not use return is that you should know your library. Usually you don't need it; it's better to use a stock method that computes what you want.
You are using a for in the imperative sense above. You don't have to use a return if you use it in a more functional sense i.e., as a for-yield or fold or takeWhile.
I think one of the biggest thing to wrap your head around when you move from imperative to functional (side-effect free) is the notion that you can express your code a sequence of expressions, each of which evaluates to a value. For example, a for-yield expression evaluates to a value. So in an imperative world you are executing a sequence of statements that is changing the state (data structures, console etc) around you.
PS: I've used a lot of terms (e.g., side-effect, for-yield, value) that may sound unfamiliar to a new Scala programmer. But with more experience they will make more sense. I would highly recommend this book - Structure and Interpretation of Computer Programs

Why does != 0 cause a compiler error

The following Statement causes a compiler error:Type '()' does not conform to protocol 'LogicValue'. In the second line
var b=1
if b!=0
{
println("not 0")
}
But
var b=1
if (!(b==0))
{
println("not 0")
causes no compiler error.
For what reason 0 can't be compared using the != Operator, but can be compared using the == Operator ?What is the best way to deal with this?
This is probably due to the lack of whitespace around your != operator - Swift is quite fussy about whitespace, and interprets operators differently depending on their surrounding whitespace.
The language specification describes the various rules, although it is not particularly obvious from these that b!=0 should be invalid.
So you probably need to say b != 0 rather than b!=0
See also: Is this response from the compiler valid?
What's wrong with a nice and simple b != 0? It's easy to read and easy to implement.
The reason why the second option works is because the ! here means "not". So if b equalled 0, the statement would be "not True", or "False".
It's a case of missing whitespace:
var b=1
if b != 0 {
println("not 0")
}
compiles fine.

Scala return does not return

There is some misunderstanding between me and Scala
0 or 1?
object Fun extends App {
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) { // when this is true
return 1 // and we are about to return 1, the code goes to the next line
}
foo(list.tail, count + 1) // I know I do not use "return here" ...
count
}
val result = foo( List(1,2,3) )
println ( result ) // 0
}
Why does it print 0?
Why does recursion work even without "return"
(when it is in the middle of function, but not in the end)?
Why doesn't it return 1? when I use "return" explicitly?
--- EDIT:
It will work if I use return here "return foo(list.tail, count + 1)'.
Bu it does NOT explain (for me) why "return 1" does not work above.
If you read my full explanation below then the answers to your three questions should all be clear, but here's a short, explicit summary for everyone's convenience:
Why does it print 0? This is because the method call was returning count, which had a default value of 0ā€”so it returns 0 and you print 0. If you called it with count=5 then it would print 5 instead. (See the example using println below.)
Why does recursion work even without "return" (when it is in the middle of function, but not in the end)? You're making a recursive call, so the recursion happens, but you weren't returning the result of the recursive call.
Why doesn't it return 1? when I use "return" explicitly? It does, but only in the case when list is empty. If list is non-empty then it returns count instead. (Again, see the example using println below.)
Here's a quote from Programming in Scala by Odersky (the first edition is available online):
The recommended style for methods is in fact to avoid having explicit, and especially multiple, return statements. Instead, think of each method as an expression that yields one value, which is returned. This philosophy will encourage you to make methods quite small, to factor larger methods into multiple smaller ones. On the other hand, design choices depend on the design context, and Scala makes it easy to write methods that have multiple, explicit returns if that's what you desire. [link]
In Scala you very rarely use the return keyword, but instead take advantage that everything in an expression to propagate the return value back up to the top-level expression of the method, and that result is then used as the return value. You can think of return as something more like break or goto, which disrupts the normal control flow and might make your code harder to reason about.
Scala doesn't have statements like Java, but instead everything is an expression, meaning that everything returns a value. That's one of the reasons why Scala has Unit instead of voidā€”because even things that would have been void in Java need to return a value in Scala. Here are a few examples about how expressions work that are relevant to your code:
Things that are expressions in Java act the same in Scala. That means the result of 1+1 is 2, and the result of x.y() is the return value of the method call.
Java has if statements, but Scala has if expressions. This means that the Scala if/else construct acts more like the Java ternary operator. Therefore, if (x) y else z is equivalent to x ? y : z in Java. A lone if like you used is the same as if (x) y else Unit.
A code block in Java is a statement made up of a group of statements, but in Scala it's an expression made up of a group of expressions. A code block's result is the result of the last expression in the block. Therefore, the result of { o.a(); o.b(); o.c() } is whatever o.c() returned. You can make similar constructs with the comma operator in C/C++: (o.a(), o.b(), o.c()). Java doesn't really have anything like this.
The return keyword breaks the normal control flow in an expression, causing the current method to immediately return the given value. You can think of it kind of like throwing an exception, both because it's an exception to the normal control flow, and because (like the throw keyword) the resulting expression has type Nothing. The Nothing type is used to indicate an expression that never returns a value, and thus can essentially be ignored during type inference. Here's simple example showing that return has the result type of Nothing:
def f(x: Int): Int = {
val nothing: Nothing = { return x }
throw new RuntimeException("Can't reach here.")
}
Based on all that, we can look at your method and see what's going on:
def foo(list:List[Int], count:Int = 0): Int = {
// This block (started by the curly brace on the previous line
// is the top-level expression of this method, therefore its result
// will be used as the result/return value of this method.
if (list.isEmpty) {
return 1 // explicit return (yuck)
}
foo(list.tail, count + 1) // recursive call
count // last statement in block is the result
}
Now you should be able to see that count is being used as the result of your method, except in the case when you break the normal control flow by using return. You can see that the return is working because foo(List(), 5) returns 1. In contrast, foo(List(0), 5) returns 5 because it's using the result of the block, count, as the return value. You can see this clearly if you try it:
println(foo(List())) // prints 1 because list is empty
println(foo(List(), 5)) // prints 1 because list is empty
println(foo(List(0))) // prints 0 because count is 0 (default)
println(foo(List(0), 5)) // prints 5 because count is 5
You should restructure your method so that the value that the body is an expression, and the return value is just the result of that expression. It looks like you're trying to write a method that returns the number of items in the list. If that's the case, this is how I'd change it:
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) count
else foo(list.tail, count + 1)
}
When written this way, in the base case (list is empty) it returns the current item count, otherwise it returns the result of the recursive call on the list's tail with count+1.
If you really want it to always return 1 you can change it to if (list.isEmpty) 1 instead, and it will always return 1 because the base case will always return 1.
You're returning the value of count from the first call (that is, 0), not the value from the recursive call of foo.
To be more precise, in you code, you don't use the returned value of the recursive call to foo.
Here is how you can fix it:
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) {
1
} else {
foo(list.tail, count + 1)
}
}
This way, you get 1.
By the way, don't use return. It doesn't do always what you would expect.
In Scala, a function return implicitly the last value. You don't need to explicitly write return.
Your return works, just not the way you expect because you're ignoring its value. If you were to pass an empty list, you'd get 1 as you expect.
Because you're not passing an empty list, your original code works like this:
foo called with List of 3 elements and count 0 (call this recursion 1)
list is not empty, so we don't get into the block with return
we recursively enter foo, now with 2 elements and count 1 (recursion level 2)
list is not empty, so we don't get into the block with return
we recursively enter foo, now with 1 element and count 2 (recursion level 3)
list is not empty, so we don't get into the block with return
we now enter foo with no elements and count 3 (recursion level 4)
we enter the block with return and return 1
we're back to recursion level 3. The result of the call to foo from which we just came back in neither assigned nor returned, so it's ignored. We proceed to the next line and return count, which is the same value that was passed in, 2
the same thing happens on recursion levels 2 and 1 - we ignore the return value of foo and instead return the original count
the value of count on the recursion level 1 was 0, which is the end result
The fact that you do not have a return in front of foo(list.tail, count + 1) means that, after you return from the recursion, execution is falling through and returning count. Since 0 is passed as a default value for count, once you return from all of the recursed calls, your function is returning the original value of count.
You can see this happening if you add the following println to your code:
def foo(list:List[Int], count:Int = 0): Int = {
if (list.isEmpty) { // when this is true
return 1 // and we are about to return 1, the code goes to the next line
}
foo(list.tail, count + 1) // I know I do not use "return here" ...
println ("returned from foo " + count)
count
}
To fix this you should add a return in front of foo(list.tail.....).
you return count in your program which is a constant and is initialized with 0, so that is what you are returning at the top level of your recursion.

irrespective of the values, the if block is executing in C#

if (updateYN.ToUpper() != Constants.NO
|| updateYN.ToUpper() != Constants.N)
{
// execute code for any other updateYN
}
I am trying to perform a filtration that if the value of updateYN is not NO(Constants.NO) or N(Constants.N), then execute the statement.
But the problem is that, irrespective of the values, the if block is executing.
It seems like you want an AND statement...no? (NOT NO AND NOT N)
Logically think about it this way:
your statement breaks down into three components
a = updateYN.ToUpper() != Constants.NO
b = updateYN.ToUpper() != Constants.N
c = a or b
But if you think about it, if updateYN.ToUpper() is Constants.NO then a is false, but b is true, and thus c is true. And if updateYN.ToUpper() is Constants.N then b is false, but a is true, and thus c is true. What you seem to want is
if(updateYN.ToUpper() != Constants.NO && updateYN.ToUpper() != Constants.N)
This means that updateYN.ToUpper() must equal something other than Constants.NO and Constants.N in order for the entire statement to be true.
OK, your problem is you are translating language to code. Your statement should be:
if (updateYN.ToUpper() != Constants.NO
&& updateYN.ToUpper() != Constants.N)
{
// execute code for any other updateYN
}
This tells the compiler that updateYN.ToUpper() should not be NO and should not be N.
EDIT: To make it more clear why your if condition is always getting concluded, here is some explanation. Imagine this statement:
if (x != 1 || x != 2)
{
...
}
You would imagine that if x is 1 or 2, the block shouldn't be executed, but it WILL, because this statement consists of two parts actually:
x != 1
x != 2
The or part tells the compiler that if any of these conditions is true, then the whole condition is true. Obviously, if x is 1, then it is not 2, so the condition is fulfilled, and same thing if it is 2. Think of all the values in the world, they can't be equal to 1 and 2, so this block will always get executed. Same with your case here. Hope that explains your problem well.
If Constants.NO and Constants.N are not equal, this is always true. It is probably always different from either NO or N.