Re: Rolling back transactions with clojure.java.jdbc
Thanks Sean. I'll give it a try! On Fri, Oct 25, 2013 at 11:21 AM, Sean Corfield seancorfi...@gmail.comwrote: Second bug in your code: (delete-scores-for-column db cid) Should be: (delete-scores-for-column t cid) Sorry I didn't see that (additional) bug first time around when I suggested removing :transaction? from delete! execute! does not call with-open if it can find an active connection in the passed in db-spec. Inside a transaction, there is an active connection. But if you pass the original db-spec instead of the transaction-aware one, it will do what you ask (create a new connection) instead of what you want (use the same connection). Most of the bugs I see in java.jdbc usage code are the result of overthinking and not just letting the library do its thing :) Sean On Fri, Oct 25, 2013 at 6:33 AM, Mark mjt0...@gmail.com wrote: Scratch that aside, I think I have that part working. It was a little gnarly because the datasource provider was written in Scala and posed a few potentially confusing interop problems, and I must have gotten it wrong on at least one account. However, I'm still seeming to commit automatically. On Friday, October 25, 2013 9:17:03 AM UTC-4, Mark wrote: That doesn't seem to work. Neither does explicitly setting :transaction? to false. Looking at the source of execute!, it looks like the statement is running within a with-open on the java.sql.Connection, which is where a commit or rollback would occur. I presume that the with-open is closing the connection, which is resulting in a commit. Is there some way I can set autocommit to false on the connection through the db-spec? Unrelated to this, I had earlier been trying to use a DataSource provider that we have and wrap it with {:datasource ds}, which worked fine for executing queries, but db-set-rollback-only! would throw a NullPointerException (from reset!) if I created the data source that way. I dug around in the source code a bit more, but didn't see immediately what was going on - that being said, I'm not terribly familiar with how atoms work in Clojure. Thanks for your help! Mark On Friday, October 25, 2013 2:10:18 AM UTC-4, Sean Corfield wrote: Remove :transaction? true from the delete! call. You're telling delete! to run inside its own transaction - you don't want that: that's why your deletes do not rollback. Sean On Thu, Oct 24, 2013 at 2:03 PM, Mark mjt...@gmail.com wrote: I've been working on a small utility script to clean up a very large table (~1 billion rows). Because the table is so large, I want to go through and delete it chunk at a time. I've written a simple script that does this, but when I was testing it against our dev instance, I found that it wasn't rolling back, as I'd hoped it would. You can see a simplified version of the script here: https://gist.github.com/anonymous/14ed57085709a2772ee0 It's using an Oracle database (11GR1, I think) and clojure.java.jdbc version 0.3.0-alpha5. I've dug through the clojure.java.jdbc docs and code, but I don't see an obvious problem with what I'm doing, although I presume that to someone who knows this library better, my problem is quite simple. Does anyone have any idea what I'm doing wrong? Can you point to an example that issues deletes (or inserts, or updates) that rollback? Thanks! Mark -- -- 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. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- 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
Re: Rolling back transactions with clojure.java.jdbc
Looks like that was a success. Thanks for the help! On Fri, Oct 25, 2013 at 11:26 AM, Mark Tomko mjt0...@gmail.com wrote: Thanks Sean. I'll give it a try! On Fri, Oct 25, 2013 at 11:21 AM, Sean Corfield seancorfi...@gmail.comwrote: Second bug in your code: (delete-scores-for-column db cid) Should be: (delete-scores-for-column t cid) Sorry I didn't see that (additional) bug first time around when I suggested removing :transaction? from delete! execute! does not call with-open if it can find an active connection in the passed in db-spec. Inside a transaction, there is an active connection. But if you pass the original db-spec instead of the transaction-aware one, it will do what you ask (create a new connection) instead of what you want (use the same connection). Most of the bugs I see in java.jdbc usage code are the result of overthinking and not just letting the library do its thing :) Sean On Fri, Oct 25, 2013 at 6:33 AM, Mark mjt0...@gmail.com wrote: Scratch that aside, I think I have that part working. It was a little gnarly because the datasource provider was written in Scala and posed a few potentially confusing interop problems, and I must have gotten it wrong on at least one account. However, I'm still seeming to commit automatically. On Friday, October 25, 2013 9:17:03 AM UTC-4, Mark wrote: That doesn't seem to work. Neither does explicitly setting :transaction? to false. Looking at the source of execute!, it looks like the statement is running within a with-open on the java.sql.Connection, which is where a commit or rollback would occur. I presume that the with-open is closing the connection, which is resulting in a commit. Is there some way I can set autocommit to false on the connection through the db-spec? Unrelated to this, I had earlier been trying to use a DataSource provider that we have and wrap it with {:datasource ds}, which worked fine for executing queries, but db-set-rollback-only! would throw a NullPointerException (from reset!) if I created the data source that way. I dug around in the source code a bit more, but didn't see immediately what was going on - that being said, I'm not terribly familiar with how atoms work in Clojure. Thanks for your help! Mark On Friday, October 25, 2013 2:10:18 AM UTC-4, Sean Corfield wrote: Remove :transaction? true from the delete! call. You're telling delete! to run inside its own transaction - you don't want that: that's why your deletes do not rollback. Sean On Thu, Oct 24, 2013 at 2:03 PM, Mark mjt...@gmail.com wrote: I've been working on a small utility script to clean up a very large table (~1 billion rows). Because the table is so large, I want to go through and delete it chunk at a time. I've written a simple script that does this, but when I was testing it against our dev instance, I found that it wasn't rolling back, as I'd hoped it would. You can see a simplified version of the script here: https://gist.github.com/anonymous/14ed57085709a2772ee0 It's using an Oracle database (11GR1, I think) and clojure.java.jdbc version 0.3.0-alpha5. I've dug through the clojure.java.jdbc docs and code, but I don't see an obvious problem with what I'm doing, although I presume that to someone who knows this library better, my problem is quite simple. Does anyone have any idea what I'm doing wrong? Can you point to an example that issues deletes (or inserts, or updates) that rollback? Thanks! Mark -- -- 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. -- Sean A Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ World Singles, LLC. -- http://worldsingles.com/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- 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
Re: Why is using (not (empty? coll)) not idiomatic?
Even so, what do you do when you're using someone else's code as a library? On Mon, May 13, 2013 at 10:42 AM, Meikel Brandmeyer (kotarak) m...@kotka.dewrote: Hi, Am Montag, 13. Mai 2013 16:16:36 UTC+2 schrieb Mark: That's a fair point, but do you always know that what you've gotten back is a sequence or a data structure, if you aren't looking directly at the code that you're calling? Most of my code are either sequence-y things (mostly transformations). Then I call seq on the argument and work with the result together with a when-let. (maybe transforming things back into the original type of thing afterwards) Or it's about data structures. Then - most of the time - you have to know anyway what you are working on, because the data structures have different usage scenarios. Typical case: (into (empty x) (map some-fn (take some-number (filter some-pred x That said: my code is usually not representative. 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 --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/WEoAo6BcCV0/unsubscribe?hl=en. To unsubscribe from this group and all its topics, 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: Names and clojure.core
I definitely agree that nomenclature is often one of the hardest things to handle well. I'm actually a professional software engineer in real life, but I don't get to use Clojure at work. I suppose the names I suggested were uninspired partially because I only get a few minutes at a time to work on my hobby projects outside of work. Thanks! On Thu, Mar 28, 2013 at 11:21 AM, Gregg Reynolds d...@mobileink.com wrote: On Thursday, March 28, 2013 8:51:15 AM UTC-5, Mark wrote: I'm still just a Clojure hobbyist, but I have a question for folks who are using Clojure professionally or for larger scale projects. Recently, I've been finding that it's difficult to come up with names for variables and functions that aren't already in the clojure.core namespace. If it's any consolation, I find that coming up with good names is one of the hardest (and least appreciated) aspects of programming. For instance, I have a little toy project that digs through DNA sequence data to extract some simple metrics. I obviously can't call a variable or function seq because that's meaningful in clojure.core already. It turns out, I also can't call it bases, because that's a function in clojure.core also. I could call it dna, but that's sort of undescriptive (it's important to me that the name indicate the sequential nature of what the binding refers to). Think metaphorically - dozens of possibilities. String, slab, run, flow, clip (of film = seq of frames), chain, train, parade, etc. I find that sometimes digging through etymologies (www.etymonline.com) turns up new ideas. -Gregg -- -- 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 a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/LIUAgA4GSB8/unsubscribe?hl=en. To unsubscribe from this group and all its topics, 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: Are there any plans for more allowed symbol characters?
I agree with you in principle, but I suspect that the answer is deliberately delegated to Java's definition of letter or number. Mark On Mar 2, 3:17 am, Michael Wood esiot...@gmail.com wrote: On 2 March 2010 00:24, Joost jo...@zeekat.nl wrote: On 1 mrt, 23:02, Michael Wood esiot...@gmail.com wrote: I don't know if the following's allowed, but it works: user= (def ð Math/PI) #'user/ð user= ð 3.141592653589793 Sine the JVM considers all strings to be 16-bit unicode, I would expect all the usual java/unicode number/letter types to be valid, including the special unicode number/letter category, (accented) upper, title and lower case and a few more. See also, Java's Char.isLetterOrDigit documentation. What Java thinks of as a letter or digit doesn't necessarily come into it. This is not a technical thing, but rather a what did Rich mean thing. I don't see any particular reason to disallow non-ASCII letters/digits, though, except that the pi[1] in my e-mail was turned into an eth[2] in your reply... 1.http://www.unicodemap.org/details/0x03c0/ 2.http://www.unicodemap.org/details/0x00F0/ -- Michael Wood esiot...@gmail.com -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: Dubious performance characteristics of hash-maps
I'd suggest allocating more heap than the default JVM settings, or running the JVM in server mode. I'm not sure what Haskell's underlying implementation is, but I'd assume that it can grow its heap (somewhat) arbitrarily, which the JVM cannot, beyond a fixed bound. On Feb 23, 12:51 am, Edward Z. Yang ezy...@mit.edu wrote: I'd first like to state that I went into this exercise expecting Bagwell's Hash Array Mapped Tries to blow the competition out of the water; I'd get a fast functional map and give it to Haskell and people would rejoice. Instead, I found a functional hash-map that was approximately four times slower than Haskell's IntMap. I find this puzzling, and would love to puzzle it out with you folks. First, the test case: (ns maptest (:gen-class)) (defn mk-random-stream [] (let [r (new ec.util.MersenneTwisterFast)] (repeatedly (fn [] (. r (nextInt)) (defn -main [sn] (let [n (Integer/parseInt sn) rs (take (* 2 n) (mk-random-stream))] (time (let [m (apply hash-map (take (* n 2) (interleave rs rs)))] (reduce (fn [s k] (let [v (get m k)] (+ s (if (nil? v) 0 v 0 (take n (drop (/ n 2) rs))) We generate an n-sized hash tree, and then do n accesses, half of which match and half of which miss. We compute the sum of all the values that catch. We see the following characteristics: n Clojure Haskell (HAMT) Haskell (IntMap) 32K .56s .30s .09s 64K .84s .69s .22s 128K 1.65s 1.50s .46s 256K 2.94s 3.23s 1.17s 512K 7.32s 6.96s 2.70s I was careful to compile the Clojure code before attempting to run it. I also pre-allocate the entire random sequence to prevent it from muddying the execution time (although I am using Sean Luke's excellent fast Mersenne Twister [1]). The full string I used to invoke the program was: /usr/lib/jvm/java-6-sun-1.6.0.16/bin/java -Dfile.encoding=UTF-8 \ -classpath $CLASSES maptest $@ The fact that it's similar in performance to the Haskell reimplementation (I'd say that the variance is not particularly significant and both are about on par performance wise) seems to validate the testing methodology, I hope, though the real proof of the pudding would lie in implementing Haskell-style IntMap in Java. You can see the test code for the Haskell versions here: http://github.com/ezyang/hamt So... what's up with these numbers? Is my methodology wrong? Is the garbage collector sucking? Is the algorithm just not as good as it makes out to be? Cheers, Edward [1]http://www.cs.gmu.edu/~sean/research/ -- 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: Seattle Clojure meeting
Oh, man. I just moved from Seattle to Boston in December, and I miss Zoka's coffee. Have fun, everyone!Maybe we can get some of the Boston-area Clojure folks to meet up sometime. On Feb 11, 7:30 pm, Phil Hagelberg p...@hagelb.org wrote: On Fri, Feb 5, 2010 at 12:50 PM, Phil Hagelberg p...@hagelb.org wrote: Wow, I certainly was not expecting that level of response; this is great. Looks like the 11th (Thursday) is the crowd favorite. Once again, the location ishttp://bit.ly/c9jinW We'll be meeting in the back. Zoka is a big place, but it can get crowded with all those college students around, so I'll try to save some space. Look for the laptop with the my other car is a cdr sticker, or for me; my photo is athttp://technomancy.us/colophon Just a reminder: this is tonight. I'd love to see you there. -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: Access to nested static classes
That's fair, except that it's a little disappointing that I can't reference nested structures from Clojure in the natural way, akin to Java. In Java, if I had imported NestedStatics, I could reference NestedStatics.LevelOne without bringing LevelOne into my namespace (and possibly into conflict with other imports!). In Clojure, however, it appears that any class that I want to reference needs to be fully qualified or explicitly imported into my own namespace. On Dec 28, 11:09 pm, David Brown cloj...@davidb.org wrote: On Mon, Dec 28, 2009 at 02:50:59PM -0800, Mark Tomko wrote: This, however, does not work: (ns org.tomko.konkordans.analysis (:import (org.tomko.konkordans NestedStatics))) (def foo NestedStatics$LevelOne$LevelTwo/NO) The class is called NestedStatics$LevelOne$LevelTwo, so you would have to import that if you wanted to use it. As far as the JVM is concerned, NestedStatics, NestedStatics$LevelOne and NestedStatics$LevelOne$LevelTwo are just three independent classes. Java added nested classes, but didn't really add them to the JVM. It just makes longer class names using the '$'. It's probably safe to rely on this behavior, since there is plenty of code that depends upon it working this way. 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
Access to nested static classes
Is there a way to reference nested static members of Java classes using Clojure? I tried a few things and couldn't get it to work. To simplify the question a bit, I wrote the following Java class: package org.tomko.konkordans; public class NestedStatics { public static String FOO = foo; public static class LevelOne { public static enum LevelTwo { YES,NO; } } } Then, at the REPL: user= (str org.tomko.konkordans.NestedStatics/FOO) foo user= (str.org.tomko.konkordans.NestedStatics/LevelOne) java.lang.ClassNotFoundException: str.org.tomko.konkordans.NestedStatics (NO_SOURCE_FILE:0) user= So, it's clear that I have the NestedStatics class in my classpath, and that I can reference static members that are of a fundamental data type. But attempting to reach in one level deeper does not succeed. I also tried importing LevelOne into my namespace using a :use, but that didn't work - although I'm a bit hazy on the precise syntax for that so it might be my fault. A search in this forum didn't turn up anything quite like this, but there was some discussion about import statics that might be relevant. -- 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: Access to nested static classes
This, however, does not work: (ns org.tomko.konkordans.analysis (:import (org.tomko.konkordans NestedStatics))) (def foo NestedStatics$LevelOne$LevelTwo/NO) user= (load-file /Users/mark/IdeaProjects/Konkordans/src/org/tomko/ konkordans/analysis.clj) java.lang.Exception: No such namespace: NestedStatics$LevelOne $LevelTwo (analysis.clj:5) On Dec 28, 5:48 pm, Mark Tomko mjt0...@gmail.com wrote: This appears to work: user= (str org.tomko.konkordans.NestedStatics$LevelOne) class org.tomko.konkordans.NestedStatics$LevelOne Is this depending on a detail of implementation? It feels funny to me, but perhaps it's the best way to do it. On Dec 28, 5:42 pm, David Brown cloj...@davidb.org wrote: On Mon, Dec 28, 2009 at 02:32:48PM -0800, Mark Tomko wrote: user= (str.org.tomko.konkordans.NestedStatics/LevelOne) Does str.org.tomko.konkordans.NestedStatics$LevelOne/ONE Work? You can always look in the class output directory that the Java compiler generates, and see the resulting class name that it creates (just change the slashes in the path into dots). 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
Heap implementation in Clojure
I wrote this implementation of a heap (or priority queue) in pure Clojure: http://pastebin.com/m2ab1ad5a It's probably not of any quality sufficient to be make it to the contrib package, but it seems to work. Any thoughts on how it might be improved? Thanks, Mark -- 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: Where is the Clojure 1.0 API documentation?
I second this - since many of the IDE plugins bundle the clojure-1.0 jar, new users trying out Clojure (and IDEs) can't use all the features listed in the docs, and it's hard to tell which is which. Maybe we could at least add a 'added in version' to the new method metadata? On Dec 9, 4:48 am, Jarkko Oranen chous...@gmail.com wrote: I just noticed that the API link on the clojure web site brings up documentation for the master branch of Clojure instead of 1.0.0. I can't find the 1.0.0 docs anywhere either. This is obviously a problem for 1.0.0 users, since the docs refer to features that don't exist. I think it would be good to have the API page contain links to 1.0.0 docs as well as master and perhaps other branches as well. Also, a clear indication (preferably in a bold font or something) of which revision the doc was generated for would be useful. -- Jarkko -- 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: Where is the Clojure 1.0 API documentation?
It (or something similar) is present in some of Sun's Javadocs, if I recall correctly, and I frequently found it useful, because I kept a bookmark on the 1.6 javadocs but sometimes had to write for 1.5 JVMs. Mark On Dec 9, 10:10 am, Tom Faulhaber tomfaulha...@gmail.com wrote: Enhancing the doc tool so that we have versions for the multiple branches (1.0, 1.1, master, new) is on my agenda. Maybe there's a way that Rich could add a link to the old 1.0 doc in the meantime. I think that the added in version metadata tag is a good idea, at least for clojure itself. Python does this and I've always liked it. Tom On Dec 9, 5:43 am, Mark Tomko mjt0...@gmail.com wrote: I second this - since many of the IDE plugins bundle the clojure-1.0 jar, new users trying out Clojure (and IDEs) can't use all the features listed in the docs, and it's hard to tell which is which. Maybe we could at least add a 'added in version' to the new method metadata? On Dec 9, 4:48 am, Jarkko Oranen chous...@gmail.com wrote: I just noticed that the API link on the clojure web site brings up documentation for the master branch of Clojure instead of 1.0.0. I can't find the 1.0.0 docs anywhere either. This is obviously a problem for 1.0.0 users, since the docs refer to features that don't exist. I think it would be good to have the API page contain links to 1.0.0 docs as well as master and perhaps other branches as well. Also, a clear indication (preferably in a bold font or something) of which revision the doc was generated for would be useful. -- Jarkko -- 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: Trouble implementing Dijkstra algorithm in Clojure
A priority queue implemented over a heap would be more efficient than a sorted set, in general. With a heap, you have constant time access to the smallest (WLOG) element in the heap at all times. Removing it costs a fixed O(lg n). A sorted set (especially one that's being modified) isn't necessarily going to allow you to find the smallest in constant time, and it's still going to require you O(lg n) to do the removals. To the best of my knowledge, clojure nor clojure-contrib contain a heap implementation. I wrote one myself as part of an exercise (I implemented a simple Huffman-coder), but I'm not sure it's release quality. Otherwise, I'd be happy to donate it to contrib. Maybe I'll try to clean it up and send it off for a review. Mark On Dec 7, 11:29 pm, ataggart alex.tagg...@gmail.com wrote: On Dec 7, 4:19 pm, ajay ajgop...@gmail.com wrote: Hi all, I am new to FP in general and I am trying to pick up Clojure. I am having trouble thinking in FP terms. I am trying to implement the Dijkstra algorithm for shortest paths in Graph in Clojure. If this succeeds, I will implement all the advanced graph algos I am learning in this course in Clojure and post in online. My concerns regarding implementing Dijkstra in Clojure are following: 1. The way I've learnt Dijkstra, there is a distance array and we keep on updating it if we find a shorter path. Since, things are immutable, how do I do it? You call functions that give you a new, modified version of the input collection. (conj [1 2 3] 4) ;= [1 2 3 4] And you can use atoms to hold a reference to a collection. Just depends on how you want to use them. 2. Does Clojure have a Priority Queue data structure inbuilt. I would need that for Dijkstra algorithm. I think sorted-set or sorted-set-by should suffice. If not, you could make one or see if there's on in contrib somewhere. Thanks, Ajay G. -- 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: swap two elements in an arbitrary collection
Indeed it does. I still think the array implementation of a heap is probably worth using, in spite of its use of indexes, but rather than use a generalized swap implementation to percolate elements up and down the tree, I'll stick with a vector implementation and keep it all hidden beneath the implementation details. I notice you used the '-' macro. Perhaps I'm a little dense, but I haven't found the documentation for it to be terribly helpful. Do you have simple, succinct explanation for what it does? Thanks! Mark On Nov 13, 12:22 am, Christophe Grand christo...@cgrand.net wrote: It's a pet peeve of mine but, please, try hard not to use indices :-) (or if you need indices pick a better suited data structure) The code you try to write is hard to write because you are going against the grain. If you try to write swap for vectors (which support efficient random lookup and assoc) it's pretty simple: (defn swap [v i j] (- v (assoc i (v j)) (assoc j (v i But if you want to make it work with any kind of collection and return a seq (it's the code you have written) it's far less pleasant... and efficient. hth Christophe On Fri, Nov 13, 2009 at 7:07 AM, Mark Tomko mjt0...@gmail.com wrote: Let's try this again: (defn swap [coll i j] (if (= i j) coll (let [li (min i j) ui (max i j)] (let [[pre-li post-li] (split-at li coll)] (let [[post-li-pre-ui post-li-post-ui] (split-at (- ui 1 li) (rest post-li))] (concat pre-li (list (nth coll ui)) post-li-pre-ui (list (nth coll li)) (rest post-li-post-ui))) The code is actually even more complicated. I'm sure with a little more time I could clean it up. On Nov 12, 9:59 pm, Mark Tomko mjt0...@gmail.com wrote: Oh, I posted too soon. My implementation has a bug. On Nov 12, 9:56 pm, Mark Tomko mjt0...@gmail.com wrote: I came up with a way to do it, but I'm sure there's a simpler way. Here's what I have: (defn swap [coll i j] (let [li (min i j) ui (max i j)] (let [[pre-li post-li] (split-at li coll)] (let [[post-li-pre-ui post-li-post-ui] (split-at (- ui 1) (rest post-li))] (concat pre-li (list (nth coll j)) post-li-pre-ui (list (nth coll i)) (rest post-li-post-ui)) Basically, I find the lower index and the upper index. I then find the elements in the collection that appear before the lower index, and the elements that appear between the lower index and the upper index, and the elements that appear after the upper index. I then create a new list that is the concatenation of these sublists, in order. It's sort of the definition of swap on an immutable data structure, but it feels like an awful lot of code. I considered using subvec: http://clojure.org/api#toc548 But I didn't want to require that my input collection be a vector, or convert it to one. This the precursor to my implementing a heap data structure, as a little toy application. -- 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
swap two elements in an arbitrary collection
I came up with a way to do it, but I'm sure there's a simpler way. Here's what I have: (defn swap [coll i j] (let [li (min i j) ui (max i j)] (let [[pre-li post-li] (split-at li coll)] (let [[post-li-pre-ui post-li-post-ui] (split-at (- ui 1) (rest post-li))] (concat pre-li (list (nth coll j)) post-li-pre-ui (list (nth coll i)) (rest post-li-post-ui)) Basically, I find the lower index and the upper index. I then find the elements in the collection that appear before the lower index, and the elements that appear between the lower index and the upper index, and the elements that appear after the upper index. I then create a new list that is the concatenation of these sublists, in order. It's sort of the definition of swap on an immutable data structure, but it feels like an awful lot of code. I considered using subvec: http://clojure.org/api#toc548 But I didn't want to require that my input collection be a vector, or convert it to one. This the precursor to my implementing a heap data structure, as a little toy application. -- 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: swap two elements in an arbitrary collection
Oh, I posted too soon. My implementation has a bug. On Nov 12, 9:56 pm, Mark Tomko mjt0...@gmail.com wrote: I came up with a way to do it, but I'm sure there's a simpler way. Here's what I have: (defn swap [coll i j] (let [li (min i j) ui (max i j)] (let [[pre-li post-li] (split-at li coll)] (let [[post-li-pre-ui post-li-post-ui] (split-at (- ui 1) (rest post-li))] (concat pre-li (list (nth coll j)) post-li-pre-ui (list (nth coll i)) (rest post-li-post-ui)) Basically, I find the lower index and the upper index. I then find the elements in the collection that appear before the lower index, and the elements that appear between the lower index and the upper index, and the elements that appear after the upper index. I then create a new list that is the concatenation of these sublists, in order. It's sort of the definition of swap on an immutable data structure, but it feels like an awful lot of code. I considered using subvec: http://clojure.org/api#toc548 But I didn't want to require that my input collection be a vector, or convert it to one. This the precursor to my implementing a heap data structure, as a little toy application. -- 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: swap two elements in an arbitrary collection
Let's try this again: (defn swap [coll i j] (if (= i j) coll (let [li (min i j) ui (max i j)] (let [[pre-li post-li] (split-at li coll)] (let [[post-li-pre-ui post-li-post-ui] (split-at (- ui 1 li) (rest post-li))] (concat pre-li (list (nth coll ui)) post-li-pre-ui (list (nth coll li)) (rest post-li-post-ui))) The code is actually even more complicated. I'm sure with a little more time I could clean it up. On Nov 12, 9:59 pm, Mark Tomko mjt0...@gmail.com wrote: Oh, I posted too soon. My implementation has a bug. On Nov 12, 9:56 pm, Mark Tomko mjt0...@gmail.com wrote: I came up with a way to do it, but I'm sure there's a simpler way. Here's what I have: (defn swap [coll i j] (let [li (min i j) ui (max i j)] (let [[pre-li post-li] (split-at li coll)] (let [[post-li-pre-ui post-li-post-ui] (split-at (- ui 1) (rest post-li))] (concat pre-li (list (nth coll j)) post-li-pre-ui (list (nth coll i)) (rest post-li-post-ui)) Basically, I find the lower index and the upper index. I then find the elements in the collection that appear before the lower index, and the elements that appear between the lower index and the upper index, and the elements that appear after the upper index. I then create a new list that is the concatenation of these sublists, in order. It's sort of the definition of swap on an immutable data structure, but it feels like an awful lot of code. I considered using subvec: http://clojure.org/api#toc548 But I didn't want to require that my input collection be a vector, or convert it to one. This the precursor to my implementing a heap data structure, as a little toy application. -- 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
Finding elements in 2 sequences that match (indexwise)
This is basically a problem of parallel iteration. I've devised 2 solutions, one is recursive (alas, not tail-recursive) and the other appears to be a more idiomatic Clojure solution. Can someone suggest a more efficient or cleaner solution? Here's the literal solution: (defn matching-elements [coll1 coll2] (if (or (empty? coll1) (empty? coll2)) () (let [e1 (first coll1) e2 (first coll2)] (if (= e1 e2) (cons e1 (matching-elements (rest coll1) (rest coll2))) (matching-elements (rest coll1) (rest coll2)) In this implementation, we first check the base case, where one of the sequences is empty. If one of the sequences is empty, we return an empty list. Otherwise, we check to see if the first elements in each list are equal. If so, we return the list resulting from the addition of the matching element to the result of the recursive call to the method on the remaining elements in each list. Otherwise, we simply return the result of the recursive call to the method on the remaining elements in each list. I believe that the cons prevents the use of recur to make this tail recursive. After a little digging and reading through a thread on this group about parallel iteration, I devised the following alternative solution, which makes use of lazy sequences: (defn matching-elements2 [coll1 coll2] (map first (filter #(let [[e1 e2] %] (= e1 e2)) (partition 2 (interleave coll1 coll2) Can anyone suggest an improved implementation of either implementation? Thanks! --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Finding elements in 2 sequences that match (indexwise)
Thanks, this was very helpful. I am pretty new at Clojure (and functional programming) - I'm just tinkering with it a bit in my spare time these days, with an eye towards integrating it into a larger project once I'm a little more comfortable with it. Just to follow up on a few things - by SICP, do you mean the book Structure and Interpretation of Computer Programs? That's the most likely match I could find. I'm not familiar with the book, though, so I might have another reading project. So, map et. al let me tandem-iterate multiple sequences? I had an early implementation that did basically that using the 'for' list comprehension, but I couldn't figure out how to add an element to my result for some steps in the iteration and not others. The early implementation got around this because I was actually writing a method that would count matching elements, but couldn't return them. It looked something like this: (defn count-matching-elements [coll1 coll2] (reduce + (for [e1 coll1 e2 coll2] (if (= e1 e2) 1 0 I wanted instead to re-implement this solution as: (defn count-matching-elements [coll1 coll2] (count (matching-elements coll1 coll2))) This was partially for my own debugging purposes, so I could see what things were being counted. On Oct 14, 12:23 am, John Harrop jharrop...@gmail.com wrote: On Wed, Oct 14, 2009 at 2:06 AM, Mark Tomko mjt0...@gmail.com wrote: This is basically a problem of parallel iteration. I've devised 2 solutions, one is recursive (alas, not tail-recursive) and the other appears to be a more idiomatic Clojure solution. Can someone suggest a more efficient or cleaner solution? Meikel provided a quickie high-level-function solution, but I thought I might take a look at this anyway: Here's the literal solution: (defn matching-elements [coll1 coll2] (if (or (empty? coll1) (empty? coll2)) () (let [e1 (first coll1) e2 (first coll2)] (if (= e1 e2) (cons e1 (matching-elements (rest coll1) (rest coll2))) (matching-elements (rest coll1) (rest coll2)) First of all, the second matching-elements call is in tail position, so you can improve this to: (defn matching-elements [coll1 coll2] (if (or (empty? coll1) (empty? coll2)) () (let [e1 (first coll1) e2 (first coll2)] (if (= e1 e2) (cons e1 (matching-elements (rest coll1) (rest coll2))) (recur (rest coll1) (rest coll2)) But it can be made fully tail-recursive: (defn- matching-elements* [coll1 coll2 res] (if (or (empty? coll1) (empty? coll2)) res (let [e1 (first coll1) e2 (first coll2)] (if (= e1 e2) (recur (rest coll1) (rest coll2) (cons e1 res)) (recur (rest coll1) (rest coll2) res) (defn matching-elements [coll1 coll2] (matching-elements* coll1 coll2 nil)) This handy trick is described fairly early in SICP and can generally be applied almost anywhere where you're almost tail recursive, because you do something to massage the return value of the recursive call on the way out but don't make multiple recursive calls on a single path through the function. I believe that the cons prevents the use of recur to make this tail recursive. Only on the first recursive call, and only if the above trick isn't employed. After a little digging and reading through a thread on this group about parallel iteration, I devised the following alternative solution, which makes use of lazy sequences: (defn matching-elements2 [coll1 coll2] (map first (filter #(let [[e1 e2] %] (= e1 e2)) (partition 2 (interleave coll1 coll2) That's clever, though it's eclipsed by Meikel's. Apparently you didn't realize that map and friends can tandem-iterate more than one sequence at a time. Understandable enough if you're fairly new to Clojure. Can anyone suggest an improved implementation of either implementation? Meikel improved the second; I improved the first, above, not because it's better than Meikel's but because I think it might be enlightening to many readers here interested in tail recursion and, more generally, in design and optimization of recursive functions. HTH, HAND, and all that. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---
Help with closures
Okay, I'm flummoxed. Given the following definition: (defn make-n-gram-fn [n] (fn [coll] (map vec (partition n 1 coll I can do this: (def bi-gram (make-n-gram-fn 2)) (bi-gram abc) ([\a \b] [\b \c]) But, if I add the following: ; counts the number of indexes in a pair of collections where the elements at the ; indexes match one another (defn count-matching-elements [coll1 coll2] (reduce + (for [e1 coll1 e2 coll2] (if (= e1 e2) 1 0 ; uses the matching element count to compute a simple similarity between ; the two collections (defn raw-coll-similarity [coll1 coll2] (let [maxlen (max (count coll1) (count coll2))] (/ (double (count-matching-elements coll1 coll2)) maxlen))) ; a more general collection similarity that applies the same transformation to both ; collections, then applies the simpler coll similarity function (defn coll-similarity [coll1 coll2 transform] (let [ncoll1 (transform coll1) ncoll2 (transform coll2)] (raw-coll-similarity ncoll1 ncoll2))) ; a returns a new similarity function that applies the provided transform function ; before comparing a pair of collections (defn make-coll-similarity-fn [coll-transform] (fn [coll1 coll2] coll-similarity [coll1 coll2 coll-transform])) ; makes an n-gram similarity function using the provided value for 'n' (defn make-n-gram-similarity [n] (make-coll-similarity-fn (make-n-gram- fn n))) Then use my new similarity function generator: (def bigram-similarity (make-coll-similarity-fn (make-n-gram-fn 2))) (bigram-similarity abcde abc) I get the following: [abcde abc #similarity$make_n_gram_fn__114$fn__116 org.ricercata.similarity$make_n_gram_fn__114$fn__...@219ba640] I must be missing something obvious, but I can't see it. --~--~-~--~~~---~--~~ 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: Help with closures
Of course. I'm not sure what I was thinking. Thank you. On Oct 9, 7:47 pm, Shawn Hoover shawn.hoo...@gmail.com wrote: On Fri, Oct 9, 2009 at 10:37 PM, Mark Tomko mjt0...@gmail.com wrote: ; a returns a new similarity function that applies the provided transform function ; before comparing a pair of collections (defn make-coll-similarity-fn [coll-transform] (fn [coll1 coll2] coll-similarity [coll1 coll2 coll-transform])) ; makes an n-gram similarity function using the provided value for 'n' (defn make-n-gram-similarity [n] (make-coll-similarity-fn (make-n-gram- fn n))) Then use my new similarity function generator: (def bigram-similarity (make-coll-similarity-fn (make-n-gram-fn 2))) (bigram-similarity abcde abc) I get the following: [abcde abc #similarity$make_n_gram_fn__114$fn__116 org.ricercata.similarity$make_n_gram_fn__114$fn__...@219ba640] I must be missing something obvious, but I can't see it. It looks like you're missing parens in make-coll-similarity-fn. It does nothing with coll-similarity and then returns a vector. Should it be more like this? (defn make-coll-similarity-fn [coll-transform] (fn [coll1 coll2] (coll-similarity coll1 coll2 coll-transform))) --~--~-~--~~~---~--~~ 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: What does this error mean?
Can you give some more context? On Oct 8, 6:38 am, kunjaan kunj...@gmail.com wrote: java.lang.ClassFormatError: Unknown constant tag 52 in class file queries__init (Trial.clj: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: immutable defs?
This is pretty much what I'd had in mind. I don't see how the text of the Exception is set by the macro, but it'd be really spectacular if the message were more clear. Is that message coming from the defvar form? On Oct 6, 6:14 pm, Stephen C. Gilardi squee...@mac.com wrote: On Oct 2, 2009, at 10:29 AM, Mark wrote: Is there a way to make a declaration in Clojure that cannot be rebound later? Ideally, I'd like something that fails if I try to do this: (def myname mark) ; ...more code, elided... (def myname Mark) Along these lines, I was thinking of adding defconst to clojure.contrib.def. It's like Common Lisp's defconst, but the fact that its value isn't allowed to change is enforced: (defmacro defconst Defines a var with a constant value and optional doc string. Any attempt to redefine, bind, or set! the const to a different value will throw an exception. ([name init] `(do (set-validator! (defvar ~name ~init) #{~init}) (var ~name))) ([name init doc] `(defconst ~(with-meta name (assoc (meta name) :doc doc)) ~init))) It does allow a redefine, binding, or set! to an equal value mainly as an artifact of its implementation, but also because such a change would be harmless to the semantics of it being constant. user= (defconst pi (* 4 (Math/atan 1))) #'user/pi user= pi 3.141592653589793 user= (binding [pi 3] (prn pi)) java.lang.IllegalStateException: Invalid reference state (NO_SOURCE_FILE:0) user= (binding [pi pi] (prn pi)) 3.141592653589793 nil user= (binding [pi pi] (set! pi 3)) java.lang.IllegalStateException: Invalid reference state (NO_SOURCE_FILE:0) user= (defconst pi 3) java.lang.IllegalStateException: Invalid reference state (NO_SOURCE_FILE:7) user= (def pi 3) java.lang.IllegalStateException: Invalid reference state (NO_SOURCE_FILE:10) user= (defconst pi (* 4 (Math/atan 1))) #'user/pi I'd appreciate hearing any suggestions for improvement or other feedback. --Steve smime.p7s 3KViewDownload --~--~-~--~~~---~--~~ 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: Memory Characteristics of Persistent Datastructures
To be explicit, the doall needs to be before the call to recur (that is, it affects the map). Is that right? On Oct 5, 1:31 am, Meikel Brandmeyer m...@kotka.de wrote: Hi, On Oct 5, 9:50 am, Volkan YAZICI volkan.yaz...@gmail.com wrote: (defn leak [] (loop [v [0 0]] (recur (map + v [1 1] Adding a doall call fixed the leak. Could you please provide a more concrete (if possible working) example? I'm trying to figure out the actual reason of the problem, and there are still some missing parts in the maze. map is lazy and hence has to store a reference to the original sequence, which is released when realising the map sequence. The loop builds up a stack of maps which each keeps references in their guts. So the memory builds up and up and up and *BOOM*. The doall realises the sequence and hence the reference to the input sequence can be dropped. It gets GC'd and everything is fine. 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: immutable defs?
When I write code in Java, I declare everything final that's possible to be declared final, and I deliberately look for solutions that avoid reassignment to variables, so all my variables are final). I'm new to Clojure, so I might be wrong, but it seems that within a function, mutable bindings must be explicitly created, either through refs, atoms, or using the 'binding' form (or is it macro?). That's great, because within any lexical scope inside a function, I can pretty much count on my bindings to never change. However, outside the scope of a function, it seems that it's possible for bindings to be redefined later in a file without causing an immediate error. This could easily lead to mistakes that would manifest as silent and potentially inexplicable behavior later. Mark On Oct 2, 8:10 am, Meikel Brandmeyer m...@kotka.de wrote: Hi, On Oct 2, 4:29 pm, Mark mjt0...@gmail.com wrote: Is there a way to make a declaration in Clojure that cannot be rebound later? Ideally, I'd like something that fails if I try to do this: (def myname mark) ; ...more code, elided... (def myname Mark) Perhaps this is obvious, but I see a lot of discussion of immutable data structures, but I can't find a way to prevent my bindings from changing. I'm not aware of such a feature. Putting {:macro true} in the metadata of the Var has this effect, but this is almost surely not what you want. Why do you need this functionality? 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: immutable defs?
That's what I meant when I mentioned the 'binding' form above. The reason that's okay (to me) is that it explicitly calls out that bindings may be about to change. On Oct 2, 11:47 am, John Newman john...@gmail.com wrote: Also, I'm not sure if your understanding of binding is correct. because within any lexical scope inside a function, I can pretty much count on my bindings to never change. binding is actually like a lexical re-def: user= (def x 1) #'user/x user= (binding [x 2] (pr x) (binding [x 3] (pr x)) x) 232 user= x 1 This allows us to confine var re-def to specific scope, safely -- which is the convention over redefing a var globally. That's my understanding of it at least. Anyone can feel free to correct me if I'm wrong. --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---