I am writing a function to remove a list of elements from another list. So given a list of elements to be removed [a c] and the list to remove it from [c b d a e] I want to run rembero twice on the list and have it return [b d e]. I have written a pretty messy recursion and it seems to work. However when I am scaling up the rest of my program I start to get a stack overflow and I think this recursion could be one of the pain points. Does anyone have any advice on a better way of doing this?
;;recursion to remove a list of inputs from the world state
(defn rembero-all [lst state temp]
(conde
[(== lst ())
(== state temp)]
[(fresh [fst rst rectemp]
(conso fst rst lst)
(rembero fst state temp)
(rembero-all rst temp rectemp))]))Hi! I would write something like this (dunno if this impl is correct 😆), not for performance but in my opinion is more readable. Be ware that pattern matching (matche defne ) shadows local variable names.
;;modified from rembero implementation
(defne rembero-all
"relation where `o` is the result of removing all occurrences of `x` from `l`"
[x l o]
([_ [] []])
([_ [y] []] ;; edited
(== x y))
([_ [y . ys] [z . zs]] ;; edited
(== x y)
(!= x z)
(rembero-all x ys o))
([_ [y . ys] [y . zs]]
(!= y x)
(rembero-all x ys zs)))
(defne rembero-many
"relation where `o` is result of removing all items `xs` from `l`"
[xxs l o]
([_ [] []])
([[] ys ys])
([[x . xs] _ _]
(fresh [l']
(rembero-all x l l')
(rembero-many xs l' o))))
(run 1 [q]
(rembero-many [1 2 3] [1 4 2 5 3 7 1 8 2 9 3] q))
Sorry, I can't help with performance 😅