I know that continuations can be used to implement cooperative multitasking, but is it possible to implement preemptive multitasking with continuations?
@mskoh52 has joined the channel
You need some extra ingredient, such as an asynchronous timer where you can attach a continuation capture and swap to the timer expiration.
Hi everyone. I came up with this function to move an element inside a list. Does this seem like a reasonable way to do it?
(define (reorder-list lst find-item find-new-successor)
(define (extract lst pred)
(let ([result (foldl (lambda (x acc)
(if (pred x)
(cons x (cdr acc))
(cons (car acc) (cons x (cdr acc)))))
(cons '() '())
lst)])
(values (car result) (cdr result))))
(letrec-values ([(it filt) (extract lst (λ (x) (find-item x)))]
[(front back) (splitf-at filt (λ (x) (not (find-new-successor x))))])
(if (null? back)
(cons it front)
(reverse (append front (cons (car back) (cons it (cdr back))))))))
It takes a list and two predicate functions, one for the item you want to move and one for the item you want to move in front of. I’m assuming here that the list is all unique elements w.r.t. the predicates
@cowbs has joined the channel
@mskoh52 any reason you’re not just passing find-item
instead of (λ (x) (find-item x))
and likewise w/ the other predicate?
Can you give a one line description of the purpose? (Is it just moving the found elements to the front?)
good catch on the first one…that was just some leftover cruft from before. but for find-new-successor, i wanted the sense inverted ,so that you provide a predicate that returns true when it finds the thing
Ah, I didn’t read closely on the second :)
i want to move elements aroun the list, so if you have '(1 2 3 4 5)
you can turn it into '(1 3 2 4 5)
by providing the right predicate. In this example, it would be (lambda (x) (= x 3))
and (lambda (x) (= x 2))
respectively
At first glance, this seems overly complicated. Also, it might be worth optimizing for the case where the item to be removed is before the item to insert in front of, but that would likely make the cod uglier. My initial thought is simply to have (remove-if pred lst)
and (insert-if pred lst)
lol great
i don’t find (remove-if) in the manual though
You have to write both, but they seem simple.
i see..yeah might make it clearer
The first one seems good enough to have in the stdlib
There’s a tradeoff - using two functions like the above would probably make the code very readable, but AFAIK it wouldn’t allow the optimization of when the removed item is before the insert before item.
What if the list is (1 2 4 3 2 2 3 4 3)
?
i’m assuming no dups. i mention this in below the code block :slightly_smiling_face:
i came up with something following your suggestion, but I think I still need/want the extract
function instead of remove-if
, so that I can use the removed value
@mskoh52 I haven’t fully vetted the above code, but I think it will do what you want. Returns a list of items and the list with the item removed.
By return a list of items, 1) you can tell if the item was found since the list would be ’(), 2) allows for duplicate items to be removed e.g. all the 2’s
Cool ty. I like this better than the foldl building up a pair that I used
let loop
is your friend :)
why did you call it remove-if*
with the *
Because it removes all the elements for which the pred
returns true.
That seems to be a scheme naming convention.
If it only removed the first element, it would be remove-if
but that brings up a tricky issue - how do you determine whether an element was found? In other words, what sentinel value do you use for the initial default? In most cases, using #f
would be fine, but what if it was a list of booleans and you wanted to remove a #f
? :)
I suppose I’d still use a list in that case.
thanks for the explanation :+1:
I have a code in racket: #lang racket
(match '(cond [#t a b c]
[#f x y z])
[`(cond [,(? boolean? preds)
,(? symbol? bodys)
...]
...)
bodys])
Output: '((a b c) (x y z))
I rewrote it in typed/racket: #lang typed/racket
(match '(cond [#t a b c]
[#f x y z])
[`(cond [,(? boolean? #{preds : (Listof Boolean)})
,(? symbol? #{bodys : (Listof (Listof Symbol))})
...]
...)
bodys])
But it failed: Type Checker: type mismatch
expected: (U (List 'a 'b 'c) (List 'x 'y 'z))
given: (U (List 'b 'c) (List 'y 'z))
in: (match (quote (cond (#t a b c) (#f x y z))) ((quasiquote (cond ((unquote (? boolean? preds)) (unquote (? symbol? bodys)) ...) ...)) bodys))
How should I make it work?