Find the Kth Element, official
№3.1 · 99 Picat ProblemselementAt([X|_],1) = X.
elementAt([_|Xs],K) = Kth, K > 1 => Kth = elementAt(Xs,K-1).
Explanation
In the original breakdown we used a simpler guard syntax, but the official solution from picat-lang.org demonstrates an important pattern for using guards with function return values.
Base case (line 1):
elementAt([X|_],1) = X.
- When K = 1 (first position), return the head of the list
- The tail is ignored with
_since we found our element
Recursive case with guard (line 2):
elementAt([_|Xs],K) = Kth, K > 1 => Kth = elementAt(Xs,K-1).
This line demonstrates the guard pattern for functions:
= Kth- Introduces a variable to hold the return value, K > 1- Guard condition (comma means "and also check this")=>- Separates the guard from the function bodyKth = elementAt(Xs,K-1)- Computes the actual return value
Why use this pattern? Because guards must come before the =>, we need a place to put them. We can't write:
elementAt([_|Xs],K) = elementAt(Xs,K-1), K > 1. % Syntax error!
The guard must precede =>, so we introduce an intermediate variable:
elementAt([_|Xs],K) = Kth, K > 1 => Kth = elementAt(Xs,K-1).
Think of it as: "This function returns Kth, but only if K > 1, and here's how to compute Kth..."
Complete Example
main =>
go_03_1.
go_03_1 =>
A = [5,4,3,2,1],
B = elementAt(A, 2),
println(B).
elementAt([X|_],1) = X.
elementAt([_|Xs],K) = Kth, K > 1 => Kth = elementAt(Xs,K-1).
How it works:
elementAt(A, 2)finds the element at position 2 (1-based indexing)- The guard
K > 1ensures we only recurse when K is greater than 1 println(B)outputs4(the second element)
Example Execution
elementAt([5,4,3,2,1], 2)
→ elementAt([4,3,2,1], 1), K > 1 check passes (K=2 > 1, recurse)
→ 4 (K=1, base case)
The guard ensures we don't try to recurse when K = 1.
Takeaways
-
Guard syntax with functions: When you need guards in a function clause, use the pattern
= Result, guard => Result = expression. This is different from simpler functions where you can write= expressiondirectly. -
Why not just
K > 1after the equals? Picat's syntax requires guards to come before=>. Compare:% Our simpler version (Problem 3) elementAt([_|Xs], K) = elementAt(Xs, K-1), K > 1. % Official version (Problem 3.1) elementAt([_|Xs],K) = Kth, K > 1 => Kth = elementAt(Xs,K-1).The official version is more explicit about the guard-checking phase vs. the computation phase.
-
Intermediate variables with guards: The
Kthvariable serves as a placeholder for the return value. It's bound after the guard succeeds. This pattern appears throughout idiomatic Picat code when combining guards with function return values. -
Both work: The simpler syntax from Problem 3 and this official syntax both accomplish the same goal. The official version is more consistent with how guards work elsewhere in Picat (with predicates and backtracking).