Re: soft question: should remote channels appear like local channels

2014-01-31 Thread Cedric Greevey
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

2014-01-30 Thread Cedric Greevey
+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

2014-01-28 Thread Cedric Greevey
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)

2014-01-27 Thread Cedric Greevey
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

2014-01-27 Thread Cedric Greevey
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

2014-01-27 Thread Cedric Greevey
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

2014-01-26 Thread Cedric Greevey
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 ?

2014-01-26 Thread Cedric Greevey
(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

2014-01-25 Thread Cedric Greevey
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

2014-01-25 Thread Cedric Greevey
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

2014-01-24 Thread Cedric Greevey
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

2014-01-24 Thread Cedric Greevey
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

2014-01-24 Thread Cedric Greevey
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

2014-01-24 Thread Cedric Greevey
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

2014-01-23 Thread Cedric Greevey
[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

2014-01-23 Thread Cedric Greevey
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

2014-01-23 Thread Cedric Greevey
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

2014-01-22 Thread Cedric Greevey
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

2014-01-22 Thread Cedric Greevey
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

2014-01-13 Thread Cedric Greevey
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?

2014-01-10 Thread Cedric Greevey
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

2014-01-09 Thread Cedric Greevey
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

2014-01-09 Thread Cedric Greevey
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

2014-01-09 Thread Cedric Greevey
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

2014-01-09 Thread Cedric Greevey
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

2014-01-06 Thread Cedric Greevey
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

2014-01-05 Thread Cedric Greevey
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

2014-01-04 Thread Cedric Greevey
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

2014-01-03 Thread Cedric Greevey
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

2014-01-03 Thread Cedric Greevey
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

2013-12-31 Thread Cedric Greevey
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 ?

2013-12-31 Thread Cedric Greevey
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

2013-12-31 Thread Cedric Greevey
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

2013-12-30 Thread Cedric Greevey
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

2013-12-30 Thread Cedric Greevey
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

2013-12-30 Thread Cedric Greevey
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

2013-12-30 Thread Cedric Greevey
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

2013-12-30 Thread Cedric Greevey
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

2013-12-29 Thread Cedric Greevey
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?

2013-12-29 Thread Cedric Greevey
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?

2013-12-29 Thread Cedric Greevey
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

2013-12-29 Thread Cedric Greevey
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

2013-12-29 Thread Cedric Greevey
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?

2013-12-28 Thread Cedric Greevey
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?

2013-12-28 Thread Cedric Greevey
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?

2013-12-28 Thread Cedric Greevey
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?

2013-12-28 Thread Cedric Greevey
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?]

2013-12-27 Thread Cedric Greevey
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?]

2013-12-27 Thread Cedric Greevey
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?]

2013-12-27 Thread Cedric Greevey
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.

2013-12-26 Thread Cedric Greevey
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?

2013-12-26 Thread Cedric Greevey
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?

2013-12-26 Thread Cedric Greevey
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.

2013-12-24 Thread Cedric Greevey
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?

2013-12-23 Thread Cedric Greevey
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

2013-12-23 Thread Cedric Greevey
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

2013-12-18 Thread Cedric Greevey
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

2013-12-17 Thread Cedric Greevey
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

2013-12-16 Thread Cedric Greevey
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?

2013-12-16 Thread Cedric Greevey
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

2013-12-16 Thread Cedric Greevey
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

2013-12-16 Thread Cedric Greevey
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

2013-12-13 Thread Cedric Greevey
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

2013-12-11 Thread Cedric Greevey
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

2013-12-11 Thread Cedric Greevey
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

2013-12-10 Thread Cedric Greevey
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

2013-12-10 Thread Cedric Greevey
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

2013-12-10 Thread Cedric Greevey
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?

2013-12-03 Thread Cedric Greevey
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

2013-12-03 Thread Cedric Greevey
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

2013-11-29 Thread Cedric Greevey
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

2013-11-29 Thread Cedric Greevey
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

2013-11-29 Thread Cedric Greevey
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

2013-11-28 Thread Cedric Greevey
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

2013-11-27 Thread Cedric Greevey
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

2013-11-27 Thread Cedric Greevey
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

2013-11-27 Thread Cedric Greevey
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

2013-11-26 Thread Cedric Greevey
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

2013-11-26 Thread Cedric Greevey
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

2013-11-25 Thread Cedric Greevey
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

2013-11-25 Thread Cedric Greevey
(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

2013-11-25 Thread Cedric Greevey
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

2013-11-24 Thread Cedric Greevey
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

2013-11-24 Thread Cedric Greevey
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

2013-11-24 Thread Cedric Greevey
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

2013-11-23 Thread Cedric Greevey
(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

2013-11-20 Thread Cedric Greevey
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

2013-11-19 Thread Cedric Greevey
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

2013-11-18 Thread Cedric Greevey
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

2013-11-17 Thread Cedric Greevey
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

2013-11-17 Thread Cedric Greevey
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

2013-11-16 Thread Cedric Greevey
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

2013-11-16 Thread Cedric Greevey
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

2013-11-16 Thread Cedric Greevey
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

2013-11-16 Thread Cedric Greevey
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

2013-11-16 Thread Cedric Greevey
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

2013-11-16 Thread Cedric Greevey
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

2013-11-13 Thread Cedric Greevey
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

2013-11-12 Thread Cedric Greevey
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

2013-11-10 Thread Cedric Greevey
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 

  1   2   3   4   5   6   >