# How to implement parallel-or?

**URL:** <https://racket.discourse.group/t/how-to-implement-parallel-or/3987>\
**Category:** Questions & Answers\
**Tags:** question, parallelism, futures\
**Created:** [October 27, 2025, 3:29pm UTC](https://racket.discourse.group/t/how-to-implement-parallel-or/3987 "2025-10-27T15:29:09Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![LiberalArtist](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/liberalartist/32/151_2.png) [@LiberalArtist](https://racket.discourse.group/u/LiberalArtist)\
**Post date:** [October 27, 2025, 11:42pm UTC](https://racket.discourse.group/t/how-to-implement-parallel-or/3987/4 "2025-10-27T23:42:20Z")

</div>

> [@ohqo](#):
>
> Is there a good way of managing multiple racket installations? I'd like to try out the new feature but would still like to have an easy way of reverting back to the stable release for other stuff.

There are several good options.

From a download site like [https://pre-release.racket-lang.org](https://pre-release.racket-lang.org), you can have the installer perform an in-place installation (or select a distribution packaged as a tarball), putting the whole installation in a directory like `~/racket-8.18.0.19/`, so that the `racket` executable is at `~/racket-8.18.0.19/bin/racket`. That works especially well for a one-off short-term use like this, given that the Racket 9.0 release should be [on Friday](https://racket.discourse.group/t/racket-v9-0-branching-is-done/3973), give or take.

The [`raco cross`](https://docs.racket-lang.org/raco-cross/index.html) tool can serve as a more automated way of doing basically the same thing, even if you don't need its additional features for cross-compilation and such.

You can also install multiple Racket versions on a machine long-term, similar to the way `/lib/qt5/` and `/lib/qt6/` both exist on my laptop. Details will vary depending on your system. This is less likely to be useful for Racket, though, because Racket's strong emphasis on compatibility means you should almost never have to change your code to upgrade to the latest Racket release.

> [@ohqo](#):
>
> The use case I have in mind is purely functional. I'm not familiar with custodians and I wonder how much the code could be simplified if both thunks are pure.

You can simplify somewhat (see below), but you need to substitute `kill-thread` for one of the `custodian-shutdown-all` calls, because, if one thread terminates with a non-false value, you surely want to terminate the other thread.

Custodians can manage more general resource-cleanup issues. For example, imagine you wanted to look up the weather in Chicago, and wanted to use `parallel-or` to try both the [National Weather Service API](https://www.weather.gov/documentation/services-web-api) and [Open-Meteo](https://open-meteo.com/), returning the result from whichever supplies it fastest. Using `thread-kill` would stop the thread, freeing CPU resources, but it could potentially leave open file descriptors or other OS-level resources implementing an HTTP connection. More generally, a given thread could have launched other threads to perform its work. Using custodians can reliably reclaim all potentially-used resources.

```scheme
(define (do-parallel-or a-thunk b-thunk)
  (define (spawn thunk)
    (thread #:pool 'own #:keep 'results thunk))
  (define a-thd
    (spawn a-thunk))
  (define b-thd
    (spawn b-thunk))
  (define ready-thd
    (sync a-thd b-thd))
  (define other-thd
    (if (equal? ready-thd a-thd)
        b-thd
        a-thd))
  (cond
    [(thread-wait ready-thd)
     => (λ (rslt)
          (kill-thread other-thd)
          rslt)]
    [else
     (thread-wait other-thd)]))

```

> [@ohqo](#):
>
> To provide some context, I was doing a coding exercise which involves a matrix of letters and the goal is to check whether you can find a string. I coded up a purely functional solution which ended up twice as slow as an imperative solution. I want to try parallelizing the algorithm to see if the functional data structures pay off with more cores. Parallel-or seems to make sense in this case because the short circuiting could give a performance boost.

Outside of an exercise, these find-a-string problems are very well studied, so you probably would want to make sure you're implementing one of the current state-of-the-art algorithms (though I couldn't say off-hand what you want). But your results from adding parallelism, whether to an optimal algorithm or not, might be useful to help evaluate the still-quite-new implementation of parallel threads:

> [@Help test via snapshots: parallel threads](https://racket.discourse.group/t/help-test-via-snapshots-parallel-threads/3920/):
>
> We expect that the next Racket release (tentatively v9.0) will have additional support for parallelism. We need your help to get it right. Racket has always provided lightweight threads for concurrency, but Racket threads have never taken advantage of multiple processor cores to run in parallel, unlike threads provided by an operating system or in many other languages. Racket provides places and futures for parallelism, but those constructs have restrictions that make them less easy to use than…

---

_[View the full topic](https://racket.discourse.group/t/how-to-implement-parallel-or/3987)._
