The error I'm getting is missing an "else" expression in:
(if (not (eq? current_token next_token))
(return #f))
I have the else statement in the image below as you can see. Just not sure why the program can't find it.
scheme code image
Images are really poor way to include code in your questions. For every if you need 3 additional elements. (if predicate consequence alternative). In the code you included there are the form (not (eq? current_token next_token)) that is the predicate, then you have (return #f) which is the consequet, but you have no alternative for when the predicate is false. It has nothing to do with the else term in the cond because that is optional and it's a pert of the cond not the if that is in one of the cond consequents.
So how I see it when current-token and next-token both are symbols the conseqent is evaluated. Once a term hit it will it will do the consequences and not other tems will be visited. The if then checks if the two are the same. If they are not the same the error happens.
Note that the syntax of an if conditional is:
(if test-expr then-expr else-expr)
such that if test-expr produces any value other than #f, then then-expr gets evaluated, and if #f is produced, else-expr gets evaluated.
You currently have the following:
(if (not (eq? current_token next_token)) (return #f))
which is equivalent to:
(if test-expr then-expr)
; test-expr = (not (eq? current_token next_token))
; then-expr = (return #f)
; Not complete - missing an else expression
Add an else expression to fix the problem.
For example:
> (if true 0) ; test-expr = true, then-expr = 0
if: missing an "else" expression in: (if true 0)
> (if true 0 1) ; test-expr = true, then-expr = 0, else-expr = 1
0
> (if false 0 1) ; test-expr = false, then-expr = 0, else-expr = 1
1
Related
The following code was an attempt at a recursive bubble sort in F#, where I received the error
"This expression was expected to have type 'unit' but here has type ''a []'"
for the middle three lines:
let swap i j (arr : 'a []) =
let tmp = arr.[i]
arr.[i] <- arr.[j]
arr.[j] <- tmp
let rec recursiveBubbleSort i j (sequence : 'a []) =
if i = sequence.Length then sequence //error
elif j = sequence.Length then recursiveBubbleSort (i+1) 0 sequence //error
elif sequence.[i] > sequence.[j] then swap i j sequence //error
recursiveBubbleSort i (j+1) sequence
This is really puzzling me, as all of the resources I have found haven't sufficiently explained or implied why this is actually occurring. Any help would be greatly appreaciated.
I think this is what you wanted to write:
let rec recursiveBubbleSort i j (sequence : 'a []) =
if i = sequence.Length then sequence
elif j = sequence.Length then recursiveBubbleSort (i+1) 0 sequence
else
if sequence.[i] > sequence.[j] then swap i j sequence |> ignore
recursiveBubbleSort i (j+1) sequence
So, the last elif you wrote has to be an else, within that else there is another if that checks whether to perform the swap or not.
All if .. then, including elif or not, must end with an else unless it's a unit expression (as the call to swap).
That's why you were getting that error.
Finally note that your comparison is inverted, you will sort the list in descending order.
I got this problem in a coding challenge. I couldn't solve it on time but I still want to know how could it be done. I am not very familiar with expression trees and I found it hard to model the problem. The description goes like this:
Input: expression_tree | sequence_of_operations
The input is a single line of text with a expression tree and a sequence of operations separated by | character and ended by a \n newline character. Spaces are allowed in the input but should be ignored.
The expression tree is a sequence of 1-character variables A-Z and with sub expression trees formed by parenthesis (expression_tree). Examples: AB, A(B C D), (AB)C((DE)F)
The sequence of operations is a string of with characters R (reverse) or S (simplify)
Reverse means reverse the order of everything in expression tree. Applying reverse twice in a row cancels out.
Example: (AB)C((DE)F) | R should print (F(ED))C(BA)
Simplify means remove the parentheses around the very first element in the expression tree and each of its subexpression trees. Applying S multiple times should have same result as applying S once.
Example: (AB)C((DE)F) | S should print ABC(DEF)
Output: Read the expression tree and apply the sequence of operations from left to right to the expression tree, print out the result without characters.
What I would like to know the most is how to model the expression tree to handle the parentheses and how does the simplify operation should work?
'''
Examples are as follows :
INPUT:
(AB)(C(DE))/SS
(((AB)C)D)E/SS
(((AB)C)D)E/SR
(AB)C((DE)F)/SRS
(AB(CD((EF)G)H))(IJ)/SRS
(AB(CD((EF)G)H))(IJ)/SSSRRRS
(A(B(C)D)E(FGH(IJ)))/SRRSSRSSRRRSSRS
(A(BC(D(E((Z)K(L)))F))GH(IJK))/S
-------------------------------
OUTPUT:
AB(C(DE))
ABCDE
EDCBA
FEDCBA
JI(H(GFE)DC)BA
JI(H(GFE)DC)BA
JIHFGE(D(C)B)A
A(BC(D(E(ZK(L)))F))GH(IJK)/S
'''
'''
operationReverse function returns a reversed expression tree
Example : AB(CD) -> (DC)BA
'''
def operationReverse(expression):
'''============== Reversing the whole expressions ================'''
expression = expression[::-1]
expression = list(expression)
'''========= Replace Closing brace with Opening brace and vice versa ========='''
for x in range(0, len(expression)):
if(expression[x] != ')' and expression[x] != '('):
continue
elif(expression[x] == ")"):
expression[x] = "("
else:
expression[x] = ")"
expression = ''.join(expression)
return expression
'''
operationSimplify function returns a simplified expression tree
Example : (AB)(C(DE)) -> AB(C(DE))
operationSimplify uses recursion
'''
def operationSimplify(expression):
'''========= If no parenthesis found then return the expression as it is because it is already simplified ========='''
'''========= This is also the base condition to stop recursion ============='''
if(expression.find('(')==-1):
return expression
'''If 1st character is opening brace then find its correspoinding closing brace and remove them and call the function by passing the values between the opening and closing brace'''
if(expression[0] == '('):
x = 1
#numOfOpeningBrackets = maintains the count of opening brackets for finding it's corresponding closing bracket
numOfOpeningBrackets = 1
while(x < len(expression)):
if(expression[x] != ')' and expression[x] != '('):
x = x + 1
continue
elif(expression[x] == "("):
numOfOpeningBrackets = numOfOpeningBrackets + 1
x = x + 1
else:
numOfOpeningBrackets = numOfOpeningBrackets - 1
if(numOfOpeningBrackets == 0):
posOfCloseBracket = x
break
x = x + 1
expression = operationSimplify(expression[1:posOfCloseBracket]) + expression[posOfCloseBracket+1:]
'''========= If no parenthesis found then return the expression as it is because it is already simplified ========='''
if(expression.find('(')==-1):
return expression
'''========= Find the opening brace and it's closing brace and new expression tree will be concatenation of start of string till opening brace including the brace and string with in the opening brace and closing brace passed as an argument to the function itself and the remaining string ========='''
x = 0
#numOfOpeningBrackets = maintains the count of opening brackets for finding it's corresponding closing bracket
recursion = False
numOfOpeningBrackets = 0
while (x < len(expression)):
if(expression[x] != ')' and expression[x] != '('):
x = x + 1
elif(expression[x] == "("):
if(numOfOpeningBrackets == 0 or recursion == True):
numOfOpeningBrackets = 0
recursion = False
posOfStartBracket = x
y = x
numOfOpeningBrackets = numOfOpeningBrackets + 1
x = x + 1
else:
numOfOpeningBrackets = numOfOpeningBrackets - 1
if(numOfOpeningBrackets == 0):
posOfCloseBracket = x
x = y
expression=expression[0:posOfStartBracket+1]+operationSimplify(expression[posOfStartBracket+1:posOfCloseBracket])+expression[posOfCloseBracket:]
recursion = True
x = x + 1
return expression
'''
solution fucntion prints the final result
'''
def solution(inputString):
'''========= Remove the spaces from the input ==============='''
#inputString = inputString.replace("\n","")
inputString = inputString.replace(" ","")
inputString = inputString.replace("\t","")
#inputString = inputString.replace("()","")
'''=============== The substring before '/' is expression tree and substring after '/' is sequence of operations ======================'''
#posOfSlash = Position Of Slash Character
posOfSlash = inputString.find('/')
if(posOfSlash == -1):
print (inputString)
return
#expressionTree = Expression Tree
expressionTree = inputString[0:posOfSlash]
#seqOfOp = sequence of operations to be performed
seqOfOp = inputString[posOfSlash+1:]
'''============ If sequence Of Operations is empty then print the expression tree as it is ============== '''
if(len(seqOfOp)==0):
print(expressionTree)
return
'''============= Removing all the pairs of RR from the sequence Of Operations =================='''
seqOfOp = seqOfOp.replace(r+r,'')
'''============ All mulptiple S are replaced by one single S ================'''
while(seqOfOp.find(s+s) != -1):
seqOfOp = seqOfOp.replace(s+s,s)
'''============ If to perform operation R then call operationReverse() else if to perform operation S call operationSimplify() ================'''
for x in range (0 , len(seqOfOp)):
if(seqOfOp[x] == r):
expressionTree = operationReverse(expressionTree)
else :
expressionTree = operationSimplify(expressionTree)
print(expressionTree)
return
'''======= Global variables r and s representing operations R and S'''
r = 'R'
s = 'S'
while True:
try:
inputString = input()
'''==================== Calling function solution ======================'''
solution(inputString)
except EOFError:
break
This question already has answers here:
Rewrite variable in Erlang
(3 answers)
Closed 6 years ago.
I has code that is looking for max palindrome, alias N = reverse(N). The code isn't complete yet. But help me please find out reason of exception.
find_palindrome(List1, List2, Increment, IfPalindrome) ->
List_of_values = [X * Y || X <- List1, Y <- List2],
find_palindrome(0, 1, List_of_values, Increment, IfPalindrome).
find_palindrome(Max, N, List_of_values, Increment, IfPalindrome) ->
case IfPalindrome(lists:nth(N, List_of_values)) of
true ->
case Max < lists:nth(N, List_of_values) of
true ->
Max = lists:nth(N, List_of_values),
find_palindrome(Max, Increment(N), List_of_values, Increment, IfPalindrome);
false ->
find_palindrome(Max, Increment(N), List_of_values, Increment, IfPalindrome)
end;
false ->
find_palindrome(Max, Increment(N), List_of_values, Increment, IfPalindrome)
end.
check_palindrome(N) ->
(N) == (list_to_integer(lists:reverse(integer_to_list(N)))).
problem4() ->
find_palindrome(lists:seq(100, 999), lists:seq(100, 999), fun(X) -> X = X + 1 end, fun check_palindrome/1).
I am constantly getting exception:
** exception error: no match of right hand side value 2
in function euler4:'-problem4/0-fun-0-'/1 (euler4.erl, line 36)
in call from euler4:find_palindrome/5 (euler4.erl, line 28)
Try this in Erlang shell:
1> X = 1.
1
2> X = X + 1.
** exception error: no match of right hand side value 2
This is because in Erlang variables can only be assigned once. It's called single assignment. Once a variable is bound to a value, that variable can't be be bound to any other value. The value stored in a variable can't change. You need to create a new variable. In this particular case you could write:
3> Y = X + 1.
2
You should know that = is really a pattern matching operator, not assignment. The left-hand side can be any pattern, not just a variable. You can write e.g. 2 = 1 + 1 and this will successfully match, while 3 = 1 + 1 will give you no match of right hand side value 2. And bound variables can be used in the pattern for their values, e.g. X = 2, X = 1 + 1 will succeed.
So in Max = lists:nth(N, List_of_values), because Max is already bound (as the argument of the function), its value is used, and it ends up being 0 = lists:nth(1, List_of_values) (with values from find_palindrome(0, 1, List_of_values, Increment, IfPalindrome) which will fail unless List_of_values starts with 0.
Coming from a Lisp background, Erlang's case statement seems a bit baffling to me. I'm currently working on the Sieve of Eratosthenes problem, trying to generate a list of the prime factors of a number N. However I can't seem to migrate what seems like a simple cond statement in Lisp to the equivalent in Erlang.
So far I have constructed an if statement that resembles how I would go about things in Lisp:
prime_factors(N) -> pf_helper(N, [], 2).
pf_helper(M, PL, D) ->
if
prime_p(M) == true -> [ M | PL ];
(prime_p(D) == true) and (M rem D == 0) -> pl_helper(M div D, [ D | PL ], D+1);
(prime_p(D) == true) and (M rem D /= 0) -> pl_helper(M, PL, D+1);
prime_p(D) == false -> pl_helper(M, PL, D+1)
end.
I am aware that this will not compile since I can only have BIF calls in my guards. The problem is that I cannot conceptualize how this would run as a case statement, since case handles a conditional expression on one argument. In the case that I represent the three pf_helper arguments in a tuple:
pf_helper(M,PL,D) -> pf_helper({M, PL, D}).
what would the patterns be inside the case statements that correspond to the conditional expressions
prime_p(M) == true
(prime_p(D) == true) and (M rem D == 0)
(prime_p(D) == true) and (M rem D /= 0)
prime_p(D) == false
?
Use some guards:
case {prime_p(M), prime_p(D)} of
{true, _} -> [M|PL];
{false, true} when (M rem D == 0) -> ...;
{false, true} when (M rem D /= 0) -> ...;
{false, false} -> ...
end
I think Anthony Ramine was working on implementing cond at one point.
Suppose we have 3 variables and we need to ASSERT that they can either all be equal to -1 or neither can be equal to -1. I wrote the following code:
x := 1;
y := 1;
z := 1;
ASSERT( (x = -1) = (y = -1) = (z = -1) );
I often write this kind of check, but for two variables. Surprisingly the triple comparison compiled too, but it doesn't work as expected. For (1, 1, 1) values I expect it to evaluate to true. After substitution of variable values and simplification we get:
ASSERT( False = False = False );
and I thought that it should evaluate to True, but it doesn't. So how is this triple comparison evaluated?
First of all, the = operator is a binary operator: it always works on a pair of values. So there's no such thing as a "triple equality". The compiler will evaluate one pair, and use the result to evaluate the other.
When the compiler sees multiple linked operators, it needs to group them into pairs using what's called the "precedence of operators". It's clear if you think about the basic arithmetic operators we learned in primary school. There's no doubt what: 3+2*4 evaluates to: it's equivalent to 3+(2*4). When in doubt, always add the grouping yourself. If you do that, you see your expression is equivalent to:
((False = False) = False), and it's obvious it evaluates to:
(True = False).
What you probably want is to use the AND operator and group your initial Assert like this:
ASSERT(((x = -1) = (y = -1)) and ((y = -1) = (z = -1)))
Then I'd probably either write that expression on multiple lines to make the AND operator obvious (SQL habit, I know), or rewrite it completely:
Assert (
((x = -1) = (y = -1))
and
((x = -1) = (z = -1))
);
or this variant:
Assert (
((x = -1) and (y = -1) and (z = -1))
or
((x <> -1) and (y <> -1) and (z <> -1))
);
My rule is: if it takes more then 1 second to figure out the precedence of operators, add parentheses.
Comparison is associative: False=False=False is equivalent to (False=False)=False. The first False=False evaluates to True, leading to comparison True=False which in turn is False.