-
Notifications
You must be signed in to change notification settings - Fork 90
Small hashmap additions #1709
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
Small hashmap additions #1709
Conversation
|
will wait for @shirok to comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm curious how it will fit into the broader plan of mapping and collection interface.
Also, tests would be nice, even the trivial ones.
library/hashmap.lisp
Outdated
| (Tuple (HashMap newnode) aux))) | ||
|
|
||
| (inline) | ||
| (declare modify (Hash :k => HashMap :k :v -> :k -> (:v -> :v) -> Tuple (HashMap :k :v) (Optional :v))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like the code is written to return Tuple (Optional (HashMap :k :v)) (Optional :v).
If this pattern is useful, we want to have it in the mapping protocol. I wonder, though, if it is useful to return (Optional (HashMap :k :v))---as update is the most general protocol, we want modify to be a convenience utility, as easy to use as possible. Do the caller wants to know whether the map is modified or not?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does compile, if that's what you're concerned about. The overall modify function just returns the HashMap, and returns an optional modified value (None in case the the key was missing). I included this version that returns the (Optional :v) because sometimes it is nice to do a modify-and-get all at once. But I could be convinced to get rid of this one, and just make modify_ be modify. I'm sure that's the most common of any of these "specialized version of update" use cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, and feel free to chime in here: #1329. It would be great to get all of the good discussion on the map interface together.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, my bad. I confused update protocol even I wrote that. Please disregard Optional thing.
library/hashmap.lisp
Outdated
| (Tuple (Some result) (Some result)))))))) | ||
|
|
||
| (inline) | ||
| (declare modify_ (Hash :k => HashMap :k :v -> :k -> (:v -> :v) -> HashMap :k :v)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above: The code returns (Optional (HashMap :k :v)).
Another question is the naming convention. If we'll have modify and modify_, I'd like to have the (mostly) consistent interface for other foo and foo_ variations. If this variations fit into the broader collection framework, I'm ok with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure? It's compiling on my machine, and I'm using it in a project. Maybe our versions of the repo are out of sync, or something? In any case, I just added some tests, so maybe take a look at those?
Yeah, the _ suffix convention is something I like using for simpler versions of functions that have a less expressive (but sometimes more useful) type signature. I don't know if there's much of that pattern in the standard library, though. Alternatively, this one could be modify and the other one could be modify-get or something.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as the convention of _ will be established, I'm fine with it.
library/hashmap.lisp
Outdated
| (define-instance (Hash :k => Monoid (HashMap :k :v)) | ||
| (define mempty Empty)) | ||
|
|
||
| (define-instance ((Hash :k) (Into :k String) (Into :v String) => Into (HashMap :k :v) String) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Into * String can be one of two things: Convert a thing into a string representation (obtaining external representation), or convert a sequence to a character sequence. Example of the latter is to convert a list of characters or a vector of characters into a string. I think those two needs to have distinct names.
My instinct is to keep Into * String as a sequence-seqence conversion (e.g. so it can be parallel with Into * List or Into * Seq etc., and have a separate protocol to get an external representation, much like Haskell's show.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I agree about Show. I think that's the long term plan. (#1641). And I agree this would be more suited to a "Show" instance than a conversion instance.
We could put this in for now and change it to Show later, when it gets added, or wait to add this (or something like it) then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm for having intermediate plan before we have full show protocol. In that case, how about having a different name (e.g. to-string or stringify) so that it will be easier to move once show is in place?
I'm afraid that once we conflate into, it would be cumbersome to discern different protocols later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with this. Maybe even just call it show-*.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just pushed up a commit simply calling it show. Eventually when we do get a show typeclass, that should make it easy for any code that uses it to convert.
library/hashmap.lisp
Outdated
| #:remove | ||
| #:update | ||
| #:modify | ||
| #:modify_ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a big fan of this convention. It's vague ("the simpler/reduced call"). I don't feel the need to be a stickler about it though.
|
@shirok I reset your review since you just commented. I'm not a huge fan of the I'm open to ideas. |
|
@stylewarning Yes, my hunch is it's more natrual to expect I don't see much use case in obtaining the new value; if I can spend some more cycles I can lookup again with the key, or I can fall back to the general |
That's reasonable. In that case, I think |
|
(tests fail because of a bug that's been fixed on main; just rebase) |
Adds two small functions, a docstring, and an (Into x String) instance
450c6ad to
71cf7af
Compare
modify_ -> modify, modify->modify-get
71cf7af to
dfbc664
Compare
Hmm. I rebased but I'm still getting the SBCL failures. It doesn't look like my branch is behind |
|
lol, this is the outdated quicklisp issue and named-readtables... will fix |
Adds two small functions that just wrap
update, a docstring, and an (Into x String) instance.@shirok