Re: special handling of :type in meta data
On 27.04.2009, at 00:33, David Chamberlin wrote: > I can get round this by not using a structure map for the metadata, > but since I'm going to be creating container loads of these structures > I understand that I need to be using struct-maps for efficiency. > > Is there a reason why this should not work? Here is why it does not work. Any attempt to print a value causes a call to clojure.core/print-method. This is a multimethod that dispatches on clojure.core/type, i.e. by the :type on the metadata or, if there is no metadata or no :type tag, on class. If there is a :type tag but it has no implementation of print-method, a :default implementation removes the :type tag and tries again. It's removing the type tag that fails in your case. On March 27 I sent a message to this group that contains a patch for clojure.core that fixes this problem, and other of a similar kind. The subject is "PATCH: printing a ref with type metadata". I can't find the message in Google's archive, so I wonder if it got lost. The patch is attached again to this message. As for efficiency, I doubt that struct maps make that much of a difference, but I didn't do any timings. Note that in your example, you create the metadata map once and assign it to m. The map is thus created only once, no matter to how many values you attach it later. That's how I handle metadata maps as well. The only potential difference in execution time thus comes from looking up :type. Compared to the rest of the work done in multimethod dispatching, I can't imagine that key lookup is that much more efficient for struct maps that it makes a difference overall. 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 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 -~--~~~~--~~--~--~--- print-method.patch Description: Binary data
Unloading a namespace?
Is it possible to unload/remove a namespace at runtime at all? Mark ...and then Buffy staked Edward. The End. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Getting slime-edit-definition to work with Clojure
On Sun, Apr 26, 2009 at 7:25 AM, Baishampayan Ghose wrote: > I am a Clojure newbie and I have been trying to get M-. > (slime-edit-definition) and the corresponding > M-,(slime-pop-find-definiton-stack) to work with Clojure. > > Right now, if I press M-. I get "Search failed" in he minibuffer. > > Is there any way to get it to work, or am I doing something completely > wrong? It works for me. Are you trying to look up a built-in clojure function or one from your own application? How did you install SLIME and swank-clojure etc? If you installed by hand, you could try using M-x clojure-install from a recent copy of clojure-mode.el. This should download and configure all the necessary things to hook up Emacs and Clojure via SLIME. If it's still not working, try pasting the contents of your *Messages* buffer to the list. -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 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: Abstract data types in functional languages
GENIOUS idea Laurent ;) Extremely terse and uniform. Also because I switched the implementation to use multimethods, performance has jumped quite a bit. In fact if you memoize find-accessors, the code is only a little bit slower than update-in/assoc-in/get-in! The defset and defget macros now check to make sure their definition only defines 2 or 1 arguments respectively. find-accessor throws an error if you attempt to use an accessor in acc-in that hasn't been previously defined . The code is for now hosted here http://github.com/swannodette/accessors/tree/master. Does anybody care to see this in contrib? If so I'll send in my CLA :) (comment (accessors x y z) ; {:x 4} (acc-x {} 4) ; 4 (acc-x {:x 4}) (defset x [m v] (assoc (assoc m :new "new") :x v)) ;; {:new "new", :x {:y {:z 1}}} (acc-in {:x {:y {:z 0}}} '(x y z) 1) ;; 0 (acc-in {:x {:y {:z 0}}} '(x y z)) ; {:x 4, :new "new", :foo 9} (let [z {:foo 9}] (acc-x z 4)) ; 10 (let [y {:z 10}] (acc-z y)) ; [0 1 2] (map acc-x [{:x 0}, {:x 1}, {:x 2}]) ; performance -- ; ~180ms 2.53ghz MBP Core2Duo (time (dotimes [x 10] (assoc-in {:x {:y {:z 0}}} [:x :y :z] 1))) ; ~700ms 2.53ghz MBP Core2Duo (time (dotimes [x 10] (acc-in {:x {:y {:z 0}}} '(x y z) 1))) ; ~300ms 2.53ghz MBP Core2Duo (def find-accessor (memoize find-accessor)) (time (dotimes [x 10] (acc-in {:x {:y {:z 0}}} '(x y z) 1))) ) On Sun, Apr 26, 2009 at 6:27 PM, Laurent PETIT wrote: > > Hello, > > Maybe you should consider creating a single function with 2 arities: > with one argument, it's the getter, with two arguments, it's the > setter (that returns the new type) ! > > > (prop-foo obj) ; --> returns the property prop-foo > (prop-foo obj newval) ; --> returns a new version of obj with prop-foo > property set to newval > > Terse and uniform :-) > > ? > > > > 2009/4/26 David Nolen : > > You're right. The following includes code for handling this case via > setin > > and getin. I've also ditched macros, because that code couldn't support > new > > lexical scopes in the setter/getter definition. setin getin support works > by > > dynamically resolving getters and setters, thus this is slower than > direct > > access via assoc-in and get-in. > > Personally I have to say now that this is written, I prefer the terseness > > of: > > (set-x some-map v) > > over > > (assoc some-map :x v) > > This > > (get-x some-map) > > isn't as nice as > > (:x map) > > But it's also more explicit about how the map is being used- that a level > > indirection is required because the implementation might change. > > ;; == > > (comment > > (accessors x y z) > > ; {:x 4} > > (set-x {} 4) > > (defset x [m v] > > (assoc (assoc m :new "new") :x v)) > > ;; {:new "new", :x {:y {:z 1}}} > > (setin {:x {:y {:z 0}}} '(x y z) 1) > > ;; 0 > > (getin {:x {:y {:z 0}}} '(x y z)) > > ; {:x 4, :new "new", :foo 9} > > (let [z {:foo 9}] > > (set-x z 4)) > > ; 10 > > (let [y {:z 10}] > > (get-z y)) > > ; [0 1 2] > > (map get-x [{:x 0}, {:x 1}, {:x 2}])) > > (defn setter* [sym] > > `(defn ~(symbol (str "set-" sym)) [~'m ~'v] > > (assoc ~'m ~(keyword (str sym)) ~'v))) > > (defn getter* [sym] > > `(defn ~(symbol (str "get-" sym)) [~'m] > > (~(keyword (str sym)) ~'m))) > > (defmacro defset [sym args & forms] > > (let [set-sym (symbol (str "set-" sym))] > > `(defn ~set-sym [...@args] > >~...@forms))) > > (defmacro defget [sym args & forms] > > (let [get-sym (symbol (str "get-" sym))] > > `(defn ~get-sym [...@args] > >~...@forms))) > > (defn find-accessor [sym acc-type] > > (let [ns (or (namespace sym) > > (str *ns*)) > > sym-name (name sym)] > > (find-var (symbol ns (str (name acc-type) "-" sym-name) > > (defn setin [m [sym & syms] v] > > (let [setter (find-accessor sym :set) > > getter (find-accessor sym :get)] > > (if syms > > (setter m (set-in (getter m) syms v)) > > (setter m v > > (defn getin [m [sym & syms]] > > (let [getter (find-accessor sym :get)] > > (if syms > > (getin (getter m) syms) > > (getter m > > (defmacro accessors [& syms] > > `(do > > ~@(map setter* syms) > > ~@(map getter* syms))) > > > > On Sat, Apr 25, 2009 at 4:42 AM, MattH wrote: > >> > >> It's worth considering how *nested* accessors would work in the > >> context of immutability. > >> > >> The nested maps approach works really nicely, due in part to functions > >> like assoc-in: > >> > >> ; From Mark Volkmann's tutorial > >> (assoc-in person [:employer :address :city] "Clayton") > >> > >> What would the above update look like if 'address' was accessed using > >> functions like get-address and set-address? > >> > >> Functions like assoc-in clearly rely on a uniform way of getting/ > >> setting fields (i.e. maps). > >> > >> My *hunch* is that the right avenue is to extend/implement clojure's
Re: 32-bit Unicode character literals
On Apr 26, 2009, at 7:47 PM, samppi wrote: user=> \u1 java.lang.IllegalArgumentException: Invalid unicode character: \u1 How would I embed the character as a literal in my Clojure code? Java characters are (still) 16 bits wide. A single Java character cannot represent the Unicode character you're looking to represent. Since Clojure characters are Java characters, you'll need to do this the way the Java folks do. I found a blog post about it here: http://weblogs.java.net/blog/joconner/archive/2004/04/unicode_40_supp.html This is also a good reference: http://www.fileformat.info/info/unicode/char/1/index.htm This representation as a string from that page does seem to work in Clojure: "\ud800\udc00" --Steve smime.p7s Description: S/MIME cryptographic signature
32-bit Unicode character literals
In the REPL: Clojure user=> \u0032 \2 user=> \u1 java.lang.IllegalArgumentException: Invalid unicode character: \u1 How would I embed the character as a literal in my Clojure code? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
yet another clojure clr thread
Given the recent dust-up on c.l.l about the platform independence of clojure, I was wondering anyone was still hacking on the CLR code base. The stuff in contrib doesn't seem to have changed since it was checked in February. Matt --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: The Path to 1.0
I've created issue 110 with the patch attached in clojure's google code project. Hi Rich, Howard, I'll answer to both at the same time, trying to reconcile things a bit. Howard, my first patch was already along the lines of what you described below, I think (concerning the fact to use ant to generate with filters from templates). Then Rich asked if it was possible to not have to generate files. I understand this question a little less broadly than "not generate files at all cost", but "not generate files in the source code". So that if the generation step is not followed by some tool for some reason, things don't break - at compile time or run time -. That's why I came up with this new version: * a src/clj/clojure/version.properties file * this version.properties file is the reference for version numbers. It is on the classpath so it can be seen by clojure at runtime. It is in a subdirectory of clojure-the-project so any tool can refer to it relatively to the installation of clojure. * I've added the needed code to clojure to load clojure version number at startup time I've also added function (clojure.core/clojure-version) that will return a string representing the version from the structured *clojure-version* map. The algorithm here is simple: .[.][-][-SNAPSHOT] * I've changed the ant build.xml so that it creates fully qualified names with version attributes for the generated jars. * Note on the :interim attribute: to protect the person who makes releases from itself, instead of considering :interim to be true if there is the "true" string in the properties file, I've made the opposite choice: interim is true for any value other than "false". So if there is a typo in version.properties (e.g. tru instead of true), then the release will be marked as interim, and that will not be a big deal. In the other case, it would be a big deal if an official release was made accidentally instead of an interim. * finally, pom.xml file is now generated from ant as part of the classic init step. Note: I strongly suggest that the clojure.version.interim property remains true in svn, so that it's not possible to inadvertently release a version "too early". HTH, Feel free to use or not, -- Laurent 2009/4/24 Howard Lewis Ship : > > Another option is for the version number to be in build.xml, and for > it to generate a runtime file (so that Clojure can know its own > version number) and set the version number inside a generated pom.xml. > You can use Ant resource copying with filters to accomplish both > these goals. > > On Thu, Apr 23, 2009 at 8:24 AM, Laurent PETIT > wrote: >> >> 2009/4/23 Rich Hickey : >>> >>> >>> >>> On Apr 22, 12:41 pm, Laurent PETIT wrote: 2009/4/22 Rich Hickey : > [...] > {:major 1, :minor 0, :incremental 0, :qualifier :rc1 :interim true} > for interim versions and > {:major 1, :minor 0, :incremental 0} > for releases. :interim tracks the SNAPSHOT segment of the version > string. > [...] > I don't mind the build producing clojure-1.0.0.jar etc, but it doesn't > now. The master build is Ant. Where is the best place to put the > version info so it can be leveraged by Ant, Maven and the clojure core > runtime in order to produce *clojure-version* ? Here a patch that allows to initialize from ant and from a file version.properties the values in *clojure-version*. The patch only addresses the problematic of having a single place for version attributes. Having the ant build also use these properties for creating correctly numbered jars is not part of the patch. Note that I had to create a new file, src/clj/clojure/core_version.clj , which is created by ant as a combination of template file core_version-template.clj and the properties from version.properties. You'll see that if you don't like the names of the keys in version.properties, build.xml is the single place where to change them (apart from version.properties, of course). Also, if you don't like the name version.properties (e.g. if it should be named project.properties or whatever for easing maven users), then you just have to change its occurence in build.xml too. If you like it, it can file an issue to google code and attach the patch, >>> >>> Thanks! >>> >>> I can't say I love the idea of generating a file during build. >> Me too, that's why I have made the file as short and independent as possible. >> >> Well, I tried to keep close to the idea of having the version numbers >> "built-in", similarly to what was commited where it was also not read >> from a "simpler file" at load time. >> >>> What about clojure.jar containing a properties file it reads at load time? >> >> Why not, indeed ? The file would have to placed in the classpath, e.g. >> in directory src/jvm/clojure/lang or src/clj/clojure. >> >>> Could the same file be read by
special handling of :type in meta data
I think I'm seeing some strange effects of some special handling of :type in meta-data. I'm trying to create a structure map with meta data that is also a structure map. The meta-data includes the :type key, but I see an error when I try to do this: ( def sm ( create-struct :type ) ) ( def so ( create-struct :x ) ) ( def m ( struct sm :test ) ) ( def o ( struct so 1 ) ) ( def om ( with-meta o m ) ) any attempt to view the content of om results in java.lang.Exception: Can't remove struct key I can get round this by not using a structure map for the metadata, but since I'm going to be creating container loads of these structures I understand that I need to be using struct-maps for efficiency. Is there a reason why this should not work? --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: Abstract data types in functional languages
Hello, Maybe you should consider creating a single function with 2 arities: with one argument, it's the getter, with two arguments, it's the setter (that returns the new type) ! (prop-foo obj) ; --> returns the property prop-foo (prop-foo obj newval) ; --> returns a new version of obj with prop-foo property set to newval Terse and uniform :-) ? 2009/4/26 David Nolen : > You're right. The following includes code for handling this case via setin > and getin. I've also ditched macros, because that code couldn't support new > lexical scopes in the setter/getter definition. setin getin support works by > dynamically resolving getters and setters, thus this is slower than direct > access via assoc-in and get-in. > Personally I have to say now that this is written, I prefer the terseness > of: > (set-x some-map v) > over > (assoc some-map :x v) > This > (get-x some-map) > isn't as nice as > (:x map) > But it's also more explicit about how the map is being used- that a level > indirection is required because the implementation might change. > ;; == > (comment > (accessors x y z) > ; {:x 4} > (set-x {} 4) > (defset x [m v] > (assoc (assoc m :new "new") :x v)) > ;; {:new "new", :x {:y {:z 1}}} > (setin {:x {:y {:z 0}}} '(x y z) 1) > ;; 0 > (getin {:x {:y {:z 0}}} '(x y z)) > ; {:x 4, :new "new", :foo 9} > (let [z {:foo 9}] > (set-x z 4)) > ; 10 > (let [y {:z 10}] > (get-z y)) > ; [0 1 2] > (map get-x [{:x 0}, {:x 1}, {:x 2}])) > (defn setter* [sym] > `(defn ~(symbol (str "set-" sym)) [~'m ~'v] > (assoc ~'m ~(keyword (str sym)) ~'v))) > (defn getter* [sym] > `(defn ~(symbol (str "get-" sym)) [~'m] > (~(keyword (str sym)) ~'m))) > (defmacro defset [sym args & forms] > (let [set-sym (symbol (str "set-" sym))] > `(defn ~set-sym [...@args] > ~...@forms))) > (defmacro defget [sym args & forms] > (let [get-sym (symbol (str "get-" sym))] > `(defn ~get-sym [...@args] > ~...@forms))) > (defn find-accessor [sym acc-type] > (let [ns (or (namespace sym) > (str *ns*)) > sym-name (name sym)] > (find-var (symbol ns (str (name acc-type) "-" sym-name) > (defn setin [m [sym & syms] v] > (let [setter (find-accessor sym :set) > getter (find-accessor sym :get)] > (if syms > (setter m (set-in (getter m) syms v)) > (setter m v > (defn getin [m [sym & syms]] > (let [getter (find-accessor sym :get)] > (if syms > (getin (getter m) syms) > (getter m > (defmacro accessors [& syms] > `(do > ~@(map setter* syms) > ~@(map getter* syms))) > > On Sat, Apr 25, 2009 at 4:42 AM, MattH wrote: >> >> It's worth considering how *nested* accessors would work in the >> context of immutability. >> >> The nested maps approach works really nicely, due in part to functions >> like assoc-in: >> >> ; From Mark Volkmann's tutorial >> (assoc-in person [:employer :address :city] "Clayton") >> >> What would the above update look like if 'address' was accessed using >> functions like get-address and set-address? >> >> Functions like assoc-in clearly rely on a uniform way of getting/ >> setting fields (i.e. maps). >> >> My *hunch* is that the right avenue is to extend/implement clojure's >> map classes if injecting behaviour is ever necessary. (A standard/ >> supported way to do this would be nice.) >> >> I'd be happy using constructor functions like (make-complex-number) >> and (make-person) which can hide detail of their implementations, but >> I'd also like to benefit from all that goes with the idiomatic use of >> maps. >> >> (My 2c) >> > > > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Search Heap? (was: priority queue: some results)
my understanding of a suggestion in the chat room was to add a separate slot for an object associated with a priority rather than having comparable objects inserted. That is, the priority of something is not the something. It's just its priority. I need to play around a lot more with this to make these recent operations make sense. It could even make sense to use clojure's hashmap to hook objects to their places in the heap. If the Hashmap insert speeds are minuscule in comparison to the Heap insert speeds, then we could even end up with something I've now learned is called a Priority Search Queue. It's like a sorted map but explicitly lists heap operations and search/assoc like things . If internally using a Clojure Hashmap + the new Heap is faster than the SortedMap, and does all the stuff, and more, I'll let yuz know. On Sat, Apr 25, 2009 at 5:46 PM, e wrote: > new operations available for heap: > http://code.google.com/p/jc-pheap/source/list > > changeVal < any value inside the heap, not just the min. honor > system. if you didn't put a value in, don't lie and changes its value. > runtime varies from O(1) to O(logn). code has explanation. was ambitious > and went for 'changeVal()' so values can go *up*, *in addition* to > decreasing. > > lazyDelete < tries to put off work by usually being O(1). also relies > on honor system. notes available on when amortization breaks down in > functional setting > > eagerDelete < tries to do as much garbage collection as possible, so is > always at least O(logn). More if lazy stuff has bubbled to top of heap. > > > > On Thu, Apr 23, 2009 at 8:19 PM, e wrote: > >> "meld" results look good (unless I made a mistake somewhere). >> >> I merged two collections, each with 2 million unique elements. did union >> of sorted sets, then did meld with my heap implementation: >> >> >> performing union of two sorted sets >> "Elapsed time: 18881.81 msecs" >> - >> making another heap >> performing meld of two heaps >> "Elapsed time: 0.146 msecs" >> >> >> checking in latest version of test. >> >> >> On Tue, Apr 21, 2009 at 2:10 AM, e wrote: >> >>> I've done a little comparing to sorted-set as recommended. The following >>> test (in case there is anything bogus about it) is checked in with the java >>> project: >>> http://code.google.com/p/jc-pheap/source/browse/trunk/jc-pheap/src/persistent_heap/testing/test.clj?spec=svn8&r=8 >>> >>> deduping 2,000,000 nums >>> shuffling 1999019 nums >>> = >>> inserting into sorted set >>> "Elapsed time: 39375.887 msecs" >>> >>> popping from front of sorted set >>> "Elapsed time: 15189.0 msecs" >>> = >>> heap insert >>> "Elapsed time: 15101.546 msecs" >>> -- >>> heap pop >>> "Elapsed time: 59715.796 msecs" >>> = >>> >>> What I am finding consistently (again, unless the test is bogus) is >>> pretty much expected. *Overall* the excellently implemented sorted-set >>> outperforms the heap I'm working on if you add the all the "insert" times to >>> all the the "pop-front" times. >>> >>> That said, if you want fast inserts, and you're not even sure yet if >>> people want all the elements in sorted order, the heap has advantages ... >>> especially if you're not even planning on referencing elements in the middle >>> of the list (something I do hope to support in some fashion eventually, >>> note). It may also be the case that some smart java/algorithm people could >>> find opportunities to speed up my deleteMin().* >>> >>> a note on deduping:* >>> >>> One difference that doesn't seem to matter performance-wise much is that >>> sorted-set elements are unique. I'm not sure if clojure currently has a >>> data structure (other than considering the heap) that works like a sorted >>> multimap or sorted multiset. Would it be the same to sort a vector in >>> between inserts? That doesn't sound fast, but maybe I should have done that >>> test, too. >>> >>> So, anyway, for this test, I inserted unique elements into both >>> structures so one wouldn't have way more than the other when comparing >>> things like popping. I also sampled from a wide range of numbers, so I >>> probably didn't have to go to such lengths, as it turns 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 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: Abstract data types in functional languages
You're right. The following includes code for handling this case via setin and getin. I've also ditched macros, because that code couldn't support new lexical scopes in the setter/getter definition. setin getin support works by dynamically resolving getters and setters, thus this is slower than direct access via assoc-in and get-in. Personally I have to say now that this is written, I prefer the terseness of: (set-x some-map v) over (assoc some-map :x v) This (get-x some-map) isn't as nice as (:x map) But it's also more explicit about how the map is being used- that a level indirection is required because the implementation might change. ;; == (comment (accessors x y z) ; {:x 4} (set-x {} 4) (defset x [m v] (assoc (assoc m :new "new") :x v)) ;; {:new "new", :x {:y {:z 1}}} (setin {:x {:y {:z 0}}} '(x y z) 1) ;; 0 (getin {:x {:y {:z 0}}} '(x y z)) ; {:x 4, :new "new", :foo 9} (let [z {:foo 9}] (set-x z 4)) ; 10 (let [y {:z 10}] (get-z y)) ; [0 1 2] (map get-x [{:x 0}, {:x 1}, {:x 2}])) (defn setter* [sym] `(defn ~(symbol (str "set-" sym)) [~'m ~'v] (assoc ~'m ~(keyword (str sym)) ~'v))) (defn getter* [sym] `(defn ~(symbol (str "get-" sym)) [~'m] (~(keyword (str sym)) ~'m))) (defmacro defset [sym args & forms] (let [set-sym (symbol (str "set-" sym))] `(defn ~set-sym [...@args] ~...@forms))) (defmacro defget [sym args & forms] (let [get-sym (symbol (str "get-" sym))] `(defn ~get-sym [...@args] ~...@forms))) (defn find-accessor [sym acc-type] (let [ns (or (namespace sym) (str *ns*)) sym-name (name sym)] (find-var (symbol ns (str (name acc-type) "-" sym-name) (defn setin [m [sym & syms] v] (let [setter (find-accessor sym :set) getter (find-accessor sym :get)] (if syms (setter m (set-in (getter m) syms v)) (setter m v (defn getin [m [sym & syms]] (let [getter (find-accessor sym :get)] (if syms (getin (getter m) syms) (getter m (defmacro accessors [& syms] `(do ~@(map setter* syms) ~@(map getter* syms))) On Sat, Apr 25, 2009 at 4:42 AM, MattH wrote: > > It's worth considering how *nested* accessors would work in the > context of immutability. > > The nested maps approach works really nicely, due in part to functions > like assoc-in: > > ; From Mark Volkmann's tutorial > (assoc-in person [:employer :address :city] "Clayton") > > What would the above update look like if 'address' was accessed using > functions like get-address and set-address? > > Functions like assoc-in clearly rely on a uniform way of getting/ > setting fields (i.e. maps). > > My *hunch* is that the right avenue is to extend/implement clojure's > map classes if injecting behaviour is ever necessary. (A standard/ > supported way to do this would be nice.) > > I'd be happy using constructor functions like (make-complex-number) > and (make-person) which can hide detail of their implementations, but > I'd also like to benefit from all that goes with the idiomatic use of > maps. > > (My 2c) > > > --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to call function (or Java method) using string name?
Yes. The following should also work, without calling into Clojure implementation methods: (defn eval-string [s] (eval (read-string s))) -Stuart Sierra On Apr 26, 1:50 pm, timc wrote: > Thanks Stuart. > > I have figured out another way, which is much more general (and uses > the lowest level of how Clojure works). > > (defn evalStr [s] (clojure.lang.Compiler/eval (clojure.lang.RT/ > readString s))) > > will (attempt to) execute any valid form (i.e. the string that is the > source of the form). > > Thus: (evalStr "(+ 1 2)") --> 3 > > On Apr 26, 5:21 pm, Stuart Sierra wrote: > > > This will work: > > ((resolve (symbol "+")) 1 2 3) > > > To answer your question, a symbol is just a symbol, it doesn't have a > > value. (In Common Lisp, symbols have values, but in Clojure they do > > not.) In Clojure, values belong to Vars. "resolve" will find the Var > > that is named by the symbol. When you write (+ 1 2 3), the compiler > > automatically resolves the "+" to get the Var #'clojure.core/+ > > > To invoke Java methods by name, use the Java Reflection > > API:http://java.sun.com/docs/books/tutorial/reflect/index.html > > > -Stuart Sierra > > > On Apr 26, 10:46 am, timc wrote: > > > > Is there a way of invoking functions, or java methods "by name" in > > > Clojure? > > > Or, put another way, why does this work: > > > > (+ 1 2) > > > > but this does not: > > > > ((symbol "+") 1 2) > > > > Similarly, this works > > > > (. javaObj (methodName param)) > > > > but this does not: > > > > (. javaObj ((symbol "methodName") param)) > > > > I suppose this really comes down to the question: what is a symbol? > > > And, is the thing at the head of the list (+ 1 2 3) a symbol? > > > > [In Icon, for example, there is no difference between > > > > "funcName"(1,2,3) and funcName(1,2,3), or indeed: > > > > x := "funcName" > > > x(1,2,3) > > > > which is VERY useful.] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to call function (or Java method) using string name?
Thanks Stuart. I have figured out another way, which is much more general (and uses the lowest level of how Clojure works). (defn evalStr [s] (clojure.lang.Compiler/eval (clojure.lang.RT/ readString s))) will (attempt to) execute any valid form (i.e. the string that is the source of the form). Thus: (evalStr "(+ 1 2)") --> 3 On Apr 26, 5:21 pm, Stuart Sierra wrote: > This will work: > ((resolve (symbol "+")) 1 2 3) > > To answer your question, a symbol is just a symbol, it doesn't have a > value. (In Common Lisp, symbols have values, but in Clojure they do > not.) In Clojure, values belong to Vars. "resolve" will find the Var > that is named by the symbol. When you write (+ 1 2 3), the compiler > automatically resolves the "+" to get the Var #'clojure.core/+ > > To invoke Java methods by name, use the Java Reflection > API:http://java.sun.com/docs/books/tutorial/reflect/index.html > > -Stuart Sierra > > On Apr 26, 10:46 am, timc wrote: > > > Is there a way of invoking functions, or java methods "by name" in > > Clojure? > > Or, put another way, why does this work: > > > (+ 1 2) > > > but this does not: > > > ((symbol "+") 1 2) > > > Similarly, this works > > > (. javaObj (methodName param)) > > > but this does not: > > > (. javaObj ((symbol "methodName") param)) > > > I suppose this really comes down to the question: what is a symbol? > > And, is the thing at the head of the list (+ 1 2 3) a symbol? > > > [In Icon, for example, there is no difference between > > > "funcName"(1,2,3) and funcName(1,2,3), or indeed: > > > x := "funcName" > > x(1,2,3) > > > which is VERY useful.] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How to call function (or Java method) using string name?
This will work: ((resolve (symbol "+")) 1 2 3) To answer your question, a symbol is just a symbol, it doesn't have a value. (In Common Lisp, symbols have values, but in Clojure they do not.) In Clojure, values belong to Vars. "resolve" will find the Var that is named by the symbol. When you write (+ 1 2 3), the compiler automatically resolves the "+" to get the Var #'clojure.core/+ To invoke Java methods by name, use the Java Reflection API: http://java.sun.com/docs/books/tutorial/reflect/index.html -Stuart Sierra On Apr 26, 10:46 am, timc wrote: > Is there a way of invoking functions, or java methods "by name" in > Clojure? > Or, put another way, why does this work: > > (+ 1 2) > > but this does not: > > ((symbol "+") 1 2) > > Similarly, this works > > (. javaObj (methodName param)) > > but this does not: > > (. javaObj ((symbol "methodName") param)) > > I suppose this really comes down to the question: what is a symbol? > And, is the thing at the head of the list (+ 1 2 3) a symbol? > > [In Icon, for example, there is no difference between > > "funcName"(1,2,3) and funcName(1,2,3), or indeed: > > x := "funcName" > x(1,2,3) > > which is VERY useful.] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
How to call function (or Java method) using string name?
Is there a way of invoking functions, or java methods "by name" in Clojure? Or, put another way, why does this work: (+ 1 2) but this does not: ((symbol "+") 1 2) Similarly, this works (. javaObj (methodName param)) but this does not: (. javaObj ((symbol "methodName") param)) I suppose this really comes down to the question: what is a symbol? And, is the thing at the head of the list (+ 1 2 3) a symbol? [In Icon, for example, there is no difference between "funcName"(1,2,3) and funcName(1,2,3), or indeed: x := "funcName" x(1,2,3) which is VERY useful.] --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: The Path to 1.0
On Apr 26, 9:18 am, lpetit wrote: > On 26 avr, 15:04, Rich Hickey wrote: > > > On Apr 24, 1:57 pm, Howard Lewis Ship wrote: > > > > Another option is for the version number to be in build.xml, and for > > > it to generate a runtime file (so that Clojure can know its own > > > version number) and set the version number inside a generated pom.xml. > > > You can use Ant resource copying with filters to accomplish both > > > these goals. > > > Sounds good, if by runtime file you mean a .properties file. > > > Patch welcome. > > I can do it tonight. > > (It's already half done). > > Rich, I thought you wanted to avoid generating files in the source > directories. > So there are 2 options here: either the version number is in src/clj/ > clojure/version.properties and every other script reads from there, > either the version number is in build.xml and ant propagates it, even > to the src/clj/clojure/version.properties location. > > I prefer the former to the latter, since then nothing is generated in > the src/ folder. > > What is your preference ? If no answer, the patch I'll submit will be > along the lines of the former. > The former is fine - thanks very much! Rich --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Getting slime-edit-definition to work with Clojure
Hello, I am a Clojure newbie and I have been trying to get M-. (slime-edit-definition) and the corresponding M-,(slime-pop-find-definiton-stack) to work with Clojure. Right now, if I press M-. I get "Search failed" in he minibuffer. Is there any way to get it to work, or am I doing something completely wrong? TIA. Regards, BG -- Baishampayan Ghose oCricket.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 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: The Path to 1.0
On 26 avr, 15:04, Rich Hickey wrote: > On Apr 24, 1:57 pm, Howard Lewis Ship wrote: > > > Another option is for the version number to be in build.xml, and for > > it to generate a runtime file (so that Clojure can know its own > > version number) and set the version number inside a generated pom.xml. > > You can use Ant resource copying with filters to accomplish both > > these goals. > > Sounds good, if by runtime file you mean a .properties file. > > Patch welcome. I can do it tonight. (It's already half done). Rich, I thought you wanted to avoid generating files in the source directories. So there are 2 options here: either the version number is in src/clj/ clojure/version.properties and every other script reads from there, either the version number is in build.xml and ant propagates it, even to the src/clj/clojure/version.properties location. I prefer the former to the latter, since then nothing is generated in the src/ folder. What is your preference ? If no answer, the patch I'll submit will be along the lines of the former. -- Laurent --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: The Path to 1.0
On Apr 24, 1:57 pm, Howard Lewis Ship wrote: > Another option is for the version number to be in build.xml, and for > it to generate a runtime file (so that Clojure can know its own > version number) and set the version number inside a generated pom.xml. > You can use Ant resource copying with filters to accomplish both > these goals. > > Sounds good, if by runtime file you mean a .properties file. Patch welcome. Clojure 1.0 (and all to follow it) is waiting for someone to help me with this, so, any help would be appreciated. Thanks, Rich > > On Thu, Apr 23, 2009 at 8:24 AM, Laurent PETIT > wrote: > > > 2009/4/23 Rich Hickey : > > >> On Apr 22, 12:41 pm, Laurent PETIT wrote: > >>> 2009/4/22 Rich Hickey : > > >>> > [...] > >>> > {:major 1, :minor 0, :incremental 0, :qualifier :rc1 :interim true} > > >>> > for interim versions and > > >>> > {:major 1, :minor 0, :incremental 0} > > >>> > for releases. :interim tracks the SNAPSHOT segment of the version > >>> > string. > >>> > [...] > >>> > I don't mind the build producing clojure-1.0.0.jar etc, but it doesn't > >>> > now. The master build is Ant. Where is the best place to put the > >>> > version info so it can be leveraged by Ant, Maven and the clojure core > >>> > runtime in order to produce *clojure-version* ? > > >>> Here a patch that allows to initialize from ant and from a file > >>> version.properties the values in *clojure-version*. > > >>> The patch only addresses the problematic of having a single place for > >>> version attributes. > >>> Having the ant build also use these properties for creating correctly > >>> numbered jars is not part of the patch. > > >>> Note that I had to create a new file, src/clj/clojure/core_version.clj > >>> , which is created by ant as a combination of template file > >>> core_version-template.clj and the properties from version.properties. > > >>> You'll see that if you don't like the names of the keys in > >>> version.properties, build.xml is the single place where to change them > >>> (apart from version.properties, of course). > >>> Also, if you don't like the name version.properties (e.g. if it should > >>> be named project.properties or whatever for easing maven users), then > >>> you just have to change its occurence in build.xml too. > > >>> If you like it, it can file an issue to google code and attach the patch, > > >> Thanks! > > >> I can't say I love the idea of generating a file during build. > > Me too, that's why I have made the file as short and independent as > > possible. > > > Well, I tried to keep close to the idea of having the version numbers > > "built-in", similarly to what was commited where it was also not read > > from a "simpler file" at load time. > > >> What about clojure.jar containing a properties file it reads at load time? > > > Why not, indeed ? The file would have to placed in the classpath, e.g. > > in directory src/jvm/clojure/lang or src/clj/clojure. > > >> Could the same file be read by the various builds? > > > For ant, yes. > > > For maven2, it's more complex. > > Indeed, I have read past the entire reference of the pom, searched > > through the ml, and it seems that it's not possible at all to have > > maven2 read properties file but its own which are not suitable for our > > purpose. > > > So I that even if we don't generate a clojure source file by reading > > version.properties at load time from the classpath, it will be > > difficult to avoid having to generate the maven2 pom.xml file from a > > pom-template.xml ... > > > Not that it would be difficult, it's just a matter of adding a > > init-mvn task in the ant build.xml, and make all mvn related ant tasks > > depend on it. > > > Concerning what Howard suggested, having the maven2 pom.xml file be > > the reference where the version information is placed, I can't say I > > like this idea very much. > > That's because maven2 pom.xml is not as structured as you have > > structured the current version information (maven2 just has a single > > "version" element where you place whatever you want, it's not > > decomposed into major, minor, ... so it will be more difficult to do > > the pattern matching :-). > > And also, maven2 pom.xml is not the master build file, it's ant, so it > > sounds weird to have ant go parse maven2.xml file to extract the > > versioning information. > > > My 0,02€, > > > -- > > Laurent > > -- > Howard M. Lewis Ship > > Creator of Apache Tapestry > Director of Open Source Technology at Formos --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How do you "boot-strap" clojure from java?
Hello Christophe, Thank you. > clojure.lang.RT.load("my/script.clj") ; your script must be on the classpath > clojure.lang.RT.var("my.ns", "my-var").invoke("hello") ; to call a function This is good (so I should read more then main.clj source code nex time ;-) ). Kind regards, Vlad --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How do you "boot-strap" clojure from java?
prhlava a écrit : > But what would be really cool, if I could distribute clojure code in > the source form, load it into a java appliation _and_ call the clojure > code (which got compiled on the fly when loaded) from java. But maybe > the nature of > the java language does not permit this. > clojure.lang.RT.load("my/script.clj") ; your script must be on the classpath clojure.lang.RT.var("my.ns", "my-var").invoke("hello") ; to call a function -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (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 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: Google announcement, version 1.0 & SCM Holy War (not really)
Hello Dan, > Which version did you try? msysgit works very well. Pity that VM I used is now no-existent, but as I said it was a while ago. Maybe msysgit improoved since. The reasons I had for choosing mercurial were: 1. The hg code base is simpler and smaller that git's 2. It is more easily portable (but this is debatable, if there is a platform without python) 3. Performs well enough for what I need (simple stuff) 4. Good integration in netbeans 5. If it is good enough for Open Solaris, OpenJDK and Xen, it is good enough for me ;-) But I have nothing against git. Personally, I use mainly linux so either would work well for me. Kind regards, Vlad --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---
Re: How do you "boot-strap" clojure from java?
Hello James, > Are you aware you can compile Clojure code directly into Java class > files? Yes, this was my 1st method of distributing clojure apps (in a .jar). It works. But what would be really cool, if I could distribute clojure code in the source form, load it into a java appliation _and_ call the clojure code (which got compiled on the fly when loaded) from java. But maybe the nature of the java language does not permit this. OTOH, possibly extending the build process in netbeans with automatically compiling the .clj files to .class files would be another way... Kind regards, Vlad --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~--~~~~--~~--~--~---