kellysmith12.21
2020-8-3 18:24:37

I know that continuations can be used to implement cooperative multitasking, but is it possible to implement preemptive multitasking with continuations?


mskoh52
2020-8-3 18:30:44

@mskoh52 has joined the channel


mflatt
2020-8-3 18:32:29

You need some extra ingredient, such as an asynchronous timer where you can attach a continuation capture and swap to the timer expiration.


mskoh52
2020-8-3 18:32:53

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
2020-8-3 18:55:22

@cowbs has joined the channel


badkins
2020-8-3 19:43:34

@mskoh52 any reason you’re not just passing find-item instead of (λ (x) (find-item x)) and likewise w/ the other predicate?


soegaard2
2020-8-3 19:48:12

Can you give a one line description of the purpose? (Is it just moving the found elements to the front?)


mskoh52
2020-8-3 19:52:52

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


badkins
2020-8-3 19:53:13

Ah, I didn’t read closely on the second :)


mskoh52
2020-8-3 19:55:07

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


badkins
2020-8-3 19:55:17

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)


mskoh52
2020-8-3 19:55:51

lol great


mskoh52
2020-8-3 19:56:09

i don’t find (remove-if) in the manual though


badkins
2020-8-3 19:56:22

You have to write both, but they seem simple.


mskoh52
2020-8-3 19:56:37

i see..yeah might make it clearer


badkins
2020-8-3 19:56:37

The first one seems good enough to have in the stdlib


badkins
2020-8-3 19:57:29

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.


soegaard2
2020-8-3 20:04:39

What if the list is (1 2 4 3 2 2 3 4 3) ?


mskoh52
2020-8-3 20:05:00

i’m assuming no dups. i mention this in below the code block :slightly_smiling_face:


mskoh52
2020-8-3 20:11:21

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


badkins
2020-8-3 20:16:10

badkins
2020-8-3 20:16:52

@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.


badkins
2020-8-3 20:17:48

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


mskoh52
2020-8-3 20:24:33

Cool ty. I like this better than the foldl building up a pair that I used


badkins
2020-8-3 20:24:50

let loop is your friend :)


mskoh52
2020-8-3 20:26:23

why did you call it remove-if* with the *


badkins
2020-8-3 20:35:31

Because it removes all the elements for which the pred returns true.


badkins
2020-8-3 20:35:45

That seems to be a scheme naming convention.


badkins
2020-8-3 20:37:19

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 ? :)


badkins
2020-8-3 20:38:06

I suppose I’d still use a list in that case.


mskoh52
2020-8-3 20:38:26

thanks for the explanation :+1:


noahstorym
2020-8-4 01:38:24

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?