Re: soft question: should remote channels appear like local channels
You do need to handle connection loss in some way, which is never a concern with purely local channels. The middle level needs to detect a broken connection (as distinct from a full buffer on put or an empty one on take) and signal it somehow (OOB value, exception, put to a control channel, or etc., possibly after one or more automatic attempts to reestablish the connection in a manner transparent to the rest of the system). On Fri, Jan 31, 2014 at 2:36 AM, s...@corfield.org wrote: My question would be Why not? If you have a client using core.async and a server using core.async and you have a library that feeds data from certain channels back and forth over websockets, then you have channels everywhere. So I'm not sure why you think your con is actually a thing? Sean Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org World Singles, LLC - http://worldsingles.com *From:* t x txrev...@gmail.com *Sent:* Thursday, January 30, 2014 9:43 PM *To:* clojure@googlegroups.com Hi, With apologies for a soft question: This question is NOT: I'm in a situation where client = cljs, server = clj, and I want to figure out how to setup a core.async channel, using pr-str and edn/read-string, where I can seamlessly push data back and forth between client and server. This question is: Should I do the above? The pro being: yay, channels everywhere, everything looks the same. The con being: a local core.async channel and a remote core.async channel over a websocket are _NOT_ the same thing, and thus should not appear to be the same thing. ## Responses: Although detailed responses are always appreciated, given the nature of this soft question, responses of go read _link_ are perfectly welcome too. I suspect someone in this world has thought deeply about the question, written up their insights, and pointing me at this primary resource (rather than trying to summarize it in a three paragraph email) is perfectly fine too. 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/groups/opt_out. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Request for help optimising a Clojure program
+1 On Thu, Jan 30, 2014 at 11:13 AM, Andy Fingerhut andy.finger...@gmail.comwrote: Thanks to the work and thought of Mark Engelberg, Alex Miller, Rich Hickey, myself, and likely several others who I should be naming here but am forgetting, the latest (not yet released) Clojure master version has an improved hash function that gives a much better variety of hash values, and thus much improved performance for hash-based collections like hash maps and hash sets, than previous versions of Clojure. For example, the N-queen program that Paul Butcher wrote and was asking about its performance at the beginning of this thread, improves from 6.7 minutes before these hash changes to 12.8 seconds after the changes, when run on the 6x6 board. For the 6x9 board, the improvement is from something over 8 hours that I didn't measure precisely because I didn't want to wait down to 12.8 minutes. A few more experimental results are given on the design wiki page [1]. [1] http://dev.clojure.org/display/design/Better+hashing Andy On Sat, Nov 2, 2013 at 9:44 AM, Andy Fingerhut andy.finger...@gmail.comwrote: A few minutes ago I finished copying, pasting, and doing a little reformatting on Mark Engelberg's document on the subject. http://dev.clojure.org/display/design/Better+hashing Andy On Fri, Nov 1, 2013 at 11:28 AM, Alex Miller a...@puredanger.com wrote: Has anyone created a design page on dev.clojure for this yet? On Thursday, October 31, 2013 9:19:23 AM UTC-5, Andy Fingerhut wrote: Just a follow up after a fair amount of thinking and experimentation has been done on this problem. Mark Engelberg has a very nice document describing the existing hash functions used by Clojure, examples with why they can cause collisions so often, and suggestions for changes to them to have fewer collisions in these cases. https://docs.google.com/document/d/ 10olJzjNHXn1Si1LsSvjNqF_X1O7OTPZLuv3Uo_duY5o/edit I have made modifications to a fork of the Clojure code base with his suggested hash modifications here, for experimentation purposes: https://github.com/jafingerhut/clojure I also have some modifications to Paul's N-queens Clojure program to print out additional statistics and try out different hash functions here: https://github.com/jafingerhut/chess-clojure Running Paul's N-queens problem with a 6x6 board without any changes to Clojure takes about 7 mins on one of my computers. With those changes to the hash functions it finishes in about 12 sec. I haven't let a 6x9 board run to completion without those hash changes, but it takes a long time :-) With those changes to the hash functions it finishes in about 11 minutes. The reason for the currently slow behavior is a combination of the current hash functions and the implementation of the PersistentHashSet data structure used to implement sets. A PersistentHashSet is, very roughly, a 32-way branching tree with the hash function of the elements used to decide which branch to take. When you hit a leaf in the tree, all elements with the same hash function value are put into an array that is scanned linearly whenever you want to check whether a value is already in the set. So the more hash collisions, the more it is like using an array to store and look up set elements in O(n) time. With the 6x9 board, there are 20,136,752 solutions. The way those solutions are represented in the program as sets of vectors, those 20 million values only have 17,936 different hash values. Thus the average length of those arrays of values in the tree leaves is 1,122 values. The longest of those arrays has 81,610 values in it, all with the same hash function. With Mark's proposed hash function changes, those 20,136,752 values hash to 20,089,488 different ints, for an average array length of 1 value, and a longest array length of 3 values. Big speedup. There is nothing unique about Mark's particular hash functions that achieves this. Other hash modifications can give similar improvements. The Clojure dev team is considering which changes would be good ones to make, in hopes of changing them once and not having to do it again. Andy On Tue, Oct 22, 2013 at 9:28 AM, Paul Butcher pa...@paulbutcher.comwrote: I've been playing around with a generalised version of the N-Queens problem that handles other chess pieces. I have a Scala implementation that uses an eager depth-first search. Given enough RAM (around 12G - it's very memory hungry!) it can solve a 6x9 board with 6 pieces in around 2.5 minutes on my MacBook Pro. I then created a Clojure version of the same algorithm with the intention of (eventually) using laziness to avoid the memory issue. However, the performance of the Clojure version is several orders of magnitude worse than the Scala version (I've left it running overnight on the problem that the Scala version solves in 2.5 minutes and it still hasn't completed). I'm struggling to
Clooj 0.4.0/REPL bug parsing comments that shouldn't be being parsed
user= (defn foo [] ; 2*a/b ) NumberFormatException Invalid number: 2*a clojure.lang.LispReader.readNumber (LispReader.java:258) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) #'mercator.core/foo RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) RuntimeException Unmatched delimiter: ) clojure.lang.Util.runtimeException (Util.java:219) user= This happens at the REPL in clooj 0.4.0 but not clooj 0.2.8. It also affects loading from a source window. Any semicolon comment containing a whitespace-delimited substring that starts with a digit and contains a forward slash seems to trigger it, even though it should not be trying to read anything on a line after ; with the LispReader at all. This might not be confined to clooj; it could be a problem with one or another version of clojure.core's REPL and/or lein repl and/or nrepl. It's easy to test by pasting the above dummy function definition into any REPL that has a paste capability, and short enough to just type at one that doesn't. I'm aware that there's a clooj 0.4.1; but it hangs on startup on my machine so I can't test on 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/groups/opt_out.
Re: How to place unicode characters in span tag in reagent (formerly known as cloact)
So, the source code for the web page says amp;#8634; then? It may be already being entity escaped. Try just [:span \U] with the appropriate code (maybe the same one, 8634) for and see if that works. On Mon, Jan 27, 2014 at 6:15 AM, Sunil S Nandihalli sunil.nandiha...@gmail.com wrote: Hi Everybody, Can somebody help me figure out as to how I can place a unicode character. What I have tried is [:span #8634;] with the correct header but it renders it as-is. Thanks, Sunil. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: equality
Seems to me that BigDecimal, being essentially a BigInteger numerator and a power-of-ten denominator, could have been accommodated in Category 1 given that Ratio could. On Mon, Jan 27, 2014 at 10:26 AM, Andy Fingerhut andy.finger...@gmail.comwrote: As Jim already mentioned, you can use == to compare numbers for equality, but you must be cautious with equality for floating point numbers, as the tiniest bit of roundoff error will cause = and == to be false for such comparisons. For =, there are effectively 3 'categories' of numeric values in Clojure, each of which can be = to each other within a category, but between categories values are never = to each other. Category 1. integer values (including Java Byte, Short, Integer, Long, BigInteger, and Clojure BigInt types) and ratio values (Clojure's Ratio type) Category 2. float and double values (Java Float and Double) Category 3. BigDecimal This is better than Java equals(), where Byte and Short are never equals() to each other, etc. Two numeric values must be the same Java class for equals() to be true. Why the 3 categories, you may wonder? I didn't design it myself, but my best guess is that in order to have a hash function (in this case Clojure's hash, implemented as a Java method called hasheq()) that is consistent with Clojure =, it is difficult to make such a hash function correct and fast if there were not these 3 separate categories. Andy On Mon, Jan 27, 2014 at 5:39 AM, Eric Le Goff eleg...@gmail.com wrote: Newbie question : user= (= 42 42) true user= (= 42 42.0) false I did not expect last result. I understand that underlying classes are not the same i.e user= (class 42) java.lang.Long user= (class 42.0) java.lang.Double but anyway I'am surprised Cheers -- Eric -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Looking for a reference binary parsing
On Mon, Jan 27, 2014 at 4:13 PM, danneu danrod...@gmail.com wrote: ztellman's Gloss is magic to me. - Here's an example of my first attempt to use Gloss to parse the Bitcoin protocol: https://gist.github.com/danneu/7397350 -- In 2-chan.clj, it demonstrates using ztellman's Aleph to send Bitcoin's verack handshake to a node and ask it for blocks. I assume we don't want to know what's in 4-chan.clj. ;) - Bitcoin protocol specs are described here: https://en.bitcoin.it/wiki/Protocol_specification - The hardest part of the protocol was https://en.bitcoin.it/wiki/Protocol_specification#Variable_length_integer, but Gloss makes it easy. - The latest version of my code is here ( https://github.com/danneu/chaingun/blob/master/src/chaingun/codec2.clj) but it became coupled to my Datomic entities, so it's perhaps more confusing. I wasn't able to find any easy to follow real-world examples back when I was checking it out, so hopefully that helps someone. The amount of time Gloss has saved me is dumbfounding. What's the Bitcoin code good for though? A Clojure-based miner will be stomped into the dust by the HW-accelerated mining machines that exist nowadays. Or is this for managing a wallet and making transactions? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: clojure.edn/read-string exceptions = nil
Shouldn't that be: (defn filter-printable [obj] (cond (or (symbol? obj) (number? obj) (string? obj) (keyword? obj)) obj (vector? obj) (apply vector (map filter-printable obj)) (seq? obj) (map filter-printable obj) (set? obj) (into #{} (map filter-printable obj)) (map? obj) (into {} (for [[k v] obj] [(filter-printable k) (filter-printable v)])) true [:un-readable (pr-str obj)])) ? On Sun, Jan 26, 2014 at 3:53 AM, t x txrev...@gmail.com wrote: I recently ran into this problem again. The solution I came up with is: (defn filter-printable [obj] (cond (or (symbol? obj) (number? obj) (string? obj) (keyword? obj)) obj (vector? obj) (apply vector (map filter-printable obj)) (seq? obj) (map filter-printable obj) (set? obj) (into #{} (map filter-printable obj)) (map? obj) (into {} (for [[k v] obj] [(filter-printable v) (filter-printable v)])) true [:un-readable (pr-str obj)])) ## example: (filter-printable {:k 20 :f 'abc :d '(+ 1 2 3 foo) :other (async/chan 10)}) Anyone have a better / more elegant solution? On Thu, Jan 16, 2014 at 10:17 AM, t x txrev...@gmail.com wrote: After looking at edn/read-string and realizing I would have to modify Java code, I have decided that modifying the sender in clojure land isn't so bad after all. On Thu, Jan 16, 2014 at 9:41 AM, Alex Miller a...@puredanger.com wrote: I think I would change the sender to elide whatever parts you don't want to send rather than mess with the receiver. On Thursday, January 16, 2014 2:11:02 AM UTC-6, t x wrote: Hi, Right now if I do (clojure.edn/read-string ...) on a string with a unreadable part, I get an exception. Instead, I would like to just get nil. For example: ## code (clojure.edn/read-string (pr-str {:tag :message :chan (async/chan 10)})) ## currently returns java.lang.RuntimeException: Unreadable form at clojure.lang.Util.runtimeException (Util.java:219) ## instead, I would like: {:tag :message :chan :nil} Is there a way to make this happen? 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/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: async/close! called when channel is gc-ed ?
(b) is easy if you're willing to drop down to Java, or use gen-class. You can define a finalize method. On the other hand, you might also want to look into WeakReference and ReferenceQueue, which can be used from Clojure with interop. You can discover when objects become eligible for GC with ReferenceQueue, if they are held by WeakReference (or SoftReference). So you could create a channel, a ReferenceQueue, a WeakReference on the channel set up to use that ReferenceQueue, and a map with mappings from WeakReference to some sort of identifiers, as well as mappings from identifiers to functions to call. When a reference shows up on the queue the mapping is used to look up the id and then the function and invoke it. The modified channel can directly call the same function when closed. The function can take the id as a parameter and use a map in the other direction, from id to WeakReference, to remove all of the mappings for a given id when called with that id, before doing whatever else it does. It won't have access to the channel object, at least not if that's been GC'd, but it wouldn't be able to do much with it anyway in the case where the channel was closed, save use the channel as a lookup key itself, and the id can serve that purpose. On Sun, Jan 26, 2014 at 4:42 AM, t x txrev...@gmail.com wrote: ## Context: I'm doing some communication across cljs/clj with core.async ## Problem: I want a certain function called whenever: (a) the first time the channel is closed (b) when the channel is gc-ed (if not previously closed) (a) is rather easy: I define my own channel, wrapped around ManyToManyChannel, and define my own https://github.com/clojure/core.async/blob/master/src/main/clojure/clojure/core/async/impl/protocols.clj#L22 (b) I have no idea how to do -- is there someway to register some function that gets called when a channel is gc-ed ? (perferably in both cljs + clj -- although, if it just works in cljs, it suffices) 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/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: core.async over websocket + cljs + clojure
What about a hybrid blocking/timeout approach? At the sending end of the network bridge you have the taker and at the receiving end the putter. The putter, when it sees an object on the wire, puts it on a local channel (blocking put with timeout). If it succeeds it sends an ack up the wire. If the timeout elapses it sends a heartbeat up the wire instead, then tries again. The taker, meanwhile, takes from a channel and sends the object on the wire, then waits for an ack or a heartbeat with a longer timeout. If neither arrives within this timeout, it uses another channel to signal the application that the network connection to the putter was lost. If a heartbeat arrives it waits again, with the clock restarted. If an ack arrives, it takes another object from a channel and sends it on the wire. This should cause backpressure to go over the network to the sending end and block the sender, but with the caveat that if the network connection is actually lost, the sender's business logic will discover that shortly, and can distinguish it from the receiver just being slow to process each item. In particular, it can listen for a network drop event on a control channel, and separately use a timeout when putting onto the taker channel to react if the receiver is too slow but still connected. On Sat, Jan 25, 2014 at 9:11 AM, Patrick Logan patrickdlo...@gmail.comwrote: In CSP you might have a limited size buffer, but then block on the next Put. That's not something you want to casually attempt over a distance. It seems you want an interface like Channels that deal in fully formed objects, but you don't want CSP blocking semantics. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure memory usage
You might want to use the G1 collector (JVM opt UseG1GC) if you're using Java 7 as I've heard that the G1 collector gives memory back to the OS more readily than the other options. On Sat, Jan 25, 2014 at 1:55 PM, Jarrod Swart jcsw...@gmail.com wrote: This was talked about here: https://groups.google.com/forum/#!searchin/clojure/user$3A$20g$20vim/clojure/XqPGnX5aSAI/PoLYaydgX3cJ TLDR: The JVM carves out its own chunk of memory from the OS. It then uses very advanced and finely tuned means to manage said memory. So even though the app isn't doing anything the JVM is still using its memory. Best to load up your app and profile it with VisualVM to see what is actually going on. On Saturday, January 25, 2014 12:44:28 PM UTC-5, Anurag Ramdasan wrote: I've been playing around with clojure for a while now but never actually made anything in it. Today I started looking around into pedestal and started following its tutorials. Once I kept the server running for a few hours I noticed that it took upto 500MB of my ram even though it wasn't really doing anything. Is pedestal usually this memory hungry? I know that usually things running on JVM have some amount of memory usage. Are all full-fledged apps written in Clojure usually memory intensive? If not, does clojure have a lightweight, less memory consuming web framework? Thanks, Anurag Ramdasan. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: semantics of ! on closed channels
That shouldn't affect anything until the next time I try to navigate, say to the next thread with unread messages. Something caused the browser to spontaneously start navigating on its own. I didn't click a link and get redirected to the signin page at that time. It went there all by itself without my hands even being on the keyboard or mouse. Web browsers are not supposed to have minds of their own and start browsing around by themselves. Now it is possible that the session had timed out while I was reading those messages, and a prank navigation-triggering thingy thus triggered the signin page instead of doing something else ... which, if anything, is worrying. If the session had not been timed out at the time the prank input was generated, could it have taken gmail actions on my behalf such as deleting messages or even sending mail impersonating me? As it is it cost me my read/unread information for this thread at the time, and I had to review the whole thing to find the messages it had marked read that I hadn't actually read. Rather rude. I'd like to know how to protect myself against any message display triggering any kind of auto-navigation by the browser, partly because it clearly can cause inconvenience (what if this thread had been one of the real long ones, with 50+ messages, and I'd lost my place in that?) and partly because of the risk of the auto-navigation command being the equivalent of a phantom click on delete or send or something. Even if the cause in this case was something that would have been harmless even without a timed-out session preventing it from doing anything but send me to the gmail login prompt, the next time might be something more malicious, and might happen without the session being timed out. On Fri, Jan 24, 2014 at 3:20 AM, John Szakmeister j...@szakmeister.netwrote: On Thu, Jan 23, 2014 at 9:17 PM, Cedric Greevey cgree...@gmail.com wrote: [meta, but about something apparently triggered by the message, from this thread, that I'm quoting] Why did reading this post cause gmail to go bonkers? I saw this thread had new articles since earlier today, brought it up, and read the previous message, then just after I'd scrolled down to this one, leaned back, and started reading it the browser just suddenly began spinning on its own and navigated by itself. Apparently about 10 seconds after I sat back *something* input a click on the little down-triangle in the upper right corner of the page and then clicked sign out because it went to the gmail login page. And a second or so before that the chat thingy at the left crashed as a popup there distracted me by appearing suddenly and saying something like Oops, problem connecting to chat. GMail's sessions time out periodically. I forget the interval (or if it's random... it seems to be at times), but when it does, it has similar behavior to what you've described. Chat goes a little wonky, and then you're brought to the sign in page some moments later. I think the behavior is slightly worse if you have two accounts in GMail (I have a regular GMail account and one that's in the Apps for Business). They sometimes interact badly, especially around starting and ending sessions. -John -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: clojure.core/reduce calls (f) if given a reducible coll and no init value
An interesting question this raises is if there is any sensible way to define (intersection). It would need to behave as an identity element for intersection, so would need to behave as a set (so, (set? (intersection)) = truthy) that contained everything (so, (contains? (intersection) foo) = foo no matter what foo is; (partial contains? (intersection)) = identity). The problem would be what to do with seq? Ideally an infinite seq that will produce any particular value after finite time would be produced, but there's no way to sensibly produce any particular value given the wide variety of constructor semantics, builders, factory methods, things not known to this particular runtime instance but that conceptually exist somewhere, etc.; of course, the seq return is a dummy of sorts anyway since you couldn't really use it sensibly to it might as well just return (range). Printing should likely be overridden to just print (intersection) rather than b0rk the REPL with a neverending stream of integers (or whatever). But then it also subtly violates another property of Clojure set objects: if (= a b), (not (identical? a b)), and (identical? (a-set a) a), then (identical? (a-set b) a) and thus (not (identical? (a-set b) b)). The latter is true under the hypothesis for every real set but would be false for (intersection). Perhaps this is why (intersection) is not supported at this time, even though (union) returns an empty set object, the identity element for the union operation. On Fri, Jan 24, 2014 at 3:34 PM, Jarrod Swart jcsw...@gmail.com wrote: Ah cool, thanks for posting your solution! On Friday, January 24, 2014 3:29:49 PM UTC-5, Tassilo Horn wrote: Jarrod Swart jcs...@gmail.com writes: The reason you can't get this to work is that r/map returns a reducible not a coll for reduce to operate on. Ah, indeed. I couldn't see the forest for the trees. I'm not sure of a solution because I'm not familiar with core.reducers. This works: (reduce set/intersection (r/foldcat (r/map set [[1 2] [3 1] [1 3]]))) Bye, Tassilo -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: clojure.core/reduce calls (f) if given a reducible coll and no init value
Intersection is associative and commutative: (intersection A B) = (intersection B A) and (intersection A (intersection B C)) = (intersection (intersection A B) C) = the elements common to all three sets. So it's actually perfectly well-founded for use with reducers, at least in principle, and intersecting A B C D can be parallelized sensibly by parallel intersecting A B and C D and then intersecting the two resulting sets. On Fri, Jan 24, 2014 at 6:43 PM, Jarrod Swart jcsw...@gmail.com wrote: If I understand you correctly I am in agreement. I don't think you could take this problem to clojure.core.reducers/reduce or fold because the problem is inherently sequential is it not? The reduction is basically (intersection (intersection (intersection A B) C) D). I was curious of this myself, how do I abstract out the order of the (reduce set/intersection ...). I couldn't think of one. Breaking this problem out into 'parallel' units of reduction isn't possible because the problem is dependent on order. Which reducers can't have, or so I think after what I have read today. On Friday, January 24, 2014 3:56:23 PM UTC-5, Cedric Greevey wrote: An interesting question this raises is if there is any sensible way to define (intersection). It would need to behave as an identity element for intersection, so would need to behave as a set (so, (set? (intersection)) = truthy) that contained everything (so, (contains? (intersection) foo) = foo no matter what foo is; (partial contains? (intersection)) = identity). The problem would be what to do with seq? Ideally an infinite seq that will produce any particular value after finite time would be produced, but there's no way to sensibly produce any particular value given the wide variety of constructor semantics, builders, factory methods, things not known to this particular runtime instance but that conceptually exist somewhere, etc.; of course, the seq return is a dummy of sorts anyway since you couldn't really use it sensibly to it might as well just return (range). Printing should likely be overridden to just print (intersection) rather than b0rk the REPL with a neverending stream of integers (or whatever). But then it also subtly violates another property of Clojure set objects: if (= a b), (not (identical? a b)), and (identical? (a-set a) a), then (identical? (a-set b) a) and thus (not (identical? (a-set b) b)). The latter is true under the hypothesis for every real set but would be false for (intersection). Perhaps this is why (intersection) is not supported at this time, even though (union) returns an empty set object, the identity element for the union operation. On Fri, Jan 24, 2014 at 3:34 PM, Jarrod Swart jcs...@gmail.com wrote: Ah cool, thanks for posting your solution! On Friday, January 24, 2014 3:29:49 PM UTC-5, Tassilo Horn wrote: Jarrod Swart jcs...@gmail.com writes: The reason you can't get this to work is that r/map returns a reducible not a coll for reduce to operate on. Ah, indeed. I couldn't see the forest for the trees. I'm not sure of a solution because I'm not familiar with core.reducers. This works: (reduce set/intersection (r/foldcat (r/map set [[1 2] [3 1] [1 3]]))) Bye, Tassilo -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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
Re: clojure.core/reduce calls (f) if given a reducible coll and no init value
No, the identity for intersection is a set that has everything, as (intersection A Everything) = A no matter what A is. On Fri, Jan 24, 2014 at 7:38 PM, Jarrod Swart jcsw...@gmail.com wrote: Good points. But the identity thing is still what gets me. What is the identity of an intersection? Like you said it can't be #{}. If you seed an intersection with #{} you get #{}, so you can't intersect from the empty set. The identity for an intersection is whatever the common element is, but how would you know that? On Friday, January 24, 2014 7:03:40 PM UTC-5, Cedric Greevey wrote: Intersection is associative and commutative: (intersection A B) = (intersection B A) and (intersection A (intersection B C)) = (intersection (intersection A B) C) = the elements common to all three sets. So it's actually perfectly well-founded for use with reducers, at least in principle, and intersecting A B C D can be parallelized sensibly by parallel intersecting A B and C D and then intersecting the two resulting sets. On Fri, Jan 24, 2014 at 6:43 PM, Jarrod Swart jcs...@gmail.com wrote: If I understand you correctly I am in agreement. I don't think you could take this problem to clojure.core.reducers/reduce or fold because the problem is inherently sequential is it not? The reduction is basically (intersection (intersection (intersection A B) C) D). I was curious of this myself, how do I abstract out the order of the (reduce set/intersection ...). I couldn't think of one. Breaking this problem out into 'parallel' units of reduction isn't possible because the problem is dependent on order. Which reducers can't have, or so I think after what I have read today. On Friday, January 24, 2014 3:56:23 PM UTC-5, Cedric Greevey wrote: An interesting question this raises is if there is any sensible way to define (intersection). It would need to behave as an identity element for intersection, so would need to behave as a set (so, (set? (intersection)) = truthy) that contained everything (so, (contains? (intersection) foo) = foo no matter what foo is; (partial contains? (intersection)) = identity). The problem would be what to do with seq? Ideally an infinite seq that will produce any particular value after finite time would be produced, but there's no way to sensibly produce any particular value given the wide variety of constructor semantics, builders, factory methods, things not known to this particular runtime instance but that conceptually exist somewhere, etc.; of course, the seq return is a dummy of sorts anyway since you couldn't really use it sensibly to it might as well just return (range). Printing should likely be overridden to just print (intersection) rather than b0rk the REPL with a neverending stream of integers (or whatever). But then it also subtly violates another property of Clojure set objects: if (= a b), (not (identical? a b)), and (identical? (a-set a) a), then (identical? (a-set b) a) and thus (not (identical? (a-set b) b)). The latter is true under the hypothesis for every real set but would be false for (intersection). Perhaps this is why (intersection) is not supported at this time, even though (union) returns an empty set object, the identity element for the union operation. On Fri, Jan 24, 2014 at 3:34 PM, Jarrod Swart jcs...@gmail.comwrote: Ah cool, thanks for posting your solution! On Friday, January 24, 2014 3:29:49 PM UTC-5, Tassilo Horn wrote: Jarrod Swart jcs...@gmail.com writes: The reason you can't get this to work is that r/map returns a reducible not a coll for reduce to operate on. Ah, indeed. I couldn't see the forest for the trees. I'm not sure of a solution because I'm not familiar with core.reducers. This works: (reduce set/intersection (r/foldcat (r/map set [[1 2] [3 1] [1 3]]))) Bye, Tassilo -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+u...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clo...@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+u...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en
Re: semantics of ! on closed channels
[meta, but about something apparently triggered by the message, from this thread, that I'm quoting] Why did reading this post cause gmail to go bonkers? I saw this thread had new articles since earlier today, brought it up, and read the previous message, then just after I'd scrolled down to this one, leaned back, and started reading it the browser just suddenly began spinning on its own and navigated by itself. Apparently about 10 seconds after I sat back *something* input a click on the little down-triangle in the upper right corner of the page and then clicked sign out because it went to the gmail login page. And a second or so before that the chat thingy at the left crashed as a popup there distracted me by appearing suddenly and saying something like Oops, problem connecting to chat. I don't like having my stuff suddenly go spinning out of control like that. I wasn't touching the keyboard or the mouse at the time. The browser should not have done anything but sit there patiently displaying this page until *I* *CHOSE* to navigate away from it. If there is something in your message that hijacks the browsers of people reading it, then I would like you to know that I consider such a thing to be extremely poor etiquette and in extremely poor taste. Do not do it again. If it was not that particular message then I'd like to know what *did* reach into *MY* computer and start issuing instructions on *MY* behalf *without* *MY* permission, and how to stop that from ever happening again. This is *MY* copy of Firefox and it goes where *I* say it does, when *I* say it does it, and not a moment sooner. Is that absofrickinglutely clear? That is non-negotiable. Anyone who willfully violates this edict *will* be added to my spam filter and I will not see any future post by that author. Is *that* clear? On Thu, Jan 23, 2014 at 7:21 AM, t x txrev...@gmail.com wrote: Hi, * This is the time I've heard the one who's feeding the channel is the one in charge of closing it -- previously, my channel code was fairly ad-hoc and agressive (since I need to kill many (go-loop [msg (! ... )] (when msg ...)) blocks). * I still feel this breaks the conveyor belt metaphor -- when a conveyor belt shuts down, it's understandable that we after we take what's on the belt, in future takes, we get nothing. However, when putting items on a stopped conveyor belt, messages should not just *poof* vanish into the void. :-) * This existing semantics makes debugging annoying (perhaps this is due to my lack of skill). When something should be happening, and nothing is happening, I'm basically going around hunting for where did I do a put on a closed channel, whereas if it threw an exception of some form, it'd be easier to handle then this silent fail. On Thu, Jan 23, 2014 at 3:50 AM, Meikel Brandmeyer (kotarak) m...@kotka.dewrote: Hi, probably the idea is, that the one who's feeding the channel is the one in charge of closing it. After all, they know when there is no more input available. Do you have a use case where this problem manifests? Or is that just a vague fear that it might happen? Kind regards Meikel -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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
Re: semantics of ! on closed channels
Which part didn't you understand? When I scrolled down to t x's message, after a short delay *something* wrested control of Firefox away from me and issued a sequence of navigation commands the effect of which was to log me out of gmail, much as if I'd clicked the little down arrow by my username and then clicked signout. I don't know if it was something in t x's message that triggered it (if so, it didn't have the same effect when I viewed it again after logging back in), but I do know that I do not appreciate having my computer hijacked. I'm sure you can understand how it's rather alarming to have your stuff just suddenly start acting on its own initiative, right in front of your eyes, when the damned thing isn't supposed to *have* its own initiative. In any event, if anyone can shed any light on this incident I'd appreciate information. (For example: does an expert on browser security see anything in t x's post, or any other in this thread, that could have triggered anything unusual in susceptible versions of Firefox? Should I wipe and reinstall this machine on the presumption that the seemingly superficial hijack left it infected with a nasty rootkit of some sort, or was it just a prank, or even a known software bug somewhere?) On Thu, Jan 23, 2014 at 9:20 PM, Timothy Baldridge tbaldri...@gmail.comwrote: Umwat? On Jan 23, 2014 7:17 PM, Cedric Greevey cgree...@gmail.com wrote: [meta, but about something apparently triggered by the message, from this thread, that I'm quoting] Why did reading this post cause gmail to go bonkers? I saw this thread had new articles since earlier today, brought it up, and read the previous message, then just after I'd scrolled down to this one, leaned back, and started reading it the browser just suddenly began spinning on its own and navigated by itself. Apparently about 10 seconds after I sat back *something* input a click on the little down-triangle in the upper right corner of the page and then clicked sign out because it went to the gmail login page. And a second or so before that the chat thingy at the left crashed as a popup there distracted me by appearing suddenly and saying something like Oops, problem connecting to chat. I don't like having my stuff suddenly go spinning out of control like that. I wasn't touching the keyboard or the mouse at the time. The browser should not have done anything but sit there patiently displaying this page until *I* *CHOSE* to navigate away from it. If there is something in your message that hijacks the browsers of people reading it, then I would like you to know that I consider such a thing to be extremely poor etiquette and in extremely poor taste. Do not do it again. If it was not that particular message then I'd like to know what *did* reach into *MY* computer and start issuing instructions on *MY* behalf *without* *MY* permission, and how to stop that from ever happening again. This is *MY* copy of Firefox and it goes where *I* say it does, when *I* say it does it, and not a moment sooner. Is that absofrickinglutely clear? That is non-negotiable. Anyone who willfully violates this edict *will* be added to my spam filter and I will not see any future post by that author. Is *that* clear? On Thu, Jan 23, 2014 at 7:21 AM, t x txrev...@gmail.com wrote: Hi, * This is the time I've heard the one who's feeding the channel is the one in charge of closing it -- previously, my channel code was fairly ad-hoc and agressive (since I need to kill many (go-loop [msg (! ... )] (when msg ...)) blocks). * I still feel this breaks the conveyor belt metaphor -- when a conveyor belt shuts down, it's understandable that we after we take what's on the belt, in future takes, we get nothing. However, when putting items on a stopped conveyor belt, messages should not just *poof* vanish into the void. :-) * This existing semantics makes debugging annoying (perhaps this is due to my lack of skill). When something should be happening, and nothing is happening, I'm basically going around hunting for where did I do a put on a closed channel, whereas if it threw an exception of some form, it'd be easier to handle then this silent fail. On Thu, Jan 23, 2014 at 3:50 AM, Meikel Brandmeyer (kotarak) m...@kotka.de wrote: Hi, probably the idea is, that the one who's feeding the channel is the one in charge of closing it. After all, they know when there is no more input available. Do you have a use case where this problem manifests? Or is that just a vague fear that it might happen? Kind regards Meikel -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group
Re: semantics of ! on closed channels
I didn't say a virus. I pointed out that it appeared to be triggered by viewing a particular message in this thread. It may be that there's some gimmick text you can embed in a mail that screws up gmail -- there's certainly precedent, anyone on a dialup connection will get their line dropped when they load this message because it contains +++ATH0. In any case, what the incident most resembled to me was a prank of a similar sort to that old classic from the BBS days and any of numerous commonplace college dorm pranks; in which case the place to address it is right here where the person who perpetrated the inappropriate prank can explain that that's what it was (if that *is* what it was) and apologize, and/or the group's moderators can take any appropriate action against the perpetrator. (I'd be happy with their receiving a warning, *if* this was a first offense.) On Thu, Jan 23, 2014 at 9:49 PM, Timothy Baldridge tbaldri...@gmail.comwrote: Which part didn't you understand? The part where you think that this is the appropriate channel for discussing general IT problems you are having with your computer I don't know if it was something in t x's message that triggered it Well you accused him of that pretty much right off the bat... In any event, if anyone can shed any light on this incident I'd appreciate information. Sure, it can be a number of things. a) a bug in your mouse driver. b) a failing mouse battery. c) dirt on/in the mouse d) a bug in your browser e) a virus on your computer. f) a bug in gmail. All of these are much, much more likely than what you originally suggested. The idea that someone posting to a google group can get a virus through a text email, and that that virus somehow affected your browser, is just laughable. Timothy On Thu, Jan 23, 2014 at 7:34 PM, Cedric Greevey cgree...@gmail.comwrote: Which part didn't you understand? When I scrolled down to t x's message, after a short delay *something* wrested control of Firefox away from me and issued a sequence of navigation commands the effect of which was to log me out of gmail, much as if I'd clicked the little down arrow by my username and then clicked signout. I don't know if it was something in t x's message that triggered it (if so, it didn't have the same effect when I viewed it again after logging back in), but I do know that I do not appreciate having my computer hijacked. I'm sure you can understand how it's rather alarming to have your stuff just suddenly start acting on its own initiative, right in front of your eyes, when the damned thing isn't supposed to *have* its own initiative. In any event, if anyone can shed any light on this incident I'd appreciate information. (For example: does an expert on browser security see anything in t x's post, or any other in this thread, that could have triggered anything unusual in susceptible versions of Firefox? Should I wipe and reinstall this machine on the presumption that the seemingly superficial hijack left it infected with a nasty rootkit of some sort, or was it just a prank, or even a known software bug somewhere?) On Thu, Jan 23, 2014 at 9:20 PM, Timothy Baldridge tbaldri...@gmail.comwrote: Umwat? On Jan 23, 2014 7:17 PM, Cedric Greevey cgree...@gmail.com wrote: [meta, but about something apparently triggered by the message, from this thread, that I'm quoting] Why did reading this post cause gmail to go bonkers? I saw this thread had new articles since earlier today, brought it up, and read the previous message, then just after I'd scrolled down to this one, leaned back, and started reading it the browser just suddenly began spinning on its own and navigated by itself. Apparently about 10 seconds after I sat back *something* input a click on the little down-triangle in the upper right corner of the page and then clicked sign out because it went to the gmail login page. And a second or so before that the chat thingy at the left crashed as a popup there distracted me by appearing suddenly and saying something like Oops, problem connecting to chat. I don't like having my stuff suddenly go spinning out of control like that. I wasn't touching the keyboard or the mouse at the time. The browser should not have done anything but sit there patiently displaying this page until *I* *CHOSE* to navigate away from it. If there is something in your message that hijacks the browsers of people reading it, then I would like you to know that I consider such a thing to be extremely poor etiquette and in extremely poor taste. Do not do it again. If it was not that particular message then I'd like to know what *did* reach into *MY* computer and start issuing instructions on *MY* behalf *without* *MY* permission, and how to stop that from ever happening again. This is *MY* copy of Firefox and it goes where *I* say it does, when *I* say it does it, and not a moment sooner. Is that absofrickinglutely clear
Re: core.async question - canceling thread
It's not safe if the thread is holding any locks. It *may* also leak native resources if the thread is holding those, but native resources held by a heap-allocated Java object are supposed to be cleaned up by the finalizer if the object is GC'd, and I think Thread.stop properly removes that thread's locals as root set objects for GC, so native leaking would only happen if the thread held native resources directly in locals, which would only happen if it was executing a native method at the time of the stop. I don't know if the JVM/JNI has a safeguard against native leaks from threads being aborted while in native code, but I'd be mildly surprised if it did. Clojure threads will potentially be holding locks if they are using locking, dosync, swap!, or pretty much any of the concurrency primitives in Clojure. That *might* include Var lookups; I'm not sure (*dynamic* var lookups involve ThreadLocal, which might use locks under the hood). Many Java objects use locks somewhere under the hood as well -- certainly everything in j.u.concurrent is suspect in that regard (and therefore, swap! and many other Clojure concurrency primitives). I'd be very leery of playing around with Thread.stop in any circumstance more complicated than the thread's .run method is doing a pure math loop or something similar. If it touches Java libraries (outside of java.lang.String, java.math, and other value types) or uses Clojure primitives (and how is it supposed to join its results back into the bigger picture without them?) then it's dangerous. If it is a tight loop of math stuff then you can check for the interrupted flag. My recommendation? Stay far, far away from Thread.stop (and .suspend) and sprinkle Thread.sleep(1)s here and there in the math (maybe every certain number of iterations -- a millisecond is still a LONG time compared to primitive arithmetic ops). That should cause the thread to die with an InterruptedException if .interrupt is called on it. If the thread does any blocking I/O (or blocking core.async/j.u.concurrent stuff) with any frequency it should also go tits up pretty quickly if .interrupted. On Wed, Jan 22, 2014 at 4:31 PM, Mark Engelberg mark.engelb...@gmail.comwrote: So I guess this gets back to my earlier question: when is it safe to terminate a thread? I know that I often hit Ctrl-C in the REPL to terminate a long running function, and I've never really worried about it screwing things up. On Wed, Jan 22, 2014 at 1:29 PM, Shantanu Kumar kumar.shant...@gmail.comwrote: On Thursday, 23 January 2014 02:37:43 UTC+5:30, puzzler wrote: Is there a convenient way within Clojure to launch a Clojure function or Java call in a separate process as opposed to a separate thread? Only way I know of is to literally shell out to the command prompt and launch a new executable. There's ProcessBuilder and Runtime.exec stuff, but it will have the JVM and Clojure initialization overhead anyway. http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html http://www.tutorialspoint.com/java/lang/runtime_exec_envp.htm Shantanu -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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
Re: avoiding repetition in ns declarations
Maybe there should be a way to export stuff for transitive inclusion: (ns common-includes (:require [foo.core :refer [fooify] :export true]) ...) ... (ns my-ns (:require [common-includes :as c])) (defn bar [x] (c/fooify x 42)) On Wed, Jan 22, 2014 at 4:22 PM, Stuart Sierra m...@stuartsierra.comwrote: On Wed, Jan 22, 2014 at 3:19 PM, t x txrev...@gmail.com wrote: (defn load-standard-requires [] (require ... ) (require ... )) ... Can either of you confirm this is the main plan of attack you have suggested? I don't actually *recommend* doing this. But it will work. My recommendation is to just repeat the :require directives in every namespace that needs them, or refactor your code to use fewer namespaces. -S -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Eastwood lint tools - some Qs
IMO, :eastwood-arglist (and a proliferation of other tool-specific metadata) would be exactly the wrong approach; :arglists should be the real defn-form arglists. Instead there should be an optional :pretty-arglists for documentation generators to use in lieu of :arglists if it is present. That would address the documentation need while being tool-agnostic and not prone to grow like kudzu until sometime before 2020 we wind up usually writing defn forms like (defn ^{:foo-arglists [a b xyz] :special-tooly-stuff-count 42 :another-thingy-base /etc/data :another-thingy-defs /etc/data/.defs-file :miscellaneous-stuff-v1.1 :pure-function :miscellaneous-stuff-v2.0 #{:pure-function :noprims} :superduperoptionizer4 #{[a? b] [a? b jump? speed] [a? b jump? speed direction]} bar docstring ([thingys] ...)) On Tue, Jan 14, 2014 at 12:56 AM, Andy Fingerhut andy.finger...@gmail.comwrote: Nicola can answer more authoritatively, as I haven't checked that part of tools.analyzer recently, but I am pretty sure that the :arglists with things like doc-string? attr-map? are simply treated as if they were normal positional arguments, with no 'guessing' that they are optional due their symbols ending with a question mark. A function with :arglists ([x xs]) is checked that it takes 1 or more args, so only warning if a call is made with 0 args. That is why the current release of Eastwood will give incorrect :wrong-arity warning messages if one manually sets :arglists for a function to something other than what defn would make it. For macros, they are all expanded during Eastwood analysis, so any incorrect number of arguments should cause an exception to be thrown during analysis, much like it would if you attempted to compile such code. Andy On Mon, Jan 13, 2014 at 6:57 PM, Colin Fleming colin.mailingl...@gmail.com wrote: This is an interesting discussion, I've been thinking about some of these problems as I move towards adding inspections in Cursive. arglist parsing is a real problem in Clojure. I'd like to be able to flag invocations of functions with bad arities in the editor, but it's very difficult. Even defn is complicated, given that its :arglists is: :arglists '([name doc-string? attr-map? [params*] prepost-map? body] [name doc-string? attr-map? ([params*] prepost-map? body)+ attr-map?]) and its actual args declaration is: [form env name fdecl] There's really no way to parse either of them automatically well. Does Eastwood use the actual fn declaration or :arglists for linting? What would it do in the case above? It's impossible to tell if doc-string? is a boolean or if it's an optional arg. Oh, and I agree that invalid :arglists as documentation is probably a bad idea, since it'll inevitably make this sort of tooling more difficult than it already is. On 14 January 2014 14:03, Sean Corfield s...@corfield.org wrote: On Jan 13, 2014, at 3:09 PM, Nicola Mometto brobro...@gmail.com wrote: To be honest I don't like the idea of libraries attaching not-valid :arglists meta to Vars at all since the doc[1] for `def` says that :arglists will be a list of vector(s) of argument forms, as were supplied to defn and the clojure Compiler uses :arglists for type-hints handling. I agree with you in principle - and I'm happy to change java.jdbc to avoid the issue. Could Eastwood (or j.t.a) flag invalid :arglists? The example ones in both java.jdbc and congomongo are clearly invalid according the special forms page (but they silently work). Perhaps if Eastwood finds invalid / suspicious metadata in :arglists, it could use a different linter warning? Sean Corfield -- (904) 302-SEAN An Architect's View -- http://corfield.org/ Perfection is the enemy of the good. -- Gustave Flaubert, French realist novelist (1821-1880) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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
Re: How can I improve this?
On Fri, Jan 10, 2014 at 10:22 AM, Laurent PETIT laurent.pe...@gmail.comwrote: Hi, Use frequencies to get a map of path = nb of occurrences, then for each entry of the map, create unique names. Cannot provide an impl on the uPhine, sorry uPhine? :) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Counterclockwise 0.21.0
You might like to know that PeerBlock (and therefore probably other privacy software, especially any using iblocklist.com's Level 1 bad-actor list) is false positiving on ccw-ide.org, misidentifying it as something called OVH Somethingorother. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Counterclockwise 0.21.0
That's weird. Some kind of hijack? It looks normal from here (when I disable PeerBlock), including just a few minutes ago. Maybe your DNS has been poisoned. On Thu, Jan 9, 2014 at 2:55 PM, Dima Sabanin sdmi...@gmail.com wrote: When I visit http://ccw-ide.org/ I see this page: http://cl.ly/image/280j3J2Q1X2m Thought for a while that domain has expired. On Thu, Jan 9, 2014 at 2:51 PM, Cedric Greevey cgree...@gmail.com wrote: You might like to know that PeerBlock (and therefore probably other privacy software, especially any using iblocklist.com's Level 1 bad-actor list) is false positiving on ccw-ide.org, misidentifying it as something called OVH Somethingorother. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Best regards, Dima Sabanin http://twitter.com/dimasabanin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Counterclockwise 0.21.0
And the iblocklist false positive? (I assume ccw-ide.org is not *actually* spying for the government, MPAA, RIAA, or any of them internet-freedom-haters?) On Thu, Jan 9, 2014 at 3:34 PM, Laurent PETIT laurent.pe...@gmail.comwrote: OK, I did a quick dirty html redirect so that people don't see the ugly page again, thanks for the report 2014/1/9 Dima Sabanin sdmi...@gmail.com Redirect would indeed be helpful, as it was quite confusing when I was trying to help someone get up and running and we were looking in all the wrong places to download standalone CCW install. Btw, thanks for the great work Laurent! On Thu, Jan 9, 2014 at 3:07 PM, Laurent PETIT laurent.pe...@gmail.comwrote: There's nothing currently at the root. This is my bad, but expected atm. Only doc.ccw-ide.org , standalone.ccw-ide.org and updatesite.ccw-ide.orgare valid. Maybe I should at least point ccw-ide.org to doc.ccw-ide.org for the moment ... 2014/1/9 Dima Sabanin sdmi...@gmail.com It's weird indeed. My DNS is Google's 8.8.8.8 $ host ccw-ide.org ccw-ide.org has address 213.186.33.3 $ host doc.ccw-ide.org doc.ccw-ide.org has address 213.186.33.3 doc.ccw-ide.org work properly for me while ccw-ide.org doesn't. It doesn't seem like a hijack either because the site apparently is indeed hosted on OVH.com (which is a hosting provider). On Thu, Jan 9, 2014 at 3:00 PM, Cedric Greevey cgree...@gmail.comwrote: That's weird. Some kind of hijack? It looks normal from here (when I disable PeerBlock), including just a few minutes ago. Maybe your DNS has been poisoned. On Thu, Jan 9, 2014 at 2:55 PM, Dima Sabanin sdmi...@gmail.comwrote: When I visit http://ccw-ide.org/ I see this page: http://cl.ly/image/280j3J2Q1X2m Thought for a while that domain has expired. On Thu, Jan 9, 2014 at 2:51 PM, Cedric Greevey cgree...@gmail.comwrote: You might like to know that PeerBlock (and therefore probably other privacy software, especially any using iblocklist.com's Level 1 bad-actor list) is false positiving on ccw-ide.org, misidentifying it as something called OVH Somethingorother. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Best regards, Dima Sabanin http://twitter.com/dimasabanin -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- Best regards, Dima Sabanin http://twitter.com/dimasabanin -- -- 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
Re: [ANN] Counterclockwise 0.21.0
On Thu, Jan 9, 2014 at 4:01 PM, Laurent PETIT laurent.pe...@gmail.comwrote: ccw-ide.org is hosted by OVH France. Of what significance is that? Unless you mean to say that they abuse their customers by sometimes using the machine hosting a customer's site to generate nefarious network activity, which then gets blamed on said customer? If they do things like that then you should find a different provider. If they do abuse customers' trust by taking their own actions in the customers' names, then for all you know next they'll generate a load of spam and you'll land in the SORBS blacklist too, and it'll start swallowing the messages from CCW's developer listserv, or something else like that. Also, CCW's reputation would get tarnished if the CCW site webserver is doing anything questionable, even if it's the hosting provider that's making it do so. But I find all of that highly unlikely, because no hosting provider would keep its customers for very long if it did things like that in their names. And without website customers, the nefarious activity would no longer have any cover and would become unprofitable too. So it's pretty much gotta be a false positive, if neither you nor the hosting company, the two entities with access to the CCW site's server, are using it for anything other than the CCW site itself, which is innocuous. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Possible heisenbug in test suite (not in individual test runs) with memoization
It's possibly an interaction between memoization and dynamic vars; more specifically, a result might be being memoized with one with-precision context active, and then recalled with a different one active, with arguments that compare equal despite the different precisions (say, because those arguments that are BigDecimals are exactly representable at the lower of the two precisions). If the result is *not* the same at the higher precision, that could cause an expected-equal check to fail in your test. I'd also wonder at possibly having a test work if it used a memoized result generated earlier with a finite precision in effect, and fail with ArithmeticException without the memoization if the test doesn't set a precision limit itself and the result's not exactly representable at any finite precision (e.g. 1/7); but this would likely result in a test that worked in the suite and failed in isolation, instead of the reverse. However, if high memory use is causing a memoized value computed at limited precision to be forgotten and then recalculated with no precision limit, that might trigger failures in the suite of tests that worked in isolation. In any event, subtle interaction of with-precision's underlying dynamic var *math-context* with memoization is an obvious suspect worth investigating, even if it might ultimately be acquitted by the jury. :) On Mon, Jan 6, 2014 at 1:21 PM, Justin Kramer jkkra...@gmail.com wrote: Shot in the dark: check that arguments passed to your memoized functions use consistent typing. A BigDecimal such as 1M does not necessarily equal 1 (a Long): (= 1 1M) false (== 1 1M) true Your memoized functions could be recomputing values unnecessarily if you're giving them different types of numbers. Justin On Monday, January 6, 2014 12:57:49 PM UTC-5, David James wrote: I've got a Clojure test suite that fails when run as whole but passes when run piecemeal. This just started happening. I've tested the code thoroughly. The bug pops up in a part of the code that I did not change. So, at present, it feels like a heisenbug! These may be some relevant pieces: * I'm using memoization; the failures happen in memoized functions. * I'm doing a lot of various precision BigDecimal math. Some tentative guesses: * Somehow one test is affecting another test Questions (there are speculative): * What are some possible ways that memoization might fail (e.g. return an incorrect value)? * Is it possible that higher memory usage could cause memoization results to get lost? Unfortunately, it is a sizable code base, and I don't have a small, reproducible example. Any suggestions? -David -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Cute Clojure tricks
How many states can the US have and keep a flag with a reasonably close to square arrangement of stars like it currently has? (take-while #(= % 100) (sort (distinct (for [m (range 3 20) n (range (int (* m 3/4)) (inc m))] (- (* 2 m n) m n -1) (8 13 18 23 25 32 39 41 50 59 61 72 83 85 94 98) The next close-to-squarish possibility is 59 states. The stars would be a 7x5 grid with a superposed 6x4 grid, versus the present 6x5 and 5x4. But just two states after that it could be exactly square, with 6x6 and 5x5 arrays. :) Also: the flag would have to change if the US annexed either of its large neighbors. Canada has 13 internal divisions which would become new states, but 63 is not a solution. Mexico's 31 internal states would give the US 81 in total, but that is not a solution either. Both miss solutions by 2, but in opposite directions. Mexico, plus graduating Puerto Rico and the U.S. Virgin Islands to full statehood, would give 83, allowing a flag with 8x6 and 7x5 arrays of stars. (Of course, the GOP would never stand for anything like this that would make such a large fraction of US voters Latino.) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Sorting Nested Vectors and filter out some
You might wish to consider a different data structure. For example, the inner objects might be better off as maps with named keys, so your lookup keys would be things like :amount rather than 5. And instead of out of band values like the string N/A you'd just omit a mapping in such cases. At the very least you may wish to consider using nil instead of N/A as an out of band value for not there. But a map would allow easily adding more data later on, as well as enable giving the lookup keys meaningful names, and would keep the existing keys stable when new ones were added. A map may also perform better if you end up with a lot of optional keys, as missing mappings don't take up space while N/A values in a vector do. As for naming integer positions using constants, such as (def amount 5), there are two weaknesses with that approach. First, inserting new values will shift all of the existing ones that are farther to the right to higher indices, so you'd have to change amount to 6 and hope you hadn't missed any direct lookups with 5 instead of amount. But if you use a map with a key of :amount, adding more keys can never move the actual amount value away from :amount. And second, you can namespace keys to avoid collisions, with :my-ns/amount and :other-ns/amount not colliding. You can namespace def'd integer constants too, with (in-ns 'my-ns) (def amount 5) and (in-ns 'other-ns) (def amount 7), but if one day you end up with a situation where two namespaces def two different things to the key 5, the namespacing isn't going to help you. Maps with named and namespaceable :keyword keys are much more robust and scalable in large (or potentially-in-the-future-large) projects and in the presence of many optional keys. With Clojure, it's strongly recommended to use maps with named keys instead of positionally-significant entries in vectors to represent structured tuples of data like you seem to have here. The robustness becomes especially significant if you save and load data and keep old data around as the application grows. If you reorder the vectors, or insert new fields before existing ones, and then read in old data, the values will end up with the wrong keys, whereas if you use maps, keywords, and edn format the values in old data can never end up reading back in with the wrong keys (as long as you never rename already-used keys for any reason, which with meaningful names and especially namespacing you should never need to do). -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Core.async, Rules for passing clojure vals to go block
Your best bet is to move your system atom out to a top-level def, like so: (def system-atom (atom '({}))) Then just use (eval `(~afn system-atom)) later on, from places where the system-atom Var is visible (same ns, or :use'd), or use (eval `(~afn x/system-atom)) to qualify the name. The syntax quote will cause the eval'd code to use a fully qualified name regardless. If you don't want lots of stuff depending on a top-level singleton object (say, because you might want to have two parallel tasks in the same JVM with two different system-atoms), and can't get rid of eval, you can use a top-level map: (def system-atoms (atom {})) (defn new-system-atom! [k] (swap! system-atoms assoc k (atom '({} ... (new-system-atom! :foo) ... (eval `(~afn (:foo @system-atoms))) ... (eval `(~bfn (:bar @system-atoms))) On Fri, Jan 3, 2014 at 7:20 PM, Jason Wolfe ja...@w01fe.com wrote: Glad to help. I admittedly haven't taken the time to understand what's going on in your code, but whenever I see `eval` I feel compelled to ask: are you sure you need it? With that out of the way, here's a trick I've used to work around related errors: https://groups.google.com/d/msg/clojure/BZwinR2zNgU/8HGOgzOxzosJ Best, Jason On Friday, January 3, 2014 3:18:22 PM UTC-8, frye wrote: Hey Jason, You were exactly right (which is pretty impressive, being that you've never seen my code). In my (s/defn ..) form, there was an error that was failing silently. (s/defn [one two] ... *#_(def params (atom '({}) ))* (def params '({})) (try (eval `(~afn ~@params)) (catch Exception e (println Exception: (.getMessage e) So the abouve code works. But if I instead use the commented version, I'll get an exception. It seems there's a problem passing in a form containing an atom to be dynamically eval'd. The error is mentioned on these posts (here http://clojure-log.n01se.net/date/2009-03-02.htmland here http://www.raynes.me/logs/irc.freenode.net/clojure/2012-09-17.txt#). Is there a way to pass in a form containing an atom to be dynamically eval'd? It's pretty important to my architecture, that all functions treat that system-atom the same. Any insights are welcome. *java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: clojure.lang.Atom@1c99db7 (NO_SOURCE_FILE:0)* Thanks Tim Washington Interruptsoftware.com http://interruptsoftware.com On Fri, Jan 3, 2014 at 2:39 PM, Jason Wolfe ja...@w01fe.com wrote: Thanks for the report. Schema fns inside of go blocks seem to work fine for me. It seems likely that you're seeing an exception inside the go block, which is swallowed by default: user (clojure.core.async/go (println A)) #ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@ 46ae10a6 A user (clojure.core.async/go (throw (RuntimeException.)) (println A)) #ManyToManyChannel clojure.core.async.impl.channels.ManyToManyChannel@ 427c78c1 Would you mind wrapping the body of your go block in a try/catch and printing the exception stack trace, or posting a gist that demonstrates the issue so I can look into it further? Thanks! On Friday, January 3, 2014 10:21:16 AM UTC-8, frye wrote: Forwarding... -- Forwarded message -- From: Timothy Washington twas...@gmail.com Date: Fri, Jan 3, 2014 at 1:17 PM Subject: Re: Core.async, Rules for passing clojure vals to go block To: Shaun Gilchrist shaun...@gmail.com I'm using Prismatic's Schema in my code base. Now, it looks like defining some functions with s/defnhttps://github.com/Prismatic/schema/blob/master/src/clj/schema/macros.clj#L453, yields some wonky behaviour. Particularly, not running, when being invoked in a go block. It just fails silently, which is why it was so hard to track down. Don't yet know why this is happening. But an fyi for the devs and users of this package. Still love schema, I just need to figure out where the call chain breaks down. Hth Tim Washington Interruptsoftware.com http://interruptsoftware.com On Fri, Jan 3, 2014 at 9:58 AM, Timothy Washington twas...@gmail.comwrote: Hey Shaun, Thanks for looking into this. Your example does indeed work. I'll have to teardown my own code and see where the invocations are failing. At least I know it's not core.async. Cheers Tim Washington Interruptsoftware.com http://interruptsoftware.com -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving
Re: Core.async, Rules for passing clojure vals to go block
Yeah, he probably could. But maybe he has a good reason for avoiding it that we're not aware of. Though I'm not sure what that could be. On Fri, Jan 3, 2014 at 8:11 PM, Jason Wolfe ja...@w01fe.com wrote: On Fri, Jan 3, 2014 at 4:43 PM, Timothy Washington twash...@gmail.comwrote: The crux of the problem is that the size of *params* can be variable. Only at runtime, does the code match the loaded *afn*, with the passed in *params*. So I basically just need to break out the *~@params* into individuated input arguments. The only other way I can think to do that, without using eval, would be to curry afn, for each input param. Can you just use `apply`? Tim Washington Interruptsoftware.com http://interruptsoftware.com On Fri, Jan 3, 2014 at 7:20 PM, Jason Wolfe ja...@w01fe.com wrote: Glad to help. I admittedly haven't taken the time to understand what's going on in your code, but whenever I see `eval` I feel compelled to ask: are you sure you need it? With that out of the way, here's a trick I've used to work around related errors: https://groups.google.com/d/msg/clojure/BZwinR2zNgU/8HGOgzOxzosJ Best, Jason On Friday, January 3, 2014 3:18:22 PM UTC-8, frye wrote: Hey Jason, You were exactly right (which is pretty impressive, being that you've never seen my code). In my (s/defn ..) form, there was an error that was failing silently. (s/defn [one two] ... *#_(def params (atom '({}) ))* (def params '({})) (try (eval `(~afn ~@params)) (catch Exception e (println Exception: (.getMessage e) So the abouve code works. But if I instead use the commented version, I'll get an exception. It seems there's a problem passing in a form containing an atom to be dynamically eval'd. The error is mentioned on these posts (here http://clojure-log.n01se.net/date/2009-03-02.htmland herehttp://www.raynes.me/logs/irc.freenode.net/clojure/2012-09-17.txt#). Is there a way to pass in a form containing an atom to be dynamically eval'd? It's pretty important to my architecture, that all functions treat that system-atom the same. Any insights are welcome. *java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: clojure.lang.Atom@1c99db7 (NO_SOURCE_FILE:0)* Thanks Tim Washington Interruptsoftware.com http://interruptsoftware.com On Fri, Jan 3, 2014 at 2:39 PM, Jason Wolfe ja...@w01fe.com wrote: Thanks for the report. Schema fns inside of go blocks seem to work fine for me. It seems likely that you're seeing an exception inside the go block, which is swallowed by default: user (clojure.core.async/go (println A)) #ManyToManyChannel clojure.core.async.impl. channels.ManyToManyChannel@46ae10a6 A user (clojure.core.async/go (throw (RuntimeException.)) (println A)) #ManyToManyChannel clojure.core.async.impl. channels.ManyToManyChannel@427c78c1 Would you mind wrapping the body of your go block in a try/catch and printing the exception stack trace, or posting a gist that demonstrates the issue so I can look into it further? Thanks! On Friday, January 3, 2014 10:21:16 AM UTC-8, frye wrote: Forwarding... -- Forwarded message -- From: Timothy Washington twas...@gmail.com Date: Fri, Jan 3, 2014 at 1:17 PM Subject: Re: Core.async, Rules for passing clojure vals to go block To: Shaun Gilchrist shaun...@gmail.com I'm using Prismatic's Schema in my code base. Now, it looks like defining some functions with s/defnhttps://github.com/Prismatic/schema/blob/master/src/clj/schema/macros.clj#L453, yields some wonky behaviour. Particularly, not running, when being invoked in a go block. It just fails silently, which is why it was so hard to track down. Don't yet know why this is happening. But an fyi for the devs and users of this package. Still love schema, I just need to figure out where the call chain breaks down. Hth Tim Washington Interruptsoftware.com http://interruptsoftware.com On Fri, Jan 3, 2014 at 9:58 AM, Timothy Washington twas...@gmail.com wrote: Hey Shaun, Thanks for looking into this. Your example does indeed work. I'll have to teardown my own code and see where the invocations are failing. At least I know it's not core.async. Cheers Tim Washington Interruptsoftware.com http://interruptsoftware.com -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to a topic in the Google Groups Clojure group. To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/j8QWNnFNIVg/unsubscribe. To
Re: case/java interop weirdness
Not really, as the lookups will happen at macroexpansion time and not at runtime. It should be as efficient as a normal (case ...). On Tue, Dec 31, 2013 at 7:00 AM, Paul Butcher p...@paulbutcher.com wrote: On 30 Dec 2013, at 16:34, Cedric Greevey cgree...@gmail.com wrote: To do it with case, you'd need to wrap case in a macro that expanded to `(case ~thingy ~(eval case1) ...) or something along those lines Thanks, but I suspect that that might be another way of saying use condp :-) Cheers, -- paul.butcher-msgCount++ Silverstone, Brands Hatch, Donington Park... Who says I have a one track mind? http://www.paulbutcher.com/ LinkedIn: http://www.linkedin.com/in/paulbutcher Skype: paulrabutcher -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Akka-like framework in Clojure ?
On Tue, Dec 31, 2013 at 9:26 AM, Jakub Holy jakub.h...@iterate.no wrote: I also believe that Rich Hickey has some good reasons for why / when not to use actor-based concurrency. I cannot find the reference now, perhaps it is mentioned (also) in the StrangeLoop 2013 Clojure core.async Channelshttp://www.infoq.com/presentations/clojure-core-async talk. Does anyone else think we could use a central, searchable clearinghouse containing all of the various arguments, rationales, and philosophical essays underpinning Clojure's design choices in text format? AFAICT a lot of that stuff is currently scattered hither and thither across the web, and a lot of it is buried in the audio tracks of videos where search tools can't find it, and even the videos aren't gathered in one place (e.g. a Youtube channel) but instead are disseminated all over the place across dozens of different hosting sites. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: core.async - extracting code from a go block
It should work if it's inlined or a macro. It won't shrink foo's generated code size any if bar is a macro, but it will split up the source code into smaller pieces if that's all you're concerned about. On Tue, Dec 31, 2013 at 8:50 PM, Paul Butcher p...@paulbutcher.com wrote: I recently discovered that parking calls only work if they're directly contained within a go block. So this works fine: (defn foo [ch] (go (! ch))) But this: (defn bar [ch] (! ch)) (defn foo [ch] (go (bar ch))) Results in Assert failed: ! used not in (go ...) block Is there any way around this? If I have a go block that's getting too big and want to extract some portion of it into a separate function, what's the best approach? -- paul.butcher-msgCount++ Silverstone, Brands Hatch, Donington Park... Who says I have a one track mind? http://www.paulbutcher.com/ LinkedIn: http://www.linkedin.com/in/paulbutcher Skype: paulrabutcher -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: case/java interop weirdness
To do it with case, you'd need to wrap case in a macro that expanded to `(case ~thingy ~(eval case1) ...) or something along those lines, with the evals snapping lookups like FetcherEvent/EVENT_TYPE_FEED_POLLED to the associated constants. This will have the effect of classloading the class with the constants at macroexpansion time, but that's likely happening anyway if you're importing that class. On Mon, Dec 30, 2013 at 9:07 AM, Paul Butcher p...@paulbutcher.com wrote: On 30 Dec 2013, at 13:57, Nicola Mometto brobro...@gmail.com wrote: The test clauses of case expressions are not evaluated, so that case is trying to match the symbol 'FetcherEvent/EVENT_TYPE_FEED_POLLED, not the value of FetcherEvent/EVENT_TYPE_FEED_POLLED. Ah - I was aware of the requirement for the constants to be compile-time literals, but assumed that give that they were final static Strings, that would work. Obviously not. Is there any way to achieve the effect I'm after with case? Or do I need to switch to condp? -- paul.butcher-msgCount++ Silverstone, Brands Hatch, Donington Park... Who says I have a one track mind? http://www.paulbutcher.com/ LinkedIn: http://www.linkedin.com/in/paulbutcher Skype: paulrabutcher -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: protocols and overloading
On Mon, Dec 30, 2013 at 12:13 PM, Massimiliano Tomassoli kiuhn...@gmail.com wrote: On Sunday, December 29, 2013 10:11:47 PM UTC+1, tbc++ wrote: Not mentioned in Cedric's post are two other important things: Protocols can be extended to existing types. For example: (defprotocol IType (type-as-string [x])) (extend-protocol IType String (type-as-string [x] string) Integer (type-as-string [x] integer)) = (type-as-string 42) integer Here we are adding new methods to sealed closed classes that already exist in the JVM. We never modify these classes, we simply extend our protocol to them. Secondly, all protocol functions are namespaced. This allows us to extend classes without fear of overwriting existing methods. This then is more powerful than monkey patching in Ruby or Python as the resulting method is more like 42.user_type-as-string(). Clojure's namespace system then allows you to refer to one method or the other just as you would any normal functions. You're not really adding methods to classes in Clojure. You're just defining external functions. Can you make them private or protected? In my opinion, the Expression Problem in FP and OOP are two different problems. In FP you can solve it more easily because you use pseudo-classes which don't behave like real classes at all. The proof of this is that any sufficiently dynamic OO language can solve the problem the same way Clojure does just by using classes with no methods and by using overloading resolved at runtime. Of course, you don't do that in OOP because you want to work with real classes. For instance, C# has extension methods which let you add methods to existing classes without any recompilation. Problem solved? I don't think so. Extension methods are just static functions that emulate the behavior of instance methods, but without any kind of encapsulation and possibility of inheritance. Encapsulation is less important without a lot of mutable state lying around, and remains important mainly at module boundaries, not class-like boundaries, where code belonging to different programmers comes into contact. If I change the internals of doohickey A and that breaks doohickey B inside the same module, I can fix B, and I know how to, and I know to do so as soon as I change A. It's when someone else changes doohickey C in a different module that I'm in trouble if I'm depending on the internals, but then hopefully there's an encapsulation boundary at the module boundary between my stuff and doohickey C. As for inheritance, it's *highly* overrated, complecting as it does composition and polymorphism. We Clojurians tend to keep those separated, and as a result protocols are purely about polymorphism while composition is dealt with in some orthogonal way. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: protocols and overloading
On Mon, Dec 30, 2013 at 12:30 PM, Massimiliano Tomassoli kiuhn...@gmail.com wrote: On Sunday, December 29, 2013 11:30:16 PM UTC+1, Cedric Greevey wrote: On Sun, Dec 29, 2013 at 4:11 PM, Timothy Baldridge tbald...@gmail.comwrote: Not mentioned in Cedric's post are two other important things: Protocols can be extended to existing types. These are important for the Expression Problem, but not for the OP's query as originally stated, which simply asked for the contrast with overloading. That contrast is dynamic vs. static dispatch. As for C++ being able to solve the Expression Problem and thus being equally powerful, well, both languages are also Turing complete. But which will generally let you be more expressive, with less ceremony and verbosity? Which has templates and macros that are unhygienic and a bugbear to work with, and which has macros that are very safe and clean? What I was saying was more subtle. If C++ can solve the Expression Problem the same way Clojure does, why do you say that Clojure's solution is acceptable whereas C++ programmers don't accept the same solution for C++? That's simple: external functions are not real methods. So we're accepting Clojure's solution because Clojure doesn't support real methods and objects, but we're rejecting the same solution in C++ because C++ *does* have real methods and objects. Isn't that absurd? I think you'll need to define what you mean by real methods and objects, and in what way the word real is supposed to be establishing a contrast. A contrast with what, exactly? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: protocols and overloading
On Mon, Dec 30, 2013 at 12:45 PM, Massimiliano Tomassoli kiuhn...@gmail.com wrote: On Monday, December 30, 2013 6:27:05 PM UTC+1, Cedric Greevey wrote: On Mon, Dec 30, 2013 at 12:13 PM, Massimiliano Tomassoli kiuh...@gmail.com wrote: On Sunday, December 29, 2013 10:11:47 PM UTC+1, tbc++ wrote: Not mentioned in Cedric's post are two other important things: Protocols can be extended to existing types. For example: (defprotocol IType (type-as-string [x])) (extend-protocol IType String (type-as-string [x] string) Integer (type-as-string [x] integer)) = (type-as-string 42) integer Here we are adding new methods to sealed closed classes that already exist in the JVM. We never modify these classes, we simply extend our protocol to them. Secondly, all protocol functions are namespaced. This allows us to extend classes without fear of overwriting existing methods. This then is more powerful than monkey patching in Ruby or Python as the resulting method is more like 42.user_type-as-string(). Clojure's namespace system then allows you to refer to one method or the other just as you would any normal functions. You're not really adding methods to classes in Clojure. You're just defining external functions. Can you make them private or protected? In my opinion, the Expression Problem in FP and OOP are two different problems. In FP you can solve it more easily because you use pseudo-classes which don't behave like real classes at all. The proof of this is that any sufficiently dynamic OO language can solve the problem the same way Clojure does just by using classes with no methods and by using overloading resolved at runtime. Of course, you don't do that in OOP because you want to work with real classes. For instance, C# has extension methods which let you add methods to existing classes without any recompilation. Problem solved? I don't think so. Extension methods are just static functions that emulate the behavior of instance methods, but without any kind of encapsulation and possibility of inheritance. Encapsulation is less important without a lot of mutable state lying around, and remains important mainly at module boundaries, not class-like boundaries, where code belonging to different programmers comes into contact. If I change the internals of doohickey A and that breaks doohickey B inside the same module, I can fix B, and I know how to, and I know to do so as soon as I change A. It's when someone else changes doohickey C in a different module that I'm in trouble if I'm depending on the internals, but then hopefully there's an encapsulation boundary at the module boundary between my stuff and doohickey C. As for inheritance, it's *highly* overrated, complecting as it does composition and polymorphism. We Clojurians tend to keep those separated, and as a result protocols are purely about polymorphism while composition is dealt with in some orthogonal way. That's your opinion and I respect that. Maybe someday I'll come around to seeing things your way as I delve into Clojure, but I doubt it :) But I still think that we can't compare OOP and non-OOP languages w.r.t. the Expression Problem. If the Expression Problem consists in extending classes then non-OOP languages must be excluded because they don't have classes. We can't put datatypes and classes on the same level. They're just different things. That would then suggest that the Expression Problem is a problem that only OOP has. ;) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: protocols and overloading
On Mon, Dec 30, 2013 at 12:59 PM, Massimiliano Tomassoli kiuhn...@gmail.com wrote: On Monday, December 30, 2013 6:31:52 PM UTC+1, Cedric Greevey wrote: On Mon, Dec 30, 2013 at 12:30 PM, Massimiliano Tomassoli kiuh...@gmail.com wrote: On Sunday, December 29, 2013 11:30:16 PM UTC+1, Cedric Greevey wrote: On Sun, Dec 29, 2013 at 4:11 PM, Timothy Baldridge tbald...@gmail.comwrote: Not mentioned in Cedric's post are two other important things: Protocols can be extended to existing types. These are important for the Expression Problem, but not for the OP's query as originally stated, which simply asked for the contrast with overloading. That contrast is dynamic vs. static dispatch. As for C++ being able to solve the Expression Problem and thus being equally powerful, well, both languages are also Turing complete. But which will generally let you be more expressive, with less ceremony and verbosity? Which has templates and macros that are unhygienic and a bugbear to work with, and which has macros that are very safe and clean? What I was saying was more subtle. If C++ can solve the Expression Problem the same way Clojure does, why do you say that Clojure's solution is acceptable whereas C++ programmers don't accept the same solution for C++? That's simple: external functions are not real methods. So we're accepting Clojure's solution because Clojure doesn't support real methods and objects, but we're rejecting the same solution in C++ because C++ *does* have real methods and objects. Isn't that absurd? I think you'll need to define what you mean by real methods and objects, and in what way the word real is supposed to be establishing a contrast. A contrast with what, exactly? A class must support encapsulation, inheritance and polymorphism. If it doesn't, then it isn't a class. The same way, a method is a function that belongs to a class and can be public, private or protected. If a function is external to an object (i.e. it can't be made private or protected) than it isn't a method. I'd submit that your definition is too narrow, since it excludes quite possibly *the* most archetypal of object oriented languages. I speak, of course, of Smalltalk, which the last time I checked had classes whose fields were automatically private and methods automatically public (though you could comment that you didn't intend a method to be called by outside users -- and you can use defn- in clojure, or make this is private comments in any language that has comments or sufficiently generous limits on identifiers as to permit calling a bunch of things names like private_foo). -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: protocols and overloading
On Sun, Dec 29, 2013 at 12:27 PM, Massimiliano Tomassoli kiuhn...@gmail.com wrote: What's the difference between protocols and simple overloading? Dynamic dispatch. Overloading uses just the static type for dispatch, so this Java code: aBase = new Base(); aDerived = new Derived(); aBase2 = aDerived; something.foo(aBase); something.foo(aBase2); something.foo(aDerived); will call the same version of foo the first two times, though the third time it might call a different overload of foo (if there's a separate foo(Derived x) method in the class of something). Dynamic dispatch uses the runtime type. In Java you get this when you call aBase.bar(); aBase2.bar(); aDerived.ber(); and (if Derived overrides bar) get the Derived version of bar called for the second as well as the third calls, because aBase2's runtime type is Derived. Clojure protocols dispatch on the runtime type of the first argument, much like (non-static) Java methods (with this considered to be the first argument). Clojure multimethods can dispatch on the runtime type (or even other characteristics) of *all* of the arguments. I don't think anything Clojure does dispatches on the static type of anything, only on the number of arguments and sometimes on runtime types or other information, with the exception of some built-in inline functions (arithmetic +, for example) on primitive numeric arguments, and possibly also macros that encounter primitives. Indeed, primitive locals are just about the only static types to be found in Clojure (notwithstanding core.typed, whose use AFAIK does not influence the dispatch semantics of anything). -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Why is add-watch still in alpha?
On Sun, Dec 29, 2013 at 4:24 PM, larry google groups lawrencecloj...@gmail.com wrote: And here is where the greatest disappointment arrives: neither futurehttp://clojuredocs.org/clojure_core/clojure.core/future nor promise http://clojuredocs.org/clojure_core/clojure.core/promise in Clojure supports listening for completion/failure asynchronously. ... As much as I love Clojure concurrency primitives like STM and agents, futures feel a bit underdeveloped. Lack of event-driven, asynchronous callbacks that are invoked whenever futures completes (notice that add-watchhttp://clojuredocs.org/clojure_core/clojure.core/add-watch doesn't work futures - and is still in alpha) greatly reduces the usefulness of a future object. We can no longer: - map futures to transform result value asynchronously - chain futures - translate list of futures to future of list - ...and much more, see how Akka does ithttp://nurkiewicz.blogspot.no/2013/02/javautilconcurrentfuture-basics.html and Guava to some extenthttp://nurkiewicz.blogspot.no/2013/02/advanced-listenablefuture-capabilities.html That's a shame and since it's not a technical difficulty but only a missing API, I hope to see support for completion listeners soon. So, I am curious if we will see support for completion listeners. Or is there a feeling that stuff like core.async has addressed some of this and nothing more is needed? Well, core.async directly subsumes the entire functionality of promises. And adds watch capability: (let [c (chan)] ; instead of (promise) (go ; prefer thread if the long calculation is REALLY long (! c (long calculation here)) ; instead of (future (deliver ...)) (close! c)) (let [d (go (let [x (! c)] (println Special delivery! x) ; Watch! x))] (!! d))) ; (instead of @c) The channel here is used just like a promise: the first go asynchronously does some calculation and delivers a result to it, then closes it, which results in behavior like a delivered promise, i.e. it can't be delivered to again. One could just use (!! c) to grab the result (blocking until available), like @some-promise. The second go block shows one bit of added power: you can add an asynchronous watch for the result to appear. The go block takes it from c as soon as it's available, executes the watch (in this case a simple println), and then evaluates to the delivered value. Letting [d (go ...)] results in d being bound to a channel that will get this value pushed onto it (and then get closed) when the go block terminates, and (!! d) blocks the main thread until this happens and then evaluates to the result. The one thing missing is that whereas you can @some-promise repeatedly to retrieve the value once it's delivered, you can't (!! d) repeatedly without getting the delivered value once and then nils thereafter. But you could change it slightly to combine channels *with* promise: (let [c (chan)] (go (! c (long calculation here)) (close! c)) (let [d (promise)] (go (let [x (! c)] (println Special delivery! x) (deliver d x)))] @d)) Now d is a promise, but it's delivered by a go block that can also asynchronously watch for completion. But leaving d as a channel might be better. You can always put the result in another kind of container once it's delivered, and deref that repeatedly, and by leaving d a channel you can use alt! and timeout on this channel, for example, to add timeout behavior to your checking for delivery. Futures used locally can be watched asynchronously trivially: instead of (future (long calculation here)) you have (future (let [x (long calculation here)] (hey-x-got-finished! x) x)). The (hey-x-got-finished! x) call will take place in the future's thread. If you don't want it blocking the main thread (i.e. you want (hey-x-got-finished! x) able to run concurrently with whatever derefs the future, instead of the latter maybe being blocked longer) then you'd use (future (let [x (long calculation here)] (future (hey-x-got-finished! x)) x)). :) That deals with watching for completion. Watching for error is as easy with future: wrap a try ... catch around the body inside (future ...). With promise/core.async, you need the try block in the producer's code, whereas core.async lets you add completion watching at the consumer end as easily as at the producer. (Even to a normal promise generated by, say, code you can't change: just (let [c (thread @p)] ...) to turn promise p into channel c that will get @p pushed onto it when p is delivered; thread is used instead of go because a blocking job in a go is not recommended. Wrap the @p in something that will do something with its argument and return its argument to add a completion watch, for values of do something that can of course include spawning further async processes.) Futures you get passed from code you don't control (never heard of this happening, but I
Re: Why is add-watch still in alpha?
Actually, one simple way to use core.async to asynchronously watch a future or a promise, or *any* other blocking-derefable thingy, for delivery, is just to throw a (thread (do-something-with @thingy)) in your code somewhere. The thread will block until the thingy is ready, and then do whatever. Meanwhile your usual code can just @thingy like it would have anyway somewhere, without its behavior there being changed. This can be done anywhere the thingy is visible. What can't be done with any of these (including core.async used natively) is to catch errors without being able to put (or amend) a try block into the producer end of things. This suggests that anything where consumers might want notification of failure should employ a separate error channel (core.async) or out of band values (future, promise, core.async) produced in a try block. For example (future (try (/ a b) (catch ArithmeticException _ :error))) where the consumer can look for :error instead of a number when derefing (in this case, this would be caused by the edge case b = 0). On Sun, Dec 29, 2013 at 5:01 PM, Cedric Greevey cgree...@gmail.com wrote: On Sun, Dec 29, 2013 at 4:24 PM, larry google groups lawrencecloj...@gmail.com wrote: And here is where the greatest disappointment arrives: neither futurehttp://clojuredocs.org/clojure_core/clojure.core/future nor promise http://clojuredocs.org/clojure_core/clojure.core/promise in Clojure supports listening for completion/failure asynchronously. ... As much as I love Clojure concurrency primitives like STM and agents, futures feel a bit underdeveloped. Lack of event-driven, asynchronous callbacks that are invoked whenever futures completes (notice that add-watchhttp://clojuredocs.org/clojure_core/clojure.core/add-watch doesn't work futures - and is still in alpha) greatly reduces the usefulness of a future object. We can no longer: - map futures to transform result value asynchronously - chain futures - translate list of futures to future of list - ...and much more, see how Akka does ithttp://nurkiewicz.blogspot.no/2013/02/javautilconcurrentfuture-basics.html and Guava to some extenthttp://nurkiewicz.blogspot.no/2013/02/advanced-listenablefuture-capabilities.html That's a shame and since it's not a technical difficulty but only a missing API, I hope to see support for completion listeners soon. So, I am curious if we will see support for completion listeners. Or is there a feeling that stuff like core.async has addressed some of this and nothing more is needed? Well, core.async directly subsumes the entire functionality of promises. And adds watch capability: (let [c (chan)] ; instead of (promise) (go ; prefer thread if the long calculation is REALLY long (! c (long calculation here)) ; instead of (future (deliver ...)) (close! c)) (let [d (go (let [x (! c)] (println Special delivery! x) ; Watch! x))] (!! d))) ; (instead of @c) The channel here is used just like a promise: the first go asynchronously does some calculation and delivers a result to it, then closes it, which results in behavior like a delivered promise, i.e. it can't be delivered to again. One could just use (!! c) to grab the result (blocking until available), like @some-promise. The second go block shows one bit of added power: you can add an asynchronous watch for the result to appear. The go block takes it from c as soon as it's available, executes the watch (in this case a simple println), and then evaluates to the delivered value. Letting [d (go ...)] results in d being bound to a channel that will get this value pushed onto it (and then get closed) when the go block terminates, and (!! d) blocks the main thread until this happens and then evaluates to the result. The one thing missing is that whereas you can @some-promise repeatedly to retrieve the value once it's delivered, you can't (!! d) repeatedly without getting the delivered value once and then nils thereafter. But you could change it slightly to combine channels *with* promise: (let [c (chan)] (go (! c (long calculation here)) (close! c)) (let [d (promise)] (go (let [x (! c)] (println Special delivery! x) (deliver d x)))] @d)) Now d is a promise, but it's delivered by a go block that can also asynchronously watch for completion. But leaving d as a channel might be better. You can always put the result in another kind of container once it's delivered, and deref that repeatedly, and by leaving d a channel you can use alt! and timeout on this channel, for example, to add timeout behavior to your checking for delivery. Futures used locally can be watched asynchronously trivially: instead of (future (long calculation here)) you have (future (let [x (long calculation here)] (hey-x-got-finished! x) x)). The (hey-x-got-finished! x) call will take place
Re: protocols and overloading
On Sun, Dec 29, 2013 at 4:11 PM, Timothy Baldridge tbaldri...@gmail.comwrote: Not mentioned in Cedric's post are two other important things: Protocols can be extended to existing types. These are important for the Expression Problem, but not for the OP's query as originally stated, which simply asked for the contrast with overloading. That contrast is dynamic vs. static dispatch. As for C++ being able to solve the Expression Problem and thus being equally powerful, well, both languages are also Turing complete. But which will generally let you be more expressive, with less ceremony and verbosity? Which has templates and macros that are unhygienic and a bugbear to work with, and which has macros that are very safe and clean? (Incidentally, it was template woes that eventually broke the camel's back for me with C++. I gave up on C++ when I found that one of the most widely-used free software C++ compilers would give duplicate definition errors at link time if the same template was used with the same parameters in two separate compilation units, and the developers had *no sane fix or workaround* or even an ETA on a fix...imagine if importing java.util.Map and using MapString,Integer in Foo.java and also importing java.util.Map and using MapString,Integer in Bar.java and then running something using both classes Foo and Bar had resulted in linkage errors instead of two classes coexisting at runtime that both used MapString,Integers. Java 1.5 would have never gotten off the ground! But this C++ compiler -- and yes, it was then-current gcc -- would do exactly that if you #included hash_map and used hash_mapconst char *,int,some_string_hashfn,strcmp in two compilation units.) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: protocols and overloading
Yeah, it was sometime in the 90s. The only workaround I could think of was maybe to create a single compilation unit for template use, and there derive a trivial subclass of each used template specialization, then use that subclass elsewhere in lieu of the template. Needless to say, not a solution that scales nicely to any substantial team effort, because of the coordination problem involved in discovering when two team members are specializing the same template the same way (hopefully, earlier than when linkage errors break the build!), then adding it to the central file of template specialization subclasses, then communicating to *everyone* to use this new class instead of a particular template with particular parameters ... and once everyone's including the same unit (with these subclasses) there'd be a giant temptation to start shoving everything else widely referenced into there as well, including the kitchen sink, until it turned into a god object with all of the headaches *that* entails. And sooner or later the thing would grow unwieldy, leading to duplications bloating generated code size; or we'd have one single unit using some template directly at the end, also causing duplication. And if all went *well* the end result would contain not tidy vectorints and similarly regular and understandable C++, but vec_of_int and other nonstandard class names instead, leading to head-scratching among the maintenance programmers. Doubly so if the names ended up being less than fully self-explanatory, such as if hash_mapconst char *,int,my_case_insensitive_hash,stricmp was used to derive a trivial extension that got named person_salary because of its use in employee_directory.cpp and payroll.cpp ... and then wound up used also in orderform.cpp for SKU-quantity mapping, and in storelocator.cpp for store location-number of widgets in stock, and etc., later on down the line when other string to integer mappings started being needed. On Sun, Dec 29, 2013 at 6:04 PM, Sean Corfield seancorfi...@gmail.comwrote: That must have been a long time ago? That problem was solved well before I left the C++ committee in '99 and gcc was normally pretty good at tracking the emerging standard at the time... But, yes, the template compilation model and it's impact on linking modules that specialized the same template had been problematic earlier on. On Sun, Dec 29, 2013 at 2:30 PM, Cedric Greevey cgree...@gmail.com wrote: (Incidentally, it was template woes that eventually broke the camel's back for me with C++. I gave up on C++ when I found that one of the most widely-used free software C++ compilers would give duplicate definition errors at link time if the same template was used with the same parameters in two separate compilation units, and the developers had *no sane fix or workaround* or even an ETA on a fix...imagine if importing java.util.Map and using MapString,Integer in Foo.java and also importing java.util.Map and using MapString,Integer in Bar.java and then running something using both classes Foo and Bar had resulted in linkage errors instead of two classes coexisting at runtime that both used MapString,Integers. Java 1.5 would have never gotten off the ground! But this C++ compiler -- and yes, it was then-current gcc -- would do exactly that if you #included hash_map and used hash_mapconst char *,int,some_string_hashfn,strcmp in two compilation units.) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: In your opinion, what's the best, and what's the worst aspects of using Clojure?
On Sat, Dec 28, 2013 at 3:56 AM, Lee Spector lspec...@hampshire.edu wrote: On Dec 27, 2013, at 11:33 PM, guns wrote: On Fri 27 Dec 2013 at 11:23:22PM -0500, Lee Spector wrote: On Dec 27, 2013, at 11:18 PM, guns wrote: (defmacro dump-locals [] ... ` When and where do you call this? I call this inside of the closest function that raised the exception. Ah, so you have to see an exception, edit your code to include a call to this, re-run, and get to the same exception. So it will only help for exception-raising situations that are easy to repeat, which mine often are not. It helps to go with the functional, immutable flow, in which case if you get an unwanted exception it should *usually* have bubbled up from some failing test. Add a dump-locals where suggested by the stack trace and rerun the failing test and voila! That should do it for almost all non-exogenous exceptions, leaving mainly things like network timeouts and other wonkiness caused by factors outside of your code (and, often, outside of your control anyway). -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: In your opinion, what's the best, and what's the worst aspects of using Clojure?
On Sat, Dec 28, 2013 at 12:45 PM, Lee Spector lspec...@hampshire.eduwrote: On Dec 28, 2013, at 11:27 AM, Cedric Greevey wrote: It helps to go with the functional, immutable flow, in which case if you get an unwanted exception it should *usually* have bubbled up from some failing test. Add a dump-locals where suggested by the stack trace and rerun the failing test and voila! That should do it for almost all non-exogenous exceptions, leaving mainly things like network timeouts and other wonkiness caused by factors outside of your code (and, often, outside of your control anyway). You've given me some interesting things to think about re: the role of testing, but I think that it may be hard to map your approach directly on to the kind of work that I do. I often work with stochastic simulations which run for days and for which repeatability is hard to engineer, especially in a multicore context. There's a lot of unpredictable dynamism and usually code is generated and run dynamically (and mutated and recombined; this is genetic programming). Even if you code functionally and immutably (which I try to do, to a reasonable extent), and stamp out all nondeterminism (which would be a pain), it may take days to re-create a situation. Your requirements are unusual. That being said, you might want to consider: 1. Using a PRNG with recordable seed, and sane concurrency semantics, to achieve repeatability -- rerun with same seed to get identical replay of events. 2. If crashes are happening after days, add snapshotting -- some ability to save the state of the whole simulation from time to time (including current PRNG state). Use the last snapshot before a crash to investigate the crash. Requires item 1, above, for rerunning from the same snapshot to produce unvarying results. I'd suggest using a ref world, with a periodically waking thread that does a (spit (dosync (dump-all-the-refs-to-some-data-structure))) or something. (If retries become a big problem you'll need to add more coordination, maybe using core.async to get everything else to take a breather during each state dump.) You also need order-independence (which suggests a deterministic breaking up of the world into the domains of different threads, with defined interaction channels and times, and a separate PRNG per thread -- I'd suggest a state-dumpable Mersenne Twister instance per thread, seeded at startup using values from java.util.Random, itself seeded with a known startup seed). -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: In your opinion, what's the best, and what's the worst aspects of using Clojure?
Adding to the above, in the specific context of genetic programming, I'd suggest dividing the population into N subsets, one per core, and trialling them in parallel to generate fitness scores; then parallel-mergesort to get a ranked order; then (apply map vector (partition (/ num-to-keep num-cores) (take num-to-keep sorted-population))) to cull all but the best num-to-keep and distribute them across N new subsets with each subset a representative sample of the range of fitness scores (so any correlation between trial speed and fitness won't make some populations slow and stop), then apply any recombination/crossovers to generate, say, M new genomes in each subset (parallel, uses the static data from the previous round and per-thread PRNGs to decide which pairs of survivors to use to make offspring added to that thread's subpopulation), then apply mutation (parallel, each thread mutates its own subpopulation), then next trial... No thread-order-of-action dependencies this way. Snapshot once a round by saving the subpopulations and per-thread PRNG internal states right before each fitness trial phase. Snapshot should evolve deterministically if restored with the same values for num-to-keep and num-cores and whatever other parameters. Last snapshot before crash should crash the same way every time. On Sat, Dec 28, 2013 at 2:56 PM, Cedric Greevey cgree...@gmail.com wrote: On Sat, Dec 28, 2013 at 12:45 PM, Lee Spector lspec...@hampshire.eduwrote: On Dec 28, 2013, at 11:27 AM, Cedric Greevey wrote: It helps to go with the functional, immutable flow, in which case if you get an unwanted exception it should *usually* have bubbled up from some failing test. Add a dump-locals where suggested by the stack trace and rerun the failing test and voila! That should do it for almost all non-exogenous exceptions, leaving mainly things like network timeouts and other wonkiness caused by factors outside of your code (and, often, outside of your control anyway). You've given me some interesting things to think about re: the role of testing, but I think that it may be hard to map your approach directly on to the kind of work that I do. I often work with stochastic simulations which run for days and for which repeatability is hard to engineer, especially in a multicore context. There's a lot of unpredictable dynamism and usually code is generated and run dynamically (and mutated and recombined; this is genetic programming). Even if you code functionally and immutably (which I try to do, to a reasonable extent), and stamp out all nondeterminism (which would be a pain), it may take days to re-create a situation. Your requirements are unusual. That being said, you might want to consider: 1. Using a PRNG with recordable seed, and sane concurrency semantics, to achieve repeatability -- rerun with same seed to get identical replay of events. 2. If crashes are happening after days, add snapshotting -- some ability to save the state of the whole simulation from time to time (including current PRNG state). Use the last snapshot before a crash to investigate the crash. Requires item 1, above, for rerunning from the same snapshot to produce unvarying results. I'd suggest using a ref world, with a periodically waking thread that does a (spit (dosync (dump-all-the-refs-to-some-data-structure))) or something. (If retries become a big problem you'll need to add more coordination, maybe using core.async to get everything else to take a breather during each state dump.) You also need order-independence (which suggests a deterministic breaking up of the world into the domains of different threads, with defined interaction channels and times, and a separate PRNG per thread -- I'd suggest a state-dumpable Mersenne Twister instance per thread, seeded at startup using values from java.util.Random, itself seeded with a known startup seed). -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: In your opinion, what's the best, and what's the worst aspects of using Clojure?
Eh, the above should just parallelize working with a single big population. It's not partitioned as far as making-the-cut is concerned, nor crossover (given that each thread adds its M crossover-generated entities by reference to the whole pool of survivors from the previous round). The only constraint the above scheme imposed, in fact, was to force the population size to be divisible by the number of cores, which could be relaxed with the only consequence being a mildly underutilized core (whichever got fewer than the others in its subpopulation). If you have dynamics involving subpopulations that are subjected to separate fitness cuts, reproductively isolated, or what-have-you, that just seems to afford more scope for parallelizing without the order of execution of particular bits of stuff on particular threads affecting things. On Sat, Dec 28, 2013 at 3:54 PM, Lee Spector lspec...@hampshire.edu wrote: On Dec 28, 2013, at 3:11 PM, Cedric Greevey wrote: Adding to the above, in the specific context of genetic programming, I'd suggest dividing the population into N subsets, one per core, and trialling them in parallel to generate fitness scores; then parallel-mergesort to get a ranked order; then (apply map vector (partition (/ num-to-keep num-cores) (take num-to-keep sorted-population))) to cull all but the best num-to-keep and distribute them across N new subsets with each subset a representative sample of the range of fitness scores (so any correlation between trial speed and fitness won't make some populations slow and stop), then apply any recombination/crossovers to generate, say, M new genomes in each subset (parallel, uses the static data from the previous round and per-thread PRNGs to decide which pairs of survivors to use to make offspring added to that thread's subpopulation), then apply mutation (parallel, each thread mutates its own subpopulation), then next trial... No thread-order-of-action dependencies this way. Snapshot once a round by saving the subpopulations and per-thread PRNG internal states right before each fitness trial phase. Snapshot should evolve deterministically if restored with the same values for num-to-keep and num-cores and whatever other parameters. Last snapshot before crash should crash the same way every time. Some of what you're suggesting would have implications for evolutionary dynamics. Maybe good, maybe bad, some related to things that I and others have studied (e.g. various schemes for working with subpopulations), and some maybe incompatible with other experimental things that I may be working with. I'm a researcher in this area, so I do care about and have tried related things for various reasons, but I don't want my search/evolution algorithm design to be driven by inadequacies of my programming environment (e.g. difficulties in finding sources of crashes). -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Namespaces [was Re: Is Clojure right for me?]
On Fri, Dec 27, 2013 at 1:08 PM, Mark Engelberg mark.engelb...@gmail.comwrote: Solution 2: (defn foo [shared-info x] ... body uses shared-info) (defn bar [shared-info x] ... body uses shared-info) Call these functions via: (foo info 2) (bar info 3) In what way is this any worse than info.foo(2); info.bar(3); which is how OO would do this with methods foo and bar of a common class with an instance info having private data? Only the punctuation and VSO vs. SVO word order differ here. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Namespaces [was Re: Is Clojure right for me?]
On Fri, Dec 27, 2013 at 2:32 PM, Mark Engelberg mark.engelb...@gmail.comwrote: On Fri, Dec 27, 2013 at 10:27 AM, Cedric Greevey cgree...@gmail.comwrote: On Fri, Dec 27, 2013 at 1:08 PM, Mark Engelberg mark.engelb...@gmail.com wrote: Solution 2: (defn foo [shared-info x] ... body uses shared-info) (defn bar [shared-info x] ... body uses shared-info) Call these functions via: (foo info 2) (bar info 3) In what way is this any worse than info.foo(2); info.bar(3); In an OO implementation, the definitions of foo and bar could be dramatically more concise because from within the object, references to the other components of the object don't need to be prefixed with info. This is a big deal. Erm, (defn foo [{:keys [thingy mumble fiddly]} x] (...thingy ... mumble ... fiddly ... mumble ... mumble ... x ... thingy ...)) After from one brief incantation in the parameter list you can just go ahead and refer to the fields like in an OO method body. There's also protocol + defrecord and record fields referenced in the function bodies in the defrecord. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Namespaces [was Re: Is Clojure right for me?]
On Fri, Dec 27, 2013 at 3:13 PM, john walker john.lou.wal...@gmail.comwrote: This works (clever hack!), but you would have to reduplicate the keys in (defn bar [..]...), (defn baz [...] ...) etc. (defmacro defthingyfn [name arglist body] `(defn name ~(vec (cons '{:keys [thingy mumble fiddly]} arglist)) ~@body)) (defthingyfn foo [x] (...thingy ... mumble ... fiddly ... mumble ... mumble ... x ... thingy ...)) (defthingyfn bar [x] (...mumble ... thingy ... mumble ... mumble ... x ... thingy ... fiddly ... thingy ...)) ... (Extending that to cope with docstrings and multiple arities is left as an exercise for the reader. :)) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How to go about 'proving' why dynamically typed languages are better.
On Tue, Dec 24, 2013 at 12:23 PM, Rich Morin r...@cfcl.com wrote: On Dec 24, 2013, at 02:09, Cedric Greevey wrote: On Mon, Dec 23, 2013 at 7:37 PM, Rich Morin r...@cfcl.com wrote: Media for Thinking the Unthinkable: Designing a new medium for science and engineering http://worrydream.com/MediaForThinkingTheUnthinkable/ Is this available in a form that is skimmable, is greppable, is cheap for mobile users, can be perused at leisure, fits on a thumb drive, is convertible for Kindle use, and doesn't require installing and enabling notoriously insecure browser plugins to view, or is it only available as video? :( There is a video presentation, which could be downloaded and watched at leisure (eg, on a smart phone). I don't think this presents any security issues. Oh, I don't doubt that the *video* doesn't present any security issues. It's the Flash plugin needed to watch it that presents security issues. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: get rid of reflection in proxy-super?
I'd suggest instead amending the core language to add a special form, maybe named .!, that works like . except it sees protected methods (and will cause an IllegalAccessError if it calls a protected method from outside of a subclass), and amend proxy to use .! for proxy-super (and put the proxy-super call in the method body and not in the fn that the rest of the proxy body goes into, which will avoid IllegalAccessError but make it so that on-the-fly modification of the proxy can't change the proxy-super part). On Wed, Dec 25, 2013 at 3:04 PM, Colin Fleming colin.mailingl...@gmail.comwrote: Right, it doesn't fix your original problem of the reflection warning. Thinking about it, there's no way to get rid of that warning since in the end all interop (unless it uses a built in form) must expand to the dot form, which has no way to call a protected method. The only solution I can see would be to derive a Java class from JPanel and just override paintComponent and make it public, then you can proxy that class. On 25 December 2013 23:14, Jim - FooBar(); jimpil1...@gmail.com wrote: Thanks Colin, I did vote for it but its title implies something different...something restoring original binding on exception... Jim On 25/12/13 04:06, Colin Fleming wrote: That is indeed the same issue, and it even includes a patch with a test! I've voted for this one, please consider doing the same if this issue has caught you. Link: http://dev.clojure.org/jira/browse/CLJ-983 On 25 December 2013 13:22, Matching Socks phill.w...@gmail.com wrote: (Re Colin's note that a proxy gets damaged if super throws - goodness gracious! Is it the same matter as Clojure Jira issue No.983? It's marked as minor and affecting Clojure 1.3, and no one has voted for 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/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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
Re: get rid of reflection in proxy-super?
On Thu, Dec 26, 2013 at 6:57 PM, Colin Fleming colin.mailingl...@gmail.comwrote: The problem is that your approach requires creating the proxy class with the method bodies actually compiled into the body of the proxy class method, they can't be in fns in a proxy map as they are now. This is ok in the case where a method body is just the proxy-super call, but most aren't - they call proxy-super as part of a much larger method. Changing that is a fundamental change to the way proxies work, and IMO would be better served by creating a new form (extend-class or something similar) which would behave in a more similar way to reify but would allow extension. If you read my previous post carefully, it says that *the proxy-super call* (if any) would need to go into the method body. Think something like this. Java: public class Whatever extends SomeClass { public int someMethod (int x, String y) { x = fred(x,42); int foo = super.someMethod(x, y); // someMethod protected in SomeClass return mumble(foo, thingy.frotz(x)); } } proxy (now) (byte code equivalent of): public class Whatever extends SomeClass { public MapString,IFn proxyMap = some longmessy initializer; public int someMethod (int x, String y) { return proxyMap.get(someMethod).invoke(this, x,y); } // And a similar thingy for each additional public-or-protected method in SomeClass } public class WhateverSomeMethodVersion1 implements IFn { public Object invoke (Whatever th1s, Object x, Object y) { x = th1s.fred((int)(Integer)x,42); int foo = Class.forName(SomeClass) .getMethod(someMethod, Integer.TYPE, String.class) .invoke(th1s, (int)(Integer)x, (String)y); // Eww, reflection, slow slow slow return th1s.mumble(foo, thingy.frotz((int)(Integer)x)); } } proxy (proposed) (byte code equivalent of): public class Whatever extends SomeClass { public MapString,IFn proxyMap = some longmessy initializer; public int proxySuperSomeMethod (Object x, Object y) { super.someMethod((int)(Integer)x, (String)y); // Needs .! or whatever to emit } // And a similar thingy for each additional protected method in SomeClass public int someMethod (int x, String y) { return proxyMap.get(someMethod).invoke(this, x,y); } // And a similar thingy for each additional public-or-protected method in SomeClass } public class WhateverSomeMethodVersion1 implements IFn { public Object invoke (Whatever th1s, Object x, Object y) { x = th1s.fred((int)(Integer)x,42); int foo = th1s.proxySuperSomeMethod(x, y); return th1s.mumble(foo, thingy.frotz((int)(Integer)x)); } } I've considered writing such a thing myself due to the limitations and idiosyncrasies of proxy/genclass but I've not investigated whether it's even possible without hacking the compiler - I suspect it's not. Not without implementing .! (or whatever name you prefer), or adding another bytecode emitter specialized to produce proxySuperSomeMethods. I guess every proxied class will need a proxy-hook subclass with -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: How to go about 'proving' why dynamically typed languages are better.
On Mon, Dec 23, 2013 at 7:37 PM, Rich Morin r...@cfcl.com wrote: Media for Thinking the Unthinkable: Designing a new medium for science and engineering http://worrydream.com/MediaForThinkingTheUnthinkable/ Is this available in a form that is skimmable, is greppable, is cheap for mobile users, can be perused at leisure, fits on a thumb drive, is convertible for Kindle use, and doesn't require installing and enabling notoriously insecure browser plugins to view, or is it only available as video? :( -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: bug in clojure.zip when calling next on empty list node?
On Sun, Dec 22, 2013 at 12:26 PM, Lee Spector lspec...@hampshire.eduwrote: The issue I was rasing is that, when traversing '(() 0) with zip/next, one should first visit the root, then (), and then 0. But what actually happens is that between then () and the 0 one lands on a non-existent nil node. So one ends up visiting 4 nodes when there are only 3, and the extra one is a nil. As I mentioned previously this leads to null pointer exceptions in my application, and the only ways around it that I see are recoding everything without zippers or some nasty special case hackery. Point of order: I'm somewhat dubious of the contention that wrapping the output of the traversal in (filter identity ...) before passing it to whatever's throwing the NPEs quite qualifies as nasty special case hackery. :) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: When does clojure.lang.PersistentArrayMap become clojure.lang.PersistentHashMap
The two classes have essentially the same semantics, but performance differences, which is why Clojure sometimes uses one and sometimes the other. If you want to enforce that a map is returned, enforce that the return is a subtype of java.util.Map rather than checking for a specific concrete class of map. On Sun, Dec 22, 2013 at 3:07 PM, larry google groups lawrencecloj...@gmail.com wrote: Hmm, I see. get-distinct was returning an empty lazyseq, which apparently made the difference. On Sunday, December 22, 2013 2:56:01 PM UTC-5, larry google groups wrote: Hmm, the different return types seem tied to the 2 different functions being called, but both functions have the same return type, which is a lazyseq. I am using Monger to get data from MongoDb. These functions are private: (defn- get-distinct [request] {:pre [(= (type request) clojure.lang.PersistentHashMap)] :post [(= (type %) clojure.lang.LazySeq)]} (monger/get-distinct (:item-type request))) (defn- paginate-results [request] {:pre [ (= (type request) clojure.lang.PersistentHashMap)] :post [(= (type %) clojure.lang.LazySeq)]} (monger/paginate-results (:item-type request) (if (:which-page request) (:which-page request) 0))) Both of these functions return lazyseqs, as expected. The results from both get run through a (reduce) function that does some minor filtering. Yet in one case the return type (from the reduce function) is clojure.lang.PersistentArrayMap and in the other it is clojure.lang.PersistentHashMap. I'd like to be able to write a :post condition that enforces strictness, but that seems impossible because I can not figure out what the rule is that handles the conversion. I don't care if the return type is clojure.lang.PersistentArrayMap or clojure.lang.PersistentHashMap, all I want is it for it be consistently one or the other. On Sunday, December 22, 2013 2:31:45 PM UTC-5, larry google groups wrote: I am surprised that a map literal is clojure.lang.PersistentArrayMap but as soon as I assign it to a var, it becomes clojure.lang.PersistentHashMap. Are there any rules for being able to predict when these conversions occur? user (type {}) clojure.lang.PersistentArrayMap user (type {:what why?}) clojure.lang.PersistentArrayMap user (def curious {:what why?}) #'user/curious user (type curious) clojure.lang.PersistentHashMap user (def sug (assoc curious :whodoneit mikey)) #'user/sug user (type sug) clojure.lang.PersistentHashMap I am curious because I wrote a (reduce) function which mostly just builds a map: (assoc map-of-data (:item-name next-item) next-item)) Since I was using assoc I was certain I would get clojure.lang.PersistentHashMap back, but instead I got clojure.lang.PersistentArrayMap. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Hoplon: web applications in Clojure and ClojureScript
On Wed, Dec 18, 2013 at 10:45 PM, Micha Niskin micha.nis...@gmail.comwrote: The difference between a cell and an atom with watchers attached is that cells guarantee consistency. That is to say that the evaluation mechanism ensures that a formula cell is never updated until all of the cells it depends on have been updated, that the formula is evaluated at most one time, and that the cell's formula is evaluated only when the value of a cell it depends on has changed. A cool property here is that the entire graph of cells updates atomically and consistently, even though the individual cells are updating themselves one at a time. The consistency guarantee ensures that each cell sees the world as if it updates atomically; no cell can ever see other cells in a half-evaluated state; each cell acts as if it were the last cell to update. You can think of the entire graph as a single value. What happens if the formula cells have circular dependencies? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] cljs-start 0.0.7 now support source-map
On Tue, Dec 17, 2013 at 5:48 AM, Mimmo Cosenza mimmo.cose...@gmail.comwrote: May be for newcomers like me it will be good to add some integraional tips for emacs(others) editors.. I always feel guilty when talking about editors because I use emacs. It seems that the top clojurists are pushing people to switch from emacs to something more used by younger/front-end programmers. In someway it seems that emacs could be felt as an incidental complexity on the path toward Clojure. Calling emacs incidental complexity is like calling the North Pole a bit nippy this time of year. :) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Clojure.org: Concurrency screencast 404
On a related note, why is the 301 Moved Permanently HTTP status never used in actual practice? Instead, when things move you always get 404s and have to hunt them down manually. :P On Mon, Dec 16, 2013 at 3:44 AM, abhi abhiji...@gmail.com wrote: Hello, Concurrency screencast link to blip.tv is throwing a 404. Is this a temporary thing or has it moved permanently? Most of this is covered in more detail in the concurrency screencasthttp://blip.tv/file/812787 . -- Queer little twists and quirks go into the making of an individual. To suppress them all and follow clock and calendar and creed until the individual is lost in the neutral gray of the host is to be less than true to our inheritance Life, that gorgeous quality of life, is not accomplished by following another man's rules. It is true we have the same hungers and same thirsts, but they are for different things and in different ways and in different seasons Lay down your own day, follow it to its noon, your own noon, or you will sit in an outer hall listening to the chimes but never reaching high enough to strike your own. - Angelo Patri -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Is Clojure more functional then Scala?
So, in other words, like most which is the best programming language? questions, the answer to this one is It depends. :) On Mon, Dec 16, 2013 at 5:31 AM, Эльдар Габдуллин eldar...@gmail.comwrote: Clojure targets multiple platforms, Scala - one. Clojure is Lisp. That means almost any programming paradigm/DSL is just a library. But if you are interested in FP per se, I think Scala illustrates it better. With strong type system, pattern matching it's much closer to Haskell, which is the best language to learn in such case. Haskell literally serves as a definition of what FP is and almost every academic paper in FP field is written with Haskell nowadays. понедельник, 16 декабря 2013 г., 7:33:35 UTC+4 пользователь John Kida написал: I jumped on the FP bandwagon over a year ago and have been using Scala both at work and for personal interest. Recently however I decided to take a closer look at Clojure and see if it is something i actually like. I have to admit at first the syntax form was awkward, but im starting to really see the simplicity behind it. I have heard many people claim that Clojure sets you up and supports you for FP more so then Scala does. However they never provide any examples of something Clojure does that is more supporting of FP then the way idiomatic Scala does it. Here are some things that I have heard people say when comparing Clojure vs Scala in reference to FP Clojure has immutable persistance data structures. but so does Scala Scala also tries to get you to use its immutable collections, like Vectors, and are also persistent data structures. However they are not as uniform as Clojures Seq i agree with that. Also Scala recommends using vals and not vars, which gives you immutable references points I am certainly learning towards dropping Scala for a bit and giving Clojure a real shot. The reason i even picked up Scala was because i wanted to learn more about FP, and if there is a better tool for both doing and learning FP then i want it. So tell me, if you have used both Scala and Clojure, do you have some real examples of some things where Clojure really does support you better when doing FP, where Scala really leads you no way, or worse the imperative way? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: IE compatibility of clojurescript, Element undefined problem
Everyone should give up IE6. And, preferably, every other version of IE. On Mon, Dec 16, 2013 at 7:59 AM, Xiangtao Zhou tao...@gmail.com wrote: hi all, I'm new for clojurescript. I found there is compatibility problem under IE6, closurescript use Element which IE 6 dos not have. Line 34266, Element.prototype.clojure$browser$event$EventType$ = true; Is clojurescript give up IE6? Joe -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: cider status
On Mon, Dec 16, 2013 at 12:27 PM, Gary Johnson gwjoh...@uvm.edu wrote: Just to inject another sample into the population: As another hacker who lives in Emacs, I found the nrepl - cider transition to be quite painless. It took me maybe an hour of reading the website docs, installing/uninstalling packages with package.el, and updating the relevant sections of my .emacs.d/init.el file. Not to poo-poo on anyone's parade, but it really did seem pretty straightforward to me. Interesting, isn't it, what emacs users consider to be quite painless. Users of non-legacy tools tend to set the bar rather higher, needless to say, typically expecting upgrading something (other than the operating system itself) to take a few minutes, tops, with most of that spent doing something else while progress meters (first downloading, then installing) crawl to 100% and the result working OOTB without manual config changes or other nursemaiding. So maybe some of the pain points people are feeling have to do with general challenges with configuring Emacs rather than specific problems with following the online cider docs. That much is quite believable. :) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: cider status
On Fri, Dec 13, 2013 at 2:43 AM, Adrian Mowat adrian.mo...@gmail.comwrote: Is cider just a new release of nrepl.el or a different thing entirely? The former. Sorry to be a noob, but this is awfully confusing to the uninitiated. Of course it is -- it's emacs. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Code layout
On Wed, Dec 11, 2013 at 2:00 AM, Mark Engelberg mark.engelb...@gmail.comwrote: Put as much as is legible on one line. If you need to break lines, break after the function name, not after the first parameter, in order to minimize rightward drift. I've always preferred (map foo coll1 coll2) over breaking after map, and a few similar cases with HOFs whose first parameter is a function. It always feels to me that map foo in its entirety is a kind of operator (although the bare map also is, at the same time) and the intent is clearer if it's not split up internally. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: type-hinting functions with variable (but known) return types
The only thing I can think of off the top of my head is to write a hinted-array macro that turns (hinted-array Class expr) into ^Class (into-array Class expr). Emitting type hints or other form metadata in macros is do-able, but sometimes a bit tricky. Something like this might work (untested): (defmacro hinted-array [class expr] (with-meta `(into-array ~class ~expr) {:tag class})) On Wed, Dec 11, 2013 at 12:04 PM, Phillip Lord phillip.l...@newcastle.ac.uk wrote: Sorry, full of questions about type hinting at the moment. I've found myself writing a lot of expressions like this: ^[Lorg.semanticweb.owlapi.model.OWLClassExpression; (into-array OWLClassExpression [(ensure-class o name) (ensure-class o disjoint)]) Now the strange thing here is that I have to type hint an expression which clojure clearly knows the return type of (although only for the expression and not for the function). This is particularly painful because I'm only constructing the array to call a variadic method in Java, and the type hint is particularly verbose. Is there an easier way? Phil -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: My first attempt at a macro: can not recognize symbol
On Tue, Dec 10, 2013 at 12:53 PM, James Reeves ja...@booleanknot.comwrote: Remember that only the last form will be returned. So: (defn foo [] 1 2 3 4) `(defn ~start-function-name [] will always return 4. The same principle applied with your macro. You define four forms, but only return the last one. Instead, try wrapping all the forms in a do block. Let contains an implicit (do ...) ... ... but it looks like what's needed is an explicit `(do ...) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: loop/recur with multiple branches
On Tue, Dec 10, 2013 at 6:09 PM, Glen Mailer glenja...@gmail.com wrote: I was recently working on some toy recursion problems, when I ran into a function that I can express simply using normaly recursion, but I can't seem to convert it into a form that works nicely with loop/recur. It's certainly not the right way to solve this problem, but I'm intrigued to see what this pattern looks like with explicit tail calls: Problem: Extract a slice from a list (slice [ 3 4 5 6 7 8 9 ] 2 4) ;= [ 5 6 7 8 ] Normal Recursive Solution: (defn slice [[h tail] s n] (cond (zero? n) nil (zero? s) (cons h (slice tail s (dec n))) :else (slice tail (dec s) n))) What would the tail recursive version of this look like? can it retain the nice readability of this form? What about the accumulator pattern? (defn slice ([h s n] (slice h s n nil)) ([[h tail] s n acc] (cond (zero? n) acc (zero? s) (recur tail s (dec n) (cons h acc)) :else (recur tail (dec s) n acc -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: loop/recur with multiple branches
On Tue, Dec 10, 2013 at 6:29 PM, Vincent Chen noodle...@gmail.com wrote: Try this (not tested, might be missing parens and whatnot): (defn slice [x s n] (loop [[h tail] x, s s, n n, acc []] (cond (zero? n) acc (zero? s) (recur tail s (dec n) (conj acc h)) :else (recur tail (dec s) n acc Few notes: - When trying for tail recursions, use an accumulator. The accumulator carries the eventual result, which is returned at the base case. - Since we're destructuring into head and tail, I used vectors. conj will push to the end of the vector. - In Clojure, vectors tend to be more natural than lists. Accumulating into lists usually requires a reverse in the base case. If you're going to go with vectors, why not go transient as well? (defn slice [x s n] (loop [[h tail] x, s s, n n, acc (transient [])] (cond (zero? n) (persistent! acc) (zero? s) (recur tail s (dec n) (conj! acc h)) :else (recur tail (dec s) n acc Might be more runtime efficient. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: I need a vector not a list?
Seems to me that you can make a case for a seq is sort of like an immutable PersistentIterator would be. Iterator - next (get object) seq - first (get object) Iterator - next (mutate to point to next object) seq - next (return new seq whose first is next object) On Tue, Dec 3, 2013 at 2:49 AM, Andy Smith the4thamig...@googlemail.comwrote: Great point... -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Best way to loop a map of maps
Tree-seq? But then, if the data is structured so each level has a distinct purpose, that's not really a great fit. Perhaps we need a for/doseq analog of assoc-in, update-in, etc.? At the very least I think this might work: (doseq [[outer-keys collections] m [collection-name collection] collections [string-id data] collection] ;; do stuff with the above ) On Tue, Dec 3, 2013 at 6:08 PM, Jay Fields j...@jayfields.com wrote: I was going to type in the example with multiple bindings, but this will probably be more helpful: http://blog.jayfields.com/2013/05/clojure-combining-calls-to-doseq-and-let.html On Tue, Dec 3, 2013 at 6:05 PM, Ryan arekand...@gmail.com wrote: Hi all, I am trying to figure out a better way to loop the following map than using nested doseq. The map has the following structure: (def m {outerKeyA {:innerKeyA {string id {:foo 1 :bar 2}}} outerKeyB {:innerKeyB {string id {:bar 5 :baz 10) So, right now i am doing the following: (doseq [[outer-keys collections] m] (doseq [[collection-name collection] collections] (doseq [[string-id data] collection] ;; do stuff with all the above ))) Is there a more idiomatic/better way to do deeply nested iterations/traversal of map of maps? Thank you for any replies! Ryan -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: core.async and performance
Have you checked for other sources of performance hits? Boxing, var lookups, and especially reflection. I'd expect a reasonably optimized Clojure version to outperform a Python version by a very large factor -- 10x just for being JITted JVM bytecode instead of interpreted Python, times another however-many-cores-you-have for core.async keeping all your processors warm vs. Python and its GIL limiting the Python version to single-threaded performance. If your Clojure version is 2.5x *slower* then it's probably capable of a *hundredfold* speedup somewhere, which suggests reflection (typically a 10x penalty if happening heavily in inner loops) *and* another sizable performance degrader* are combining here. Unless, again, you're measuring mostly overhead and not real workload on the Clojure side, but not on the Python side. Put a significant load into each goroutine in both versions and compare them then, see if that helps the Clojure version much more than the Python one for some reason. * The other degrader would need to multiply with, not just add to, the reflection, too. That suggests either blocking (reflection making that worse by reflection in one thread/go holding up progress systemwide for 10x as long as without reflection) or else excess/discarded work (10x penalty for reflection, times 10x as many calls as needed to get the job done due to transaction retries, poor algo, or something, would get you a 100-fold slowdown -- but retries of swap! or dosync shouldn't be a factor if you're eschewing those in favor of go blocks for coordination...) On Fri, Nov 29, 2013 at 10:13 PM, Ben Mabey b...@benmabey.com wrote: On Fri Nov 29 17:04:59 2013, kandre wrote: Here is the gist: https://gist.github.com/anonymous/7713596 Please not that there's no ordering of time for this simple example and there's only one event (timeout). This is not what I intend to use but it shows the problem. Simulating 10^5 steps this way takes ~1.5s Cheers Andreas On Saturday, 30 November 2013 09:31:08 UTC+10:30, kandre wrote: I think I can provide you with a little code snipped. I am talking about the very basic car example (driving-parking-driving). Running the sim using core.async takes about 1s for 10^5 steps whereas the simpy version takes less than 1s for 10^6 iterations on my vm. Cheers Andreas On Saturday, 30 November 2013 09:22:22 UTC+10:30, Ben Mabey wrote: On Fri Nov 29 14:13:16 2013, kandre wrote: Thanks for all the replies. I accidentally left out the close! When I contrived the example. I am using core.async for a discrete event simulation system. There are hundreds of go blocks all doing little but putting a sequence of events onto a channel and one go block advancing taking these events and advancing the time similar to simpy.readthedocs.org/ http://simpy.readthedocs.org/ The basic one car example under the previous link executes about 10 times faster than the same example using core.a sync. Hi Andreas, I've been using core.async for DES as well since I think the process-based approach is useful. I could try doing the same simulation you're attempting to see how my approach compares speed-wise. Are you talking about the car wash or the gas station simulation? Posting a gist of what you have will be helpful so I can use the same parameters. -Ben -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. I've verified your results and compared it with an implementation using my library. My version runs 1.25x faster than yours and that is with an actual priority queue behind the scheduling for correct simulation/time semantics. However, mine is still 2x slower than the simpy version. Gist with benchmarks: https://gist.github.com/bmabey/7714431 simpy is a mature library with lots of performance tweaking and I have done no optimizations so far. My library is a thin wrapping around core.async with a few hooks into the internals and so I would expect that most of the time is being spent in core.async (again, I have done zero profiling to actually verify this). So, it may be that core.async is slower
Re: core.async and performance
Hmm. Another possibility, though remote, is that the Clojure version manages to trigger pathological worst-case behavior in the JIT and/or hardware (frequent cache misses, usually-wrong branch prediction, etc.) and the Python version doesn't (no JIT and maybe the interpreter is simply too slow to make processor caches and branch prediction count for much, other than that the interpreter itself would be slower than it already is without these). On Fri, Nov 29, 2013 at 10:33 PM, Cedric Greevey cgree...@gmail.com wrote: Have you checked for other sources of performance hits? Boxing, var lookups, and especially reflection. I'd expect a reasonably optimized Clojure version to outperform a Python version by a very large factor -- 10x just for being JITted JVM bytecode instead of interpreted Python, times another however-many-cores-you-have for core.async keeping all your processors warm vs. Python and its GIL limiting the Python version to single-threaded performance. If your Clojure version is 2.5x *slower* then it's probably capable of a *hundredfold* speedup somewhere, which suggests reflection (typically a 10x penalty if happening heavily in inner loops) *and* another sizable performance degrader* are combining here. Unless, again, you're measuring mostly overhead and not real workload on the Clojure side, but not on the Python side. Put a significant load into each goroutine in both versions and compare them then, see if that helps the Clojure version much more than the Python one for some reason. * The other degrader would need to multiply with, not just add to, the reflection, too. That suggests either blocking (reflection making that worse by reflection in one thread/go holding up progress systemwide for 10x as long as without reflection) or else excess/discarded work (10x penalty for reflection, times 10x as many calls as needed to get the job done due to transaction retries, poor algo, or something, would get you a 100-fold slowdown -- but retries of swap! or dosync shouldn't be a factor if you're eschewing those in favor of go blocks for coordination...) On Fri, Nov 29, 2013 at 10:13 PM, Ben Mabey b...@benmabey.com wrote: On Fri Nov 29 17:04:59 2013, kandre wrote: Here is the gist: https://gist.github.com/anonymous/7713596 Please not that there's no ordering of time for this simple example and there's only one event (timeout). This is not what I intend to use but it shows the problem. Simulating 10^5 steps this way takes ~1.5s Cheers Andreas On Saturday, 30 November 2013 09:31:08 UTC+10:30, kandre wrote: I think I can provide you with a little code snipped. I am talking about the very basic car example (driving-parking-driving). Running the sim using core.async takes about 1s for 10^5 steps whereas the simpy version takes less than 1s for 10^6 iterations on my vm. Cheers Andreas On Saturday, 30 November 2013 09:22:22 UTC+10:30, Ben Mabey wrote: On Fri Nov 29 14:13:16 2013, kandre wrote: Thanks for all the replies. I accidentally left out the close! When I contrived the example. I am using core.async for a discrete event simulation system. There are hundreds of go blocks all doing little but putting a sequence of events onto a channel and one go block advancing taking these events and advancing the time similar to simpy.readthedocs.org/ http://simpy.readthedocs.org/ The basic one car example under the previous link executes about 10 times faster than the same example using core.a sync. Hi Andreas, I've been using core.async for DES as well since I think the process-based approach is useful. I could try doing the same simulation you're attempting to see how my approach compares speed-wise. Are you talking about the car wash or the gas station simulation? Posting a gist of what you have will be helpful so I can use the same parameters. -Ben -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. I've verified your results and compared it with an implementation using my library. My version runs 1.25x faster than yours and that is with an actual priority queue
Re: core.async and performance
On Fri, Nov 29, 2013 at 11:03 PM, Ben Mabey b...@benmabey.com wrote: On 11/29/13, 8:33 PM, Cedric Greevey wrote: Have you checked for other sources of performance hits? Boxing, var lookups, and especially reflection. As I said, I haven't done any optimization yet. :) I did check for reflection though and didn't see any. I'd expect a reasonably optimized Clojure version to outperform a Python version by a very large factor -- 10x just for being JITted JVM bytecode instead of interpreted Python, times another however-many-cores-you-have for core.async keeping all your processors warm vs. Python and its GIL limiting the Python version to single-threaded performance. This task does not benefit from the multiplexing that core.async provides, at least not in the case of a single simulation which has no clear logical partition that can be run in parallel. The primary benefit that core.async is providing in this case is to escape from call-back hell. Hmm. Then you're still looking for a 25-fold slowdown somewhere. It's hard to get Clojure to run that slow *without* reflection, unless you're hitting one of those cases where parallelizing actually makes things worse. Hmm; core.async will be trying to multithread your code, even while the nature of the task is limiting it to effectively serial performance anyway due to blocking. Perhaps you're getting some of the slowdown from context switches that aren't buying you anything for what they cost? The GIL-afflicted Python code wouldn't be impacted by the cost of context switches, by contrast. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: hash comparison
Presumably it then compares the objects element by element. If the common case is for the arguments to (= x y) to be unequal with unequal hashes, though, this is still considerably faster. On Thu, Nov 28, 2013 at 5:03 PM, Andy Smith the4thamig...@googlemail.comwrote: Hi, I heard Rich Hickey talking about how identity in clojure is synonymous with value-based tests of equality. To make this efficient he describes that objects store cached hashes that are used to speed up these tests of equality, so clojure isnt comparing every data member of a complex data structure. However, how does this actually work since a comparison of hashes doesn't guarantee that two objects are equal. How does clojure handle the case where two hashes are the same for two distinctly different values. Andy -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Overtone 0.9.0 Released
Ah, good. In the past I've been curious, but what little documentation I found seemed to imply* that there were a number of dependencies that sounded like external libraries or applications that were needed, and which (being not Java/Clojure components themselves) would not be installed automatically by Leiningen (and might not even be available for some hardware/OS combinations). Is that not the case, or else no longer the case, then? * Specifically, various software seemed to be named that I wasn't familiar with, but there was no explicit setup instructions or ingredients-needed list either. The general state of the documentation gave the impression of a pre-beta state without a well-organized setup procedure existing yet. Most other Clojure projects and libraries announced, by contrast, include such right in the announcement message -- and it's usually just add [some dependency vector] to your project.clj. If that's the case also for Overtone now, why was that not included in the announcement message? :) On Wed, Nov 27, 2013 at 2:12 AM, Samuel Aaron samaa...@gmail.com wrote: Hi Cedric, On 26 Nov 2013, at 16:45, Cedric Greevey cgree...@gmail.com wrote: Is there a turnkey download/install/play with version of this yet, or is that not until 1.0? For a Clojure developer, Overtone is already as 'turnkey' as it gets. Simply add overtone 0.9.1 to your dependencies in project.clj, start a REPL with Leiningen and then (use 'overtone.live) - your powerful music REPL awaits! Sam --- http://sam.aaron.name -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Breaking out of doseq
What about (first (filter identity (map (fn [[rx f]] (if (matches? rx input) (f input))) regexes))), where regexes is something like [[regex1 f1] [regex2 f2] ...] and input is some string. As long as none of the fs returns nil, this should work, using lazy sequence behavior to stop at the first matching regex. (You may want to do something to de-chunk the regexes vector, if you use a vector, if the fs have side effects or any of the regexes or fs are expensive, and use the de-chunked seq as the argument to map.) The whole shebang should return nil if none of the regexes match (via calling first on an empty sequence). On Wed, Nov 27, 2013 at 10:21 AM, Phillip Lord phillip.l...@newcastle.ac.uk wrote: I think you want to use some instead -- you need a list of regexps anyway given that, as you say, the order is significant. Some can return the first match that hits. doseq is not good for this anyway, since doseq doesn't return anything. Phil Jonathon McKitrick jmckitr...@gmail.com writes: To clarify what I'm trying to do, I have a map of regexes, and after iterating them, when one matches (the order of the regexes is significant) I want exactly one result returned by applying the looked up function to the string. After that regex matches, no more matches should be attempted. What is the 'reduced' function? On Wednesday, November 27, 2013 9:26:21 AM UTC-5, Jonathon McKitrick wrote: I'm iterating a map (regex - function) and I'd like to call FUNCTION with the result of re-groups after a match for REGEX is found. I also want to exit the sequence, returning the results of FUNCTION. In common lisp, I would use return-from, but how would this be done in clojure? -- -- Phillip Lord, Phone: +44 (0) 191 222 7827 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk School of Computing Science, http://homepages.cs.ncl.ac.uk/phillip.lord Room 914 Claremont Tower, skype: russet_apples Newcastle University, twitter: phillord NE1 7RU -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Overtone 0.9.0 Released
Uh ... so it *does* require something to be installed separately, or it *doesn't*? Make up your mind. :) On Wed, Nov 27, 2013 at 1:00 PM, Mark Engelberg mark.engelb...@gmail.comwrote: One point of confusion for me when installing overtone was that the docs say that the internal server doesn't work everywhere, without providing any info about what systems it is known to work on or known not to work on. A second point of confusion is that I can't determine from the docs what's involved with creating a deliverable executable app that uses overtone, as opposed to just installing it for oneself to play around with at the REPL. Do users of the app have to install supercollider separately? What about instruments like the sampled piano? Does the user have to wait several minutes for those samples to be downloaded the first time she runs the app, or is there a way to bundle all that with the app? Is there any way to get rid of the long pause when starting the server? Is overtone too heavyweight to use it embedded in an app to produce tones and/or music, and if so, is there a better way in Clojure? On Wed, Nov 27, 2013 at 9:45 AM, Samuel Aaron samaa...@gmail.com wrote: Hi Cedric, if you're interested in installing Overtone and understanding its dependencies, I highly recommend you take a look at the installation instructions on our Wiki: https://github.com/overtone/overtone/wiki/Installing-overtone If anything isn't clear or obvious - please do let me know. Happy Hacking! Sam --- http://sam.aaron.name On 27 Nov 2013, at 16:33, Cedric Greevey cgree...@gmail.com wrote: Ah, good. In the past I've been curious, but what little documentation I found seemed to imply* that there were a number of dependencies that sounded like external libraries or applications that were needed, and which (being not Java/Clojure components themselves) would not be installed automatically by Leiningen (and might not even be available for some hardware/OS combinations). Is that not the case, or else no longer the case, then? * Specifically, various software seemed to be named that I wasn't familiar with, but there was no explicit setup instructions or ingredients-needed list either. The general state of the documentation gave the impression of a pre-beta state without a well-organized setup procedure existing yet. Most other Clojure projects and libraries announced, by contrast, include such right in the announcement message -- and it's usually just add [some dependency vector] to your project.clj. If that's the case also for Overtone now, why was that not included in the announcement message? :) On Wed, Nov 27, 2013 at 2:12 AM, Samuel Aaron samaa...@gmail.com wrote: Hi Cedric, On 26 Nov 2013, at 16:45, Cedric Greevey cgree...@gmail.com wrote: Is there a turnkey download/install/play with version of this yet, or is that not until 1.0? For a Clojure developer, Overtone is already as 'turnkey' as it gets. Simply add overtone 0.9.1 to your dependencies in project.clj, start a REPL with Leiningen and then (use 'overtone.live) - your powerful music REPL awaits! Sam --- http://sam.aaron.name -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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
Re: println / for unexpected behaviour
On Tue, Nov 26, 2013 at 8:58 AM, Alex Miller a...@puredanger.com wrote: Realizing a lazy sequence incurs overhead on every item. Chunked seqs amortize that cost by realizing a chunk of items at a time giving you better overall performance at the cost of less laziness. And in this case that resulted in all the side effects occurring before any of the nils were printed, instead of the [:empty :empty...] vectors being interleaved with the nils in the output. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] Overtone 0.9.0 Released
Is there a turnkey download/install/play with version of this yet, or is that not until 1.0? On Tue, Nov 26, 2013 at 10:24 AM, Joseph Burnett josephburnet...@gmail.comwrote: Sweet! On Monday, November 25, 2013 8:46:44 AM UTC-8, Sam Aaron wrote: Hi there noise polluters! It's that glorious time again - another version of Overtone has forced its timbral wings out of its cocoon. 0.9.0 is here and is edgy. It was so edgy, that it burst into flames and mutated into 0.9.1 before a blink of the eye![1] This release represents a fundamental shift in our development approach. Instead of designing and implementing new abstractions that may possibly prove useful, all of the features and modifications in 0.9.1 have been implemented as a reaction to specific performance/composition requirements. One of our major users is the Clojure powered band Meta-eX[2] and they have been using and testing 0.9.1 in all of their recent gigs, including a straight hour techno set in Club Noxx, Antwerp. Now, that's real performance testing ;-) So, what's new? Well, let me invite you to read our Changelog[3] which is much more detailed than previous versions. Major improvements/contributions can be summarised as follows: * apply-by/at improvements * Improved Synth Positioning Syntax * MIDI API revamp * New Graphviz support * Bus Monitoring system * Simple Persistent Store * More pervasive stop fns * Node event handlers * Improved envelope helper fns * New workshop examples As usual, let us know your thoughts and experiences over on the Overtone mailing list: http://groups.google.com/group/overtone/ Happy Hacking! Sam http://sam.aaron.namehttp://www.google.com/url?q=http%3A%2F%2Fsam.aaron.namesa=Dsntz=1usg=AFQjCNEsUuWmV3E-LSTI-iup3Il7NI8oEA [1]: https://github.com/overtone/overtone/commit/ ec66e790ca14ce36fb9a7c50804e72a3d23ff2bfhttps://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fovertone%2Fovertone%2Fcommit%2Fec66e790ca14ce36fb9a7c50804e72a3d23ff2bfsa=Dsntz=1usg=AFQjCNH1_o8fQ1qKlI627NwQCGnQZk3H6A [2]: http://meta-ex.comhttp://www.google.com/url?q=http%3A%2F%2Fmeta-ex.comsa=Dsntz=1usg=AFQjCNGUiEln-K_e8qIgLsMaxgvuo5MoBw [3]: https://github.com/overtone/overtone/blob/master/CHANGELOG.mdhttps://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fovertone%2Fovertone%2Fblob%2Fmaster%2FCHANGELOG.mdsa=Dsntz=1usg=AFQjCNEkvArG4bNGb8eFfcs0hfaCIEGDxQ -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Spit seems to use incorrect line terminator on Windoze
And yet it does happen, with PrintWriter and similar. Consider the output of (println) on different operating systems. On Mon, Nov 25, 2013 at 12:59 AM, Stefan Kamphausen ska2...@gmail.comwrote: I agree with Alex. I would not want any magic to happen to my string. Best, Stefan -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Spit seems to use incorrect line terminator on Windoze
(println) outputs nothing *but* the host's line terminator. On Mon, Nov 25, 2013 at 6:22 AM, Tim Visher tim.vis...@gmail.com wrote: On Mon, Nov 25, 2013 at 6:18 AM, Cedric Greevey cgree...@gmail.com wrote: And yet it does happen, with PrintWriter and similar. Consider the output of (println) on different operating systems. Do you have an example of println converting a \n character embedded in a string to the host's line terminator? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: println / for unexpected behaviour
Clearly board is a chunked seq in this case. Use doseq when you want side effects for-each of some seqable, but don't care about the return values. The arguments for doseq are identical to those for for, but a) doseq will return nil and b) if the output of for was discarded (rather than the repl realizing the sequence to print the nils) the side effects would never take place, whereas doseq forces them to take place whether or not the nil *it* returns is used or discarded. On Mon, Nov 25, 2013 at 8:25 AM, Ambrose Bonnaire-Sergeant abonnaireserge...@gmail.com wrote: Hi Edward, I believe the return value of your expression is (nil nil nil nil ...), but the printlns are forced just after the ( is printed. Thanks, Ambrose On Mon, Nov 25, 2013 at 9:14 PM, edw...@kenworthy.info wrote: Some (println) weirdness (board is a vector to vectors): (println (board 0)) (println (board 1)) (println (board 2)) (println (board 3)) (println (board 4)) (println (board 5)) (println (board 6)) (println (board 7)) Works as I would expect, printing to the console. However: (for [row board] (println row)) Doesn't: the output from println is part of the result of evaluating the for (along with a slew of nils). ([:empty :empty :empty :empty :empty :empty :empty :empty] [:empty :empty :empty :empty :empty :empty :empty :empty] [:empty :empty :empty :empty :empty :empty :empty :empty] [:empty :empty :empty :white :black :empty :empty :empty] [:empty :empty :empty :black :white :empty :empty :empty] [:empty :empty :empty :empty :empty :empty :empty :empty] [:empty :empty :empty :empty :empty :empty :empty :empty] [:empty :empty :empty :empty :empty :empty :empty :empty] nil nil nil nil nil nil nil nil) Any idea why there is any difference at all between the two? The only thing I can think of is for's lazy evaluation but I don't see how. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Spit seems to use incorrect line terminator on Windoze
On Sun, Nov 24, 2013 at 3:36 PM, Tim Visher tim.vis...@gmail.com wrote: Sounds like a bug to me. You could open a ticket to get further discussion going. Actually, TTBOMK I cannot, since I think one needs an account at some site I don't have an account at to do that. But someone who does and has a 'doze box can quickly verify this for themselves at a REPL and then do so. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Spit seems to use incorrect line terminator on Windoze
Not everyone wants to go to that much trouble just to tell everyone what he already told everyone via this list. On Sun, Nov 24, 2013 at 4:56 PM, Timothy Baldridge tbaldri...@gmail.comwrote: Anyone can create an account on JIRA and create a ticket. Timothy On Sun, Nov 24, 2013 at 2:19 PM, Cedric Greevey cgree...@gmail.comwrote: On Sun, Nov 24, 2013 at 3:36 PM, Tim Visher tim.vis...@gmail.com wrote: Sounds like a bug to me. You could open a ticket to get further discussion going. Actually, TTBOMK I cannot, since I think one needs an account at some site I don't have an account at to do that. But someone who does and has a 'doze box can quickly verify this for themselves at a REPL and then do so. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Spit seems to use incorrect line terminator on Windoze
I already have more than enough user/pass pairs to keep straight. I'm not creating yet another one just to submit one lousy bug report that I've *already* posted where I know the developers often read. On Sun, Nov 24, 2013 at 7:32 PM, Timothy Baldridge tbaldri...@gmail.comwrote: Not everyone wants to go to that much trouble just to tell everyone what he already told everyone via this list. So instead you ask that language maintainers read every email you write, in the off-chance that you might be reporting a bug? Don't be ridiculous. If you think you might have a bug, write a bug report, and do us all a favor. Timothy On Sun, Nov 24, 2013 at 3:10 PM, Cedric Greevey cgree...@gmail.comwrote: Not everyone wants to go to that much trouble just to tell everyone what he already told everyone via this list. On Sun, Nov 24, 2013 at 4:56 PM, Timothy Baldridge tbaldri...@gmail.comwrote: Anyone can create an account on JIRA and create a ticket. Timothy On Sun, Nov 24, 2013 at 2:19 PM, Cedric Greevey cgree...@gmail.comwrote: On Sun, Nov 24, 2013 at 3:36 PM, Tim Visher tim.vis...@gmail.comwrote: Sounds like a bug to me. You could open a ticket to get further discussion going. Actually, TTBOMK I cannot, since I think one needs an account at some site I don't have an account at to do that. But someone who does and has a 'doze box can quickly verify this for themselves at a REPL and then do so. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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
Spit seems to use incorrect line terminator on Windoze
(spit C:\\foo.txt test1\n) (spit C:\\foo.txt test2\n :append true) open file in notepad = test1test2 (spit C:\\foo.txt test1\r\n) (spit C:\\foo.txt test2\r\n :append true) open file in notepad = test1 test2 So a newline in the string passed to spit seems to be emitted as 0x10, regardless of the platform, and you have to use \r\n in the string to get a Windoze newline. Since (AIUI) spit is designed to emit text files (who writes binary files via a Writer?), shouldn't each \n in the input be getting coerced to (System/getProperty line.separator) somewhere along the way? -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: core.async timeout channels are values - is this intended
Isn't that not only violating least astonishment, but potentially introducing a terrible bug into the library? One could use two different timeout channels in two different alts, and if the timeout channels are aliased, then perhaps only one of the alts would actually get notified. On Wed, Nov 20, 2013 at 5:05 AM, Michał Marczyk michal.marc...@gmail.comwrote: The reason = considers you timeout channels to be equal is that they are, in fact, the same object. In fact, they may end up being the same object even with different timeout values: (identical? (timeout 1) (timeout 2)) ;= true Except I got a false just now with a fresh REPL and same timeout value... All subsequent invocations return true though, and I'm sure with a little digging the reason for the false would become clear. The reason for them being the same object is that timeout goes out of its way to avoid creating to many timeout channels and will reuse existing ones if their timeouts are due within a small amount of time (clojure.core.async.impl.timers/TIMEOUT_RESOLUTION_MS, currently 10 ms) of the requested timeout. Cheers, Michał On 20 November 2013 10:08, Thomas G. Kristensen thomas.g.kristen...@gmail.com wrote: Hi all, I ran into a core.async behaviour that confused me a bit the other day. In some of our systems, we need to fire different timeouts, perform actions and schedule a new timeout. The problem is, that if the timeouts are of the same number of ms, we can't distinguish them, and therefore not keep track of and remove them from a set (at least not easily). That sounds a bit fuzzy. Hopefully this spike will make it clearer what I'm trying to say: (require '[clojure.core.async :refer [chan timeout alts!! alts!]]) (= (chan) (chan)) ;; false (= (timeout 1) (timeout 2)) ;; false (= (timeout 1) (timeout 1)) ;; true (do (loop [ch-v (into {} (for [v [1 2 3]] [(timeout 1000) v]))] (when-let [chs (keys ch-v)] (let [[_ ch] (alts!! chs)] (println (ch-v ch)) (recur (dissoc ch-v ch) (println done)) ;; only fires 3, the last channel in the map The intended behaviour of the last loop is to print 1, 2 and 3 (not necessarily in that order). However, the ch-v map will only contain one key, as timeouts with the same duration are considered the same value. In the real example, a new timeout with the same value should be scheduled again, by being put in the map. So, my questions are: - Is this intended behaviour? - Is there a different pattern for achieving the scheduling behaviour I'm looking for? Thanks for your help, Thomas -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: 2013 State of Clojure ClojureScript survey results
On Tue, Nov 19, 2013 at 10:02 AM, James Reeves ja...@booleanknot.comwrote: I think in this case it's more a problem with the Java API, which the fs library wraps. Until Java 7, I don't think relative path normalisation existed in the core Java libraries. It didn't, and .toPath isn't in the 1.6 java.io.File class in particular. 1.6 gives you these options: user= (reduce #(File. %1 %2) [one two .. three]) #File one\two\..\three user= (.getCanonicalFile (reduce #(File. %1 %2) [one two .. three])) #File C:\Windows\System32\one\three user= (.getPath (reduce #(File. %1 %2) [one two .. three])) one\\two\\..\\three Of these only getCanonicalFile normalizes, but it also makes it absolute, treating it as having been relative to (on the Win32 box I tested it on) the OS system directory of all places. It *is* interesting that Ruby Pathname objects and Java File objects get printed very similarly by Ruby and Clojure, respectively. I assume that / will replace \ as the separator (and the base directory used by getCanonicalFile will vary) if the above is used on other operating systems' JVMs. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Using xlisp assoc-lists in clojure
It would probably be better to convert to/from normal Clojure maps at the edges of the Clojure code. If the input is '((k1 v1) (k2 v2) (k3 v3) (k1 v4)) and we want the earliest occurrence of k1 to win, then that suggests (into {} (reverse alist)). If the input's flattened that would be (into {} (reverse (partition 2 alist))). The reverse makes sure that into assoces {k1 v4} first and then overwrites it with {k1 v1}, so the earliest occurrence of k1 wins. If conj onto a map rejects two-element lists (as opposed to vectors; I don't have the docs or a repl in front of me where I am right now) then you'll need a (map vec) in there or something as well. Output is simpler; (seq amap) alone might suffice, but (map seq amap) should give you the '((k1 v1) (k2 v2) ...) form from prn, and (mapcat seq amap) '(k1 v1 k2 v2 ...). Of course, if you want the key-shadowing behavior not as a cheap overwrite but as a kind of stack, so that (drop 1) on the original example would result in (k1 v4) being a mapping, then you need something beyond a normal Clojure map -- possibly a map of keys to stacks of values (maintained in vectors, say), or a stack of maps, depending on the exact use case. On Mon, Nov 18, 2013 at 10:54 AM, Tassilo Horn t...@gnu.org wrote: Justin Smith noisesm...@gmail.com writes: Hi Justin Hans-Peter, Typically in clojure we use hash-maps (represented literally as {}) where other lisps would use an alist. One difference between alists and maps is that in alists a key can occur multiple times, and then the first entry with that key shadows all following entries with that key (with respect to retrieval with `assoc`). Well, that feature is probably not used very often, but if you can't rule out its usage, you also can't convert alists to maps and expect they're equivalent. Regarding reading assoc list literals, I wouldn't be surprised if someone had written this function already, but I doubt it is in the core language. This should do the trick: (defn alist-assoc [key alist] (first (filter #(= key (first %)) alist))) And to add a list to an alist one would use `cons` in Clojure just like one would use `cons` in CL, Scheme, or Elisp, too. Bye, Tassilo -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] overload-middleware 0.1.1
Is that intended as some sort of an insult aimed at me? I'm just pointing out that the web != everything that might conceivably be done with the HTTP protocol. The web is that thing you browse with Firefox, more or less by definition (even if sometimes tools like curl and wget are used as shortcuts when downloading files or scraping data off some site, and testing tools used to find dead links, and the like -- the web is that HTTP-served stuff whose *primary* interface is intended to be a web browser). So, for example, although the Gnutella file-sharing software uses HTTP under the hood for file transfers, it's not the web. On Sun, Nov 17, 2013 at 8:04 AM, Clinton Dreisbach clin...@dreisbach.uswrote: People, you are not going to win a fight with a Level 65 Troll Wizard. Back away slowly. Rob, this is a cool library: thanks for writing it. -- Clinton Dreisbach On Sun, Nov 17, 2013 at 7:53 AM, Cedric Greevey cgree...@gmail.comwrote: So, when people here are talking about the web, they might not be talking about the web. Erm, okay, I guess ... On Sun, Nov 17, 2013 at 7:11 AM, James Reeves ja...@booleanknot.comwrote: On 17 November 2013 05:25, Cedric Greevey cgree...@gmail.com wrote: On Sat, Nov 16, 2013 at 9:35 PM, James Reeves ja...@booleanknot.comwrote: On 17 November 2013 01:52, Cedric Greevey cgree...@gmail.com wrote: The distribution will be narrow and peak at around 1 second, though, which may not be what you want. Of course, the OP has since indicated that he meant non-web uses of HTTP rather than serving web sites... Web services are generally considered to be part of the web, hence the term *web* service :) Well, which is it? Either it's the web, and the user will probably promptly hit reload if faced with a 503 error at what should be a working URL, or else it's not the web, and lies outside the scope of my original remark. You're going to be very confused if you keep believing that the web only refers to the visible parts you can access through a browser! When people talk about web apps, they're not necessarily talking about websites. You just need to use your common sense to discern what they mean. If someone suggests something that might seem undesirable for a user-facing website to have, maybe they're talking about a machine-readable web service instead. - 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/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- 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
Re: [ANN] overload-middleware 0.1.1
On Sun, Nov 17, 2013 at 8:22 AM, Christian Romney xmlb...@gmail.com wrote: Maybe you should re-read this whole thread. Clinton is just pointing out how impolite it is, particularly as the first response to an ANN post, to poopoo all over someone else's work, Please provide a citation to back up your claim that I did anything of the kind. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] overload-middleware 0.1.1
I can think of very few web apps where this would be a desirable approach. A user getting a spurious error in response to a URL that they *know* is valid is just going to hammer on the reload button until they get a correct response from the server. So the server will end up even more congested than if it just responded sluggishly but otherwise normally to the request. On Sat, Nov 16, 2013 at 1:21 PM, Rob Day r...@rkd.me.uk wrote: Hi all, I've just published the first working version of a Ring middleware that some of you might find useful. It's designed for web apps where, if you're overloaded, it's better to serve some requests quickly and fail the others than to try and serve all the requests and do it slowly. (My background is in telecoms, where that's often the best approach.) Specifically, you specify a target latency that you want 90% of requests to try and meet, and it applies the algorithm from http://www.eecs.harvard.edu/%7Emdw/papers/control-usits03.pdf to try and keep your latency below that threshold. The exact parameters of the algorithm are tunable, and different URLs or groups of URLs can have different targets and parameters. It still needs a bit of tidying - docstrings, cleaning up some of the Midje tests, and so on - but it works and I think the documentation is usable, so I'm announcing it now. Github (w/ docs): https://github.com/rkday/overload-middleware Clojars: https://clojars.org/overload-middleware Let me know if you have any feedback! Rob P.S. I threw together a simple demo (available from https://github.com/rkday/overload-middleware-demo) and tested it It works as designed - the URL wrapped in the overload middleware fails about 50% of requests, and so for the ones that succeed there's a noticeable speed improvement (80% of results are served in 120ms as opposed to 233ms for the unwrapped URL), though I suspect ab might be counting the immediate 503s in this result and throwing it off. If anyone has ideas for better tests, let me know! 2049 14:05:02 overload-demo $ for i in unwrapped wrapped; do ab -n 5 -c 300 -q http://localhost:3000/$i; done ... Document Path: /unwrapped .. Failed requests:0 ... Percentage of the requests served within a certain time (ms) 50%178 66%204 75%216 80%233 90%358 95% 1117 98% 1211 99% 3097 100% 15196 (longest request) ... Document Path: /wrapped ... Failed requests:25285 (Connect: 0, Receive: 0, Length: 25285, Exceptions: 0) Write errors: 0 Non-2xx responses: 25285 ... Percentage of the requests served within a certain time (ms) 50% 67 66% 86 75%108 80%120 90% 1028 95% 1080 98% 1287 99% 3082 100% 15120 (longest request) There's also no noticeable overhead in non-overload cases: 2050 14:07:30 overload-demo $ for i in unwrapped wrapped; do ab -n 50 -c 1 -q http://localhost:3000/$i; done ... Document Path: /unwrapped .. Failed requests:0 ... Percentage of the requests served within a certain time (ms) 50% 33 66% 33 75% 33 80% 33 90% 33 95% 34 98% 35 99% 35 100% 35 (longest request) ... Document Path: /wrapped ... Failed requests:0 ... Percentage of the requests served within a certain time (ms) 50% 33 66% 34 75% 34 80% 34 90% 34 95% 34 98% 34 99% 34 100% 34 (longest request) -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] overload-middleware 0.1.1
Web browsers don't pick a random sleep time before trying again, though; they display a 500 error page and the user promptly clicks reload while making an exasperated sigh. If the client is something other than a web browser, then we're no longer talking about the web, but some other thing, like SMTP or whatever. And then we're outside the scope of my earlier remark, which specifically mentioned the web. Not to mention outside the scope of the OP's product, which was clearly referred to as a Ring middleware and not some other sort of server component for some other kind of server. Or were you meaning to suggest that the *users* pick a random sleep time before trying again? Good luck herding them cats. See also http://en.wikipedia.org/wiki/Wicked_problem ... On Sat, Nov 16, 2013 at 4:24 PM, James Reeves ja...@booleanknot.com wrote: It may be useful for certain web services. If the server gets overloaded by a temporary spike, the clients could pick a random sleep time before trying again. - James On 16 November 2013 21:15, Cedric Greevey cgree...@gmail.com wrote: I can think of very few web apps where this would be a desirable approach. A user getting a spurious error in response to a URL that they *know* is valid is just going to hammer on the reload button until they get a correct response from the server. So the server will end up even more congested than if it just responded sluggishly but otherwise normally to the request. On Sat, Nov 16, 2013 at 1:21 PM, Rob Day r...@rkd.me.uk wrote: Hi all, I've just published the first working version of a Ring middleware that some of you might find useful. It's designed for web apps where, if you're overloaded, it's better to serve some requests quickly and fail the others than to try and serve all the requests and do it slowly. (My background is in telecoms, where that's often the best approach.) Specifically, you specify a target latency that you want 90% of requests to try and meet, and it applies the algorithm from http://www.eecs.harvard.edu/%7Emdw/papers/control-usits03.pdf to try and keep your latency below that threshold. The exact parameters of the algorithm are tunable, and different URLs or groups of URLs can have different targets and parameters. It still needs a bit of tidying - docstrings, cleaning up some of the Midje tests, and so on - but it works and I think the documentation is usable, so I'm announcing it now. Github (w/ docs): https://github.com/rkday/overload-middleware Clojars: https://clojars.org/overload-middleware Let me know if you have any feedback! Rob P.S. I threw together a simple demo (available from https://github.com/rkday/overload-middleware-demo) and tested it It works as designed - the URL wrapped in the overload middleware fails about 50% of requests, and so for the ones that succeed there's a noticeable speed improvement (80% of results are served in 120ms as opposed to 233ms for the unwrapped URL), though I suspect ab might be counting the immediate 503s in this result and throwing it off. If anyone has ideas for better tests, let me know! 2049 14:05:02 overload-demo $ for i in unwrapped wrapped; do ab -n 5 -c 300 -q http://localhost:3000/$i; done ... Document Path: /unwrapped .. Failed requests:0 ... Percentage of the requests served within a certain time (ms) 50%178 66%204 75%216 80%233 90%358 95% 1117 98% 1211 99% 3097 100% 15196 (longest request) ... Document Path: /wrapped ... Failed requests:25285 (Connect: 0, Receive: 0, Length: 25285, Exceptions: 0) Write errors: 0 Non-2xx responses: 25285 ... Percentage of the requests served within a certain time (ms) 50% 67 66% 86 75%108 80%120 90% 1028 95% 1080 98% 1287 99% 3082 100% 15120 (longest request) There's also no noticeable overhead in non-overload cases: 2050 14:07:30 overload-demo $ for i in unwrapped wrapped; do ab -n 50 -c 1 -q http://localhost:3000/$i; done ... Document Path: /unwrapped .. Failed requests:0 ... Percentage of the requests served within a certain time (ms) 50% 33 66% 33 75% 33 80% 33 90% 33 95% 34 98% 35 99% 35 100% 35 (longest request) ... Document Path: /wrapped ... Failed requests:0 ... Percentage of the requests served within a certain time (ms) 50% 33 66% 34 75% 34 80% 34 90% 34 95% 34 98% 34 99% 34 100% 34 (longest request) -- -- 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
Re: [ANN] overload-middleware 0.1.1
On Sat, Nov 16, 2013 at 5:06 PM, James Reeves ja...@booleanknot.com wrote: Web servers are often used to serve information to clients other than web browsers. [citation needed] -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] overload-middleware 0.1.1
The distribution will be narrow and peak at around 1 second, though, which may not be what you want. Of course, the OP has since indicated that he meant non-web uses of HTTP rather than serving web sites... On Sat, Nov 16, 2013 at 7:10 PM, Colin Fleming colin.mailingl...@gmail.comwrote: Web browsers don't pick a random sleep time before trying again, though; they display a 500 error page and the user promptly clicks reload while making an exasperated sigh. That sounds like picking a random sleep time before trying again to me :-) If the client is something other than a web browser, then we're no longer talking about the web, but some other thing, like SMTP or whatever. And then we're outside the scope of my earlier remark, which specifically mentioned the web. Not to mention outside the scope of the OP's product, which was clearly referred to as a Ring middleware and not some other sort of server component for some other kind of server. Or were you meaning to suggest that the *users* pick a random sleep time before trying again? Good luck herding them cats. See also http://en.wikipedia.org/wiki/Wicked_problem ... On Sat, Nov 16, 2013 at 4:24 PM, James Reeves ja...@booleanknot.comwrote: It may be useful for certain web services. If the server gets overloaded by a temporary spike, the clients could pick a random sleep time before trying again. - James On 16 November 2013 21:15, Cedric Greevey cgree...@gmail.com wrote: I can think of very few web apps where this would be a desirable approach. A user getting a spurious error in response to a URL that they *know* is valid is just going to hammer on the reload button until they get a correct response from the server. So the server will end up even more congested than if it just responded sluggishly but otherwise normally to the request. On Sat, Nov 16, 2013 at 1:21 PM, Rob Day r...@rkd.me.uk wrote: Hi all, I've just published the first working version of a Ring middleware that some of you might find useful. It's designed for web apps where, if you're overloaded, it's better to serve some requests quickly and fail the others than to try and serve all the requests and do it slowly. (My background is in telecoms, where that's often the best approach.) Specifically, you specify a target latency that you want 90% of requests to try and meet, and it applies the algorithm from http://www.eecs.harvard.edu/%7Emdw/papers/control-usits03.pdf to try and keep your latency below that threshold. The exact parameters of the algorithm are tunable, and different URLs or groups of URLs can have different targets and parameters. It still needs a bit of tidying - docstrings, cleaning up some of the Midje tests, and so on - but it works and I think the documentation is usable, so I'm announcing it now. Github (w/ docs): https://github.com/rkday/overload-middleware Clojars: https://clojars.org/overload-middleware Let me know if you have any feedback! Rob P.S. I threw together a simple demo (available from https://github.com/rkday/overload-middleware-demo) and tested it It works as designed - the URL wrapped in the overload middleware fails about 50% of requests, and so for the ones that succeed there's a noticeable speed improvement (80% of results are served in 120ms as opposed to 233ms for the unwrapped URL), though I suspect ab might be counting the immediate 503s in this result and throwing it off. If anyone has ideas for better tests, let me know! 2049 14:05:02 overload-demo $ for i in unwrapped wrapped; do ab -n 5 -c 300 -q http://localhost:3000/$i; done ... Document Path: /unwrapped .. Failed requests:0 ... Percentage of the requests served within a certain time (ms) 50%178 66%204 75%216 80%233 90%358 95% 1117 98% 1211 99% 3097 100% 15196 (longest request) ... Document Path: /wrapped ... Failed requests:25285 (Connect: 0, Receive: 0, Length: 25285, Exceptions: 0) Write errors: 0 Non-2xx responses: 25285 ... Percentage of the requests served within a certain time (ms) 50% 67 66% 86 75%108 80%120 90% 1028 95% 1080 98% 1287 99% 3082 100% 15120 (longest request) There's also no noticeable overhead in non-overload cases: 2050 14:07:30 overload-demo $ for i in unwrapped wrapped; do ab -n 50 -c 1 -q http://localhost:3000/$i; done ... Document Path: /unwrapped .. Failed requests:0 ... Percentage of the requests served within a certain time (ms) 50% 33 66% 33 75% 33 80% 33 90% 33 95% 34 98% 35 99% 35 100% 35 (longest request) ... Document Path: /wrapped ... Failed requests:0 ... Percentage of the requests served within a certain time (ms) 50% 33 66% 34 75% 34 80% 34 90% 34 95
Re: Question on Sequences
This efficiency is why built-in functions to map, filter, etc. vectors to vectors aren't provided; better to use (into []) on a chain of seq-outputting transformations of a vector than to chain these hypothetical vector-native functions. OTOH, it occurs to me that efficient chaining can still be achieved in library form, by using monads of some sort to transform it into (into [] (op1 (op2 (op3 ... v under the hood. We have something like (into [] (filter x v)), (into [] (map y v)), etc. that we'd like composed into (into [] (filter x (map y (filter z ... v, rather than stacking repeated (into [])s, and that pattern *looks* an awful lot like it should be expressible as a monadic transformation of some kind. I don't have enough monad-fu to write out an actual implementation, though. :) That also leads to the weird thought that there might be some way to use monads to create reducers-like functionality for nearly any underlying data structure, with only the need to parametrize a few things for different underlying storage. On Sat, Nov 16, 2013 at 7:11 PM, Andy Fingerhut andy.finger...@gmail.comwrote: I don't know if it is idiomatic, but it certainly looks like a good way to achieve the desired effect. If you chained together calls to several functions like your example only-evens, it would not be lazy, and it would build up a separate instance of collections of the original type at each step of the way. Likely it would be more efficient to delay the conversion back to the original collection type until after the last sequence operation you wanted to perform. Andy On Sat, Nov 16, 2013 at 4:01 PM, Alexandru Nedelcu a...@bionicspirit.comwrote: Hi, I'm trying to understand the design of Clojure's collections and one thing that I find odd is the return of functions operating on sequences. Like for instance a call such as this will return a lazy-seq and not a vector: (drop 2 [1 2 3 4]) The reason why I find it odd is that data-structures have different characteristics and one may want to use a vector because it supports efficient indexing and appending to the end. Of course, dropping 2 elements like above from a vector is probably going to have O(n) complexity and thus returning something lazy is more appropriate. And while there are some operations, like conj, pop and peek that preserve the type, functions such as map and filter also return lazy-seq. And I worry that the property of the collection you start with is lost, given that this returns a cons: (conj (filter even? [1 2 3 4 5]) 6) So lets say that I want to write a generic function that preserves the type of that collection. Is something like this idiomatic? (defn only-evens [coll] (into (empty coll) (filter even? coll))) Thanks, -- Alexandru Nedelcu www.bionicspirit.com PGP Public Key: https://bionicspirit.com/key.aexpk -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: [ANN] overload-middleware 0.1.1
On Sat, Nov 16, 2013 at 9:35 PM, James Reeves ja...@booleanknot.com wrote: On 17 November 2013 01:52, Cedric Greevey cgree...@gmail.com wrote: The distribution will be narrow and peak at around 1 second, though, which may not be what you want. Of course, the OP has since indicated that he meant non-web uses of HTTP rather than serving web sites... Web services are generally considered to be part of the web, hence the term *web* service :) Well, which is it? Either it's the web, and the user will probably promptly hit reload if faced with a 503 error at what should be a working URL, or else it's not the web, and lies outside the scope of my original remark. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: A Design (Simplification) Problem
One might also wish to consider a pull model, in which clients explicitly request information they need from the server. A client could ask for an object's health, given its ID; or for the current ids and positions of monsters in a particular small geographical area (which the server would look up using interval trees). On Wed, Nov 13, 2013 at 1:46 PM, Phlex ph...@telenet.be wrote: Instead of making changes to your data structure, then creating an event, you could : -create a modification command as a data structure {:type :move :character-id 12 :move-to {some coords..}} -apply it to your data structure (each and every modification to the data structure would have to be done via those commands) -send it to the client as an event (some filtering might be in order) This way you have a clear way to channel all your commands to your world, a clean separation between command, world and client. A clean interface to your world and finally a clean wire protocol ! (and easy logging, replay from save point etc...) Sacha -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Out of Memory Error
Yeah, rewrite that to not hold the head of lines. In particular, get rid of counts entirely, get rid of (nth lines ...), and use something like (loop [lines (seq lines) res {}] (if lines (recur (next lines) (update-res res (first lines))) res)) as your loop. On Tue, Nov 12, 2013 at 3:19 AM, Jiaqi Liu liujiaq...@gmail.com wrote: hi , guys I wrote the following codes to parse log files. it's alright to parse small one. But with big log files , i got the following error: OutOfMemoryError GC overhead limit exceeded clojure.core/line-seq (core.clj:2679) (defn parse-file [file] (with-open [rdr (io/reader file)] (println Statistic result : (parse-recur rdr (defn parse-recur [rdr] (let [lines (line-seq rdr) counts (count lines)] (loop [len counts res {}] (if (zero? len) res (recur (dec len) (update-res res (nth lines (- counts len (defn update-res [res line] (let [params (string/split line #,) id (if ( (count params) 1) (params 0) 0)] (if (res id) (update-in res [id] inc) (assoc res id 1 How can fix this bug ? and how to optimize this produce to run faster ? Any suggestion will be appreciated~ BR 刘家齐 (Jacky Liu) 手机:15201091195邮箱:liujiaq...@gmail.com Skype:jacky_liu_1987 QQ:406229156 -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out. -- -- You received this message because you are subscribed to the Google Groups Clojure group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Does Pedestal have a future in the long run
IMO it can often be a lack of readable, searchable, nice-to-navigate text/hypertext that can be a barrier to entry. In fact all of these are unfortunately common in various parts of the geekosphere: 1. Projects whose *only* documentation (or the only version of certain key information) is in videos. Not searchable. Not easy to navigate to a particular part (need to remember roughly when it is, or rewatch half the thing). Expensive for mobile users with capped or per-megabyte data plans. 2. Projects whose *only* documentation is reference-type material that does not introduce the library/whatever to total n00bs. A common case is for there to be beautifully detailed Javadoc for every public class, method, and constant in some Java library, but nothing to give a n00b a clue as to where to start using it. Sometimes it's fairly obvious (there's a problem domain class Foo that it makes sense to instantiate first, and that class has a public constructor, has a public static getInstance method, or sits next to a FooFactory class in the same package, and this is well-documented) but often it's not. Regardless, it would be preferable for there to be a getting started guide. With a textual version that can be searched with grep or other tools. 3. Projects whose *only* documentation is a getting-started guide, tour, tutorial, or similar. When one knows the basic patterns of usage but wants to recall the argument order for the (burbling-mumblefrotz ...) function, having to find where it was introduced in a tutorial (which chapter? The one on mumbling or the one on burbling? Near the start, middle, or end? Page 2 or 29???) is a pain in the neck. A reference is organized differently, for making a specific known entity easy to re-find. Javadocs and Clojure docstrings are good for this. In particular: * Every key fact, example, or other piece of documentation should exist somewhere in a form that Google can find on the web and grep can find in your local copy if you make one. And that local copy shouldn't cost a fortune to download and a ton-lot of disk space to keep, nor should it be a pain in the ass to scroll forward and backward through. Ideally, it should be browseable on a fairly low-spec machine if need be, as well, even one that makes video playback stutter at 3 FPS. * There needs to be two differently organized written forms of documentation: one oriented around discovering how to do X, for people that don't know the name of the function, class, method, or other entity that does X; and one oriented around specifying precisely the usage, behavior, and applicable preconditions/gotchas/etc. of a particular function, method, class, or whatever that one *does* know the name to. The latter is typically partly machine-generated and organized hierarchically and alphabetically by package/namespace and name. The former tends to be mainly human-authored and often linear, or at most a few branches, of exposition, which shows how the parts are interrelated and how to build up from those parts to useful working systems of some sort. Videos do have their uses, but should not be regarded as *substitutes* for either written reference documentation or written tutorial documentation, and the latter are not substitutes for one another. I'd regard a lack of good *written* introductory material as a much worse barrier to entry than a lack of good videos, where the subject matter lends itself to textual exposition (math, programming). (That last restriction of scope is necessary; no amount of written material telling people how to play golf, for instance, is likely to beat a good video showing a proper stance and backswing. Gross motor skills in general benefit strongly from, at minimum, video clips of key moves/actions. Most things benefit from the occasional illustrative still image, however.) On Sun, Nov 10, 2013 at 10:10 AM, Ryan Waters ryan.or...@gmail.com wrote: Thank you Saravana. I'm finding a number of the posts David Nolen [1] has written on his blog to be invaluable. Once I figure out what mix of libraries I'll be using I can let you know! [1] http://swannodette.github.io/ On Sat, Nov 9, 2013 at 12:33 PM, Ryan Neufeld r...@cognitect.com wrote: Stuart Halloway is doing a presentation and we’ll be dumping a lot more new stuff into the repository. I made a mistake in saying we had an announcement, it’s more just that we’ll be talking more publicly about what we’re working on following next week. -Ryan On November 8, 2013 at 5:39:34 PM, Andreas Liljeqvist (bon...@gmail.com//bon...@gmail.com) wrote: Will there by any presentation on Pedestal, or just announcements? On Fri, Nov 8, 2013 at 1:38 AM, Ryan Neufeld r...@thinkrelevance.comwrote: Speaking as a core Pedestal team member and engineer at Cognitect I can say we are *very* serious about continuing to grow and support Pedestal. It may be quiet, but we're using the entirety of Pedestal with a number of client and are fervently