I'm new to Scheme and am trying to have an if-statement perform more than one action if its condition is true. I tried something like:
(if (char=? (string-ref str loc) #\a)
((+ count 1) (+ reference 1))
~else action, etc.~
And it complains about my action, saying
application: not a procedure
If I remove the parentheses, so that the action for a true condition is:
(+ count 1) (+ reference 1)
It complains
if: bad syntax
and fails to run at all. What am I missing?
A nested if in C is an if statement that is the target of another if statement. Nested if statements mean an if statement inside another if statement. Yes, both C and C++ allow us to nested if statements within if statements, i.e, we can place an if statement inside another if statement.
The if-else statement is used to execute both the true part and the false part of a given condition. If the condition is true, the if block code is executed and if the condition is false, the else block code is executed.
There are two problems with the code. The first, an if
form can't have more than one expression in the consequent and in the alternative. Two possible solutions for that - you can either use begin
(not just a couple of parenthesis, that's for procedure application) to surround multiple expression:
(if (char=? (string-ref str loc) #\a)
; needs an explicit `begin` for more than one expression
(begin
(+ count 1)
(+ reference 1))
; needs an explicit `begin` for more than one expression
(begin
~else action, etc~))
... or use a cond
, which is a better alternative because it already includes an implicit begin
:
(cond ((char=? (string-ref str loc) #\a)
; already includes an implicit `begin`
(+ count 1)
(+ reference 1))
(else
; already includes an implicit `begin`
~else action, etc~))
The second problem is more subtle and serious, both of the expressions in the consequent part are probably not doing what you expect. This one: (+ count 1)
is doing nothing at all, the incremented value is lost because you didn't use it after incrementing it. Same thing with the other one: (+ reference 1)
, but at least here the value is being returned as the result of the conditional expression. You should either pass both incremented values along to a procedure (probably as part of a recursion):
(cond ((char=? (string-ref str loc) #\a)
; let's say the procedure is called `loop`
(loop (+ count 1) (+ reference 1)))
(else
~else action, etc~))
Or directly update in the variables the result of the increments, although this is not the idiomatic way to write a solution in Scheme (it looks like a solution in C, Java, etc.):
(cond ((char=? (string-ref str loc) #\a)
; here we are mutating in-place the value of the variables
(set! count (+ count 1))
(set! reference (+ reference 1)))
(else
~else action, etc~))
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