30-MAR-2025
1514 - spring-cleaning-1
I pulled out the integration test, and right now I think I’m just going to focus on moving tests into their own modules where it makes sense. Eventually most tests will not be co-located with the code-under-test, as I talked about before. I haven’t brought in any new frameworks just yet, as I’m still determining what the best approach is going to be.
Now that I’ve got everything else pulled out though, I think it’s time to return to extracting the parser stuff, at
which point I think -core is sufficiently gutted so as to be ready for the great renaming.
I’m leaving the unused dependencies in place for the test crate for now, I suspect it’ll be worthwhile to reduce it at some point.
The only other item I need to actually add to the list above is “10. move to a nix run #ci like tabitha has”, I
think that should greatly simplify my CI pipeline and make it easier to add in lints and git hooks and stuff later.
So the current TODO list is:
- Cache needs to be refactored to a generic key, ultimately this will be a LRU cache with a generic key type.
- Spell needs to have Familiar refactored to rely on a SpellState trait
- Tape needs to be renamed to Spell
-
Move
BEN-> -basic- This means figuring out the
to_fen_positionextension, which might be able to stay put? IDK. In theory that means this can just be moved over and no api change, since query is already over there.
- This means figuring out the
- FIXMEs, TODOs, and the like need an audit.
- Reorganize directory structure
- Rename -core to -representation
- rename -basic to -core
- Get all the tests uncommented (in place) and passing.
- nix run #ci
I think #9 is the next port of call, I can use it as an opportunity to move some tests around as well.
1536 - spring-cleaning-1
One of the things I need to sit and think about is the way I convert between representations.
I was reading a bit about the fearless-simd project. It uses ZSTs as ‘tokens’ representing the capability of SIMD
independent of the implementation of SIMD, in a relatively ‘low cost’ sort of way to encode the intent into the type
system and then use it to determine an optimal implementation using whatever SIMD primitives are locally available. I
think I’d like to try something similar at some point for my representations. A recurring frustration is the need to
pick a representation as ‘canonical’ when no such representation really deserves that title. Bitboards are useful
sometimes, rank-file tuples others, strings others, it’s not natural to pick any one. There is no good type to give the
raw number or tuple-of-numbers that doesn’t include generally unnecessary bound checking. Bitboards are fine for what
they can do but quite limited in other ways, same with strings. Ideally I should be able to pick whatever representation
is ‘best’ for the current situation, leaving the others behind, but I don’t know what the ‘best’ rep is ahead of time.
To square this (hah), I rely on impl Into<Square> frequently, but htis is also a representation with a downside. It
says, “I can become a specific known implemnetation, but you will have to pay at least the .into() cost and maybe
a second to convert it to the ‘real’ type you want.” I can justfy paying something, but I hate paying it twice.
Relying on From/Into also leads to a lot of weird situations where I can’t rely on type inference to ‘do the right
thing’ and guess the type correctly, leaving me to add annotations inconveniently.
If I instead had something like Square as a collection of ZSTs, each with constant implementations of what are now
From/Intos, I could have an API like:
#[quickcheck] {
A1.bitboard().is_set((A1.rank(), A1.file())) == true
}
Which isn’t too bad, and it means that the actual type I’m passing around is a finite type family, something like:
// This presumes I can const-trait...
trait Square {
const fn bitboard() -> Bitboard;
const fn rank() -> usize;
// ...
}
struct A1; impl Square for A1;
// ...
There aren’t too many representations to target, but I could do similar things with Piece, Color, etc where it was
needed. Essentially this is the same thing as how I tend to rely on Query, but where Query is really an open
specification with a potentially unbounded number of implementors, Square is really finite and basically will never
be extended.
Something to chew on, anyway.
1620 (nice) - spring-cleaning-1
- Cache needs to be refactored to a generic key, ultimately this will be a LRU cache with a generic key type.
- Spell needs to have Familiar refactored to rely on a SpellState trait
- Tape needs to be renamed to Spell
-
Move
BEN-> -basic- This means figuring out the
to_fen_positionextension, which might be able to stay put? IDK. In theory that means this can just be moved over and no api change, since query is already over there.
- This means figuring out the
- FIXMEs, TODOs, and the like need an audit.
- Reorganize directory structure
- Rename -core to -representation
- rename -basic to -core
-
Get all the tests uncommented (in place) and passing.
- With caveats, there are still some tests pending a refactor, but I think I got everything that could be easily re-enabled.
- nix run #ci
- -parser extraction