I imlemented quicksort using SWISH this way:
qsort([],[]).
qsort([H|T],S) :-
partition([X,O]>>compare(O,X,H),T,L,E,G),
qsort(L,A),
qsort(G,Z),
append([A,[H|E],Z],S).
main :-
length(L,22),
maplist(random(0,9),L),
qsort(L,S),
maplist(writeln,[L,S]).
It doesn't work correctly. The input and output lists are the same. However when I run this in the REPL there on the right:
length(S,22), maplist(random(0,9),S),[H|T]=S, partition([X,O]>>compare(O,X,H),T,L,E,G).
the random lists do get sorted. Whence the difference?
When the second clause for the qsort/2
predicate is compiled, there's no information on H
other than it's a variable when compiling the lambda expression. Any variable occurring in the lambda expression that's not find in a local lambda parameter must be declared using the {}/1
construct. But when running your query at the top-level interpreter, by the time the lambda expression is interpreted, H
is bound and thus no longer a variable (making the use of the {}/1
construct unnecessary).
Note that there are several details here at play that are out of scope of the lambda library itself: (1) is the compiler recognizing at compile time that you're calling a meta-predicate with an argument that's a lambda expression? (2) how's a top-level query interpreted? Is the full query first fully compiled or is it meta-interpreted? These details depend on the system itself.