Re: Functions and vars and meta-data
Hi Alex, first of all thank your this exhaustive explanation. I still don't get some things, though, and kindly ask for more enlightenment. On Nov 8, 3:46 am, Alex Osborne wrote: > So after resolving, it then has a Var object. A Var, is as it's > name suggests, a variable. It consist of a name (symbol+ > namespace),metadatamap and a value (called the binding). As far as the documentation says, Vars can't have metadata: "Symbols and collections support metadata," -- http://clojure.org/metadata "Symbols, Lists, Vector, Sets and Maps can have metadata" -- http://clojure.org/reader I tried to understand the Java implementation underneath which seems to be in line with the documentation. E.g. a symbol extends AFn, which extents Obj which implements IObj, which in turn extends IMeta which seems to be the relevant implementation of the metadata interface. However, there is some metadata code in Var.java which indicates that Vars *can* have metadata, but according to documentation they can't. An example also seems to indicate that Vars can have metadata: user=> (def #^{:hasmeta "yes"} my-var [1 2 3]) #'user/my-var user=> (meta my-var) nil user=> (meta (var my-var)) {:ns #, :name my-var, :file "NO_SOURCE_PATH", :line 63, :hasmeta "yes"} > Now formetadata"on" functoins. When you write this: > > (defn #^{:xxx 1} greet [] "hello") > > The #^{...} syntax means that Clojure creates a list of two symbols > (defn and greet), and empty vector and a string "hello". The second symbol > greet has > the metadata{:xxx 1} associated with it. Really? Then why the metadata of the symbol empty? user=> (meta 'greet) nil Or am I not accessing the symbol's metadata that way? This question is also related to the following part of your explanation. > The greet symbol still keeps it's metadata. Now the def special form: > > 1. Creates a var. > 2. Copies the metadata{:xxx 1} from the symbol greet to the var. > 3. Binds the var to the function (fn ([] "hello")). > 4. Creates a mapping in the current namespace ("user") from the symbol > greet to the var. All items agreed, except for 2. which I don't grok yet. I think for me it boils down to * Is the documentation wrong or my understanding of it? * What part of the (Java)-code should I read to understand the implementation of metadata (if I assume that my understanding of how the classes extent/implement is not correct). The reason for asking this is, that I *really* want to understand what I am talking about. Kind regards, Stefan -- 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: Space leak with lazy sequences.
Hi, not sure if it works here, but what about adapting advice from Stuart Halloway's Programming Clojure (pages 159-160, 'Losing your head') and use a function returning a sequence instead of a 'bound by let' name (the actual advice in the book is to use functions returning sequences instead of vars holding the head)? This is basically a delayed evaluation trick similar to your workaround with atoms. On Fri, Nov 27, 2009 at 3:38 AM, David Brown wrote: > On Thu, Nov 26, 2009 at 05:05:17PM -0800, David Brown wrote: >>On Thu, Nov 26, 2009 at 04:00:34PM -0800, David Brown wrote: >> >>>For now, I'll do without the with-open, since in this particular case, >>>errors are going to be fairly fatal anyway. >> >>BTW, I still haven't been able to figure out how to write this >>function without hanging onto the collection across the call to >>'write-mapping'. > > Ugh, I have found a very ugly hack that works. > > It seems that the compiler only nulls out locals before a call in the > tail position, even if earlier calls don't reference the value any > more. > > So, I went down in my call-chain to the first function that uses the > sequence directly (in a doseq), and do something like this: > > (let [real-coll @coll] > (swap! coll (constantly nil)) > (doseq [item real-coll] ...)) > > I just have to wrap the collection in an atom up where I create it, > and make sure I never keep a reference to it around. > > 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 -- Miron Brezuleanu -- 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: Functions and vars and meta-data
Stefan Kamphausen writes: > On Nov 8, 3:46 am, Alex Osborne wrote: > As far as the documentation says, Vars can't have metadata: > > "Symbols and collections support metadata," -- http://clojure.org/metadata > > "Symbols, Lists, Vector, Sets and Maps can have metadata" -- > http://clojure.org/reader I don't think the documentation is *wrong* per se, it just only seems to cover the immutable types. Vars, refs, atoms, agents and namespaces can all have metadata as well, but it works a little differently for them as they are mutable. You change their metadata using the alter-meta! function. The with-meta function will not work on them. > Really? Then why the metadata of the symbol empty? > user=> (meta 'greet) > nil > > Or am I not accessing the symbol's metadata that way? You are creating a new symbol 'greet, which doesn't have metadata. Symbols are immutable types, you can't alter them and you can't alter their metadata. Instead what you do is create a new symbol with metadata attached. It might make more sense if we consider the case of metadata on collections. I can create a new empty vector with metadata using either #^ or with-meta: (meta (with-meta [] {:foo true})) ; => {:foo true} (meta #^{:foo true} []) ; => {:foo true} Having done so doesn't change the original empty vector "[]", as vectors are immutable: (meta []) ; => nil The same is true for symbols: (meta (with-meta 'greet {:a 1})) ; => {:a 1} (meta 'greet) ; => nil Note that (perhaps suprisingly) this doesn't work: (meta #^{:a 1} 'greet) ; => {:a 1} Why? Well because #^ attaches the metadata to the next read form. What's the next read form? It's 'greet. But in fact 'greet is just sugar for (quote greet). So we're actually affixing the metadata to a list containing two symbols (quote and greet). When the compiler evaluates (quote greet) it turns it into just the symbol greet and then throws the list (and thus our metadata) away. > * What part of the (Java)-code should I read to understand the > implementation of metadata (if I assume that my understanding of how > the classes extent/implement is not correct). I think you are just being confused by the differences in how metadata works with mutable and immutable types. There are three interfaces to do with metadata: IMeta.java meta -- reading metadata IObj.javawith-meta -- "changing" metadata on immutables IReference.java alter-meta! reset-meta! -- changing metadata on mutables For the immutable types the implementation is in Obj.java. For mutables it is in AReference.java. I hope that helps clarify things a bit. Alex -- 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
combining vimclojure, classpaths and leiningen
Hi All, Is there any obvious way by which you can combine vimclojure and leiningen easily? If I use leiningen to download and arrange all my jar dependencies, they all end up in a ~/.m2/repositories/... etc directory, and in the /lib directory of whatever project. I think I cannot escape spelling out the ~/.m2/paths to clojure.jar and clojure-contrib.jar in vimclojures' local.properties file, but is there any way I can get start the nailgun server from my projects' directory and it just takes ./lib as its classpath? -- 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: combining vimclojure, classpaths and leiningen
bOR_ writes: > I think I cannot escape spelling out the ~/.m2/paths to clojure.jar > and clojure-contrib.jar in vimclojures' local.properties file, but is > there any way I can get start the nailgun server from my projects' > directory and it just takes ./lib as its classpath? java -cp 'src:classes:lib/*:nailgun.jar' \ com.martiansoftware.nailgun.NGServer 127.0.0.1 Even easier there's a lein-nailgun plugin which has been uploaded by gilbertl: http://clojars.org/lein-nailgun Just add it to :dev-dependencies in your project.clj. Then you should be able to just do: lein nailgun -- 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: Functions and vars and meta-data
Hi, that have been some really embarrassing typos in my post (typing too fast in too stupid an interface, I think). On Nov 27, 12:52 pm, "Alex Osborne" wrote: > Stefan Kamphausen writes: > > On Nov 8, 3:46 am, Alex Osborne wrote: > > As far as the documentation says, Vars can't have metadata: > > > "Symbols and collections support metadata," --http://clojure.org/metadata > > > "Symbols, Lists, Vector, Sets and Maps can have metadata" -- > >http://clojure.org/reader > > I don't think the documentation is *wrong* per se, it just only seems to > cover the immutable types. Which is kind of wrong, isn't it? I strongly believe that this should be changed. > Vars, refs, atoms, agents and namespaces can > all have metadata as well, but it works a little differently for them as they > are mutable. You change their metadata using the alter-meta! > function. The with-meta function will not work on them. While I understand that the mutating functions will not apply to immutable types, I don't get why I can't create the metadata using the same interface. > > Really? Then why the metadata of the symbol empty? > > user=> (meta 'greet) > > nil > > > Or am I not accessing the symbol's metadata that way? > > You are creating a new symbol 'greet, A *new* symbol? I would have thought I'm getting the original symbol again. OK, but I see: user=> (resolve 'greet) #'user/greet user=> (meta (resolve 'greet)) {:ns #, :name greet, :file "NO_SOURCE_PATH", :line 66, :arglists ([]), :xxx 1} Sometimes the 'E' in 'REPL' stands for Enlightenment, and the 'P' must be Pleasure then. Don't ask me about 'R' and 'L', though. ;-) > It might make more sense if we consider the case of metadata on > collections. I think I already understood them. At least I can align things I read in documentation and implementation with what I find in experiments on the REPL. > Note that (perhaps suprisingly) this doesn't work: > > (meta #^{:a 1} 'greet) ; => {:a 1} > > Why? Well because #^ attaches the metadata to the next read form. > What's the next read form? It's 'greet. But in fact 'greet is just > sugar for (quote greet). So we're actually affixing the metadata to a > list containing two symbols (quote and greet). When the compiler > evaluates (quote greet) it turns it into just the symbol greet and then > throws the list (and thus our metadata) away. This is subtle! It really feels like one of those things that will still feel creepy another 50 years from now. I'll have to meditate on this a bit. > > * What part of the (Java)-code should I read to understand the > > implementation of metadata (if I assume that my understanding of how > > the classes extent/implement is not correct). > > I think you are just being confused by the differences in how metadata > works with mutable and immutable types. Definitely, and I don't like the distinction too much either. > There are three interfaces to do with metadata: > > IMeta.java meta -- reading metadata > IObj.java with-meta -- "changing" metadata on immutables > IReference.java alter-meta! reset-meta! -- changing metadata on mutables OK, I see. I missed the last one. > I hope that helps clarify things a bit. It does. I get a growing feeling of understanding how things work under the hood here. Your help is highly appreciated, thank you very much. Regards, Stefan -- 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: combining vimclojure, classpaths and leiningen
using vimclojures' nailgun, I would have a line like this added to my .vimrc file. Can I still use that? let vimclojure#NailgunClient = "/home/boris/opt/vimclojure/ng" On Nov 27, 1:43 pm, "Alex Osborne" wrote: > bOR_ writes: > > I think I cannot escape spelling out the ~/.m2/paths to clojure.jar > > and clojure-contrib.jar in vimclojures' local.properties file, but is > > there any way I can get start the nailgun server from my projects' > > directory and it just takes ./lib as its classpath? > > java -cp 'src:classes:lib/*:nailgun.jar' \ > com.martiansoftware.nailgun.NGServer 127.0.0.1 > > Even easier there's a lein-nailgun plugin which has been uploaded by > gilbertl: > > http://clojars.org/lein-nailgun > > Just add it to :dev-dependencies in your project.clj. Then you should > be able to just do: > > lein nailgun -- 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: combining vimclojure, classpaths and leiningen
Hmm. Need a bit of handholding (can't find any documentation yet on this either.) There is a vimclojure coming with adding [[lein-nailgun/lein-nailgun "0.1.0"]] to dev-dependencies (org/clojars/gilbert1/vimclojure). Do I add that to the dependencies as well? On Nov 27, 4:16 pm, bOR_ wrote: > using vimclojures' nailgun, I would have a line like this added to > my .vimrc file. Can I still use that? > > let vimclojure#NailgunClient = "/home/boris/opt/vimclojure/ng" > > On Nov 27, 1:43 pm, "Alex Osborne" wrote: > > > > > bOR_ writes: > > > I think I cannot escape spelling out the ~/.m2/paths to clojure.jar > > > and clojure-contrib.jar in vimclojures' local.properties file, but is > > > there any way I can get start the nailgun server from my projects' > > > directory and it just takes ./lib as its classpath? > > > java -cp 'src:classes:lib/*:nailgun.jar' \ > > com.martiansoftware.nailgun.NGServer 127.0.0.1 > > > Even easier there's a lein-nailgun plugin which has been uploaded by > > gilbertl: > > >http://clojars.org/lein-nailgun > > > Just add it to :dev-dependencies in your project.clj. Then you should > > be able to just do: > > > lein nailgun -- 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: combining vimclojure, classpaths and leiningen
Got it working. The only thing I need next to leiningen to set up my working environment + project is the ng client from vimclojure, the correct lines in .vimrc and the vimclojure vim plugin parts (in .vim) Good! On Nov 27, 4:16 pm, bOR_ wrote: > using vimclojures' nailgun, I would have a line like this added to > my .vimrc file. Can I still use that? > > let vimclojure#NailgunClient = "/home/boris/opt/vimclojure/ng" > > On Nov 27, 1:43 pm, "Alex Osborne" wrote: > > > > > bOR_ writes: > > > I think I cannot escape spelling out the ~/.m2/paths to clojure.jar > > > and clojure-contrib.jar in vimclojures' local.properties file, but is > > > there any way I can get start the nailgun server from my projects' > > > directory and it just takes ./lib as its classpath? > > > java -cp 'src:classes:lib/*:nailgun.jar' \ > > com.martiansoftware.nailgun.NGServer 127.0.0.1 > > > Even easier there's a lein-nailgun plugin which has been uploaded by > > gilbertl: > > >http://clojars.org/lein-nailgun > > > Just add it to :dev-dependencies in your project.clj. Then you should > > be able to just do: > > > lein nailgun -- 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: A Clojure Highlife
On Thu, Nov 26, 2009 at 4:37 AM, Chris Jenkins wrote: > > (defn flip-cell [b x y] > (let [row (nth b y) > cell (nth row x) > new-cell (- 1 cell) > new-row (assoc row x new-cell)] > (assoc b y new-row))) > (defn flip-cell [b x y] (update-in b [y x] #(- 1 %))) :) -- 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: Functions and vars and meta-data
Hi, On Nov 27, 10:19 am, Stefan Kamphausen wrote: > As far as the documentation says, Vars can't have metadata: > > "Symbols and collections support metadata," --http://clojure.org/metadata > > "Symbols, Lists, Vector, Sets and Maps can have metadata" > --http://clojure.org/reader > > I tried to understand the Java implementation underneath which seems > to be in line with the documentation. E.g. a symbol extends AFn, > which extents Obj which implements IObj, which in turn extends IMeta > which seems to be the relevant implementation of the metadata > interface. > > However, there is some metadata code in Var.java which indicates that > Vars *can* have metadata, but according to documentation they can't. Vars are one of the four reference types implementing IReference. The other three are Refs, Agents and Atoms. All IReference types support metadata. > An example also seems to indicate that Vars can have metadata: > > user=> (def #^{:hasmeta "yes"} my-var [1 2 3]) > #'user/my-var > user=> (meta my-var) > nil meta is a normal function. That means in the above case that meta is called in the vector. user=> (def #^{:hasmeta "yes"} my-var (with-meta [1 2 3] {:foo :bar})) #'user/my-var user=> (meta my-var) {:foo :bar} > Really? Then why the metadata of the symbol empty? > user=> (meta 'greet) > nil Because the is a different symbol which happens to have the same name. user=> (= 'greet 'greet) true user=> (identical? 'greet 'greet) false user=> (= 'greet (with-meta 'greet {:foo :bar})) true > Or am I not accessing the symbol's metadata that way? You are. But of a different symbol. ;) > * Is the documentation wrong or my understanding of it? Hmm.. It seems missing, but I'm sure I read somewhere about the reference types. Maybe in one Rich's talks? Hmmm.. > * What part of the (Java)-code should I read to understand the > implementation of metadata (if I assume that my understanding of how > the classes extent/implement is not correct). The chain is Var -> Aref -> AReference -> IReference -> IMeta > The reason for asking this is, that I *really* want to understand what > I am talking about. That's a Good Thing. We live to much from assumptions. Sincerely Meikel -- 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: Sneak Peek
On Nov 25, 2:32 pm, jim wrote: > Graham, > > That's exactly what it is. I used the continuation monad from > clojure.contrib.monads. Mention it on the website, and you instantly win +50 bonus Web 2.0 points for buzzword-compliance. Congraturation! > After I get the code out, I'll be writing a > tutorial on how it works which will also explain the continuation > monad. I found that monad to be the most difficult to get my head > around, but it's hugely powerful. I'd like to read that tutorial. Will you be as explicit about creative use of continuations as Haskell is? "Abuse of the Continuation monad can produce code that is impossible to understand and maintain." That sounds like a challenge. THAR BE DRAGONES. Martin -- 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: combining vimclojure, classpaths and leiningen
Hi, On Nov 27, 1:43 pm, "Alex Osborne" wrote: > Just add it to :dev-dependencies in your project.clj. Then you should > be able to just do: > > lein nailgun And make sure that the vimclojure.jar is in your classpath. It will happily use whatever nailgun is there. Sincerely Meikel -- 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
Query regarding `conj'
Hi, (rest *v1) is equal to *v2 in the below mentioned example. Then why `conj' operation on them is returning different things. user> (def *v1 [1 2 3 4 5]) #'user/*v1 user> (def *v2 [2 3 4 5]) #'user/*v2 user> (= (rest *v1) *v2) true user> (def *v3 (conj (rest *v1) 0)) #'user/*v3 user> *v3 (0 2 3 4 5) user> (def *v4 (conj *v2 0)) #'user/*v4 user> *v4 [2 3 4 5 0] user> (map #(class %) (list *v1 *v2 *v3 *v4)) (clojure.lang.PersistentVector clojure.lang.PersistentVector clojure.lang.Cons clojure.lang.PersistentVector) user> Regards, nipra -- 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: Functions and vars and meta-data
Hi, On Nov 27, 2:45 pm, Stefan Kamphausen wrote: > A *new* symbol? I would have thought I'm getting the original symbol > again. If you get back the original symbol back, it can't carry metadata... > Definitely, and I don't like the distinction too much either. But it makes sense. A Var represents an identity and hence always stays the same. Just the thing it points to might change. So we obviously need to modify the Var in order to change the meta. If we'd get a new Var, we would have a new identity. Clojure makes the distinction between such side-effecting functions and pure functions very clear. > It does. I get a growing feeling of understanding how things work > under the hood here. Watch the talk be Rich: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey There he explains the different notions and why they are required. Sincerely Meikel -- 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
reordering agent messages sent from a locked area, is it possible?
Hi, Can I assume that messages sent to an agent inside a locked area will keep their order ( the locking order)? Or is it still possible for them to be reordered like in general case when you send the messages from different threads? The following code will be run from different threads: (locking mylock (let [ somedata (somefunc) ] (send myagent myhandler somedata) ) Regards, Sergey. -- 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: Functions and vars and meta-data
On Fri, Nov 27, 2009 at 8:45 AM, Stefan Kamphausen wrote: > > Why? Well because #^ attaches the metadata to the next read form. > > What's the next read form? It's 'greet. But in fact 'greet is just > > sugar for (quote greet). So we're actually affixing the metadata to a > > list containing two symbols (quote and greet). When the compiler > > evaluates (quote greet) it turns it into just the symbol greet and then > > throws the list (and thus our metadata) away. > > This is subtle! It really feels like one of those things that will > still feel creepy another 50 years from now. > I'll have to meditate on this a bit. Maybe this ought to be fixed; i.e., if the reader sees #^{meta} 'foo it applies the metadata to foo first, then quotes it, resulting in the same thing as (quote #^{meta} foo). It would mean the reader would have to see #^{meta} and then store that, then read the next item. Currently, if the next item is also a reader macro, it expands that and then applies the meta to the result. Instead, if the next item was a read macro with an "argument" (like ' or even ^ or @ or whatever) it would apply the meta to the argument, then apply the new reader macro. -- 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: roll call of production use?
We're maintaining a large database of tagged images and had a need to perform "fuzzy search" of the database. The existing search tool takes exact queries only. So it was necessary to hack up a little tool to sit between the query source and the engine and transform the query into a "fuzzy query". You can think of it like this: the input query is something like x AND y and the output is something like (x AND (y OR y2 OR y3)) OR (y AND (x OR x2 OR x3)) where y2 and y3 are in some sense "near" y and x2 and x3 "near" x. The query transformation is simple enough, but it was really handy being able to test it at a REPL, and even hot-swap modifications and do live testing and tweaking of e.g. the neighborhood graphs used to "fuzzify" query terms. (Right now it only allows "slop" in one query term; sort of a Hamming-distance-1 matcher. Extending it further would invite a combinatorical explosion as well as lead to noisier, less useful results. Distance 1 seems to be the "sweet spot" for our app.) The code takes the input query, takes apart the terms, and generates seqs of alternatives, with some (butlast (interleave foo (repeat "OR"))) type stuff here and there, and cobbles them together again using seq functions, str, and java.lang.String methods. (Some query terms need to be parsed, e.g. are a hyphenated entity the first part of which should be fuzzy-matchable while the second part should stay constant, etc.) Rather boring? Little things like this incrementally improve services. Two guys hacking like this in their garage went on to start Google. :) We don't have such lofty aspirations, but it's still something to keep in mind. -- 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: combining vimclojure, classpaths and leiningen
Hi, On Nov 27, 4:16 pm, bOR_ wrote: > using vimclojures' nailgun, I would have a line like this added to > my .vimrc file. Can I still use that? > > let vimclojure#NailgunClient = "/home/boris/opt/vimclojure/ng" You still need this. Leiningen only starts the server, will this is the client. Without telling VC where to find the client, you cannot talk to the server. So this is required. Sincerely Meikel -- 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: reordering agent messages sent from a locked area, is it possible?
I wrote a simple test to check it and it does not see reordering on multiprocessing system. But it does not prove anything of course. (def transaction-lock (java.util.concurrent.locks.ReentrantLock.) ) (def transaction-counter (atom 0)) (def counting-agent (agent {:count 1})) (defn check [agent-state transaction-id] (if (not= (:count agent-state) transaction-id) (throw (RuntimeException. "Reordering happened")) (assoc agent-state :count (inc transaction-id)) )) (defn work [] (locking transaction-lock (let [ transaction-id (swap! transaction-counter inc) ] (send counting-agent check transaction-id) ;(println (str transaction-id " id sent.")) ))) (defn workn [n] (loop [cnt n] (when (not (zero? cnt)) (work) (recur (dec cnt) (defn work1 [] (workn 1)) (.start (Thread. work1)) (.start (Thread. work1)) (.start (Thread. work1)) (.start (Thread. work1)) (.start (Thread. work1)) (.start (Thread. work1)) (.start (Thread. work1)) (.start (Thread. work1)) (.start (Thread. work1)) (.start (Thread. work1)) (workn 1) -- 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: Sneak Peek
On Nov 25, 2:59 pm, Konrad Hinsen wrote: > On 25.11.2009, at 15:32, jim wrote: > > > That's exactly what it is. I used the continuation monad from > > clojure.contrib.monads. After I get the code out, I'll be writing a > > tutorial on how it works which will also explain the continuation > > monad. I found that monad to be the most difficult to get my head > > around, but it's hugely powerful. > > I can confirm that impression... And only wish you good luck writing > that tutorial! > >From the Haskell boys: "Abuse of the Continuation monad can produce code that is impossible to understand and maintain." That sounds to me like a challenge. -- 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
Lein adding repos
Is there currently a simple way to add new maven2 repos to download from? 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: Query regarding `conj'
Hi Nipra, 2009/11/27 nipra : > Hi, > (rest *v1) is equal to *v2 in the below mentioned example. Then why > `conj' operation on them is returning different things. > > user> (def *v1 [1 2 3 4 5]) > #'user/*v1 > user> (def *v2 [2 3 4 5]) > #'user/*v2 > user> (= (rest *v1) *v2) > true > user> (def *v3 (conj (rest *v1) 0)) > #'user/*v3 > user> *v3 > (0 2 3 4 5) > user> (def *v4 (conj *v2 0)) > #'user/*v4 > user> *v4 > [2 3 4 5 0] > user> (map #(class %) (list *v1 *v2 *v3 *v4)) > (clojure.lang.PersistentVector clojure.lang.PersistentVector > clojure.lang.Cons clojure.lang.PersistentVector) > user> (rest) returns a seq rather than a vector: user> (class (rest *v1)) clojure.lang.PersistentVector$ChunkedSeq and (conj) does different thing on seqs and vectors: user> (conj '(1 2 3) 0) (0 1 2 3) user> (conj [1 2 3] 0) [1 2 3 0] namely, conj on a vector appends the new element to the vector, and conj on a seq (or a list) prepends the new element. So, in effect you are testing the equality of (0 2 3 4 5) and [2 3 4 5 0] which are not the same, as you found out. Finally, the equality check on (rest *v1) and *v2 succeeds, because (=) treats both (rest *v1) and *v2 as seqs and traverses both checking each element for equality, i.e. it does not care that the containers are of different types. > Regards, > nipra -- ! Lauri -- 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: Functions and vars and meta-data
> Maybe this ought to be fixed; i.e., if the reader sees #^{meta} 'foo > it applies the metadata to foo first, then quotes it, resulting in > the same thing as (quote #^{meta} foo). Why introduce that special case, when you can simply do the second? I don't support the view that it's OK for programmers to not know what they're doing, which in this case means knowing that 'foo reads as (quote foo). -- 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: Query regarding `conj'
> (rest *v1) is equal to *v2 in the below mentioned example. Then why > `conj' operation on them is returning different things. rest is giving you a seq. conj is thus producing a cons where the first is 0 and the rest is that seq. (Essentially, seqs are treated as lists, and thus print with parens.) user=> (rest [1 2 3 4 5]) (2 3 4 5) user=> (type (rest [1 2 3 4 5])) clojure.lang.PersistentVector$ChunkedSeq user=> (conj (rest [1 2 3 4 5]) 1) (1 2 3 4 5) user=> (type *1) clojure.lang.Cons user=> (rest *2) (2 3 4 5) user=> (type *1) clojure.lang.PersistentVector$ChunkedSeq If you want conj to act as if it's working on a vector, you need to give it a vector: user=> (conj (vec (rest [1 2 3 4])) :a) [2 3 4 :a] user=> (conj (rest [1 2 3 4]) :a) (:a 2 3 4) -- 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: Lein adding repos
On Nov 27, 12:40 pm, David Nolen wrote: > Is there currently a simple way to add new maven2 repos to download from? I haven't done it, but looking at the code you just add :repositories [[id url]] to your project.clj. Luke -- 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: Sneak Peek
I discovered a rather subtle bug as I was coding an example web-app, so I haven't got the code out yet. Will ASAP. That tutorial is going to take a little time to write, because as the Haskell folks note, "Here be dragons!". The continuation monad is one of the most powerful and can be considered the mother of all monads: http://blog.sigfpe.com/2008/12/mother-of-all-monads.html But it will turn your brain to mush if you're not careful. Jim Martin Coxall wrote: > On Nov 25, 2:59 pm, Konrad Hinsen wrote: > > On 25.11.2009, at 15:32, jim wrote: > > > > > That's exactly what it is. I used the continuation monad from > > > clojure.contrib.monads. After I get the code out, I'll be writing a > > > tutorial on how it works which will also explain the continuation > > > monad. I found that monad to be the most difficult to get my head > > > around, but it's hugely powerful. > > > > I can confirm that impression... And only wish you good luck writing > > that tutorial! > > > > From the Haskell boys: > > "Abuse of the Continuation monad can produce code that is impossible > to understand and maintain." > > That sounds to me like a challenge. -- 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: Lein adding repos
On Nov 27, 10:09 am, Luke Renn wrote: > On Nov 27, 12:40 pm, David Nolen wrote: > > > Is there currently a simple way to add new maven2 repos to download from? > > I haven't done it, but looking at the code you just add :repositories > [[id url]] to your project.clj. That's correct. I'll try to document this more thoroughly for the next release. -Phil -- 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: Lein adding repos
Yes this worked for me. I was trying to add JOGL jars a dependency to a project. Unfortunately now running into java.lang.Security Exceptions because the JOGL jars are signed. blech. On Fri, Nov 27, 2009 at 1:28 PM, Phil Hagelberg wrote: > On Nov 27, 10:09 am, Luke Renn wrote: > > On Nov 27, 12:40 pm, David Nolen wrote: > > > > > Is there currently a simple way to add new maven2 repos to download > from? > > > > I haven't done it, but looking at the code you just add :repositories > > [[id url]] to your project.clj. > > That's correct. I'll try to document this more thoroughly for the next > release. > > -Phil > > -- > 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
Strange little difference with the reader and the java float parsers
I was working on a system that used the reader / pprint to load and save data too and from the disk and I ran into a strange issue when I reloaded my work from a JTable Apparently there are cases where read will return a slightly different float then the Float constructor will. For example: (- (new Float "1786.28") (read-string "1786.28")) 2.929687502728484E-5 I'm not sure if its just my machine or not, (Ubuntu 9.04, AMD 64 Athlon X2, Using the Sun VM 6 and JDK 6) any ideas or links? -- 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: Strange little difference with the reader and the java float parsers
On Fri, 27 Nov 2009 14:50:27 -0500, Nathan Cunningham wrote: > Apparently there are cases where read will return a slightly different > float then the Float constructor will. For example: > > (- (new Float "1786.28") (read-string "1786.28")) > 2.929687502728484E-5 read-string returns a Double for me... -- Hugo Duncan -- 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: Space leak with lazy sequences.
On Fri, Nov 27, 2009 at 01:52:05PM +0200, Miron Brezuleanu wrote: >not sure if it works here, but what about adapting advice from Stuart >Halloway's Programming Clojure (pages 159-160, 'Losing your head') and >use a function returning a sequence instead of a 'bound by let' name >(the actual advice in the book is to use functions returning sequences >instead of vars holding the head)? This is basically a delayed >evaluation trick similar to your workaround with atoms. That seems to work as long as you aren't using the sequence as part of IO where the sequence is consumed in the middle. I think the atom trick is needed for my case as far as I can tell. 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: Strange little difference with the reader and the java float parsers
On Nov 27, 9:32 pm, "Hugo Duncan" wrote: > read-string returns a Double for me... Yeah: user> (class (read-string "1786.28")) java.lang.Double user> (- (new Double "1786.28") (read-string "1786.28")) 0.0 -- 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: Functions and vars and meta-data
On Fri, Nov 27, 2009 at 12:46 PM, Richard Newman wrote: > > Maybe this ought to be fixed; i.e., if the reader sees #^{meta} 'foo > > it applies the metadata to foo first, then quotes it, resulting in > > the same thing as (quote #^{meta} foo). > > Why introduce that special case, when you can simply do the second? > > I don't support the view that it's OK for programmers to not know what > they're doing, which in this case means knowing that 'foo reads as > (quote foo). I'm not advocating in favor of programmers not knowing what they're doing. I'm advocating in favor of avoiding as many subtle gotchas as possible. -- 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: Functions and vars and meta-data
On Fri, Nov 27, 2009 at 1:23 PM, John Harrop wrote: > On Fri, Nov 27, 2009 at 12:46 PM, Richard Newman wrote: > >> > Maybe this ought to be fixed; i.e., if the reader sees #^{meta} 'foo >> > it applies the metadata to foo first, then quotes it, resulting in >> > the same thing as (quote #^{meta} foo). >> >> Why introduce that special case, when you can simply do the second? >> >> I don't support the view that it's OK for programmers to not know what >> they're doing, which in this case means knowing that 'foo reads as >> (quote foo). > > > I'm not advocating in favor of programmers not knowing what they're doing. > I'm advocating in favor of avoiding as many subtle gotchas as possible. > Interestingly, you can do what I suggested manually: user=> (meta '#^{:foo 1}foo) {:foo 1} It's a bit ugly, but it works. -- 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: Strange little difference with the reader and the java float parsers
user=> (- (new Double "1786.28") (read-string "1786.28")) 0.0 Following uip on what Hugo said, modifying your code to a double returns the following. On Nov 27, 1:32 pm, "Hugo Duncan" wrote: > On Fri, 27 Nov 2009 14:50:27 -0500, Nathan Cunningham > > wrote: > > Apparently there are cases where read will return a slightly different > > float then the Float constructor will. For example: > > > (- (new Float "1786.28") (read-string "1786.28")) > > 2.929687502728484E-5 > > read-string returns a Double for me... > > -- > Hugo Duncan -- 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: Functions and vars and meta-data
Stefan Kamphausen writes: >> I don't think the documentation is *wrong* per se, it just only seems to >> cover the immutable types. > > Which is kind of wrong, isn't it? I strongly believe that this should > be changed. Indeed. > While I understand that the mutating functions will not apply to > immutable types, I don't get why I can't create the metadata using the > same interface. Because the two operations have completely different semantics. With immutables a new object is created, with mutables an existing object is changed. Clojure could hide this behind the same function name, but you'd still need to know the distinction anyway to work with these two types of objects. Clojure makes this explicit. See what I say below on Rich's avoidance of "apparent simplicity but hidden complexity". > A *new* symbol? I would have thought I'm getting the original symbol > again. Yes, one of the differences between symbols and keywords is that symbols are created fresh each time while keywords are interned: (identical? 'foo 'foo) ; => false (identical? :foo :foo) ; => true Both are immutable, thus symbols can have metadata (as you can have two symbols that differ only by their metadata) but keywords can't, as two keywords with the same name are the same object. >> Note that (perhaps suprisingly) this doesn't work: >> >> (meta #^{:a 1} 'greet) Perhaps I should also note that this *does* work: (meta '#^{a 1} greet) As it becomes: (meta (quote greet)) ; <-- this greet symbol has metadata > This is subtle! It really feels like one of those things that will > still feel creepy another 50 years from now. > I'll have to meditate on this a bit. Clojure is a very opinionated language and one of those opinions is that Rich tries very hard to avoid incidental complexity. At times this means things may at first appear more complex on the surface than in other languages, but this is because Clojure isn't trying to hide what's going on under the hood from you. It's one of the things I really enjoy about it: there's no "magic". Clojure simplicity is real simplicity, not apparent simplicity created by hiding the complexity under the bed. It's possible and perhaps should even be expected for most Clojure programmers to have a good understanding of how things work underneath. With other languages, even if I've been using them for years I still have little clue about how things actually get evaluated. If I've taken a course in compiler writing, I might know about things like abstract syntax trees, parsers and lexers and all the special cases involved in parsing if-then-else statements, but how it works in a particular language is going to be a mystery unless I've written my own compiler. As Meikel suggested, watch Rich's talks. I think it's important to try to understand the philosophy behind Clojure's design. Rich has some very strong messages and even if you don't agree with them, they're definitely worth listening to and thinking about. Cheers, Alex -- 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: performance issues with multi-dimensional array
On Thu, Nov 26, 2009 at 11:49 AM, Amnon wrote: > I did, and it works like a charm. Couldn't figure out how to hint an > array of objects (what should I put instead of the old #^objects? > I still get it to work in 300 ms (which is not great but something I > can live with). > You have to replace #^objects with #^"[Ljava.lang.Object;" (don't use a more specialized type: it wouldn't help with aget/aset). > Thanks for the replies, > > On Nov 25, 8:01 pm, David Nolen wrote: > > Read Christophe's post about multi-dim arrays. Reflection is getting in > the > > way here. > > > > > > > > On Wed, Nov 25, 2009 at 2:55 AM, Amnon wrote: > > > Hi Konrad, > > > In the original post, I put in the code, it was removed by the post > > > editor. > > > The way I wanted it implement, I have the main in java (gui and > > > stuff). I create a 3D array in java, it's an int array (i.e. int arr[] > > > [][] ) and call with that array to clojure. > > > > > It can be done in java at least 3 orders of magnitude faster so I'm > > > sure there is something I'm doing wrong. > > > I'll appreciate any suggestion. > > > Thanks, > > > Amnon > > > > > I've squeezed my example into two functions: > > > > > (defn light [arr x y] > > >(+ (aget arr x y 0) (aget arr x y 1) (aget arr x y 2)) > > >) > > > > > (defn grey [arr] > > >(dotimes [x (length arr)] > > >(dotimes [y (alength (aget arr 0))] > > >(let [lg (int (/ (light arr x y) 3))] > > >(aset arr x y 0 lg) > > >(aset arr x y 1 lg) > > >(aset arr x y 2 lg) > > > > > > > > On Nov 24, 8:35 pm, Konrad Hinsen wrote: > > > > On 24 Nov 2009, at 17:30, Amnon wrote: > > > > > > > I hope it's not the billion time you get the question. > > > > > I wanted to use clojure for image processing. I have a 3 > dimensional > > > > > array I'm passing to clojure from java. > > > > > I then loop on the array to manipulate it. > > > > > Even the simplest task takes about half a minutes (I expected it to > be > > > > > over in less than a second) > > > > > > Could you give some more details? For example, what is the Java class > > > > you use for the 3D arrays? How are you accessing it from Clojure? How > > > > do you do the loops? How do you create the destination array, and > how > > > > do you fill it with the grey-scale values? I suspect that many of > > > > these steps could be optimized, but it's hard to say without knowing > > > > how your current code works. > > > > > > Konrad. > > > > > -- > > > 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 > -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.cgrand.net/ (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: AOT'd namespaces lose their metadata
Tom Faulhaber writes: > I'm super-excited about Leiningen, btw. I've been thinking about how > to turn my autodoc stuff into a Leiningen plugin so that we can get > easy doc for any project. Awesome. We've already got someone started working on a doc plugin; please join the leiningen mailing list if you'd like to coordinate work on that. The contrib HTML documentation is really great, and I'd love it if it were easier for more projects to produce output like that. http://groups.google.com/group/clojure -Phil -- 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: Functions and vars and meta-data
Hi, On Nov 27, 11:06 pm, "Alex Osborne" wrote: > > A *new* symbol? I would have thought I'm getting the original symbol > > again. > > Yes, one of the differences between symbols and keywords is that symbols > are created fresh each time while keywords are interned: > > (identical? 'foo 'foo) ; => false > (identical? :foo :foo) ; => true Whoa! Cool example. This is rather an important point, I think. I mean it's not important, when your "only" programming with Clojure, which will usally work, and you always have the REPL... But it becomes more important for those, trying to understand. It's about grokking a language's design vs. experimenting with the code long enough so that it seems to work. > >> Note that (perhaps suprisingly) this doesn't work: > > >> (meta #^{:a 1} 'greet) > > Perhaps I should also note that this *does* work: > > (meta '#^{a 1} greet) To be honest, I think it looks even worse. There is some reader macro which by happy accident works in a certain way together with the other read syntax. No, I don't think it should work. > Clojure is a very opinionated language and one of those opinions is that > Rich tries very hard to avoid incidental complexity. Which is a Good Idea(tm). > At times this > means things may at first appear more complex on the surface than in > other languages, but this is because Clojure isn't trying to hide what's > going on under the hood from you. It's one of the things I really enjoy > about it: there's no "magic". Clojure simplicity is real simplicity, > not apparent simplicity created by hiding the complexity under the bed. Hm, is it possible you're coming from Java here? For me, coming more from CL than Java, some things in Clojure feel very --let's say-- Perlish: there is so much syntax there. Don't get me wrong, I think Clojure delivers what arc promised, it does a hell of a job revolutionizing Lisp. I hardly can disagree with many of the design principles, I just like the documentation to tell the whole story so not everyone new to Clojure will have to figure it out for him/ herself. > It's possible and perhaps should even be expected for most Clojure > programmers to have a good understanding of how things work underneath. Agreed. The docs should say so, agreed? I'd very much like to volunteer on docs, but I just don't know how I could keep up with development, since I am doing almost all my Clojure stuff after work when the children are in bed. > With other languages, even if I've been using them for years I still > have little clue about how things actually get evaluated. That may be related to the lesser importance of order of evaluation in other languages. I mean, Perl has a *lot* of syntax, but usually it all takes place at the same time, or at least, you as a developer won't have to care. Anyway, not worth a discussion. > As Meikel suggested, watch Rich's talks. I do, and I really like them. One can hear, that Rich's got a story to tell. They are very valuable for understanding the philosophy behind many of Clojure's design decisions. The screencast/ presentation/video-thing helps learning a new language nowadays. > I think it's important to try to understand the philosophy behind Clojure's > design. Wait, I've heard that before... Deja vu? > Rich has some > very strong messages and even if you don't agree with them, they're > definitely worth listening to and thinking about. There, another Deja vu. ;-) Alex, John, Meikel, Richard, thanks for taking your time. Kind regards, Stefan -- 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: Functions and vars and meta-data
> Whoa! Cool example. This is rather an important point, I think. I > mean it's not important, when your "only" programming with Clojure, > which will usally work, and you always have the REPL... But it > becomes more important for those, trying to understand. It's about > grokking a language's design vs. experimenting with the code long > enough so that it seems to work. Yeah, pretty awesome :) I love how almost any technical question on this list can be answered by a three-line REPL interaction! >> (meta '#^{a 1} greet) > > To be honest, I think it looks even worse. There is some reader macro > which by happy accident works in a certain way together with the other > read syntax. No, I don't think it should work. It's not really a happy accident, it's as specified. ' quotes the next read form. #^ applies metadata to the next read form. Granted, I have some experience with reader macros from CL, but I feel this should be an area that a moderately well-educated programmer should encounter, perhaps trip up, say "oh yes, I see why that happens", and move on, rather than viewing it as some kind of fault to be corrected. When you realize that reader macros and quotation marks are a way of communicating with the reader that's parsing the text of your code, things become a little simpler. > Hm, is it possible you're coming from Java here? For me, coming more > from CL than Java, some things in Clojure feel very --let's say-- > Perlish: there is so much syntax there. Coming from CL myself, I have two inputs to this debate. Firstly, CL has more syntax than one at first thinks (for a Lisp, at least) — particularly the raft of reader macros (including configurable ones), but also things like format string keywords. It simply doesn't have a plurality of *delimiters*: just double-quote, block comment, and parens, really. Secondly, I view most of Clojure's syntax — mainly delimiters for literal maps, sets, and vectors — to be completely worth the sacrifice of simplicity. The delimiter characters are there, and it would be foolish to waste them. The things that makes Perl "Perlish" to me are the special variable line-noise ($/, $_, $&, etc.), contexts (scalar etc.), and extreme parse-time lexical manipulation, all of which conspire to make the meaning of a piece of code enormously context- and runtime-dependent. (For example, you can't parse Perl without executing it.) I don't think Clojure's additional delimiters compared to Common Lisp moves it towards Perl in this way. I hate Perl, and I don't have that reaction to Clojure! :) > I just like the documentation to tell the whole story so > not everyone new to Clojure will have to figure it out for him/ > herself. As I'm sure you know, this is an unfortunate consequence of Clojure's youth. Clojure only turned 2 last month, so I think its vibrant library collection and community are actually surprisingly large and vigorous. Docs take time to accrete, and Rich is devoted more to development than to filling in perceived gaps; a lot of knowledge is tied up in mailing list posts, videos, and presentations. I know Tom and others have been working to improve the doc situation. > Alex, John, Meikel, Richard, > thanks for taking your time. My pleasure. I love this community! -- 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: Functions and vars and meta-data
Stefan Kamphausen writes: >> (meta '#^{a 1} greet) > > To be honest, I think it looks even worse. There is some reader macro > which by happy accident works in a certain way together with the other > read syntax. No, I don't think it should work. I agree this is ugly and unintuitive and I wouldn't use it in a real program, I'd use with-meta instead. I included it as an illustration that some reader macros like ~, ' and @ are just shorthand for regular macros: unquote, quote and deref respectively, while others change the behaviour of the reader, like #^, ; and #_. Unfortunately syntax-quote (`) currently falls into the latter camp, but I hope that will change in Clojure-in-Clojure. Try this to see something scary: '`(foo) => (clojure.core/seq (clojure.core/concat (clojure.core/list (quote user/foo The reason it needs to break the list down like that is so that it can implement splicing-unquote. > Hm, is it possible you're coming from Java here? For me, coming more > from CL than Java, some things in Clojure feel very --let's say-- > Perlish: there is so much syntax there. Don't get me wrong, I think > Clojure delivers what arc promised, it does a hell of a job > revolutionizing Lisp. Yes, I have a mainly non-lisp background, much C, Python, Ruby and some Java and Haskell and various other languages. I had dabbled in Common Lisp and Scheme a bit before discovering Clojure but found Common Lisp very complex and Scheme very verbose and the lack of syntax for common data structures like hash tables frustrating. So perhaps I fall towards the slightly more sugary side of the spectrum compared to Scheme, especially when it comes to data structures but I do agree that things might be clearer without the ^ and #' reader macros and restricting #^ just to type hints. > I hardly can disagree with many of the design > principles, I just like the documentation to tell the whole story so > not everyone new to Clojure will have to figure it out for him/ > herself. Yes. Stuart's book "Programming Clojure" is a much better introduction to the language. The website is mostly okay as a reference but it is incomplete and usually out of date. -- 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: Functions and vars and meta-data
On Nov 27, 5:46 pm, Richard Newman wrote: > > I don't support the view that it's OK for programmers to not know what > they're doing, which in this case means knowing that 'foo reads as > (quote foo). FWIW I *strongly* agree; getting reader macros straight in my head was a *big* help in macro writing; the special case would reinforce the "wrong" impression, IMO On Nov 27, 10:06 pm, "Alex Osborne" wrote: > Clojure is a very opinionated language and one of those opinions is that > Rich tries very hard to avoid incidental complexity. At times this > means things may at first appear more complex on the surface than in > other languages, but this is because Clojure isn't trying to hide what's > going on under the hood from you. It's one of the things I really enjoy > about it: there's no "magic". Clojure simplicity is real simplicity, > not apparent simplicity created by hiding the complexity under the bed. > Yes! One of the greatest aspects of Clojure is the clean consistency of the base language. One of the things that put me off really using Scala in anger was that the language itself seemed to have a lot of corner cases etc. (1) Scala was easier to pick up coming from Java, but Clojure easier to really get to grips with. -Dave 1. This is entirely subjective of course; if you consider Scala well- nigh spherical in its lack of corners, roll on. -- 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
Krishnamurthi's Automata in Clojure (OutOfMemoryError)
I've been working on a problem that requires me to write a small state machine for processing XML documents. Out of curiousity (I'm new to functional programming) I hit Google to see how automata are written in other functional languages. I found Shriram Krishnamurthi's paper: http://lambda-the-ultimate.org/node/569 It is discussed further, along with a Clojure implementation, here: http://list.cs.brown.edu/pipermail/plt-scheme/2007-November/thread.html#21571 The implementation listed there doesn't work, and is before Rich introduced "letfn", so I decided to try my own implementation using letfn and trampoline: (defn machine [start-stream] (letfn [(init [stream] #(cond (empty? stream) true (= \c (first stream)) (more (rest stream)) :else false)) (more [stream] #(cond (empty? stream) true (= \a (first stream)) (more (rest stream)) (= \d (first stream)) (more (rest stream)) (= \r (first stream)) (end (rest stream)) :else false)) (end [stream] #(cond (empty? stream) true :else false))] (trampoline init start-stream))) This works, but if I try to run it on an infinite sequence, it eventually runs out of memory: (machine (iterate (fn [c] (if (= c \c) \a \d)) \c)) Java heap space [Thrown class java.lang.OutOfMemoryError] I don't understand the underlying model of Clojure's runtime well enough to understand why this is occurring. I'm not getting a stack overflow error, so it seems likely that something is holding onto memory (perhaps the entire stream?). Does anyone have any insight into this? Thanks! Charles Gordon -- 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: Atomic reloads and snapshots of namespaces
On 27 Nov., 04:33, pmf wrote: > On Nov 26, 7:39 pm, Richard Newman wrote: > > > "Re consistency: I seem to recall Pascal Costanza working on > > activation of layers, so you can swap a whole set of stuff across your > > program. He spoke about it at ILC2009, but I'm not sure I've found the > > right paper. Common Lisp-specific, though." > > > He showed a website, paused mid-request, where he swapped out several > > functions. Unpausing the request still ran to completion with the old > > functions. A new request ran with the new functions. Impressive. > > CLOS and the MOP allows you to change a class and have all already > existing instances be transformed into the new form (in an automatic > or user defined way), which makes these things much easier to achieve > than in Java- and Clojure-world. I think there is a misunderstanding here. Clojure makes it easy to update state, and a MOP is not needed. But I am not talking about adding/removing slots to an object, but instead of modifying *functions*. Let‘s say we have the functions A, B, C, D, E, F and G. A is calling B, B is calling C, C is calling D, and so on. Now a request R1 comes in, function A is called and this chain continues to, say, E. Now a reload happens. Some functions A-G are changed. B now may expect C to return not a value v1, but instead a vector of the values [v1 v2]. Even if the signatures didn‘t change and no exception would be thrown, it could destroy consistency of the data anyway. What I want is that any request R1, R2, R3, ... will continue to use the chain A-G. A reload should happen atomically. All functions should load and eval in the background and only become callable if everything was reloaded. All new incoming requests will now go through the new chain A-G (maybe some new functions came in and it is now A-Z, or others were removed so that it will be A-Z but without D and E) while at the same time R1 continues with the old set of functions. That way each user of (my) web services would get a constintent answer. Some users may be in a session that can go for minutes or hours or even days. In such a case we may be interested that as long this session exists this users requests will always be handled with the old set of functions. So, a way to make a “namespace snapshot” would be interesting. Each time when a request comes in one can snapshot the code, and only then begin to handle the request. If a session gets created one can store the snapshoted functions in the session object and read it out of there. I don‘t know if this makes sense and what problems may arise, and even if such a proposal sounds nice in theory it may be too hard to develop, for now. -- 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: Krishnamurthi's Automata in Clojure (OutOfMemoryError)
Hi Charles, I notice I can stop your version from running out of memory with a very small change. Changing from: ;; the [f & args] form of trampoline (trampoline init start-stream) to: ;; the [f] form of trampoline (trampoline #(init start-stream)) seems to work as expected. I would hazard a guess that this might be the same issue as described in this thread: http://groups.google.com/group/clojure/msg/dfb1c1d68ac7e742 Cheers, Mark Charles Gordon writes: > The implementation listed there doesn't work, and is before Rich > introduced "letfn", so I decided to try my own implementation using > letfn and trampoline: > > (defn machine [start-stream] > (letfn [(init [stream] > #(cond (empty? stream) true > (= \c (first stream)) (more (rest stream)) > :else false)) > (more [stream] > #(cond (empty? stream) true > (= \a (first stream)) (more (rest stream)) > (= \d (first stream)) (more (rest stream)) > (= \r (first stream)) (end (rest stream)) > :else false)) > (end [stream] >#(cond (empty? stream) true >:else false))] > (trampoline init start-stream))) > > This works, but if I try to run it on an infinite sequence, it > eventually runs out of memory: > > (machine (iterate (fn [c] (if (= c \c) \a \d)) \c)) > > Java heap space > [Thrown class java.lang.OutOfMemoryError] -- Mark Triggs -- 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: Atomic reloads and snapshots of namespaces
On Fri, Nov 27, 2009 at 7:48 PM, André Thieme wrote: > Let‘s say we have the functions A, B, C, D, E, F and G. > A is calling B, B is calling C, C is calling D, and so on. > Now a request R1 comes in, function A is called and this chain > continues to, > say, E. > Now a reload happens. Some functions A-G are changed. B now may expect > C > to return not a value v1, but instead a vector of the values [v1 v2]. > Even if the signatures didn‘t change and no exception would be thrown, > it > could destroy consistency of the data anyway. > What I want is that any request R1, R2, R3, ... will continue to use > the > chain A-G. > A reload should happen atomically. All functions should load and eval > in > the background and only become callable if everything was reloaded. > All new incoming requests will now go through the new chain A-G (maybe > some > new functions came in and it is now A-Z, or others were removed so > that it > will be A-Z but without D and E) while at the same time R1 continues > with > the old set of functions. > That way each user of (my) web services would get a constintent > answer. > There is one way to achieve something like that already, though you have to explicitly set up certain functions to be replaceable in this transactional manner: ... (def B (ref (fn [args] body))) (def A (ref (fn [args] body ... (@B foo bar) ...))) (defn something-that-calls-A [args] (dosync (@A some-stuff) etc.)) (defn replace-A-and-B [new-A-fn new-B-fn] (dosync (ref-set A new-A-fn) (ref-set B new-B-fn))) During the something-that-calls-A dosync everything will see a snapshot of the "ref world" in which no replace-A-and-B transaction is half-completed, so a particular compatible pair of functions will be seen. Related means could also be used, e.g. (def fn-set (atom {:B (fn [fn-set other-args] body) :A (fn [fn-set other-args] body ... ((:B fn-set) fn-set foo bar) ...)})) (defn session-start [params] (let [fns @fn-set] ((:A fns) fns params))) (defn replace-fn-set [fn-map] (reset! fn-set fn-map)) Each session or whatever holds a reference to a map of the functions to call, and the functions pass the map around and call the functions through the map. The map, being a Clojure map, is immutable, so a session is guaranteed to always use a consistent group of functions. Changing the function map in the global atom changes the map used by new sessions, without affecting pre-existing ones. If each session or whatever is associated with its own thread, you can also go with (def *fn-map* nil) (def fn-set (atom {:B (fn [args] body) :A (fn [args] body ... ((:B *fn-map*) foo bar) ...)})) (defn session-start [params] (binding [*fn-map* @fn-set] ((:A *fn-map*) params))) (defn replace-fn-set [fn-map] (reset! fn-set fn-map)) which avoids the ugliness of passing the session's function map as a parameter all over the place. You can even dispense with the keyword lookups with a bit more effort: (def *A* nil) (def *B* nil) (def fn-set (atom {:B (fn [args] body) :A (fn [args] body ... (*B* foo bar) ...)})) (defn session-start [params] (let [fn-map @fn-set] (binding [*A* (:A fn-map) *B* (:B fn-map)] (*A* params (defn replace-fn-set [fn-map] (reset! fn-set fn-map)) This version uses separate thread-local bindings for the individual functions, which can be called like normal Clojure functions (because they ARE normal Clojure functions). Each session binds all of them based on a single dereference of the fn-set atom, so again has a consistent set of functions, which replace-fn-set will change for subsequent (but not preexisting) sessions. I'm sure you can dream up more ways to achieve similar results. (A cookie if you can think up one using agents.) -- 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