🧠The Search-and-Select Pattern
🧠The Search-and-Select Pattern
If you zoom out and look at the big picture, you'll notice a recurring theme throughout this project: a love for abstraction and a flair for formalism. But this isn’t just a clever trick or a stylistic quirk — it reflects a unified design philosophy at the heart of the whole project.
And that philosophy? Making programming actually easy — by embracing the kinds of patterns we already use in everyday reasoning.
Let’s rewind a bit.
The What
class — from @fizzwiz/fluent — focuses on a special kind of function: multivalued functions, or functions that return iterables instead of single values.
There are two rich ways to interpret this:
- Uncertainty — the function doesn’t yet know the answer, so it gives you a few possibilities to work with.
- Exploration — when the return values are of the same type as the input, the function becomes a kind of map: starting at one point, it shows you all the directions you could go next.
That second view unlocks something powerful: multivalued functions as search spaces.
🧠Step by Step Toward a Solution
Imagine solving a tough problem. You don’t leap straight to the answer — you make a guess, tweak it, explore a few variations, toss out the bad ones, and gradually zero in on something that works.
That’s what a search space gives you. You start with a rough idea and refine it step by step. Each time, you:
- Pull the most promising candidate from a queue
- Push in all the nearby options — the "neighbors"
- Discard the least promising ones if the queue gets full
You're both searching through possibilities and selecting what to keep. That’s the essence of the Search-and-Select Pattern.
🧰 What You Need
To make this pattern work, you just need three things:
- A class to define a queue of candidate solutions
- A class to define and compose a space
- A class to define, filter, and map a search
This setup lets you:
- Define all potential solutions without generating them all
- Find a valid solution early — as soon as one matches your criteria
- Restrict or transform the search however you like
Sound familiar? That’s exactly what the Each
and What
classes are built to do.
- The library @fizzwiz/fluent provides syntactic sugar for composing, transforming, and resolving a search.
- The library @fizzwiz/sorted gives you a suite of flexible queues — each reflecting a different search strategy.
- The library @fizzwiz/pattern offers the
Search
class as an iterable of candidate solutions.
💡 Snippet: Filtering, Mapping, and Resolving a Search
const
search = new Search()
.from(start)
.through(space)
.via(queue),
result = quest
.which(predicate)
.then(map)
.what();
Here’s what’s going on:
.from(start)
begins the search from a starting point.through(space)
defines the search space of candidate solutions to explore.via(queue)
uses a queue for sorting/selecting candidate solutions.which(predicate)
filters out unwanted solutions.then(map)
transforms the survivors.what()
runs the search and returns the first good result
✨ Clean. Composable. Easy to reason about.
🎯 Why This Pattern Matters
Because when code starts to feel messy or tangled, there’s a good chance it’s secretly a search-and-select problem in disguise. And once you see it that way, things click.
You can untangle the mess with just a few well-chosen, expressive method calls — clean, focused, and easy to follow.
“Code fluently. Solve elegantly.”
—@fizzwiz ✨
Comments
Post a Comment