On Mar 9, 7:46 am, Rich Hickey <richhic...@gmail.com> wrote:
> On Mar 9, 2:19 am, Mark Engelberg <mark.engelb...@gmail.com> wrote:
>
>
>
>
>
> > On Sun, Mar 8, 2009 at 10:44 PM, mikel <mev...@mac.com> wrote:
> > > Clojure doesn't have to provide these facilities (though I wouldn't
> > > mind if it did); it just needs to stay out of my way when I decide I
> > > need to add them.
>
> > Yeah, as much as I like maps, I feel like there are several common
> > uses cases for maps that require more work in Clojure than other
> > languages.  The most obvious example is tagged structs.  In Clojure,
> > you need to do a defstruct, and then make your own custom constructor
> > that adds the tag, possibly another custom constructor that emulates
> > struct-map but adds the tag, and possibly a predicate that tests for
> > the tag.
>
> > I particularly like the way the Mozart language makes tagged structs
> > (they call them records) one of the core data structures that the
> > language is built around.
> > See section 3.6 athttp://www.mozart-oz.org/home/doc/tutorial/node3.html
>
> > I can see why the existing system is more flexible (you can have more
> > than one tag, or no tag, or make the tag part of the metadata, or use
> > different labels for the tag other than :tag or :type), but I keep
> > feeling like 90% of the time I'd be happy to just use a standard
> > tagged struct.  The good news is that it's easy to write a macro to do
> > all the boilerplate.  The bad news is that everyone will write
> > different macros that tag these structures in different ways, and it's
> > not clear to me how well code written based on different tagging
> > standards will coexist.
>
> I understand. I've pushed hard not to have the language dictate an
> object system, and especially not to tie important capabilities like
> polymorphic dispatch and hierarchy to a specific type system. That
> said, I don't want to make the common cases hard or confusing.
>
> There is now a supported convention for tagging, the :type metadata,
> and the type function which returns either the :type meta or the Class
> if none. This should provide a common way to handle the basic case - a
> single type tag. These :type tags can participate in the hierarchy
> system and thus provide a lot of flexibility.
>
> I'd like to see what people do with that and drive any further common
> utilities from shared needs.

What I'm presently doing about my wish for explicit declaration of
data layouts looks like this:

(define-model ::named-thing :required-keys [:name])

(define-model ::aged-thing :required-keys [:age])

(define-model ::person :extends [::named-thing ::aged-thing]
                                 :required-keys [:weight]
                    :policy :strict)

user> (with-model ::person :name "Fred")
{:age nil, :weight nil, :name "Fred"}

user> (model (with-model ::person :name "Fred"))
:user/person

user> (with-model ::person :name "Fred" :eyes :blue)
java.lang.Exception: Model :user/person allows only these keys: #
{:age :weight :name}, but found these: #{:eyes} (NO_SOURCE_FILE:0)


with-model creates a map from the named model. model returns the model
used to create the map (the model name is in the map's metadata).

The :policy argument optionally tells define-model that no keys except
those listed (and those collected from the models in the :extends
cause) are permitted in maps created by with-model.

Models completely ignore dispatching and provide no support for
inheritance. You can of course create whatever hierarchy you want
using derive with the model names.

Having tried both the built-in multifunctions and my own
implementation of CLOS-style generic functions, I tend to want to use
my own. I can more flexibly and easily customize dispatching with
them, and they know how to choose the most specific method without
user intervention in situations that cause MultiFn dispatch to demand
hand-tweaking with prefer-method. (I wouldn't be surprised if gf
dispatch is substantially slower than MultiFn dispatch right now,
though.)

Models are completely orthogonal to generic functions; either facility
can be used without the other, or they can be used together.


--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to