Re: Declarative Data Models
Hey Stuart, On 4 May 2011 00:19, Stuart Sierra the.stuart.sie...@gmail.com wrote: No. Clojure template (which I wrote) is a backwards way of doing macros. It happens to be useful in clojure.test, but nowhere else. Thanks that's good to know. While we're on the subject, I'm curious about cc.apply-macro. Why should it not be used? I got around a potential use-case by rearranging my macro a bit. Can it have unintended consequences? It seems like there may be cases where it would make code easier to understand. Thanks, David -Stuart S clojure.com -- 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 -- 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
Re: Declarative Data Models
apply-macro is a bad idea because it evaluates a macro at runtime. Macros are supposed to be evaluated at compile-time, so apply-macro breaks assumptions about how macros are supposed to work. It's basically a back door into `eval`, which is considered bad style in Lisp-like languages. -Stuart Sierra clojure.com -- 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
Re: Declarative Data Models
No. Clojure template (which I wrote) is a backwards way of doing macros. It happens to be useful in clojure.test, but nowhere else. -Stuart S clojure.com -- 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
Re: Declarative Data Models
Hi Ambrose, Thanks for the advice. I have already implemented my application using maps (defstruct) and busy evaluating whether I should switch to records. I like the idea of using records and protocols to help me to define strict abstractions and to do easy type dispatch. On the other hand I can see that they reduce flexibility. I will post some code to show what I am trying to do... Cheers, David On 30 April 2011 12:39, Ambrose Bonnaire-Sergeant abonnaireserge...@gmail.com wrote: Hi David, I can only comment on a subset of your post. Records can be cumbersome to work with during early stages of development, when everything is rather volatile (when isn't it?). You might like to try using maps instead. They are easier to work with when you are working out what properties you need in your records. It's also straightforward to convert from maps to records. Of course there are downsides to this (speed, lack of types) but it can be a useful strategy. Thanks, Ambrose On Sat, Apr 30, 2011 at 4:46 PM, David Jagoe davidja...@gmail.com wrote: G'day everyone, Are there any libraries or projects that are similar to Python Traits or Zope Schemas (http://pypi.python.org/pypi/zope.schema) for clojure. I am developing a compojure application and there is a lot of duplication between areas of the codebase, e.g. - Fields listed on the defrecords - Fields listed on the public constructor function - Fields listed on forms and again on handlers So it is a lot of effort to e.g. add a new field to the data model. I would like something declarative from which I can generate forms, validators etc. Cheers, David -- 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 -- 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 -- 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
Re: Declarative Data Models
Hey Paul, On 30 April 2011 20:27, Paul deGrandis paul.degran...@gmail.com wrote: I'm not exactly sure of your specific use case, but you should take a look at clojure.template. It could be what you're looking for. http://clojuredocs.org/clojure_core/clojure.template Great, I will have a look thanks. -- 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
Re: Declarative Data Models
Hi Everyone, Background to my problem: I am developing a compojure application, and there is lots of duplication in listing field names in my current data model: (i) in the defstruct (ii) in the public constructor's argument list (iii) in the hiccup form fields (iv) in the compojure argument destructuring (v) in the handler's argument list Ideally I would like to declare my data model in one place like this: (def person-entity {:name {:type String :validator name-validator} :id-number {:type String :validator id-number-validator} :height{:type Float :default 0.0} :weight{:type Float :default 0.0} :bmi {:type Float :internal true}}) And generate everything from there so that it is trivial to add fields etc. (:internal true just means that this is a calculated field or for some other reason is not supplied by the user - it is therefore not needed by the constructor, and will not show up on the edit-person form). I have tried to generate the defrecord etc from such a definition and have battled a bit, so in the interest of making some progress with my experiment I have tried this instead: (defn name-validator [val] val) (defn id-number-validator [val] val) (defn nil-validator [val] val) (defrecord Person [#^String name #^String id-number #^Float height #^Float weight #^Float bmi]) (def person-traits {:name {:validator name-validator} :id-number {:validator id-number-validator} :height{:default 100.0} :weight{:default 100.0} :bmi {:internal true}}) (def person-constructor (make-constructor Person person-traits)) (def person-editor (make-editor Person person-traits)) (def bob (person-constructor {:name Bob :id-number 123})) ;;; I don't really know how bmi is calculated!! Let's pretend it is weight (kg) / height (cm) (bob :bmi) 1.0 (bob :id-number) 123 And the person-editor is a snippet of hiccup which has all of the relevant fields (e.g. text fields by default). I plan to use flutter validators, and not to use compojure destructuring (I will have to pull the fields out of the request in the generated form handlers). I am looking for advice in the following areas: (i) Is it possible to generate the (defrecord Person ...) from the person-entity hash-map that I have shown? (ii) Is this a totally crazy idea? (iii) Am I neglecting to see a much simpler way of achieving my core objective (reduce all of the duplication)? Thanks very much. Cheers, David -- 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
Re: Declarative Data Models
On May 2, 8:37 pm, David Jagoe davidja...@gmail.com wrote: (i) Is it possible to generate the (defrecord Person ...) from the person-entity hash-map that I have shown? Sure. You may want to have a look at https://gist.github.com/876029 (and associated post to this group) for something somewhat related. (ii) Is this a totally crazy idea? I don't think so. The ability to have a model/schema that can be used to build forms, codecs and DDL statements etc would be useful to others I imagine. Such a mechanism could be used, for example, as input into Lobos. (iii) Am I neglecting to see a much simpler way of achieving my core objective (reduce all of the duplication)? If so, you and me both. Regards, Craig -- 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
Re: Declarative Data Models
On Mon, May 2, 2011 at 6:37 AM, David Jagoe davidja...@gmail.com wrote: Hi Everyone, Background to my problem: I am developing a compojure application, and there is lots of duplication in listing field names in my current data model: (i) in the defstruct (ii) in the public constructor's argument list (iii) in the hiccup form fields (iv) in the compojure argument destructuring (v) in the handler's argument list Ideally I would like to declare my data model in one place like this: (def person-entity {:name {:type String :validator name-validator} :id-number {:type String :validator id-number-validator} :height {:type Float :default 0.0} :weight {:type Float :default 0.0} :bmi {:type Float :internal true}}) And generate everything from there so that it is trivial to add fields etc. (:internal true just means that this is a calculated field or for some other reason is not supplied by the user - it is therefore not needed by the constructor, and will not show up on the edit-person form). I have tried to generate the defrecord etc from such a definition and have battled a bit, so in the interest of making some progress with my experiment I have tried this instead: (defn name-validator [val] val) (defn id-number-validator [val] val) (defn nil-validator [val] val) (defrecord Person [#^String name #^String id-number #^Float height #^Float weight #^Float bmi]) (def person-traits {:name {:validator name-validator} :id-number {:validator id-number-validator} :height {:default 100.0} :weight {:default 100.0} :bmi {:internal true}}) (def person-constructor (make-constructor Person person-traits)) (def person-editor (make-editor Person person-traits)) (def bob (person-constructor {:name Bob :id-number 123})) ;;; I don't really know how bmi is calculated!! Let's pretend it is weight (kg) / height (cm) (bob :bmi) 1.0 (bob :id-number) 123 And the person-editor is a snippet of hiccup which has all of the relevant fields (e.g. text fields by default). I plan to use flutter validators, and not to use compojure destructuring (I will have to pull the fields out of the request in the generated form handlers). I am looking for advice in the following areas: (i) Is it possible to generate the (defrecord Person ...) from the person-entity hash-map that I have shown? Shoundn't be too hard. Something like (defn to-rec-field [kword entity-map] (let [rf (symbol (name kword))] (if-let [t (:type (entity-map kword))] (with-meta rf {:tag t}) rf))) (defmacro defentity [name entity-map] (let [fields (fn [ks] (map #(to-rec-field % entity-map) ks)) optionals (filter #(:default (entity-map %)) (keys entity-map)) optional-subsets (map #(set (drop % (reverse optionals))) (range (count optionals)))] `(do (defrecord ~(symbol (str R name)) ~@(fields (keys entity-map))) (defn ~(symbol (str construct- name)) ~@(map (fn [ops] (list (vec (fields (remove ops (keys entity-map (cons (symbol (str R name .)) (map #(if (ops %) (:default (entity-map %)) (to-rec-field % entity-map)) (keys entity-map) optional-subsets)) (defn ~(symbol (str edit- name)) ~@(left as an exercise for the reader) This should (untested) produce a defrecord and arity-overloaded constructors for the whole argument list and with successively more of the fields with defaults omitted, starting at the right -- so, for your person, you'd get constructors for [name id-number height weight bmi], [name id-number height bmi], and [name id-number bmi]. You probably want it to omit bmi from the argument lists and compute it -- that will complicate things, something like: (defmacro defentity [name entity-map] (let [fields (fn [ks] (map #(to-rec-field % entity-map) ks)) default #(:default (entity-map %)) optionals (filter default (keys entity-map)) optional-subsets (map #(set (drop % (reverse optionals))) (range (count optionals))) computer #(:computer (entity-map %)) computed (filter computer (keys entity-map))] `(do (defrecord ~(symbol (str R name)) ~@(fields (keys entity-map))) (defn ~(symbol (str construct- name)) ~@(map (fn [ops] (list (vec (fields (remove (concat ops computed) (keys entity-map `(let ~(vec (interleave (fields
Re: Declarative Data Models
My comment is unrelated to Clojure but related to the general topic of avoiding redundancy. Please have a look at InfoQ's Dan Haywood's Domain-Driven Design Using Naked Objects: http://www.infoq.com/articles/haywood-ddd-no The book is definitely worth a read! Naked Object's (now called Apache Isis http://incubator.apache.org/isis/) whole purpose is to concentrate the domain knowledge (including the meta data!) in the domain model and thus avoid the typical redundancies you find across the different application layers. Here is an answer to one of my questions to their mailing list to find out how to query their central meta data infrastructure: http://mail-archives.apache.org/mod_mbox/incubator-isis-dev/201104.mbox/browser One of my ideas (don't know when and if I will ever come around to pursue that) would be to create an implementation of that meta data interface in Clojure. That way the whole feature set of the framework would be available for developing applications in Clojure. -- 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
Re: Declarative Data Models
Sorry, the link to their mailing list is here: http://mail-archives.apache.org/mod_mbox/incubator-isis-dev/201104.mbox/BANLkTim+9061Se1mPLK3=wymmj0qkdu...@mail.gmail.com -- 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
Re: Declarative Data Models
On 2 May 2011 14:06, craig worrall craig.worr...@gmail.com wrote: On May 2, 8:37 pm, David Jagoe davidja...@gmail.com wrote: (i) Is it possible to generate the (defrecord Person ...) from the person-entity hash-map that I have shown? Sure. You may want to have a look at https://gist.github.com/876029 (and associated post to this group) for something somewhat related. Excellent, thanks Craig. That is what I am looking for. -- 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
Re: Declarative Data Models
Hi Ken, Shoundn't be too hard. Something like [snip] Thanks, looks good. I haven't had a chance to play with the code yet but it looks like a very good start. You probably want it to omit bmi from the argument lists and compute it -- that will complicate things, something like: [snip] used with something like (defentity person {:name {:type String} :id-number {:type Integer} :height {:type Double :default 100.0} :weight {:type Double :default 100.0} :bmi {:type Double :computer (/ weight height)}}) Note that both the :default and the :computer can be s-expressions that just get inserted verbatim as code. The two differences are: 1. A field with :computer will not ever be a constructor parameter. 2. The :computer s-expression can refer to any of the fields; the :default can only refer to earlier ones and non-optional ones. I hope this shows how one might go about constructing a macro to take a definition similar to your original person-entity map and turn it into a record, constructor function, and possibly other structures. For example it could put code in the constructor function to run a :validator, if present, on that field, where the :validator throws an exception; or to turn a :validator field into a test and throw exception clause where the :validator is a boolean expression; etc. Yes, that is great thanks! Cheers, David -- 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
Declarative Data Models
G'day everyone, Are there any libraries or projects that are similar to Python Traits or Zope Schemas (http://pypi.python.org/pypi/zope.schema) for clojure. I am developing a compojure application and there is a lot of duplication between areas of the codebase, e.g. - Fields listed on the defrecords - Fields listed on the public constructor function - Fields listed on forms and again on handlers So it is a lot of effort to e.g. add a new field to the data model. I would like something declarative from which I can generate forms, validators etc. Cheers, David -- 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
Re: Declarative Data Models
Hi David, I can only comment on a subset of your post. Records can be cumbersome to work with during early stages of development, when everything is rather volatile (when isn't it?). You might like to try using maps instead. They are easier to work with when you are working out what properties you need in your records. It's also straightforward to convert from maps to records. Of course there are downsides to this (speed, lack of types) but it can be a useful strategy. Thanks, Ambrose On Sat, Apr 30, 2011 at 4:46 PM, David Jagoe davidja...@gmail.com wrote: G'day everyone, Are there any libraries or projects that are similar to Python Traits or Zope Schemas (http://pypi.python.org/pypi/zope.schema) for clojure. I am developing a compojure application and there is a lot of duplication between areas of the codebase, e.g. - Fields listed on the defrecords - Fields listed on the public constructor function - Fields listed on forms and again on handlers So it is a lot of effort to e.g. add a new field to the data model. I would like something declarative from which I can generate forms, validators etc. Cheers, David -- 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 -- 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
Re: Declarative Data Models
I'm not exactly sure of your specific use case, but you should take a look at clojure.template. It could be what you're looking for. http://clojuredocs.org/clojure_core/clojure.template Paul On Apr 30, 3:39 am, Ambrose Bonnaire-Sergeant abonnaireserge...@gmail.com wrote: Hi David, I can only comment on a subset of your post. Records can be cumbersome to work with during early stages of development, when everything is rather volatile (when isn't it?). You might like to try using maps instead. They are easier to work with when you are working out what properties you need in your records. It's also straightforward to convert from maps to records. Of course there are downsides to this (speed, lack of types) but it can be a useful strategy. Thanks, Ambrose On Sat, Apr 30, 2011 at 4:46 PM, David Jagoe davidja...@gmail.com wrote: G'day everyone, Are there any libraries or projects that are similar to Python Traits or Zope Schemas (http://pypi.python.org/pypi/zope.schema) for clojure. I am developing a compojure application and there is a lot of duplication between areas of the codebase, e.g. - Fields listed on the defrecords - Fields listed on the public constructor function - Fields listed on forms and again on handlers So it is a lot of effort to e.g. add a new field to the data model. I would like something declarative from which I can generate forms, validators etc. Cheers, David -- 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 -- 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