Re: Java API is copyright protected?
At the risk of getting slightly off-topic here, here's a comment on Hacker News from a well-respected commenter on legal issues - he's a lawyer specialising in startup and technology law and his analysis is uniformly excellent. He argues that while the result may be unpalatable, it's by no means the stitch-up by technological ignoramuses that that article makes it sound: https://news.ycombinator.com/item?id=7722674 Judge Alsop conflated two distinct and non-overlapping areas of intellectual property law by claiming that a copyrightable work (the API) must rise to the level of warranting patent protection. While that's a novel idea, it is nowhere in the copyright law. (Oracle, by the way, also holds patents on Java). Where the new decision might have a direct impact on Clojure would be if someone were to create a stand-alone Clojure (or other products that enable a developer to use Java directly in their products) that was compatible with the JVM-hosted version. There would seem to be a need for API-compatible functions. Doubly so if you could excute jar files. The court could find that infringing, it seems. On April 29th, Steven Vaughan-Nichols (a lawyer) predicted that Oracle would be defeated in court [0]... and he was wrong. Text is born with copyright and the API is a text specification. The EFF lawyer [1] who provided a friend-of-the-court brief seems very unhappy with the decision. Florian Mueller [2] at fosspatents.com has a much more in-depth analysis and basically agrees with the decision. He includes detailed quotes from the Court. Google claims that Sun issued Java under the GPL2. But Oracle has the freedom to change a license on its products and has made Java API changes since the Sun Java purchase. They did the same thing with MySQL, also GPL2, which is now pay-to-play. Our trouble with the Courts, and possibly with the lawyer's reasoning, is that they are not programmers. The other problem is that they are deciding the case on what the law SAYS, not on the effects. But the judge ruled that (a) Oracle could copyright the API (b) Google infringed that copyright Google's defense rests on fair use [3] quoted below. I have learned that legalese is NOT English so words don't mean what you think they mean. Legalese is also not logical but depends on prior cases. With those caveats, I don't see that Google has any chance to prevail. Oracle can certainly claim that the listed exceptions don't apply and that the 4 listed criteria all weigh in on their side. As we all know, a widely used API has network effects... you use it because everybody uses it. That's essentially why Google chose it rather than create their own. They can leverage the huge number of programmers who already use it. It would be a challenge to convince designers creating an API to create a competing, non-infringing version. Of course, Oracle claims that their API is very valuable intellectual property, vital to their business, and copyrighted. I personally hate the Court's decision but I also think they read the law as it was intended. Oracle is not SCO; they won't go away any time soon. So what would a non-JVM Clojure do? A non-profit JVM-compatible Clojure product would potentially escape using clause (1) below [3], assuming it was used for non-profit educational purposes. Can a non-Java Clojure be defined? Tim Daly = [0] http://www.zdnet.com/blog/open-source/oracle-vs-google-dead-lawsuit-walking/10843 [1] https://www.eff.org/deeplinks/2014/05/dangerous-ruling-oracle-v-google-federal-circuit-reverses-sensible-lower-court [2] http://www.fosspatents.com/2014/05/oracle-wins-android-java-copyright.html [3] Copyright Law Exceptions (quoted for comment purposes) :-) Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phonorecords, or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including multiple copies for classroom use), scholarship, or research, is not an infringement of copyright. In determining whether the use made of a work in any particular case is a fair use the factors to be considered shall include: 1. the purpose and character of the use, including whether such use is of a commercial nature or is for non-profit educational purposes; 2. the nature of the copyrighted work; 3. the amount and substantiality of the portion used in relation to the copyrighted work as a whole; and 4. the effect of the use upon the potential market for or value of the copyrighted 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 Note that posts from new members are moderated - please be patient with your first
How do I mock request with content-type in Ring?
Hi, I'm using e.g.this: (let [response (app (request :post /user-register {:par1 val :par2 val}))] ) This works, but now I have a service that is provided by external library and requires the type of the request to be explicitly set to application/json. How do I do this? I checked the apihttp://weavejester.github.io/ring-mock/ring.mock.request.html there's a content-type function: content-type (content-type request mime-type) Set the content type of the request map. I tried (let [response (app (content-type (request :post /login {:username jane :password test}) application/json))] ) Doesn't work... Also found this entryhttp://stackoverflow.com/questions/17035319/how-do-i-mock-a-json-post-request-in-ringin StackOverflow asking the same, but also seems not to work + don't like having to pass the body as escaped string instead of a map... 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 --- 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/d/optout.
Re: Proposing a new Clojure documentation system (in Clojure)
So it would be nice if people who are knowledgeable about other doc systems could contribute to it. From what I see, that may involve Tim for Emacs, Sean for reStructured, and Daniel for docco, for example? I took the liberty of fleshing out the documenthttps://docs.google.com/spreadsheets/d/1HyS9qstgEqmdv0MtDm3xEsImnDjCYQhar1PQP3fzwMc/edit#gid=0a bit, and I added sections for reStructuredText/Sphinx/ReadTheDocs.org and codox. Cheers, Sean -- 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/d/optout.
Re: [ldnclj] Clojure Java 8 Compact Profiles
Ben, We've done a few hack days on Incanter and ring/compojure in the past and I presume that there is some clojure hacking that goes on at Hack the Tower. I think sorting out the contributors' agreements and hacking on this would be a great idea. cheers, Bruce On Sun, May 11, 2014 at 7:45 AM, Julian Birch julian.bi...@gmail.com wrote: Indeed. My personal advice would be get a Contributor's Agreement signed off first. I never have... It's a genuinely interesting idea, but London Clojurians doesn't really do any communal dev (well, there's plenty of ad-hoc stuff.) J On 7 May 2014 15:55, Nathan Fisher nfis...@junctionbox.ca wrote: I wonder if this is something worth bumping to the main clojure dev list? On Wednesday, 7 May 2014, Ben Evans benjamin.john.ev...@gmail.com wrote: Hello, I mostly only lurk here, but I recently was running a small experiment with Java 8 Compact Profiles (essentially, restricted versions of the JRE designed for serverside deployments that only ship a subset of rt.jar) and thought it might be of interest. Clojure appears to depend on the full JRE, but this seems to be due to only a few packages. From my initial investigations, it seems that it wouldn't be too hard to persuade the main parts of Clojure (basically, everything which doesn't do Swing/GUI stuff) to only need compact1 (the most restrictive profile) instead. The benefits would be reduced disk footprint, better security and possible startup time and memory footprint improvements for the majority of Clojure users, at a cost of needing to subdivide the clojure jars. Is this something that the community would be interested in investigating, and if so, are there people who have cycles to contribute? Or has someone tried this already? Thanks, Ben -- You received this message because you are subscribed to the Google Groups London Clojurians group. To unsubscribe from this group and stop receiving emails from it, send an email to london-clojurians+unsubscr...@googlegroups.com. To post to this group, send email to london-clojuri...@googlegroups.com. Visit this group at http://groups.google.com/group/london-clojurians. For more options, visit https://groups.google.com/d/optout. -- Nathan Fisher w: http://junctionbox.ca/ -- You received this message because you are subscribed to the Google Groups London Clojurians group. To unsubscribe from this group and stop receiving emails from it, send an email to london-clojurians+unsubscr...@googlegroups.com. To post to this group, send email to london-clojuri...@googlegroups.com. Visit this group at http://groups.google.com/group/london-clojurians. For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups London Clojurians group. To unsubscribe from this group and stop receiving emails from it, send an email to london-clojurians+unsubscr...@googlegroups.com. To post to this group, send email to london-clojuri...@googlegroups.com. Visit this group at http://groups.google.com/group/london-clojurians. For more options, visit https://groups.google.com/d/optout. -- @otfrom | CTO co-founder @MastodonC | mastodonc.com See recent coverage of us in the Economist http://econ.st/WeTd2i and the Financial Times http://on.ft.com/T154BA -- 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/d/optout.
Re: How do I mock request with content-type in Ring?
On Sunday, May 11, 2014 3:18:56 AM UTC-5, Ivan Schuetz wrote: I tried (let [response (app (content-type (request :post /login {:username jane :password test}) application/json))] ) Take a look at the source. Params passed to ring-mock.request/request for non-GET, non-HEAD requests will always be passed through to 'body[1], and if those params are a map, they'll always be urlencoded, and the content type of the request will be set to application/x-www-form-urlencoded[2]. Your call to content-type is changing the declared content-type of the request, but the body is still urlencoded. If you instead pass in a json string, it will be converted to a byte-array and wrapped in a ByteArrayInputStream without further encoding[3]. So you should be able to do something like the following (untested). (- (request :post /login (clojure.data.json/write-str {:username jane :password test})) (content-type application/json)) [1]: https://github.com/weavejester/ring-mock/blob/master/src/ring/mock/request.clj#L92-L104 [2]: https://github.com/weavejester/ring-mock/blob/master/src/ring/mock/request.clj#L70-L73 [3]: https://github.com/weavejester/ring-mock/blob/master/src/ring/mock/request.clj#L62-L68 Doesn't work... In the future, it would be helpful to say more about how it doesn't work. For example, you could show us the return value of (content-type (request :post /login {:username jane :password test}) application/json) and, if you can see what's wrong with it, tell us what's wrong. The Stack Overflow post you linked to is about peridot, a different library for testing Ring apps. -- 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/d/optout.
What is going wrong in my code?
Hi, I'm trying to learn how to make DSL in Clojure and Korma project is a really good place to learn from. I'm trying this very simple stuff (inspired by Korma, not Korma code): (def predicates {'and :and 'or :or 'not :not ' :gt ' :lt '= :eq}) (defn parse-where [form] (walk/postwalk-replace predicates form)) (defn condition-map [clause] (apply hash-map (conj clause :op))) (defn clauses-vec [clauses] (reduce #(conj %1 (condition-map %2)) [ ] (rest clauses))) (defn select* [ ] {:type :select}) (defmacro select [ body] (make-query-then-execute #'select* body)) (defn- make-query-then-execute [fn-var body] `(let [query-map# (- (~fn-var) ~@body)] query-map#)) (defn where-form [where-form* query form] `(let [q# ~query] (~where-form* q# (clauses-vec ~(parse-where `~form) (defmacro where [query form] (where-form #'where* query form)) (defn where* [query clause] (update-in query [:where] conj clause)) But when I'm trying in the REPL: (select (where (and (= :version 1.6) (= :name Clojure)) I'm getting: ClassCastException java.lang.Character cannot be cast to clojure.lang.IPersistentCollection clojure.core/conj (core.clj:83) It is really hard to me to know what is going wrong. What is confusing me, if I'm trying the where macro alone, it is working as excepted but when integrating it with select macro, I got the exception. I know it is not your problem but your help is greatly appreciated. Thanks for help and time. -- 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/d/optout.
Re: What is going wrong in my code?
On 11 May 2014 15:18, Hussein B. hubaghd...@gmail.com wrote: Hi, I'm trying to learn how to make DSL in Clojure and Korma project is a really good place to learn from. I'm trying this very simple stuff (inspired by Korma, not Korma code): [code snipped] But when I'm trying in the REPL: (select (where (and (= :version 1.6) (= :name Clojure)) I'm getting: ClassCastException java.lang.Character cannot be cast to clojure.lang.IPersistentCollection clojure.core/conj (core.clj:83) It is really hard to me to know what is going wrong. What is confusing me, if I'm trying the where macro alone, it is working as excepted but when integrating it with select macro, I got the exception. Generally, when macros are causing problems, it's good to start debugging with macroexpand to see what's actually getting executed. (macroexpand '(select (where (and (= :version 1.6) (= :name Clojure) ; (let* [query-map__696__auto__ (clojure.core/- (#'dsltmp/select*) (where (and (= :version 1.6) (= :name Clojure] query-map__696__auto__) I then tried macroexpand on the where clause that that would generate: (macroexpand '(where select* (and (= :version 1.6) (= :name Clojure ; (let* [q__703__auto__ select*] (#'dsltmp/where* q__703__auto__ (dsltmp/clauses-vec (:and (:eq :version 1.6) (:eq :name Clojure) So the argument getting passed into clauses-vec is (:and (:eq :version 1.6) (:eq :name Clojure)) - but it's not a macro, so this is evaluated: (:and (:eq :version 1.6) (:eq :name Clojure)) ; Clojure (If it's not clear what's going on here, remember that keywords try to look themselves up in their first argument, and default to their second argument.) So 'clauses' is Clojure, '(rest clauses)' is '(\l \o \j \u \r \e)', and condition-map is invoked with the argument \l, which triggers the error you saw: (condition-map \l) ; ClassCastException java.lang.Character cannot be cast to clojure.lang.IPersistentCollection clojure.core/conj (core.clj:83) Since the problem is that clauses-vec evaluates its argument, defining it as a macro instead of a function should fix 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 --- 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/d/optout.
Re: What is going wrong in my code?
On 11 May 2014 15:18, Hussein B. hubaghd...@gmail.com wrote: Hi, I'm trying to learn how to make DSL in Clojure and Korma project is a really good place to learn from. I'm trying this very simple stuff (inspired by Korma, not Korma code): [code snipped] But when I'm trying in the REPL: (select (where (and (= :version 1.6) (= :name Clojure)) I'm getting: ClassCastException java.lang.Character cannot be cast to clojure.lang.IPersistentCollection clojure.core/conj (core.clj:83) It is really hard to me to know what is going wrong. What is confusing me, if I'm trying the where macro alone, it is working as excepted but when integrating it with select macro, I got the exception. Generally, when macros are causing problems, it's good to start debugging with macroexpand to see what's actually getting executed. (macroexpand '(select (where (and (= :version 1.6) (= :name Clojure) ; (let* [query-map__696__auto__ (clojure.core/- (#'dsltmp/select*) (where (and (= :version 1.6) (= :name Clojure] query-map__696__auto__) I then tried macroexpand on the where clause that that would generate: (macroexpand '(where select* (and (= :version 1.6) (= :name Clojure ; (let* [q__703__auto__ select*] (#'dsltmp/where* q__703__auto__ (dsltmp/clauses-vec (:and (:eq :version 1.6) (:eq :name Clojure) So the argument getting passed into clauses-vec is (:and (:eq :version 1.6) (:eq :name Clojure)) - but it's not a macro, so this is evaluated: (:and (:eq :version 1.6) (:eq :name Clojure)) ; Clojure (If it's not clear what's going on here, remember that keywords try to look themselves up in their first argument, and default to their second argument.) So 'clauses' is Clojure, '(rest clauses)' is '(\l \o \j \u \r \e)', and condition-map is invoked with the argument \l, which triggers the error you saw: (condition-map \l) ; ClassCastException java.lang.Character cannot be cast to clojure.lang.IPersistentCollection clojure.core/conj (core.clj:83) Since the problem is that clauses-vec evaluates its argument, defining it as a macro instead of a function should fix 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 --- 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/d/optout.
Clojure and Fortran
Hello! I came across this (fairly good imho) article comparing Clojure, Haskell and Julia in terms of their applicability to scientific computing: http://arstechnica.com/science/2014/05/scientific-computings-future-can-any-coding-language-top-a-1950s-behemoth/ One of Julia's selling points seems to be Fortran interop. Has anybody thought of a Clojure-to-Fortran compiler similar to ClojureScript, and how it could spread Clojure's reach into the Fortran-legacy-rich subsets of the worlds of academia, engineering, and maybe banking? Or maybe of extending (if at all possible) ClojureC so that it can interop with both Fortran and C, in a way similar to what Julia can do, which might increase ClojureC's popularity? Do these sound like reasonable ideas to you? Thanks! Deyan -- 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/d/optout.
Re: Expected inconsistency between set and map w/ ArrayList?
OK. this thread is a bit worrying. If I understand correctly, it means that we've now got inconsistent hash and equals functions. I suspect this hasn't bitten many people yet simply because it is unusual to mix Java and Clojure collections as keys in the same structure, but it seems like a really nasty issue. Hash and equality functions generally have a very simple rule: if two things are equal they must have the same hashcode. But now we've got: (= (java.util.ArrayList. [1 2]) [1 2]) = true (hash (java.util.ArrayList. [1 2])) = 994 (hash [1 2]) = 156247261 I consider this a major defect. If we want to define our own equals and hashcode that's fine, but then these functions absolutely should be consistent with each other. If it is really true that non-Clojure collections aren't considered as values and aren't expected to participate in hash/= comparisons then I'd expect an exception, not an erroneous value. Silent potential corruption of data is *much* worse than a noisy failure. But I think even that is a bad direction to go: easy Java ecosystem interop is definitely one of the main reasons why I'm using Clojure, and I'd like to see this maintained. I can think of only two sensible ways to fix this inconsistency: a) Roll back the hash changes. Correctness is much more important than a performance edge case. (I suspect the hash changes have hurt average case performance anyway...) b) Make (= (java.util.ArrayList. [1 2]) [1 2]) and similar comparisons evaluate to false (on the grounds that ArrayLists aren't Clojure collections, so should not be considered equal). On Saturday, 10 May 2014 15:51:24 UTC+1, John Hume wrote: Thanks for the ticket pointer. I didn't find it in my initial search because it Affects Version/s: None :-/, and I knew this behavior was new to 1.6. For those not up for the medium-length comment-thread read: non-Clojure-aware Java Collections Framework interface instances are not considered values,* and 'Rich says all bets should be off for hasheq/equiv of non-values.' That's a bit down in the details, but I think the upshot is that they're not currently supported as set members or hash keys. Unfortunately they used to be supported (unintentionally, I guess) due to Clojure following Java's lead, so I have some interop-heavy code to review and test very carefully. Though the above seems to frame non-support as based on principle, it seems the driver is keeping the new hasheq stuff highly performant. I would hope a performant implementation that supported the Collections interfaces would be accepted for some future version. *If there is one, I'd like to read a clear definition of what values means in Clojure. The headings on http://clojure.org/data_structures are almost an enumeration of them, except the Collections section talks a little about Java Collections classes, hashCode, and hasheq without making it clear that non-Clojure collections are not values. Unfortunately the current definition seems to admit only the Java primitives and near-primitives (String and primitive wrappers) and clojure-aware types. What not supported looks like via maps: user *clojure-version* {:major 1, :minor 6, :incremental 0, :qualifier nil} user (hash-map [1 2] v (java.util.ArrayList. [1 2]) a) {[1 2] a, [1 2] v} user {[1 2] v (java.util.ArrayList. [1 2]) a} IllegalArgumentException Duplicate key: [1 2] clojure.lang.PersistentArrayMap.createWithCheck (PersistentArrayMap.java:70) user (- {} (assoc [1 2] v) (assoc (java.util.ArrayList. [1 2]) a)) {[1 2] a} On Friday, May 9, 2014 6:34:26 PM UTC-5, Andy Fingerhut wrote: Mike is correct. This change in behavior is due to the hashing changes in Clojure 1.6. See the comments on ticket http://dev.clojure.org/jira/browse/CLJ-1372http://www.google.com/url?q=http%3A%2F%2Fdev.clojure.org%2Fjira%2Fbrowse%2FCLJ-1372sa=Dsntz=1usg=AFQjCNG6I-rrRfAMsUZUomYEbGOJkJqWGAfor some discussion of whether this is considered a bug. It appears that perhaps the hash consistency is not promised for mutable objects, only immutable ones. Below are a couple more REPL transcripts that illustrate the change in behavior: user= *clojure-version* {:major 1, :minor 5, :incremental 1, :qualifier nil} user= (= [1 2] (java.util.ArrayList. [1 2])) true user= (map hash [ [1 2] (java.util.ArrayList. [1 2]) ]) (994 994) user= (hash-map [1 2] vec (java.util.ArrayList. [1 2]) alist) {[1 2] alist} user= *clojure-version* {:major 1, :minor 6, :incremental 0, :qualifier nil} user= (= [1 2] (java.util.ArrayList. [1 2])) true user= (map hash [ [1 2] (java.util.ArrayList. [1 2]) ]) (156247261 994) user= (hash-map [1 2] vec (java.util.ArrayList. [1 2]) alist) {[1 2] alist, [1 2] vec} -- 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 -
Re: Java API is copyright protected?
Tim, I am assuming you are aware of the non-Java Clojures called ClojureScript and Clojure on .NET. There are multiple other non-Java Clojure versions of varying degrees of completeness and polish. To my knowledge, they explicitly do not try to maintain compatibility at the Java API level -- Clojure on Java is intended to take advantage of the host platform without reimplementing it, and so do these other versions of Clojure. It seems that someone would have to want to make another JVM with a large set of Java libraries compatible with Oracle's libraries before they would ever come close to running afoul of this legal decision, and there is nothing really Clojure-specific about that. Hopefully I haven't missed your point entirely here. Andy On Sat, May 10, 2014 at 11:37 PM, d...@axiom-developer.org wrote: At the risk of getting slightly off-topic here, here's a comment on Hacker News from a well-respected commenter on legal issues - he's a lawyer specialising in startup and technology law and his analysis is uniformly excellent. He argues that while the result may be unpalatable, it's by no means the stitch-up by technological ignoramuses that that article makes it sound: https://news.ycombinator.com/item?id=7722674 Judge Alsop conflated two distinct and non-overlapping areas of intellectual property law by claiming that a copyrightable work (the API) must rise to the level of warranting patent protection. While that's a novel idea, it is nowhere in the copyright law. (Oracle, by the way, also holds patents on Java). Where the new decision might have a direct impact on Clojure would be if someone were to create a stand-alone Clojure (or other products that enable a developer to use Java directly in their products) that was compatible with the JVM-hosted version. There would seem to be a need for API-compatible functions. Doubly so if you could excute jar files. The court could find that infringing, it seems. On April 29th, Steven Vaughan-Nichols (a lawyer) predicted that Oracle would be defeated in court [0]... and he was wrong. Text is born with copyright and the API is a text specification. The EFF lawyer [1] who provided a friend-of-the-court brief seems very unhappy with the decision. Florian Mueller [2] at fosspatents.com has a much more in-depth analysis and basically agrees with the decision. He includes detailed quotes from the Court. Google claims that Sun issued Java under the GPL2. But Oracle has the freedom to change a license on its products and has made Java API changes since the Sun Java purchase. They did the same thing with MySQL, also GPL2, which is now pay-to-play. Our trouble with the Courts, and possibly with the lawyer's reasoning, is that they are not programmers. The other problem is that they are deciding the case on what the law SAYS, not on the effects. But the judge ruled that (a) Oracle could copyright the API (b) Google infringed that copyright Google's defense rests on fair use [3] quoted below. I have learned that legalese is NOT English so words don't mean what you think they mean. Legalese is also not logical but depends on prior cases. With those caveats, I don't see that Google has any chance to prevail. Oracle can certainly claim that the listed exceptions don't apply and that the 4 listed criteria all weigh in on their side. As we all know, a widely used API has network effects... you use it because everybody uses it. That's essentially why Google chose it rather than create their own. They can leverage the huge number of programmers who already use it. It would be a challenge to convince designers creating an API to create a competing, non-infringing version. Of course, Oracle claims that their API is very valuable intellectual property, vital to their business, and copyrighted. I personally hate the Court's decision but I also think they read the law as it was intended. Oracle is not SCO; they won't go away any time soon. So what would a non-JVM Clojure do? A non-profit JVM-compatible Clojure product would potentially escape using clause (1) below [3], assuming it was used for non-profit educational purposes. Can a non-Java Clojure be defined? Tim Daly = [0] http://www.zdnet.com/blog/open-source/oracle-vs-google-dead-lawsuit-walking/10843 [1] https://www.eff.org/deeplinks/2014/05/dangerous-ruling-oracle-v-google-federal-circuit-reverses-sensible-lower-court [2] http://www.fosspatents.com/2014/05/oracle-wins-android-java-copyright.html [3] Copyright Law Exceptions (quoted for comment purposes) :-) Notwithstanding the provisions of sections 106 and 106A, the fair use of a copyrighted work, including such use by reproduction in copies or phonorecords, or by any other means specified by that section, for purposes such as criticism, comment, news reporting, teaching (including
Re: Expected inconsistency between set and map w/ ArrayList?
Euh From the top of my head after a long working day, aren't we comparing apples with cabbages here ? How can you expect a mutable structure to have any stability over time ? They're not values and even worse they are alien to Clojure. To how much contortions should go through to deal with this issue over all the implementations while retaining some common semantic ? I have a pretty rigid principle of keeping interop stuff away from the core of my code. Interop is needed but at the edges. My answer to such an issue is that you need to convert alien structures before getting them to participate on the Clojure side of the fence. But I may be old fashion... Luc P. OK. this thread is a bit worrying. If I understand correctly, it means that we've now got inconsistent hash and equals functions. I suspect this hasn't bitten many people yet simply because it is unusual to mix Java and Clojure collections as keys in the same structure, but it seems like a really nasty issue. Hash and equality functions generally have a very simple rule: if two things are equal they must have the same hashcode. But now we've got: (= (java.util.ArrayList. [1 2]) [1 2]) = true (hash (java.util.ArrayList. [1 2])) = 994 (hash [1 2]) = 156247261 I consider this a major defect. If we want to define our own equals and hashcode that's fine, but then these functions absolutely should be consistent with each other. If it is really true that non-Clojure collections aren't considered as values and aren't expected to participate in hash/= comparisons then I'd expect an exception, not an erroneous value. Silent potential corruption of data is *much* worse than a noisy failure. But I think even that is a bad direction to go: easy Java ecosystem interop is definitely one of the main reasons why I'm using Clojure, and I'd like to see this maintained. I can think of only two sensible ways to fix this inconsistency: a) Roll back the hash changes. Correctness is much more important than a performance edge case. (I suspect the hash changes have hurt average case performance anyway...) b) Make (= (java.util.ArrayList. [1 2]) [1 2]) and similar comparisons evaluate to false (on the grounds that ArrayLists aren't Clojure collections, so should not be considered equal). On Saturday, 10 May 2014 15:51:24 UTC+1, John Hume wrote: Thanks for the ticket pointer. I didn't find it in my initial search because it Affects Version/s: None :-/, and I knew this behavior was new to 1.6. For those not up for the medium-length comment-thread read: non-Clojure-aware Java Collections Framework interface instances are not considered values,* and 'Rich says all bets should be off for hasheq/equiv of non-values.' That's a bit down in the details, but I think the upshot is that they're not currently supported as set members or hash keys. Unfortunately they used to be supported (unintentionally, I guess) due to Clojure following Java's lead, so I have some interop-heavy code to review and test very carefully. Though the above seems to frame non-support as based on principle, it seems the driver is keeping the new hasheq stuff highly performant. I would hope a performant implementation that supported the Collections interfaces would be accepted for some future version. *If there is one, I'd like to read a clear definition of what values means in Clojure. The headings on http://clojure.org/data_structures are almost an enumeration of them, except the Collections section talks a little about Java Collections classes, hashCode, and hasheq without making it clear that non-Clojure collections are not values. Unfortunately the current definition seems to admit only the Java primitives and near-primitives (String and primitive wrappers) and clojure-aware types. What not supported looks like via maps: user *clojure-version* {:major 1, :minor 6, :incremental 0, :qualifier nil} user (hash-map [1 2] v (java.util.ArrayList. [1 2]) a) {[1 2] a, [1 2] v} user {[1 2] v (java.util.ArrayList. [1 2]) a} IllegalArgumentException Duplicate key: [1 2] clojure.lang.PersistentArrayMap.createWithCheck (PersistentArrayMap.java:70) user (- {} (assoc [1 2] v) (assoc (java.util.ArrayList. [1 2]) a)) {[1 2] a} On Friday, May 9, 2014 6:34:26 PM UTC-5, Andy Fingerhut wrote: Mike is correct. This change in behavior is due to the hashing changes in Clojure 1.6. See the comments on ticket http://dev.clojure.org/jira/browse/CLJ-1372http://www.google.com/url?q=http%3A%2F%2Fdev.clojure.org%2Fjira%2Fbrowse%2FCLJ-1372sa=Dsntz=1usg=AFQjCNG6I-rrRfAMsUZUomYEbGOJkJqWGAfor some discussion of whether this is considered a bug. It appears that perhaps the hash consistency is not promised for mutable objects, only immutable ones. Below are a couple more REPL transcripts that illustrate the change in behavior: user=
Re: Expected inconsistency between set and map w/ ArrayList?
I'm the reporter of the mentioned ticket and I'm no longer inclined into fixing the hash. The real issue seems to lay in the fact that the = equality tries to work with host non-values. Whether the usefulness of such interoperability outweights the correctness of the =/hash is the issue which should be more discussed, with real examples. So for me, the option a) is not the way we should go, and I would like to add an option c), to introduce a strict variant of = operation alongside the current one, and use it in cases where the =/hash inconsistency causes real trouble. Jozef On Sunday, May 11, 2014 9:06:15 PM UTC+2, Mikera wrote: OK. this thread is a bit worrying. If I understand correctly, it means that we've now got inconsistent hash and equals functions. I suspect this hasn't bitten many people yet simply because it is unusual to mix Java and Clojure collections as keys in the same structure, but it seems like a really nasty issue. Hash and equality functions generally have a very simple rule: if two things are equal they must have the same hashcode. But now we've got: (= (java.util.ArrayList. [1 2]) [1 2]) = true (hash (java.util.ArrayList. [1 2])) = 994 (hash [1 2]) = 156247261 I consider this a major defect. If we want to define our own equals and hashcode that's fine, but then these functions absolutely should be consistent with each other. If it is really true that non-Clojure collections aren't considered as values and aren't expected to participate in hash/= comparisons then I'd expect an exception, not an erroneous value. Silent potential corruption of data is *much* worse than a noisy failure. But I think even that is a bad direction to go: easy Java ecosystem interop is definitely one of the main reasons why I'm using Clojure, and I'd like to see this maintained. I can think of only two sensible ways to fix this inconsistency: a) Roll back the hash changes. Correctness is much more important than a performance edge case. (I suspect the hash changes have hurt average case performance anyway...) b) Make (= (java.util.ArrayList. [1 2]) [1 2]) and similar comparisons evaluate to false (on the grounds that ArrayLists aren't Clojure collections, so should not be considered equal). On Saturday, 10 May 2014 15:51:24 UTC+1, John Hume wrote: Thanks for the ticket pointer. I didn't find it in my initial search because it Affects Version/s: None :-/, and I knew this behavior was new to 1.6. For those not up for the medium-length comment-thread read: non-Clojure-aware Java Collections Framework interface instances are not considered values,* and 'Rich says all bets should be off for hasheq/equiv of non-values.' That's a bit down in the details, but I think the upshot is that they're not currently supported as set members or hash keys. Unfortunately they used to be supported (unintentionally, I guess) due to Clojure following Java's lead, so I have some interop-heavy code to review and test very carefully. Though the above seems to frame non-support as based on principle, it seems the driver is keeping the new hasheq stuff highly performant. I would hope a performant implementation that supported the Collections interfaces would be accepted for some future version. *If there is one, I'd like to read a clear definition of what values means in Clojure. The headings on http://clojure.org/data_structures are almost an enumeration of them, except the Collections section talks a little about Java Collections classes, hashCode, and hasheq without making it clear that non-Clojure collections are not values. Unfortunately the current definition seems to admit only the Java primitives and near-primitives (String and primitive wrappers) and clojure-aware types. What not supported looks like via maps: user *clojure-version* {:major 1, :minor 6, :incremental 0, :qualifier nil} user (hash-map [1 2] v (java.util.ArrayList. [1 2]) a) {[1 2] a, [1 2] v} user {[1 2] v (java.util.ArrayList. [1 2]) a} IllegalArgumentException Duplicate key: [1 2] clojure.lang.PersistentArrayMap.createWithCheck (PersistentArrayMap.java:70) user (- {} (assoc [1 2] v) (assoc (java.util.ArrayList. [1 2]) a)) {[1 2] a} On Friday, May 9, 2014 6:34:26 PM UTC-5, Andy Fingerhut wrote: Mike is correct. This change in behavior is due to the hashing changes in Clojure 1.6. See the comments on ticket http://dev.clojure.org/jira/browse/CLJ-1372http://www.google.com/url?q=http%3A%2F%2Fdev.clojure.org%2Fjira%2Fbrowse%2FCLJ-1372sa=Dsntz=1usg=AFQjCNG6I-rrRfAMsUZUomYEbGOJkJqWGAfor some discussion of whether this is considered a bug. It appears that perhaps the hash consistency is not promised for mutable objects, only immutable ones. Below are a couple more REPL transcripts that illustrate the change in behavior: user= *clojure-version* {:major 1, :minor 5, :incremental 1, :qualifier nil} user= (= [1 2]
Re: Java API is copyright protected?
Andy, Yes, I'm aware of those other efforts. ClojureScript is attacking a different platform so it is clear that some things aren't going to work. Specifically for Clojure, is there a clear line between the non-Java language and the compatiblity at the Java API level? A lot of Clojure functionality assumes the Java libraries, which was one of Rich's stated motivations for his design on the JVM. Oracle's argument is that there are infinite ways of choosing to structure libraries. Choosing exactly their design is infringement since their choice is creative design, covered by patent and published, covered by copyright. They didn't copy libc's API, for instance. What I am suggesting is that if someone wanted to create a PRODUCT that supported existing Clojure code then there might a problem. Suppose the new product compiled Clojure code to run on parallel hardware. Clearly Java support would be required (existing code, after all). Oracle stepped on the open source community with MySQL despite the outcry. The articles are too numerous to cite. I suspect that they are beginning to monetize their Sun purchase by leveraging Java. Since the world uses Java, you can be certain that Oracle sees the potential. James Gosling, father of Java, weighed in on the fight http://www.cnet.com/news/java-creator-james-gosling-google-totally-slimed-sun Tim -- 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/d/optout.
Re: Rethinking Literate Programming
Emacs org-mode provides a markdown-like language, which can be organized into a foldable outline (e.g., chapters, sections, subsections, subsubsections). Syntax is provided for headers, ordered/unordered lists, tables, inline images/figures, hyperlinks, footnotes, and (most importantly for LP) code blocks. In order to avoid having to scroll up and down forever to see your code spread through the document, you simply use TAB to fold/unfold the outline sections your are currently interested in. Pressing C-c ' within any code block automatically switches to Emacs' major mode for that language, showing only the code in its own temporary buffer. When you want to see all of your code at once, just tangle the document to a *.clj file and look at it in another buffer. Using auto-refresh on the tangled buffer provides an easy way to keep checking code changes in this way with minimal effort. When you are ready to weave the document into a nicely readable format, org-mode provides output filters to auto-generate latex articles, html webpages, OpenDocument files, latex beamer presentations, and quite a few others as well. This is just meant to clarify some of the LP-related features of this platform. Obviously, some emacs lisp hacking can extend it to do whatever else people want. -- 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/d/optout.
Re: Expected inconsistency between set and map w/ ArrayList?
On Sun, May 11, 2014 at 2:06 PM, Mikera mike.r.anderson...@gmail.comwrote: OK. this thread is a bit worrying. If I understand correctly, it means that we've now got inconsistent hash and equals functions. I suspect this hasn't bitten many people yet simply because it is unusual to mix Java and Clojure collections as keys in the same structure, but it seems like a really nasty issue. Reports of real problems in real codebases would change my own opinion of the severity of this issue. Hash and equality functions generally have a very simple rule: if two things are equal they must have the same hashcode. But now we've got: (= (java.util.ArrayList. [1 2]) [1 2]) = true (hash (java.util.ArrayList. [1 2])) = 994 (hash [1 2]) = 156247261 I consider this a major defect. If we want to define our own equals and hashcode that's fine, but then these functions absolutely should be consistent with each other. If it is really true that non-Clojure collections aren't considered as values and aren't expected to participate in hash/= comparisons then I'd expect an exception, not an erroneous value. Silent potential corruption of data is *much* worse than a noisy failure. But I think even that is a bad direction to go: easy Java ecosystem interop is definitely one of the main reasons why I'm using Clojure, and I'd like to see this maintained. Please be more specific about where an exception could be thrown (equals vs hash vs collection usage). I can think of only two sensible ways to fix this inconsistency: a) Roll back the hash changes. Correctness is much more important than a performance edge case. We're not doing that. (I suspect the hash changes have hurt average case performance anyway...) We have made hash calculation slightly slower to generate better hashes across the board. Timing info is at http://dev.clojure.org/display/design/Better+hashing but in general, the time increases per hash are on the order of nanoseconds for simple values and sub-millisecond for more complicated strings and collections (where hashes are cached and times are likely to be dwarfed by other things). The better hashes avoid catastrophically bad (and relatively easy to find) cases. It is quite challenging to predict the performance impact of the hashing changes in Strings, keywords, and symbols due to the effects of usage patterns, interning, caching, etc. I am aware of several people that have reported better performance overall in 1.6 and I don't think I've heard any reports of significantly slower performance in 1.6. I'm calling FUD on this unless you have data to report. b) Make (= (java.util.ArrayList. [1 2]) [1 2]) and similar comparisons evaluate to false (on the grounds that ArrayLists aren't Clojure collections, so should not be considered equal). Equality comparison between Clojure and Java collections is something that seems relatively common. For example, calling a Java API that returns a List and comparing the returned value with a vector. I don't want to lose that ability. c) Fail on hasheq of Java collections Adding this check would decrease the performance of hasheq for many other types. Given what I know right now, I'm not inclined to make that tradeoff. d) Fail when conj'ing Java collections into Clojure map keys or sets. This would scope the check more but still add a performance hit for this case on all other types. Note that Clojure maps or sets of only Java collections currently work so this would take away functionality that might be useful even if in a gray area. On Saturday, 10 May 2014 15:51:24 UTC+1, John Hume wrote: Thanks for the ticket pointer. I didn't find it in my initial search because it Affects Version/s: None :-/, and I knew this behavior was new to 1.6. For those not up for the medium-length comment-thread read: non-Clojure-aware Java Collections Framework interface instances are not considered values,* and 'Rich says all bets should be off for hasheq/equiv of non-values.' That's a bit down in the details, but I think the upshot is that they're not currently supported as set members or hash keys. Unfortunately they used to be supported (unintentionally, I guess) due to Clojure following Java's lead, so I have some interop-heavy code to review and test very carefully. Though the above seems to frame non-support as based on principle, it seems the driver is keeping the new hasheq stuff highly performant. I would hope a performant implementation that supported the Collections interfaces would be accepted for some future version. *If there is one, I'd like to read a clear definition of what values means in Clojure. The headings on http://clojure.org/data_structures are almost an enumeration of them, except the Collections section talks a little about Java Collections classes, hashCode, and hasheq without making it clear that non-Clojure collections are not values. Unfortunately the current definition seems to admit
Re: Headless server, no GUI, no idea
I seem to have it working for now. I managed to make a sample program launch a OS X native dialog. I had to first create the xfvb service and chmod its permissions. Then I set the /etc/ennvironment/DISPLAY variable to my server IP address. With Tomcat started, I launched a repl, and opened LT to the same repl. It all worked, so problem solved! -- 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/d/optout.
Can somebody help trouble-shoot my core.async code?
I am getting my feet wet with core.async and am trying to attach atoms to channels that update automatically and print out to the console as you take and put. This is not for anything serious, just a way to get familiar with the behavior and functionality of the library and practice my Clojure skills. Thanks in advaan Here is my code: (defn log-name [ch] (symbol (str ch '-log))) (defmacro transparent-chan [ch] ;; This is probably not correct, but I wanna do something like this (do `(def ~ch (chan)) `(def (log-name ~ch) (atom [])) `(println new transparent channel created!))) (defn- update [log v] (do (swap! log conj v) (println log test passed: v has been logged) (println channel contents: @log))) (defn transparent-put [ch v] (let [log (log-name ch)] (update log v) (println put test passed: v has been put on the channel) (println rechecking log: @log) (go (let [ch ch v v] (! ch v) (println v has been successfully put/read from the channel!) (defn transparent-take [ch] (go (let [v (! ch) log-name (symbol (str ch '-log))] (swap! log-name #(remove #{v} %)) (println v has been removed from channel))) (println removal pending)) My main questions are regarding variable scope: 1) I feel like it is a redundant to define bindings multiple times in my go and let exprs for params that are already passed in as arguments. Is there a more idiomatic way to do this? 2) Whenever I try to create a generic process to automatically generate a log-name for each channel and then call update, I get a 'symbol cannot be cast to atom' error. How can I get around this? It seems to happen even if I don't use the log-name function. 3) Is this a useful thing to be doing: is there a way to query and keep track of what's on a channel without using a macro or atoms? -- 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/d/optout.
Re: Java API is copyright protected?
On Saturday, May 10, 2014 11:37:36 PM UTC-7, da...@axiom-developer.org wrote: At the risk of getting slightly off-topic here, here's a comment on Hacker News from a well-respected commenter on legal issues - he's a lawyer specialising in startup and technology law and his analysis is uniformly excellent. He argues that while the result may be unpalatable, it's by no means the stitch-up by technological ignoramuses that that article makes it sound: https://news.ycombinator.com/item?id=7722674 Judge Alsop conflated two distinct and non-overlapping areas of intellectual property law by claiming that a copyrightable work (the API) must rise to the level of warranting patent protection. While that's a novel idea, it is nowhere in the copyright law. (Oracle, by the way, also holds patents on Java). Where the new decision might have a direct impact on Clojure would be if someone were to create a stand-alone Clojure (or other products that enable a developer to use Java directly in their products) that was compatible with the JVM-hosted version. There would seem to be a need for API-compatible functions. Doubly so if you could excute jar files. The court could find that infringing, it seems. snip... Well, the jvm on my system is licensed by Oracle. I am licensed to feed byte code into it. My license does not exclude byte code generated by another's compiler. What Google didn't license was the mobile version of java, which is different from the jdk/jre I use. I use Oracle's java library (apis) and jars as per its license. I am not attempting to re-implement any part of the sun.* or java.* packages. The clojure people do not distribute Oracle's or any one's java compiler, jvm, or runtime. Everyone who uses clojure does so by having a licensed version of the jvm. There is a higher court which may reverse on appeal. Google has a chance in the original court by making an argument that this was fair use. Whatever the merits of a standalone clojure — and that would be a lot of work and many buggy years as the jvm and the java library is reimplemented with original apis (and isn't that what Oracle said was the thing that Google did that infringed?) — now is not the moment. I don't know if this is a straw man argument or not, but for those who want to punish Oracle by leaving them their ball and going home, I don't think they care. Besides many parts of java is GPLV2, so could they really just send a bill? Not an attorney, blah, blah, blah. -- 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/d/optout.
using atoms as logs for channels in core.async
Hi everyone, I am getting my feet wet with core.async and am trying to attach atoms to channels that update automatically and print out to the console as you take and put. This is not for anything serious, just a way to get familiar with the behavior and functionality of the library and practice my Clojure skills. Thanks in advaan Here is my code: (defn log-name [ch] (symbol (str ch '-log))) ;; Is this efficiently written? (defmacro transparent-chan [ch] (do `(def ~ch (chan)) `(def (log-name ~ch) (atom [])) `(println new transparent channel created!))) (defn- update [log v] (do (swap! log conj v) (println log test passed: v has been logged) (println channel contents: @log))) (defn transparent-put [ch v] (let [log (log-name ch)] (go (let [ch ch v v] (! ch v) (println v has been successfully moved through the channel))) (update log v) (println put test passed: v has been put on the channel) (println rechecking channel contents: @log))) (defn transparent-take [ch] (go (let [v (! ch) log-name (symbol (str ch '-log))] (swap! log-name #(remove #{v} %)) (println v has been removed from channel))) (println removal pending)) ;; tests (transparent-chan c) c c-log @c-log (transparent-put c 42) (transparent-take c) My main questions are regarding variable scope: 1) I feel like it is a redundant to define bindings multiple times in my go's let exprs when the params have already been passed in as arguments. Is there a more idiomatic way to do this? 2) Whenever I try to create a generic process to automatically generate a log-name for each channel and then call update, I get a 'symbol cannot be cast to atom' error. How can I get around this? It seems to happen even if I don't use the log-name function. 3) Is there a better way to keep track of what's on a channel that doesn't use macros? -- 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/d/optout.
http://clojure.org/ link to CLR links old git
Shouldn't the link be updated to https://github.com/clojure/clojure-clr? -- 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/d/optout.
Re: http://clojure.org/ link to CLR links old git
Fixed. On Sunday, May 11, 2014 9:50:54 PM UTC-5, JP Bader wrote: Shouldn't the link be updated to https://github.com/clojure/clojure-clr? -- 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/d/optout.
Re: using atoms as logs for channels in core.async
On 12 May 2014 03:41, gamma235 jesus.diama...@gmail.com wrote: (defn log-name [ch] (symbol (str ch '-log))) ;; Is this efficiently written? (defmacro transparent-chan [ch] (do `(def ~ch (chan)) `(def (log-name ~ch) (atom [])) `(println new transparent channel created!))) This looks like you're replicating the functionality of maps using defs. Instead, consider something like: (defn transparent-chan [ch] {:channel ch, :buffer (atom [])}) Another improvement you may wish to consider is to use a queue, rather than a vector. Immutable queues exist in Clojure, but are something of a hidden feature. (defn transparent-chan [ch] {:channel ch, :buffer (atom clojure.lang.PersistentQueue/EMPTY)}) Queues act more like channels, in that popping a queue strips off the oldest item, whereas popping a vector strips off the newest. With this in mind, you could write functions like: (defn transparent-put [{:keys [channel buffer]} x] (go (! channel x) (swap! buffer conj x))) (defn transparent-take [{:keys [channel buffer]} x] (go (let [x (! channel)] (swap! buffer pop) x))) (defn transparent-buffer [{keys [buffer]}] (vec @buffer)) - James -- 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/d/optout.
Re: using atoms as logs for channels in core.async
1) I feel like it is a redundant to define bindings multiple times in my go's let exprs when the params have already been passed in as arguments. Is there a more idiomatic way to do this? I think the fact that you are re-binding in a let should show you that these variables are already in scope: that let is wholly redundant, just remove it. 2) Whenever I try to create a generic process to automatically generate a log-name for each channel and then call update, I get a 'symbol cannot be cast to atom' error. How can I get around this? It seems to happen even if I don't use the log-name function. It's simple: a symbol is not an atom. It's telling you exactly what you need to know: you cannot call swap! on a symbol. Make sure your atom is the first argument to swap! wherever you use it. 3) Is there a better way to keep track of what's on a channel that doesn't use macros? You cannot look inside of a channel, but to do what you want and get a sense of how core.async works, I think you are on the right track by logging as you put stuff in and take it out. That said, I would start by getting rid of the log and the macro--these are unnecessary complications--and do things very simply: = (require '[clojure.core.async :as async]) nil = (def c (async/chan)) #'user/c = (def my-go-loop (async/go-loop [msg (async/! c)] (println got msg msg from channel 'c))) #'user/my-go-loop = (defn put-and-print! [c msg] (println putting msg msg onto channel 'c) (async/put! c msg)) #'user/put-and-print! = (put-and-print! c I am a message!) putting msg I am a message! onto channel c got msg I am a message! from channel c nil = Printing out channel c is kind of silly since there is only one, but it sounds like you may want to do this with multiple channels so this is one way to print out the variable name--simply quote it. DD (2014/05/12 11:41), gamma235 wrote: Hi everyone, I am getting my feet wet with core.async and am trying to attach atoms to channels that update automatically and print out to the console as you take and put. This is not for anything serious, just a way to get familiar with the behavior and functionality of the library and practice my Clojure skills. Thanks in advaan Here is my code: (defn log-name [ch] (symbol (str ch '-log))) ;; Is this efficiently written? (defmacro transparent-chan [ch] (do `(def ~ch (chan)) `(def (log-name ~ch) (atom [])) `(println new transparent channel created!))) (defn- update [log v] (do (swap! log conj v) (println log test passed: v has been logged) (println channel contents: @log))) (defn transparent-put [ch v] (let [log (log-name ch)] (go (let [ch ch v v] (! ch v) (println v has been successfully moved through the channel))) (update log v) (println put test passed: v has been put on the channel) (println rechecking channel contents: @log))) (defn transparent-take [ch] (go (let [v (! ch) log-name (symbol (str ch '-log))] (swap! log-name #(remove #{v} %)) (println v has been removed from channel))) (println removal pending)) ;; tests (transparent-chan c) c c-log @c-log (transparent-put c 42) (transparent-take c) My main questions are regarding variable scope: 1) I feel like it is a redundant to define bindings multiple times in my go's let exprs when the params have already been passed in as arguments. Is there a more idiomatic way to do this? 2) Whenever I try to create a generic process to automatically generate a log-name for each channel and then call update, I get a 'symbol cannot be cast to atom' error. How can I get around this? It seems to happen even if I don't use the log-name function. 3) Is there a better way to keep track of what's on a channel that doesn't use macros? -- 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 mailto:clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout. -- 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
Re: using atoms as logs for channels in core.async
I apologize, apparently you can't use go-loop how I did below, = (def my-go-loop (async/go-loop [msg (async/! c)] (println got msg msg from channel 'c))) ...try this instead: (def my-go-loop (async/go-loop [] (let [msg (async/! c)] (println got msg msg from channel 'c Sorry about that! DD (2014/05/12 13:21), Dave Della Costa wrote: 1) I feel like it is a redundant to define bindings multiple times in my go's let exprs when the params have already been passed in as arguments. Is there a more idiomatic way to do this? I think the fact that you are re-binding in a let should show you that these variables are already in scope: that let is wholly redundant, just remove it. 2) Whenever I try to create a generic process to automatically generate a log-name for each channel and then call update, I get a 'symbol cannot be cast to atom' error. How can I get around this? It seems to happen even if I don't use the log-name function. It's simple: a symbol is not an atom. It's telling you exactly what you need to know: you cannot call swap! on a symbol. Make sure your atom is the first argument to swap! wherever you use it. 3) Is there a better way to keep track of what's on a channel that doesn't use macros? You cannot look inside of a channel, but to do what you want and get a sense of how core.async works, I think you are on the right track by logging as you put stuff in and take it out. That said, I would start by getting rid of the log and the macro--these are unnecessary complications--and do things very simply: = (require '[clojure.core.async :as async]) nil = (def c (async/chan)) #'user/c = (def my-go-loop (async/go-loop [msg (async/! c)] (println got msg msg from channel 'c))) #'user/my-go-loop = (defn put-and-print! [c msg] (println putting msg msg onto channel 'c) (async/put! c msg)) #'user/put-and-print! = (put-and-print! c I am a message!) putting msg I am a message! onto channel c got msg I am a message! from channel c nil = Printing out channel c is kind of silly since there is only one, but it sounds like you may want to do this with multiple channels so this is one way to print out the variable name--simply quote it. DD (2014/05/12 11:41), gamma235 wrote: Hi everyone, I am getting my feet wet with core.async and am trying to attach atoms to channels that update automatically and print out to the console as you take and put. This is not for anything serious, just a way to get familiar with the behavior and functionality of the library and practice my Clojure skills. Thanks in advaan Here is my code: (defn log-name [ch] (symbol (str ch '-log))) ;; Is this efficiently written? (defmacro transparent-chan [ch] (do `(def ~ch (chan)) `(def (log-name ~ch) (atom [])) `(println new transparent channel created!))) (defn- update [log v] (do (swap! log conj v) (println log test passed: v has been logged) (println channel contents: @log))) (defn transparent-put [ch v] (let [log (log-name ch)] (go (let [ch ch v v] (! ch v) (println v has been successfully moved through the channel))) (update log v) (println put test passed: v has been put on the channel) (println rechecking channel contents: @log))) (defn transparent-take [ch] (go (let [v (! ch) log-name (symbol (str ch '-log))] (swap! log-name #(remove #{v} %)) (println v has been removed from channel))) (println removal pending)) ;; tests (transparent-chan c) c c-log @c-log (transparent-put c 42) (transparent-take c) My main questions are regarding variable scope: 1) I feel like it is a redundant to define bindings multiple times in my go's let exprs when the params have already been passed in as arguments. Is there a more idiomatic way to do this? 2) Whenever I try to create a generic process to automatically generate a log-name for each channel and then call update, I get a 'symbol cannot be cast to atom' error. How can I get around this? It seems to happen even if I don't use the log-name function. 3) Is there a better way to keep track of what's on a channel that doesn't use macros? -- 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
shutdown-agents without agents
I apologize if this is just useless noise. It's after midnight on Sunday, I need to get to bed, and I know I'll totally forget about this if I don't make the scenario public. This is on clojure 1.5.1. CentOS 6.5 (virtual guest running on a Citrix Xen Server host, probably also running CentOS), and 64-bit OpenJDK 1.7.0_55. I've spent most of this weekend trying to figure out why my `lein repl` client was exiting when I tried to run a command after tools.namespace/refresh. I'm using Stuart Sierra's Workflow Reloaded, so the actual interaction looked something like (apologies in advance...I'm typing this in manually rather than copy/pasting): user= (reset) ...blah... Success! user= anything SocketException: The transport's socket appears to have lost its connection to the nREPL server clojure.tools.nrepl.transport/bencode/fn--4287/fn--4288 (transport.clj:95) clojure.tools.nrepl.transpart/bencode/fn--4287 (transport.clj: 95) clojure.tools.nrepl.transpart/fn-transport/fn--4261 (transport.clj:42) clojure.core/binding-conveyor-fn/fn--4107 (core.clj:1836) java.util.concurrent.FutureTask.run (FutureTask.java:262) java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1145) java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:615) java.lang.Thread.run (Thread.java:744) Bye for now! And I think I might have just managed to get a fairly minimalist scenario (though it still may be tied into the details of the libraries I'm loading in project.clj, or some such). If I use lein to start a REPL at the command prompt and immediately call (shutdown-agents), I get this same unhandled exception after the next form I enter. I'm not sure where to go with this one, or even if I should. I guess I really should just start with an empty default project.clj and add in libraries (if needed) until I can reproduce the problem. Except that google makes it look like no one else has ever had the same problem. So that might be a complete and total waste of time. Does anyone have any opinions about whether this is worth pursuing? Thanks, James -- 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/d/optout.