By the way, I wanted to emphasize that I don't think this would be an ideal use of metadata even if your use case was supported. But the reason metadata is so tempting is that you want frequencies and distances to be treatable as numbers and so on. If you wrap them up like I suggested, you couldn't pass them directly to core arithmetic functions like + and * but would need to perform manual wrapping and unwrapping.
The analogous case in Haskell is newtypes. Newtypes are used when you want an isomorphic but nevertheless non-equal version of an existing data type. So in your example you might have a Frequency and Distance newtype. Generally you want most of the implemented interfaces (type classes) to be inherited from the underlying types without having to implement them by manually unwrapping the operands, forwarding them, and rewrapping of the results. This is done by newtype deriving. If you write newtype Frequency = Frequency Integer deriving (Show, Eq, Ord, Num), you will inherit the behavior for displaying an integer as a string, equality checking, linear ordering, and integral arithmetic operations. But you could also leave the Show out and implement it yourself, probably deferring to the wrapped type's Show instance as part of your implementation. I think you could achieve something similar with protocols. There would be a (defnewtype frequency Protocol1 Protocol2 ... ProtocolN), which would implement the named protocols for each Frequency instance by deferring to the wrapped value. This wouldn't be possible for all protocols but only those with implemented newtype derivers. For example, the newtype deriver for the arithmetic protocol's addition function might unwrap the operands, call addition on these now unwrapped values, and then rewrap the results in the newtype wrapper. (Clojure's arithmetic tower isn't expressible via protocol-style single dispatch, so this is vastly simplified, but you get the idea.) -Per On Sat, Apr 3, 2010 at 3:18 PM, Per Vognsen <per.vogn...@gmail.com> wrote: > Unfortunately you can only attach metadata to types that implement the > IObj interface. That excludes native Java types like Integer and > Float: > > user=> (with-meta 42 {:foo 42}) > java.lang.ClassCastException: java.lang.Integer (NO_SOURCE_FILE:0) > user=> (with-meta 42.0 {:foo 42}) > java.lang.ClassCastException: java.lang.Double (NO_SOURCE_FILE:0) > user=> (with-meta (float 42.0) {:foo 42}) > java.lang.ClassCastException: java.lang.Float (NO_SOURCE_FILE:0) > > I haven't thought through all the implications, but it seems like > Clojure could support externalized metadata for these sort of types > with an identity-based weak-key hash table. > > Anyway, the way things stand, your best kept is probably to wrap your > data in some data structure. It could be as simple as [:frequency x] > or {:tag :frequency, :value x}. > > -Per > > On Sat, Apr 3, 2010 at 5:47 AM, strattonbrazil <strattonbra...@gmail.com> > wrote: >> What's the best way to keep track of what kind of value something is? >> For example, if I have a hash of floats and I want to go through each >> one and see if a given key-value, which happens to be a float, if it's >> a distance or a frequency? Or if something is a struct or a specific >> struct? I'm somewhat familiar with the pattern matching done in Scala >> and couldn't find similar documentation in Clojure. >> >> I would think there's some way to filter out values that are a certain >> struct, but I'd also like to attach information to primitives like >> floats. Should I wrap my primitives in structs or do I need >> metadata? >> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with your >> first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> >> To unsubscribe, reply using "remove me" as the subject. >> > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en