Firstly apologies if I’m using the wrong term by picking the word ‘semantics.’
I’m a big fan of generics in Java for all the obvious reasons. It helps me enormously as I work with a huge variety of odd bits of code and I often have to go back to old stuff. Today I found myself with a classic parameter misplacement bug which I probably wouldn’t have written in the pre-generic days – they have made me a bit lazy.
I’d like to know if there is a language feature, either in Java or perhaps as a similar concept in other languages, which takes the type safety of generics and extends it to a kind of semantic safety. Specifically I want to help trap the kind of errors which result from putting the right thing in the wrong place.
A simple example:
Map<String, String> myMap = new HashMap<String, String>();
String myKey = "key";
String myVal = "value";
myMap.put(myVal, myKey);
Which no compiler will catch. I could subclass make wrappers to give me a StringKey type and a Value type, I suppose. I could name my variables to indicate their use (as I’ve done in this example). What else?
So my questions are:
- out of academic interest, what is this concept called and what languages have this feature?
- In the absence of any such language feature, what are the best practices to avoid this kind of error?
Thanks
I have always used maps that have two different types for the key and value, never the same types. I suppose there are times when you would want to use the same type for the key and value as in your example. I can’t think of any languages off the top of my head that have this feature.
Actually I have used Clojure before and for maps it uses a keyword for the key which looks like
:keyand then the value is just whatever the value is. It makes it clearer but now i’m dabbling into functional programming which is not really the question you were asking. Check out Lisp-like languages.I think its just a case of not getting them mixed up, Java certainly cannot enforce this kind of checking.
Best advice would be to use different types for the key and value so the compiler can detect the type error, or name the key and value variables explicitly as you have done.