ANN: inet.data 0.5.1
Hi: Inet.data is a Clojure library for modeling various Internet-related conceptual entities as data. It is intended to support applications which are *about* the modeled entities versus *interfacing* with them. It presently contains types and associated APIs for representing IP addresses, IP networks, and DNS domains. None of the provided functions will ever perform any sort of DNS resolution or other network operation on the entity represented. Instead, it supports such operations as network address enumeration, network and DNS zone set membership tests, and domain suffix list lookups. Overview documentation and source code available at: https://github.com/llasram/inet.data Detailed API documentation at: http://llasram.github.com/inet.data/ Leiningen dependency coordinates: [inet.data 0.5.1] Feedback and contributions welcome! -Marshall -- 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: clojure.logic project.clj file
David Nolen dnolen.li...@gmail.com writes: Should core.logic support specific versions of Lein? Ideally Lein 2 would support Lein 1.X files. My understanding is that the reason the new version is lein 2.0 instead of 1.8 is because it does break backwards compatibility. However, if this is the only problem, it's fairly easy to support both versions -- just include both :source-path and :source-paths entries in the project map. -Marshall -- 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: Using gen-class to generate methods with same names and arities but different type signatures
David Greenberg dsg123456...@gmail.com writes: I can easily generate a map from signatures to implementations, but I need to generate the class with all the overloads. Is there any way to do this? Should I resign myself to writing out a .java file, and compiling that? In my experience just writing a stub Java class for this sort of situation is the simplest solution. I've found that `gen-class` works well for interop when needing to extend an abstract base class or similar scenarios. But when the need is less to interop with the JVM than specifically with Java, it is far easier to wire from Java into Clojure than vice versa. -Marshall -- 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: binding vs futures bug or feature (or more likely, am I missing the picture?)
Daniel Silén nimbus...@gmail.com writes: If I rebind a var's value it receives the new value - but it shouldn't, because it is in another thread, right?! Clojure 1.3 introduced a feature known as binding conveyance, which causes the functions passed in for futures and agent actions to be wrapped so as to capture the active thread local binding frame at instantiation. You can achieve a similar effect yourself (although the mechanism differs) by using the `bound-fn` macro or wrapping an existing function with `bound-fn*`. I believe the idea was to make the behavior of dynamic vars in these contexts less surprising / more useful, but YMMV. -Marshall -- 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 concurrency models to document?
Brian Marick mar...@exampler.com writes: Which raises the question: *is* concurrency actually a strong selling point for functional languages? It definitely was/is for me. I'd avoided threads for most of my career-to-date because in imperative languages any thread could mutate any value to be anything at any point. This is difficult to reason about when the code is written correctly, and then in C you have the added fun that an error could lead to that malevolent thread writing to absolutely any address in memory. Complete undebuggable madness! So I'd generally reached for processes in order to achieve concurrency. Using processes doesn't get rid of deadlocks etc, and introduces additional copying overhead if e.g. communicating over pipes, but does shrink the problem one needs to think about down to just the set of mechanisms explicitly used to communicate between the processes. IMHO, FP in general and Clojure in particular does two big things regarding concurrency: (1) By using immutable values, provides the same conceptual shrinking as using processes does in imperative languages, only without (well, with reduced) copying overhead. The concurrency problem is limited to just the interactions over the relatively small number of explicit concurrency points. (2) The ability to build higher-order concurrency abstractions which completely encapsulate recurring patterns. When using pure functions on immutable data, e.g. `pmap` and `reducers/fold` really do give you auto-concurrency for certain patterns of concurrent operations. Just my 2 cents, -Marshall -- 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: atom / swap! question
Vinay D.E devi...@gmail.com writes: I am a newbie and was doing some exercises when I ran across something that I don't understand. I am trying to count the number of elements in an array less than 100. My first attempt didn't work. The counter returns 0 (let [a (atom 0) i (take-while (fn[x] (swap! a inc) ( x 100)) [1 2 3 4 5])] [@a i]) = [0 (1 2 3 4 5)] The primary concrete problem is laziness, but fundamentally this sort of mutable-imperative algorithm doesn't play nice with Clojure's core features. The sequence returned by `take-while` is lazy, and none of the function applications required to generate that sequence actually happen until something forces evaluation of the sequence elements. So when you get the result of `[@a i]` what happens is: (1) `@a` is evaluated; nothing else has actually happened yet, so the result is still the initial value of `0`. (2) `i` is evaluated; now the sequence is forced and generated, and as a side-effect the atom is updated. Instead of depending on mutating side-effects to do these sorts of calculations, most of the Clojure standard library assumes that you'll be working with (largely) pure functions which operate primarily in terms of their parameters and return values. As an aside, you probably wanted `filter` instead of `take-while` even for what you were trying to do in the first place -- you should be able to figure out the difference from the docs. So, using pure functions, we can something as simple as: (count (filter #( x 100) input-sequence)) HTH, -Marshall -- 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: atom and lock
Warren Lynn wrn.l...@gmail.com writes: I have a hard time understanding why there is a need to retry when doing swap! on an atom. Why does not Clojure just lock the atom up-front and do the update? This is just my two cents, but I think the/one big reason is that Clojure atoms just *are* non-locking STM-based synchronized references. They allow you to handle shared, synchronous, independent state, but that's their typical use-case, not their definition. The Clojure atom is defined in terms of mechanism, not application. If you want locks, the Java standard library has locks aplenty. My understanding of the Clojure idiom is that when traditional threads-locks-and-queues concurrency is the best fit for the job, then just use it. My reading of the standard library suggests a strong preference for using higher-level constructs which leverage shared thread pools (futures and agents) over raw threads, but absolutely no shame in using e.g. LinkedBlockingQueue. Here's my quick stab at something implemented atop Java read-write locks: https://gist.github.com/3135772 -Marshall -- 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: compile dynamic ns ?
Stuart Sierra the.stuart.sie...@gmail.com writes: Clojure doesn't currently support generating Java classes dynamically, but you could hack the compiler to allow it. And if you don't feel like doing it yourself, check out shady and `shady.gen-class/gen-class`: https://github.com/llasram/shady/blob/master/src/shady/gen_class.clj#L25 -Marshall -- 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
[ANN] shady 0.1.0: JVM interop classes with less heartache
Hi all: Shady is intended to be a collection of JVM interop facilities. Right now it contains two useful pieces of functionality for producing iterop classes: a version of `gen-class` supporting dynamic redefinition like `deftype`; and a `defclass` macro providing a `deftype`-like interface to that `gen-class`. For example: (ns example.defclass (:use [shady.defclass :only [defclass]])) (defclass Example [field1 field2] :extend BaseClass :constructors {[String String] [String]} Example (-init [arg1 arg2] [[arg1] [arg1 arg2]]) (newMethod ^String [^int param] (str example: field1 : param : field2)) BaseClass (override ^Long [^Class class] 10) SomeInterface (implementedMethod [] Types defaulting to Object, as you'd hope.)) The interface is cleaner (IMHO), and normalized with the other Clojure type-definition facilities. The support for dynamic class redefinition is clinically proven to produce 73% less heartache for interop situations where you need full JVM classes. Be warned though, under the hood `defclass` does still use the same class-generation code as `gen-class`, with all that implies (performance, methods backed by functions bound to vars in the implementing namespace, etc). You can get the source from github: https://github.com/llasram/shady And the jar from Clojars: [shady 0.1.0] This is the first Clojure library I'm pushing for broader consumption, so feedback is more than welcome. -Marshall -- 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: Compiling Libraries With :aot
octopusgrabbus octopusgrab...@gmail.com writes: Is there any reason to compile a Clojure library with :aot? Here's all the reasons I know of for doing AOT-compilation: - The code produces JVM classes with `clojure.core/gen-class`, which only produces any results when compiling. - The code needs to expose a JVM class as an entry-point for a JVM framework which expects to find and instantiate a class through reflection. (Usually in tandem with the previous case.) - One wishes to build and distribute source-less JARs of only the compiled code. Any I'm missing? An open-source Clojure library intended for use from Clojure might hit the first case, but I don't believe very frequently. -Marshall -- 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: Initializers for AOTed deftype classes
Marshall T. Vandegrift llas...@gmail.com writes: So, is this entirely expected behavior? Or am I missing something which would make initializing the defining namespace happen as part of a static initializer for the AOTed `deftype` class? To answer my own question, the Clojure wiki page on the 1.2-introduced datatypes [1] includes loading accompanying namespace for deftype? on the same ideas list as Explicit ctor sigs? ... with bodies? Slogging through the compiler codebase shows that `deftype` indeed does not include the necessary code in generated classes' `clinit`s. Somewhat-relatedly, does anyone know why `gen-class` doesn't jump through the same class-loader hoops that `deftype` does in order to support iterative development within the same REPL session? By grabbing the private clojure.core/generate-class function, I was able to cobble together an alternative version which seems to work. [1] http://www.assembla.com/wiki/show/clojure/Datatypes -Marshall -- 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
Initializers for AOTed deftype classes
Hi, I'm trying to define some bits of Hadoop glue using `deftype` from Clojure. I'm using Leiningen to produce an AOT-complied JAR of the generated classes. At runtime, Hadoop uses reflection to load classes specified by name in (non-code) configuration. Hadoop is able to locate and instantiate instances of the class without issue, but then: java.lang.IllegalStateException: Attempting to call unbound fn: #'byteable.api/byteable? That particular example is for a var in a different namespace, but vars in the same namespace as that which `deftype`s the class cause the same problem. If I modify the type's entry-point methods to first `(require 'deytping.namespace)`, then everything works fine. So, is this entirely expected behavior? Or am I missing something which would make initializing the defining namespace happen as part of a static initializer for the AOTed `deftype` class? Thanks! -Marshall -- 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: Bug in extend-protocol macro? (Clojure 1.3.0)
Alan Malloy a...@malloys.org writes: Stuff like this always worries me. It may happen to work now, but I doubt if that's a guarantee. extend-protocol's contract is that you give it a Symbol, which it resolves into a Class. It surely isn't expecting a Class as an argument, because you can't enter that as a source-code literal. If you give it a Class, it could conceivably do something dreadful like try to call (resolve s) on it to figure out what Class you mean, and that will fail when passed a Class. I'm not entirely happy with it either, but I don't think the situation is quite that dire. The docstring for `extend-protocol' doesn't say anything about *how* it divides up the stanzas for extended types, and as pointed out elsewhere in this thread the implementation uses seq vs not-seq, not symbol? vs not-symbol?. The docstrings for `extend-type' and `extend' explicitly say that they take a type/class -- I'd interpret that to mean that they can be called with anything which resolves to a type/class via normal resolution methods, including a literal value generated via #=. For that matter, trying out your example, it doesn't seem to work for me. The first fix is to use java.lang.Class instead of just Class, since reader evaluation happens in a no-frills environment. Apologies -- I just modified the OP's original example without thinking it all the way through or running the code. One does need to specify java.lang.Class/forName, which is what I've been doing in my own source. But after that, it seems the extend-protocol just silently does nothing: (Addressed by another poster.) -Marshall -- 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: Bug in extend-protocol macro? (Clojure 1.3.0)
Peter Taoussanis ptaoussa...@gmail.com writes: Thanks- that explains it: dropping to extend works as expected. Another option I've been making use of for exactly this situation is to use the #= reader macro to evaluate the Class/forName at read-time. Something like: (extend-protocol MyProtocol java.lang.Integer (action [x] Integer) #=(Class/forName [B) (action [x] ByteArray)) It may not be ideal stylistically, but lets you use extend-protocol in such situations. -Marshall -- 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: let-else macro
Stephen Compall stephen.comp...@gmail.com writes: And may be anyway further generalized: (defmacro - [ forms] `(- ~@(reverse forms))) (- (let [x (foo) y (bar)]) (when y) (let [ ]) (do )) Another alternative, (require '[clojure.algo.monads :as m]) (m/domonad m/maybe-m [x (foo), y (bar), :let [z (baz)], :when ( z 5)] (+ x y z)) -Marshall -- 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: Clojure-in-CommonLisp?
Konrad Hinsen googlegro...@khinsen.fastmail.net writes: That may be a minority, but an implementation based on Common Lisp could also open the way to an integration with the world of C, via a Common Lisp implementation with a decent C interface. Integrating the JVM with C via JNA [1] is pretty straightforward. I've been doing all my JNA glue in Java so far because JNA depends on a few features which aren't available / convenient use in Clojure [2], but a decent Clojure wrapper API probably wouldn't be too difficult. [1] https://github.com/twall/jna [2] Structures involve definition of concrete types inheriting from other concrete types; direct method mapping requires tagging methods as `native' and providing a class-level static initializer. -Marshall -- 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: Confusing interplay between macros and metadata
Tassilo Horn tass...@member.fsf.org writes: I'm facing the same issue. I have this macro for java interop: (defmacro with-traversal-context [[g tc] body] `(let [old-tc# (.getTraversalContext ^Graph ~g)] (try (.setTraversalContext ^Graph ~g ^TraversalContext ~tc) ~@body (finally (.setTraversalContext ^Graph ~g ^TraversalContext old-tc#) But the type hints are gone in the macro expansion, thus I have 3 reflection warnings per macro application, and real, performance critical reflection warnings get lost in the shuffle. What you appear to be having is actually the different, but conceptually-related problem of the metadata reader macro and unquote operations interacting in a way which is consistent, but potentially not optimal. Fortunately in your sort of situation, you can work around the problem by replacing the metadata reader macro with explicit metadata operations. Something like the following should work: (defn assoc-meta [x kvs] (with-meta x (apply assoc (meta x) kvs))) (defmacro with-traversal-context [[g tc] body] (let [g (assoc-meta g :tag Graph) tc (assoc-meta tc :tag TraversalContext)] `(let [^TraversalContext old-tc# (.getTraversalContext ~g)] (try (.setTraversalContext ~g ~tc) ~@body (finally (.setTraversalContext ~g old-tc#)) -Marshall -- 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: Confusing interplay between macros and metadata
Alan Malloy a...@malloys.org writes: It seems to me that it would be nice to have macros automatically include, on their result forms, the metadata from their input form. Of course, macros may wish to add metadata as well, so the two maps should probably be merged. However, there are certainly some problems with this approach: for example if a macro wants to return something that can't suppport metadata (like an Integer), the compiler needs to be careful not to try to include it. So I'm hoping the community can comment on whether this feature would be useful, or whether there are fundamental problems with it that I haven't foreseen. Is there a reason this can't make it into a future version of Clojure? I think this is an excellent idea. Overall I believe this reduces the number of situations in which one needs to be actively aware that a particular expression will be subject to macro-expansion. The alternative-world where the 99% of well-behaved macros returning IMetas manually forward metadata from form seems like a world with way too much boilerplate to me. Forwarding metadata does preclude macros which use metadata applied to form as parameters and construct new metadata which may not include the literal values specified in the user-supplied metadata. I'm not sure this is a good idea anyway, but this sort of case -- and any others where metadata should not be forwarded/merged -- could easily be supported by providing a variation of defmacro with the current behavior. Or perhaps by configuring the metadata-forwarding behavior via metadata on the macro var -- something like: (defmacro foo {:forward-meta false} ...) ;; or, (defmacro ^:replace-meta foo ...) If a macro expands to something which doesn't implement IMeta, then I believe the compiler needs to error out if metadata is applied to it, just as it does applying metadata to non-IMeta literals. To do otherwise would be inconsistent, and result in the same silent data-loss as macros are yielding today. This proposal doesn't touch forwarding metadata on forms which become macro arguments, obviously. There's still room for inconsistency there, but I think that's clearly in the court of individual macro authors to implement the correct behavior. Are there other contexts where metadata should potentially be forwarded? I don't know how often this comes up, but: (= (meta ^:foo (quote foo)) (meta (quote ^:foo foo))) ;; = false -Marshall -- 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: Code problem: setting an atom from a deref'd atom that's inside a let.
Tim Robinson tim.blacks...@gmail.com writes: = (defn oops! [] (let [x1 (atom (hash-map)) v1 (filter #(let [xv1 (@data %)] (if (= xv1 v1) (swap! x1 assoc :k1 other))) (keys @data)) rxv (reset! flag @x1)] (println v1))) So why didn't the first version with deref work? Because `filter' produces a lazy list, which isn't realized (and the side effects generated) until your call to `println'. Furthermore, the documentation for `filter' explicitly notes that pred must be free of side-effects. Looking at the implementation, I'm not sure why function-argument purity matters more for `filter' than any other sequence-generating higher-order function. Does anyone else know the reason? -Marshall -- 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
Potential bug: pmap vs chunked seqs
Hi: I found what I think might be considered a bug, but I'm not certain. The doc-string for `pmap' just says that the passed-in function is applied in parallel, but the code as-written is pretty clearly intended to keep only (+ 2 #CPUS) future-wrapped function applications realized at a time. It works exactly that way for non-chunked seqs, but when called with a chunked seq instead keeps realized some arbitrary number of futures between (+ 2 #CPUS) and the next multiple of 32. Given that the code for `pmap' hasn't changed since chunked seqs were added to Clojure, this feels like a bug to me, but the parallelism semantics for `pmap' aren't exactly strictly defined. Is this worth opening a ticket for in the Clojure issue tracker? -Marshall -- 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: Potential bug: pmap vs chunked seqs
Stefan Kamphausen ska2...@googlemail.com writes: Chunked seqs are supposed to realize more elements than you consume. That's for performance reasons. But since you will only ever apply side-effect-free functions to seqs, that will make no difference, no? Sorry, yes, I'm talking about within the code of `pmap'. It creates a lazy seq of futures of application of the passed-in function to the passed-in collection via (map #(future (f %)) coll). Realizing elements of *that* seq has the side-effect of allocating/spawning a thread from the futures thread-pool. If `coll' can be turned into a chunked seq, then the futures will be realized -- and threads allocated or spawned -- in chunks of 32. If `coll' cannot be turned into chunked seq, then only (+ 2 #CPUS) threads will be allocated/spawned at a time. I think clarifying that has convinced me that this is definitely bug, just because the side-effects are inconsistent. I don't think that the chunkability (chunkiness?) of the collection argument should affect the degree of parallelism. -Marshall -- 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: Macro not working - newbie question
Dusan dusan.milorado...@gmail.com writes: (symbol(str (str (: % vv This expression is the (immediate) problem child. You are producing a symbol which contains literal space and parenthesis characters embedded in it. When you print out the macro-expansion, it looks fine, but the actual forms generated contain that weird symbol instead of the expected list structure. You do have other problems though -- - A symbol prefixed with a colon is just a symbol prefixed with a colon, not a keyword. You need to use the `keyword' function to create a keyword from a symbol or string. - Instead of calling `gensym' directly, it's probably easier to just use autogensyms in this sort of situation. For fun, here's a (hopefully) more idiomatic version: (defmacro defrecord-withstr [name fields columns include?] (let [displayed (- (if include? columns (remove (set columns) fields)) (map keyword))] `(defrecord ~name ~fields Object (toString [this#] (str/join ((juxt ~@displayed) this#)) -Marshall -- 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: when quotes and when syntax-quotes?
Guofeng Zhang guof...@radvision.com writes: I do not understand why `'~v has be to used this way. If I used `~v instead (that is, remove the quote), it still works. So my question is, why ~v needs to be first quoted and then syntax-quoted? I'm not the most experienced Clojure programmer, but I'll have a go: The key is to count the levels of quoting, and make sure they match what you need at each level for each form. Using just `~ is (almost) a no-op. Putting ' in between them yields the a form containing the quoted *value* of v, which is equivalent to the (possibly clearer) `(quote ~v). The quoting comes into play for symbols, because quoting captures any symbols as literal symbol objects vs whatever they resolve to in the lexical scope. If you pass {'a 'one} in for the ctx argument to contextual-eval as-is, then the symbol `one' ends up quoted in the generated let, and `a' properly bound to the symbol object. If you modify the function to *not* quote the value, then an unquoted `one' get inserted instead, and the function throws an error because `one' is unbound. HTH, -Marshall -- 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: Exception handling changes in Clojure 1.3.0
Stuart Sierra the.stuart.sie...@gmail.com writes: I was a little worried about this when the exception behavior for fns was changed. I think it's solvable, but don't know right now what the solution is. I'm not incredibly experienced with Java, but would using a Java construct which tricks the language into allowing unchecked exceptions be too crazy? I've seen references to both of these approaches, but haven't actually tried either for anything: http://james-iry.blogspot.com/2010/08/on-removing-java-checked-exceptions-by.html http://projectlombok.org/features/SneakyThrows.html The former even came up on #clojure, I believe. -Marshall -- 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: Closures in macros
André Thieme splendidl...@googlemail.com writes: Please try this minimal example in your REPL: (defn f [x] (fn [] x)) ; the closure factory (def foo (f 0)) ; a useful instance (defmacro bar [] `(let [a# ~foo])) and then call (bar) I'm new to Clojure and don't have much experience with Lisps in general, but trying to do this seems weird to me. My understanding is that macros are, well, macros -- code which is expanded at compile-time to other code. In which case the interface the macro facility provides isn't a set of compiler hooks, but just the ability to factor and abstract the same code you could write without the macro facility. What ultimate code-expansion are you trying to achieve? Perhaps there's a different way to do it which works within the confines of pure code re-writing. -Marshall -- 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: Closures in macros
Alessio Stalla alessiosta...@gmail.com writes: The key point is that in Lisp code does not mean text [1]. Code is made of data structures - lists, symbols, vectors, numbers, ... - and macros are just functions that operate on those data structures. Hmm, interesting. One of the things that's drawn me to learning Clojure is the malleability of code as data, but I hadn't thought about it as potentially running that deep before. Thanks for phrasing that in a way that clicked for me. In other words, valid code is no longer determined by the reader (i.e. the parser), but by the compiler and/or the interpreter, that take a rich data structure as input. The reader is only useful to us humans to enter code into the system. OTOH, the compiler still needs a defined interface. The data structures the reader is able to produce seem like a convenient definition for what data structures the compiler should meaningfully consume. Obviously the reader producing structures the compiler can't consume is useless, but the compiler consuming structures the reader can't produce seems equally problematic to me. It seems like code which doesn't have a textual representation would be much more difficult to reason about. Without guaranteeing a mapping from every valid compiler input to text which causes the reader to directly generate that input, it becomes impossible to inspect what the compiler is actually consuming. -Marshall -- 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