Re: datomic question
On Monday, 4 March 2013 01:50:56 UTC-5, edw...@kenworthy.info wrote: Okay, I think I understand that. Does that mean this code could never work as intended in a Clojure program, only at the repl (which seems a bit of a limitation) or is there a way to make it work as intended, generating a different id each time? Or is the whole approach taken in this code flawed? The tagged literal approach is best used if you need to store the entity and read it back using edn. So it's perfect for using in a data file. However, if you're generating data in code you've already seen how this can cause problems. In that case, you do what Jonas suggests and use tempid (with the appropriate partition keyword. e.g. :db.part/user). The two approaches offer different tradeoffs. tempid is a function, and can only appear in code (not a data file, or anything else read by edn). Conversely, if the the tagged literal appears in code, then it's possible for it to be referred to more than once in the same transaction, which is almost guaranteed to be counter to what you want. Paul -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: datomic question
Thanks very much Michael and Jonas. On Monday, 4 March 2013 07:20:24 UTC, Jonas wrote: Hi You can use the tempid ( http://docs.datomic.com/clojure/index.html#datomic.api/tempid) function to generate new temporary ids. Jonas On Monday, March 4, 2013 8:50:56 AM UTC+2, edw...@kenworthy.info wrote: Okay, I think I understand that. Does that mean this code could never work as intended in a Clojure program, only at the repl (which seems a bit of a limitation) or is there a way to make it work as intended, generating a different id each time? Or is the whole approach taken in this code flawed? On Sunday, 3 March 2013 21:59:45 UTC, Michał Marczyk wrote: #db/id ... is a tagged literal. It gets read in as an id object with some integer inside. The way this happens is that the reader looks up a data reader function associated with the symbol db/id in the map held by the var *data-readers* and passes to it the result of parsing the rest of the literal (a vector holding the keyword :db.part/db in this case). Importantly, this function is not pure and the integer it uses will be different on each invocation. (Given this form of the #db/id literal; you can also specify a particular number yourself -- #db/id [:db.part/db some-number-here].) In any case, once the reader reads in your code including some particular id, the compiler will compile the result preserving the particular values it sees, so it will embed code to construct *exactly this* id in the compiled output. Thus you end up with a particular id hardwired into the first version of your function. With the second version, if you invoke it multiple times at the REPL, you ask the reader for a new id at each invocation, so it works as you expect. If instead you were to use it inside a function like so: (defn foo [] (make-column-schema #db/id [:db.part/db] :results/subject :db.type/string)), then again the same id would be used for every (foo) call. Cheers, Michał On 3 March 2013 21:58, edw...@kenworthy.info wrote: So, I am studying a piece of code from the web. I've dissected most of it and am in the process of re-factoring it. What I don't understand is why one version works and the other doesn't. So for both: (ns gcse-results.core (:use [datomic.api :only [q db] :as d]) (:use quil.core)) This doesn't work: (defn make-column-schema [db-ident db-type] {:db/id #db/id[:db.part/db] :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema :results/subject :db.type/string) The value of #db/id[:db.part/db] is the same. And this works: (defn make-column-schema [db-id db-ident db-type] {:db/id db-id :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema #db/id[:db.part/db] :results/subject :db.type/string) The value of #db/id[:db.part/db] is the different, as expected. Now I thought that I understood #db/id[:db.part/db] (call to a Java constructor) but obviously my understanding is flawed as I would expect both of these functions to produce the same thing, but they don't so there's obviously some gap in my understanding. Help? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@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+u...@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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: datomic question
This page: http://clojure.org/reader Offers this explanation of what the # character does: Dispatch (#) The dispatch macro causes the reader to use a reader macro from another table, indexed by the character following #: #{} - see Sets above Regex patterns (#pattern) A regex pattern is read and compiled at read time. The resulting object is of type java.util.regex.Pattern. Var-quote (#') #'x = (var x) Anonymous function literal (#()) #(...) = (fn [args] (...)) where args are determined by the presence of argument literals taking the form %, %n or %. % is a synonym for %1, %n designates the nth arg (1-based), and % designates a rest arg. This is not a replacement for fn - idiomatic used would be for very short one-off mapping/filter fns and the like. #() forms cannot be nested. Ignore next form (#_) The form following #_ is completely skipped by the reader. (This is a more complete removal than the comment macro which yields nil). Although, for me personally, I felt like I better understood the description given on the EDN page: https://github.com/edn-format/edn # dispatch character Tokens beginning with # are reserved. The character following # determines the behavior. The dispatches #{ (sets), #_ (discard), #alphabetic-char (tag) are defined below. # is not a delimiter. tagged elements edn supports extensibility through a simple mechanism. # followed immediately by a symbol starting with an alphabetic character indicates that that symbol is a tag. A tag indicates the semantic interpretation of the following element. It is envisioned that a reader implementation will allow clients to register handlers for specific tags. Upon encountering a tag, the reader will first read the next element, then pass the result to the corresponding handler for further interpretation, and the result of the handler will be the data value yielded by the tag + tagged element, i.e. reading a tag and tagged element yields one value. This value is the value to be returned to the program and is not further interpreted as edn data by the reader. This process will bottom out on elements either understood or built- in. Thus you can build new distinct readable elements out of (and only out of) other readable elements, keeping extenders and extension consumers out of the text business. On Mar 4, 3:24 am, edw...@kenworthy.info wrote: Thanks very much Michael and Jonas. On Monday, 4 March 2013 07:20:24 UTC, Jonas wrote: Hi You can use the tempid ( http://docs.datomic.com/clojure/index.html#datomic.api/tempid) function to generate new temporary ids. Jonas On Monday, March 4, 2013 8:50:56 AM UTC+2, edw...@kenworthy.info wrote: Okay, I think I understand that. Does that mean this code could never work as intended in a Clojure program, only at the repl (which seems a bit of a limitation) or is there a way to make it work as intended, generating a different id each time? Or is the whole approach taken in this code flawed? On Sunday, 3 March 2013 21:59:45 UTC, Michał Marczyk wrote: #db/id ... is a tagged literal. It gets read in as an id object with some integer inside. The way this happens is that the reader looks up a data reader function associated with the symbol db/id in the map held by the var *data-readers* and passes to it the result of parsing the rest of the literal (a vector holding the keyword :db.part/db in this case). Importantly, this function is not pure and the integer it uses will be different on each invocation. (Given this form of the #db/id literal; you can also specify a particular number yourself -- #db/id [:db.part/db some-number-here].) In any case, once the reader reads in your code including some particular id, the compiler will compile the result preserving the particular values it sees, so it will embed code to construct *exactly this* id in the compiled output. Thus you end up with a particular id hardwired into the first version of your function. With the second version, if you invoke it multiple times at the REPL, you ask the reader for a new id at each invocation, so it works as you expect. If instead you were to use it inside a function like so: (defn foo [] (make-column-schema #db/id [:db.part/db] :results/subject :db.type/string)), then again the same id would be used for every (foo) call. Cheers, Michał On 3 March 2013 21:58, edw...@kenworthy.info wrote: So, I am studying a piece of code from the web. I've dissected most of it and am in the process of re-factoring it. What I don't understand is why one version works and the other doesn't. So for both: (ns gcse-results.core (:use [datomic.api :only [q db] :as d]) (:use quil.core)) This doesn't work: (defn make-column-schema [db-ident db-type] {:db/id #db/id[:db.part/db] :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute
datomic question
So, I am studying a piece of code from the web. I've dissected most of it and am in the process of re-factoring it. What I don't understand is why one version works and the other doesn't. So for both: (ns gcse-results.core (:use [datomic.api :only [q db] :as d]) (:use quil.core)) This doesn't work: (defn make-column-schema [db-ident db-type] {:db/id #db/id[:db.part/db] :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema :results/subject :db.type/string) The value of #db/id[:db.part/db] is the same. And this works: (defn make-column-schema [db-id db-ident db-type] {:db/id db-id :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema #db/id[:db.part/db] :results/subject :db.type/string) The value of #db/id[:db.part/db] is the different, as expected. Now I thought that I understood #db/id[:db.part/db] (call to a Java constructor) but obviously my understanding is flawed as I would expect both of these functions to produce the same thing, but they don't so there's obviously some gap in my understanding. Help? -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: datomic question
#db/id ... is a tagged literal. It gets read in as an id object with some integer inside. The way this happens is that the reader looks up a data reader function associated with the symbol db/id in the map held by the var *data-readers* and passes to it the result of parsing the rest of the literal (a vector holding the keyword :db.part/db in this case). Importantly, this function is not pure and the integer it uses will be different on each invocation. (Given this form of the #db/id literal; you can also specify a particular number yourself -- #db/id [:db.part/db some-number-here].) In any case, once the reader reads in your code including some particular id, the compiler will compile the result preserving the particular values it sees, so it will embed code to construct *exactly this* id in the compiled output. Thus you end up with a particular id hardwired into the first version of your function. With the second version, if you invoke it multiple times at the REPL, you ask the reader for a new id at each invocation, so it works as you expect. If instead you were to use it inside a function like so: (defn foo [] (make-column-schema #db/id [:db.part/db] :results/subject :db.type/string)), then again the same id would be used for every (foo) call. Cheers, Michał On 3 March 2013 21:58, edw...@kenworthy.info wrote: So, I am studying a piece of code from the web. I've dissected most of it and am in the process of re-factoring it. What I don't understand is why one version works and the other doesn't. So for both: (ns gcse-results.core (:use [datomic.api :only [q db] :as d]) (:use quil.core)) This doesn't work: (defn make-column-schema [db-ident db-type] {:db/id #db/id[:db.part/db] :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema :results/subject :db.type/string) The value of #db/id[:db.part/db] is the same. And this works: (defn make-column-schema [db-id db-ident db-type] {:db/id db-id :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema #db/id[:db.part/db] :results/subject :db.type/string) The value of #db/id[:db.part/db] is the different, as expected. Now I thought that I understood #db/id[:db.part/db] (call to a Java constructor) but obviously my understanding is flawed as I would expect both of these functions to produce the same thing, but they don't so there's obviously some gap in my understanding. Help? -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: datomic question
Okay, I think I understand that. Does that mean this code could never work as intended in a Clojure program, only at the repl (which seems a bit of a limitation) or is there a way to make it work as intended, generating a different id each time? Or is the whole approach taken in this code flawed? On Sunday, 3 March 2013 21:59:45 UTC, Michał Marczyk wrote: #db/id ... is a tagged literal. It gets read in as an id object with some integer inside. The way this happens is that the reader looks up a data reader function associated with the symbol db/id in the map held by the var *data-readers* and passes to it the result of parsing the rest of the literal (a vector holding the keyword :db.part/db in this case). Importantly, this function is not pure and the integer it uses will be different on each invocation. (Given this form of the #db/id literal; you can also specify a particular number yourself -- #db/id [:db.part/db some-number-here].) In any case, once the reader reads in your code including some particular id, the compiler will compile the result preserving the particular values it sees, so it will embed code to construct *exactly this* id in the compiled output. Thus you end up with a particular id hardwired into the first version of your function. With the second version, if you invoke it multiple times at the REPL, you ask the reader for a new id at each invocation, so it works as you expect. If instead you were to use it inside a function like so: (defn foo [] (make-column-schema #db/id [:db.part/db] :results/subject :db.type/string)), then again the same id would be used for every (foo) call. Cheers, Michał On 3 March 2013 21:58, edw...@kenworthy.info javascript: wrote: So, I am studying a piece of code from the web. I've dissected most of it and am in the process of re-factoring it. What I don't understand is why one version works and the other doesn't. So for both: (ns gcse-results.core (:use [datomic.api :only [q db] :as d]) (:use quil.core)) This doesn't work: (defn make-column-schema [db-ident db-type] {:db/id #db/id[:db.part/db] :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema :results/subject :db.type/string) The value of #db/id[:db.part/db] is the same. And this works: (defn make-column-schema [db-id db-ident db-type] {:db/id db-id :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema #db/id[:db.part/db] :results/subject :db.type/string) The value of #db/id[:db.part/db] is the different, as expected. Now I thought that I understood #db/id[:db.part/db] (call to a Java constructor) but obviously my understanding is flawed as I would expect both of these functions to produce the same thing, but they don't so there's obviously some gap in my understanding. Help? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.comjavascript: Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com javascript: 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com javascript:. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: datomic question
Hi You can use the tempid (http://docs.datomic.com/clojure/index.html#datomic.api/tempid) function to generate new temporary ids. Jonas On Monday, March 4, 2013 8:50:56 AM UTC+2, edw...@kenworthy.info wrote: Okay, I think I understand that. Does that mean this code could never work as intended in a Clojure program, only at the repl (which seems a bit of a limitation) or is there a way to make it work as intended, generating a different id each time? Or is the whole approach taken in this code flawed? On Sunday, 3 March 2013 21:59:45 UTC, Michał Marczyk wrote: #db/id ... is a tagged literal. It gets read in as an id object with some integer inside. The way this happens is that the reader looks up a data reader function associated with the symbol db/id in the map held by the var *data-readers* and passes to it the result of parsing the rest of the literal (a vector holding the keyword :db.part/db in this case). Importantly, this function is not pure and the integer it uses will be different on each invocation. (Given this form of the #db/id literal; you can also specify a particular number yourself -- #db/id [:db.part/db some-number-here].) In any case, once the reader reads in your code including some particular id, the compiler will compile the result preserving the particular values it sees, so it will embed code to construct *exactly this* id in the compiled output. Thus you end up with a particular id hardwired into the first version of your function. With the second version, if you invoke it multiple times at the REPL, you ask the reader for a new id at each invocation, so it works as you expect. If instead you were to use it inside a function like so: (defn foo [] (make-column-schema #db/id [:db.part/db] :results/subject :db.type/string)), then again the same id would be used for every (foo) call. Cheers, Michał On 3 March 2013 21:58, edw...@kenworthy.info wrote: So, I am studying a piece of code from the web. I've dissected most of it and am in the process of re-factoring it. What I don't understand is why one version works and the other doesn't. So for both: (ns gcse-results.core (:use [datomic.api :only [q db] :as d]) (:use quil.core)) This doesn't work: (defn make-column-schema [db-ident db-type] {:db/id #db/id[:db.part/db] :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema :results/subject :db.type/string) The value of #db/id[:db.part/db] is the same. And this works: (defn make-column-schema [db-id db-ident db-type] {:db/id db-id :db/ident db-ident :db/valueType db-type :db/cardinality :db.cardinality/one :db.install/_attribute :db.part/db}) Each call to: (make-column-schema #db/id[:db.part/db] :results/subject :db.type/string) The value of #db/id[:db.part/db] is the different, as expected. Now I thought that I understood #db/id[:db.part/db] (call to a Java constructor) but obviously my understanding is flawed as I would expect both of these functions to produce the same thing, but they don't so there's obviously some gap in my understanding. Help? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@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+u...@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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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 unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.