-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
The API of inclusive/exclusive ranges in select/3 is a bit problematic #3
Comments
Hi, thanks a lot for opening a discussion on this. I thought about it too. Using the long form should be always safe (in case the key is literally Your idea to use What’s your opinion? |
I agree. Half-open ranges (so inclusive min-key and exclusive max-key) are, as far as I am aware, the most wide-spread and commonly used ranges in computing science and software engineering. |
What I mean, is something like this: CubDB.select(db, [
min_key: :foo,
max_key_exclusive: :bar
]) |
Ah! I had a slightly different idea in mind, namely: CubDB.select(db, [
min_key: {:foo, 42},
min_key_exclusive: true,
max_key: {:foo, 1234},
max_key_exclusive: false
]) or possibly: CubDB.select(db, [
min_key: {:foo, 42},
min_key_settings: [exclusive: true],
max_key: {:foo, 1234},
max_key_settings: [exclusive: false]
]) What do you think? |
Adding to this discussion, right now there is another issue related with the The ideal solution would be both intuitive and free of corner cases. The best possibilities, in my view, are the following:
# Option 1:
{:ok, result} = CubDB.select(db, [
min_key: {:foo, :included},
max_key: {:bar, :excluded}
]))
# Option 2:
{:ok, result} = CubDB.select(db, [
min_key: :foo,
max_key_exclusive: :bar
])) Adding more options is also a possibility, but I would prefer to keep it simpler. I am undecided on the options above, happy to take feedback, and I will need to sleep on it in order to come to a decision 🙂 |
select
s is a bit problematicselect/3
is a bit problematic
select/3
is a bit problematic
After (a lot of) thinking, I feel that your proposal is the clearest and simplest: # Boundaries are inclusive by default
{:ok, result} = CubDB.select(db, [
min_key: {:foo, 123},
max_key: {:bar, 321}
]))
# Setting min/max key to nil means literal nil
{:ok, result} = CubDB.select(db, [
min_key: nil,
max_key: {:bar, 321}
]))
# To leave the range open, omit min/max key
{:ok, result} = CubDB.select(db, [
max_key: {:bar, 321}
]))
# Make boundaries exclusive by setting min/max_key_inclusive to false
{:ok, result} = CubDB.select(db, [
min_key: {:foo, 123},
max_key: {:bar, 321},
max_key_inclusive: false
])) I will soon implement this. It will be a breaking change, but it's good to improve this part of the API before version 1. Thanks a lot for the feedback! |
The new version v0.13.0 is published on Hex, introducing the improved API. |
Currently, changing whether
min_key:
andmax_key:
are inclusive or exclusive is changed by wrapping the key you want to match on by{your_key, :excluded}
.I think this interface could be improved, since it conflicts when someone tries to e.g. use a
{:key, :excluded}
as key. Also, it will silently fail (and not match any keys it was expected to match) if someone mistypes:excluded
.I think a better approach would be to have extra options to toggle between inclusive and exclusive, for instance named
min_key_inclusive: true
, ormin_key_settings: [exclusive: true]
.The text was updated successfully, but these errors were encountered: