Re: :require farms in Clojure?

2011-07-20 Thread stu
On Jul 20, 4:19 pm, Meikel Brandmeyer m...@kotka.de wrote:

 I think he wants more something like this:

 (ns require.farm)

 (def xxx '[[foo.bar [a :as a] [b :as b]] frob.nicate])
 (def yyy '[[foo.bar.c :as c]])

 (ns require.userA
   (:require [require.farm :as requires]))

 (apply require requires/xxx)

Yes -- this is the kind of thing I was wondering about (although
Chas' answer is immediately useful too--thanks).

At this point I'm wondering if this is an idiomatic way to work
with Clojure namespaces especially in larger projects with many sub-
components as namespaces?  Maybe one day we could have:

(ns myproject
(:require subproject.* :as :suffix) to require subproject.foo1
subproject.foo2...


Thanks

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


:require farms in Clojure?

2011-07-19 Thread stu
Hi,

In larger Clojure projects with nested namespaces I've found there are
less namespace pollution issues if I avoid (ns... :use...) forms in
preference to (ns... :require...) forms.  This approach sometimes
leads to namespace constructs like:

(ns myfuns
(:require
[foo.baz.a :as a]
[foo.baz.b :as b]
[foo.baz.c :as c...]))

Is there an idiomatic way of coalescing these :require clauses into
a :require farm that can be simply :require'd or is this the wrong
way to manage namespaces in Clojure projects?

Any advice much appreciated,

Stu


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Looking for examples of using Java iterators from Clojure...

2011-07-09 Thread stu
Hi,

I'd like to make use of Java classes implementing the Java2D
PathIterator interface:

http://download.oracle.com/javase/6/docs/api/java/awt/geom/PathIterator.html

Which leads to a serious impedance mismatch between immutable Clojure
data structures and the iterator's approach of calling next() until
isDone() and using currentSegment() to retrieve the point
coordinates.

I'd guess this kind of iterator is widely used in the Java world, so
can some kind person point to an example of Clojure code using a Java
iterator in this way?

Thanks in advance,

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Idiomatic way to reference a bundled data file from Clojure source?

2011-06-28 Thread stu
Hi,

I'd like to bundle a collection of (JSON) datafiles with a Clojure
project source tree so that Clojure functions can reliably find and
open those datafiles.

What's the idiomatic way of going about this?  In the past with other
languages I've used tricks like Ruby's .dirname(__FILE__)/...
construct but this kind of approach doesn't seem a good fit for
Clojure or for the JVM facilities it provides.

Can anyone point to a Clojure project that does this well?

Thanks,

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Idiomatic way to reference a bundled data file from Clojure source?

2011-06-28 Thread stu
On Jun 29, 12:17 pm, Stephen C. Gilardi squee...@mac.com wrote:

  I'd like to bundle a collection of (JSON) datafiles with a Clojure
  project source tree so that Clojure functions can reliably find and
  open those datafiles.

  What's the idiomatic way of going about this?

   Many thanks to Dave and Stephen for your answers--just what I
needed.

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Hygenic approach for using Java2D from Clojure?

2011-06-28 Thread stu
Hi,

I'd like to use Java2D objects in a Clojure application.  I understand
that these mutable objects will be operating in a Clojure environment
where immutability is the order of the day, and this is likely to
cause problems.

Can someone point me to some good examples of, or techniques for
safely using mutable Java objects in Clojure--especially with Clojure
parallel programming constructs in mind.

Thanks in advance,

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: 2D graphics options with Clojure?

2011-05-01 Thread stu
On Apr 30, 5:54 pm, Nathan Sorenson n...@sfu.ca wrote:

 Batik can serialize to both PNG and PDF.http://xmlgraphics.apache.org/batik/

 I currently use Batik in a clojure project doing a lot of drawing of
 2d vector-based images. It's a very extensive library but it suits my
 needs well.

  Do you have any Clojure examples of Batik use I could look at?

Thanks,

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


2D graphics options with Clojure?

2011-04-29 Thread stu
Hi,

I'm developing a Clojure project that loads and creates a bunch of
simple 2D geometry (lines, polygons, beziers, text etc). I need to
create in a batch-style way high quality 2D renderings of that
geometry, firstly as PNG files and secondly as PDF files.

What are my options for doing this from Clojure?

So far I can see it might be done with Java2D as I think this can be
used server-side to create the PNG files, but not sure about the
PDFs.  I believe I can use Incanter's wrapping of the Processing
libraries for the PNG and again I'm not sure about the PDF option.

The Cairo toolkit is also an option via the Gnome Java bindings and
Java interop?

Are there other options that I'm missing that anyone would like to
report on?

Thanks in advance,

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


How to access specific java.awt.Color constructor?

2011-04-09 Thread stu
Hi,

I'm trying to create a java.awt.Color class instance from within
Clojure, using this constructor:

Color(ColorSpace cspace, float[] components, float alpha)

But always end up with a No matching ctor found for class
java.awt.Color exception.

I can create the ColorSpace instance as I expected, but I think I'm
missing something with the rest of the Color constructor.  I've tried
changing the components to a vector of floats or a Java array of
floats with no luck.

This is with Clojure 1.2 and the Java Platform SE 6 AWT classes.

Any advice much appreciated.

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: How to access specific java.awt.Color constructor?

2011-04-09 Thread stu
On Apr 10, 8:35 am, Alan a...@malloys.org wrote:

 You probably weren't putting it into a java float array, but instead a
 Float array (boxed type). Here's a repl session doing what you want. I
 don't know anything about colorspaces so it's probably nonsense, but
 it creates a Color with that constructor.

   Thanks Alan -- I realize now there's a subtle but important
distinction there when doing Java interop.

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Polymorphic functions in Clojure (or how to stop thinking in objects)...

2011-03-17 Thread stu
Hi,

I wanted to take the opportunity to thank the people who responded to
my question on thinking beyond O-O.  The replies form a very useful
slice through Clojure design strategies and idiomatic use of the
language.

Thanks!

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Polymorphic functions in Clojure (or how to stop thinking in objects)...

2011-03-14 Thread stu
Hi,

I'd like to create a simple library of drawable shapes: lines, circles
and rectangles.  I've placed each type of shape in its own namespace
with functions that operate on that shape kind:

(ns myshapes.line)

(defn line ... creates new line ...)

(defn draw ... draws a line ...)


To keep things simple a line is just a vector of two points and
circles and rectangles are just structs.
I'd also like to have a sequence of shapes called a picture:

(ns myshapes.picture)

(defn picture ... returns picture sequence from args ...)

(defn draw ... draws whole picture)


The problem I have is with the myshapes.picture/draw function. As a
Clojure newb I keep wanting to think of this like a polymorphic
function in the O-O world that relies on each sequence member having a
draw function.

What's the idiomatic way of handling a situation like this in
Clojure?  Do I need to use richer data structures than vectors and
structs for the shapes so they carry some kind of type information?  I
can see how a draw multi-method would work if the individual shapes
could be distinguished, or am I going about this the wrong way?

Any advice much appreciated,

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Idiomatic way to handle name shadowing?...

2011-03-10 Thread stu
Hi,

This is a newb question so apologies in advance if I haven't read
enough Clojure code yet to see the answer.

Suppose I need mathematical 2D vector functions:


(ns geometry.vector)

(defstruct vector :x :y)

(defn +
Add vectors v and w, yielding a vector
[ v w ]
(...))

Which leads to the core vector function being shadowed by my struct
and the core + function shadowed by my function.  What is the
idiomatic Clojure approach for handling this situation?  Is it through
careful use of :require and :import parts of a (ns ...) form?

I've also seen instances of naming changes to avoid the problem, e.g.
(defstruct vector ...) and (defn vector+ ...)
but not sure if that's making best use of Clojure namespaces?

Any advice much appreciated,

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Idiomatic way to handle name shadowing?...

2011-03-10 Thread stu
On Mar 11, 8:35 am, Alan a...@malloys.org wrote:

  Suppose I need mathematical 2D vector functions:

  (ns geometry.vector)

  (defstruct vector :x :y)

  (defn +
          Add vectors v and w, yielding a vector
          [ v w ]
          (...))

  Which leads to the core vector function being shadowed by my struct
  and the core + function shadowed by my function.  What is the
  idiomatic Clojure approach for handling this situation?  Is it through
  careful use of :require and :import parts of a (ns ...) form?

 user= (ns math (:refer-clojure :rename {vector cvector}))
 nil
 math= vector
 java.lang.Exception: Unable to resolve symbol: vector in this context
 (NO_SOURCE_FILE:0)
 math= (def vector identity)
 #'math/vector
 math= (vector 10)
 10
 math= (cvector 10)
 [10]

Thanks for that -- please bear with me on this: does that mean that
given the flexible options available in the (ns...) form as shown
here, Clojure developers don't need to choose non-shadowed names like
vector or (defn vector+), but rather use the more natural forms and
use (ns...) clauses to make everything clear as needed?

Thanks,

Stu

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Re: Transient Data Structures

2009-08-05 Thread Stu Hood
I really, really like this feature. My only complaint is that you have to
use different names for the modifying functions. If the function signatures
will be identical to their non-transient variants, then I guess the primary
arguments would be:
 * Clojure convention for names of functions with side-effects,
 * An additional interface check in conj/assoc?

But if after calling (conj v 1), you can't use the 'v' reference anymore,
then did you really cause a side effect? Its another tree falling in the
woods situation.

Thanks,
Stu


On Wed, Aug 5, 2009 at 9:05 AM, Rich Hickey richhic...@gmail.com wrote:


 On Tue, Aug 4, 2009 at 10:13 PM, John Harropjharrop...@gmail.com wrote:
  On Tue, Aug 4, 2009 at 5:50 PM, Rich Hickey richhic...@gmail.com
 wrote:
 
  On Aug 4, 4:31 pm, John Harrop jharrop...@gmail.com wrote:
   What about things like:
  
   (persistent!
 (reduce
   (fn [x [i v]] (assoc! x i v))
   (transient (vec (repeat 0 (reduce max (map first
   coll-of-index-val-pairs)
   coll-of-index-val-pairs))
  
 
  Yes, that's completely fine intended usage, as the return value of the
  reducing fn becomes an argument to the next call.
 
   which is just the transientification of
  
 
  Nice word - transientification.
 
  Thanks.
  Of course, this makes me think of ways to possibly speed up other
  operations. For example:
  (defn vmap* [fun vect]
(let [c (count vect)]
  (loop [out (transient []) i 0]
(if (= i c)
  out
  (recur (conj! out (fun (nth vect i))) (inc i))
  (defn vmap [fun vect]
(persistent! (vmap* fun vect)))

  Vector in, vector out, conj'd up using a transient.

 Mapping into vectors and similar ops are coming, although nothing like
 vmap* would ever be exposed.

  And, of course:
  (defn vpmap [fun vect]
(loop [out (vmap* #(future (fun %)) vect) i (dec (count vect))]
  (let [o2 (assoc! out i @(nth out i))]
(if (zero? i)
  (persistent! o2)
  (recur o2 (dec i)
  Note that this last manipulates a transient vector in a single thread,
  though other threads (from the agent pool) calculate a bunch of futures
 that
  are stored in it. The transient vector of futures is generated using the
  vmap* from above, and then the futures are replaced with their values
  in-place by the loop in vpmap, before this persistentizes and returns
 that
  vector. The future-dereferencing loop works backwards from the end of the
  vector in case zero? is a quicker test than a general equality test. This
 is
  likely on hardware that implements an equality test as a subtraction
  followed by a zero test, because it eliminates the subtraction. On the
 other
  hand, hardware with a 1-cycle equality test of 32-bit ints is plausible,
 as
  is hardware that optimizes forward traversal of vectors, so I can't vouch
  for that being an optimization. The first loop has to go forward to conj
 up
  the output vector without reversing it, though.
 

 There is already a very nice pvmap in the par branch that uses
 ForkJoin. I strongly recommend against trying to write parallel ops
 with transients - that's not what they are for.

 What's nice about pvmap is that, just like transients, it also takes,
 manipulates, and returns ordinary Clojure vectors (unlike the old
 parallel lib which copied into and out of ForkJoin's ParallelArrays).
 The goal is to make using the normal data structures as powerful as
 possible, and not needing to switch to something else for performance.

 Rich

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: why is io! not enforced?

2009-06-22 Thread Stu Hood
This won't work unfortunately, because it means that the in-memory transaction 
has already commited before the disk write is performed by the agent. If the 
application crashed at that point, your write was not durable.

-- Sent from my Palm Pre
ataggart wrote:




On Jun 20, 4:59 pm, Rowdy Rednose  wrote:
 On a side-note: I actually think it can make sense to do io in
 transactions in Clojure, and I believe (knowing that transactions can
 be replayed) it is possible to use that to e.g. implement a
 transaction log written to disk that could be used to rebuild the data
 in case of a crash.

Use agents. When inside a running transaction, all agent dispatches
are held until the transaction commits.



--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Metadata for Any Object

2009-04-29 Thread Stu Hood
Hey gang,

Metadata support for pure Java objects is not currently supported, because
it requires a modification to the object. Additionally, only some Clojure
objects support metadata, due to the necessity of implementing the IMeta
interface. This can be confusing for new users, and eliminates some of the
utility.

Instead of attaching the metadata directly to the object, what if the
metadata was stored outside the object, in a global map of {object metadata,
...}? In order to handle garbage collection, something similar to Java's
WeakHashMap could be used, with the object itself as the key.

I know global state is Considered Harmful, but I think this would clarify
the usage of metadata, and remove duplication in the implementation of
Clojure.

Thoughts?
Stu

--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: [Discuss] Contribs with dependencies

2009-04-15 Thread Stu Hood
I agree. I think the breaking into modules approach is the only scalable
solution.

Someone else mentioned that clojure-contrib is/shouldbe an incubating area
for core, which seems reasonable. There should be a little more pushback
when a project wants to make it into contrib, and it should already be
organized such that its dependencies would be well known if it wanted to
make it out of 'incubation' and into core.


On Tue, Apr 14, 2009 at 5:02 PM, Howard Lewis Ship hls...@gmail.com wrote:


 I'd say to refactor clojure-contrib into a number of seperate modules;
 individual modules (each with its own pom) could have their own
 dependencies. Thus if you choose clojure-contrib-freechart, you get
 that JAR (or compiled Clojure sources) plus the jfreechart dependency.

 In this way you are using the good part of Maven: transitive
 dependency management.

 On Tue, Apr 14, 2009 at 5:19 AM, Rich Hickey richhic...@gmail.com wrote:
 
  I've been thinking recently about contribs with dependencies.
 
  I think it's very important to have layers - e.g. core depends only on
  JDK 1.5, contrib only on core. Lately there have been some ideas
  centering around Joda Time, [Parallel]Colt, AWS, JFreeChart, Fork/Join
  etc.
 
  I'd like to start a discussion about how best to support the
  contributions of libraries that depend on things not in the JDK.
 
  Obviously, without care and rules it could get crazy quickly, and I
  want to avoid the kitchen-sink effect. It is very important that
  things remain [truly, not just apparently] simple.
 
  Looking for suggestions,
 
  Rich
 
  
 



 --
 Howard M. Lewis Ship

 Creator of Apache Tapestry
 Director of Open Source Technology at Formos

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: advice needed converting large files to xml

2009-03-16 Thread Stu Hood
If you write your CSV - XML processing as a function, you could pmap (
http://clojure.org/api#pmap)  that function across the list of input files.
pmap will transparently create the threads as needed, and it will probably
be enough to saturate your disk.

Thanks,
Stu

On Mon, Mar 16, 2009 at 5:56 PM, Brian Doyle brianpdo...@gmail.com wrote:

 I've been using Clojure for about 6 months now and really like it.  I am
 somewhat new to multi-threading
 and using any of the parallel features in Clojure though.   I have a
 situation where I need to convert
 7 files from CSV to XML.  Each one of these files is about 180MB apiece in
 size.   I have dual core machine
 with 2GB of RAM and would like some advice on the best strategy for
 processing these files in a way that
 really utilizes both cores and my memory to really speed up the
 processing.I'm sure this isn't the best
 way, but I've only come up with starting up two threads at first, having
 each thread open up a file,
 call line-seq on that file, write out the XML for each line and then go to
 the next file when it's complete.   Any
 advice would be great.  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
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Bytecode optimization

2009-03-14 Thread Stu Hood
Rich has done a lot of work to make sure that when you are working with
primitives, the JVM bytecode ends up being very similar to what Java would
generate. See http://clojure.org/java_interop#toc36

Thanks,
Stu

On Thu, Mar 12, 2009 at 6:20 PM, Howard Lewis Ship hls...@gmail.com wrote:


 Well, at some point I'll open up the code and check.  Though I'll be
 overly tempted to write some comments, fix the indentation and write
 some tests if I do!

 On Thu, Mar 12, 2009 at 2:36 PM, Jarkko Oranen chous...@gmail.com wrote:
 
 
  On Mar 12, 11:15 pm, Howard Lewis Ship hls...@gmail.com wrote:
  I have to wonder a bit about the ability to optimize.  Everything
  boils down to one of the seven or so basic forms.  That's a lot of
  function calls to do even small things, like adding numbers. You might
  think that simple math would be optimized and inlined, but it isn't:
 
  Clojure
  user= (doc +)
  -
  clojure.core/+
  ([] [x] [x y] [x y  more])
Returns the sum of nums. (+) returns 0.
  nil
  user= (ns clojure.core)
  #Namespace clojure.core
  clojure.core= (defn + [x y] (* x y))
  #'clojure.core/+
  clojure.core= (+ 3 5)
  15
  clojure.core=
 
  This implies, to me, that Clojure is doing a full functional call,
  with dynamic lookup via the namespace, even for +.
 
  I think this is mistaken. Sure, for (+ foo bar) calls in the repl
  Clojure will do a full lookup,  but if you have  addition in a tight
  loop, the JVM should notice this and optimise it further. (I think
  Clojure also does some kind of caching.) You can also use type casts
  to make clojure use primitive instead of boxed math, bringing
  performance very close to Java.
 
  Now, it's probably true that the most straightforward Clojure
  implementation of an algorithm is likely not quite as fast as the Java
  equivalent, with a few tricks, you can often get pretty close.
 
  I don't have very in-depth knowledge of how Clojure handles these
  performance issues, but I believe your assumption is overly
  pessimistic. :)
 
  --
  Jarkko
  
 



 --
 Howard M. Lewis Ship

 Creator Apache Tapestry and Apache HiveMind

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Performance tips for Clojure

2009-03-14 Thread Stu Hood
There is a interface 'Counted' that a lot of Clojure data structures
implement to indicate that they provide O(1) for (count).

Thanks,
Stu

On Fri, Mar 13, 2009 at 4:59 AM, Christophe Grand christo...@cgrand.netwrote:


 Christian Vest Hansen a écrit :
  I think that count is O(n) for lists, no?
 

 Count is O(1) for lists but O(n) for a chain of conses.

 Clojure
 user= (let [l (apply list (range 10))] (time (dotimes [_ 100]
 (count l
 Elapsed time: 169.710116 msecs
 nil
 user= (let [l (apply list (range 40))] (time (dotimes [_ 100]
 (count l
 Elapsed time: 167.664046 msecs
 nil
 user= (let [l (reduce #(cons %2 %1) nil (range 10))] (time (dotimes
 [_ 100] (count l
 Elapsed time: 662.121862 msecs
 nil
 user= (let [l (reduce #(cons %2 %1) nil (range 100))] (time
 (dotimes [_ 100] (count l
 Elapsed time: 5316.110567 msecs
 nil


 --
 Professional: http://cgrand.net/ (fr)
 On Clojure: http://clj-me.blogspot.com/ (en)



 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Laziness madness

2009-03-01 Thread Stu Hood
Laziness hit home for me in Clojure when I noticed that one of our Java
library functions, looking for a Collection, had happily accepted a Clojure
(map ...) object which was going to expand a small set of integers into much
larger objects. Because Clojure deferred the work, they were only generated
when they were actually needed, and saved memory the rest of the time.

Thanks,
Stu


On Mon, Mar 2, 2009 at 1:17 AM, Laurent PETIT laurent.pe...@gmail.comwrote:

 Hello,

 The way I think about it is am I in a portion of code that does pure
 functional stuff, or am I doing side effects ?
 A pure functional stuff resembles a computation, but not the storage
 part, or the part that gets the stuff from the outside (that is, no input /
 output stuff).

 doing side effects is when your function not only responds to a call to
 it by reading its input data and computing a new one that it returns, but
 also when it reads the input data, does some stuff to change the world (by
 accessing functions that will permanently change the world), and also
 (maybe) return a value.
 In this case, generally, comes with the non pure stuff the need to
 control the flow of execution of your program. That is : function A must be
 called before function B, and the effects of A on the world must have been
 realized before function B can run.

 In your case, you're calling add-watch which is clearly (to me) a
 side-effect function because it adds watchers to a long list of watchees by
 modifying them in place (side-effect).

 Generally speaking, if this talk about side-effect free function is still
 a little bit unclear to you, here are some smells to guess if a given
 function is pure or not :

 - does the function return a value (different from nil) ? If no - probably
 a function with side effect .. or a function that really does nothing !
 - does the function return newly computed values ? If no - probably a
 function with side effect .. or a function that really does nothing !
 (please note that the inverse is not true : you can't say that a function is
 pure just because it returns a new computed value of something)

 I would like to add a third rule to this list, but currently you will not
 encounter it for a lot of cases, yet it is correct in a number of case and I
 think it applies correctly to those cases :
 - does the function implementation use calls to functions ending with a !
 ( e.g. set!) : those functions are performing side effects by permanently
 changing the value of something in the world.

 HTH,

 --
 Laurent

 2009/3/2 max3000 maxime.lar...@gmail.com


 Hi,

 I find the laziness in clojure very hard to wrap my head around. I
 understand the idea and it's probably nice in theory. However, in real
 life it doesn't seem really useful beyond hardcore mathematical
 problems.

 Case in point, I just spent 2 hours debugging a piece of code (shown
 below) that seemed simple enough. This is the 3rd time this week that
 I've lost substantial time to laziness. I'm pretty pissed to tell the
 truth and I find myself wrapping things in doseq more and more just to
 be sure. I rarely use 'for' anymore, what's the point?

 Here is the code that gave me trouble:

(map #(add-watch % watcher callback-fn) all-agents)

 This was not executing. I had to change it to the below expression:

(doseq [agent all-labor-agents]
  (add-watch agent total-labor-agent callback-fn))

 This second expression seems less elegant than the map above. Why
 doesn't clojure realize that an add-watch really should actually loop
 over all-agents? Why is it that Java calls are not made in similar
 expressions?

 Is laziness so useful that we should waste time investigating and
 fixing errors like this? Sure, there could be special constructs for
 laziness when we really need it. However, clojure shouldn't default to
 it IMO. At this point, laziness is a nice concept but it feels
 somewhat removed from reality to tell the truth. Of course I want to
 iterate over my collection when I'm doing an add-watch!

 What am I missing?

 Thanks,

 Max





 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Simple math functions should support sequences

2009-02-03 Thread Stu Hood
 This is a common misconception: passing a seq to apply doesn't force its
 evaluation.
Ahh, is this because the [ more] portion is itself a lazy sequence? That's
very cool =)

Hmm, the (reduce + ...) approach works just fine, but if it is already
implemented as reduce, it seems like it would be very easy to allow (+) to
take a sequence.

I still think the
 ( (range 10))
... use case is really worthwhile though, and I don't see a way to
accomplish it with reduce.

Thanks,
Stu

On Tue, Feb 3, 2009 at 1:36 PM, Christophe Grand christo...@cgrand.netwrote:


 Hello,

 stuhood a écrit :
  Functions like (+), (*), (-), (and probably more) should support
  sequences as parameters.
 
  The current way to accomplish this (without implementing your own sum
  using reduce) seems to be:
 
  (apply + (map #(. Math pow 2 %) (range 10)))
 
  ... which has to generate the sequence first.
 
 This is a common misconception: passing a seq to apply doesn't force its
 evaluation.
 You can test this fact by passing an infinite seq to a function:
 (defn second-arg [ args]
  (second args))
 user= (apply second-arg (iterate inc 0))
 1


 and (apply + some-seq) is really equivalent to (reduce + some-seq), see
 the def of + in core.clj:
 (defn +
 ...
  ([x y  more]
   (reduce + (+ x y) more)))

 Christophe

 --
 Professional: http://cgrand.net/ (fr)
 On Clojure: http://clj-me.blogspot.com/ (en)



 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Simple math functions should support sequences

2009-02-03 Thread Stu Hood
 but apply works very well for this use case: (apply  (range 10))
 and it stops as soon as it can:
Alright, I fold... thanks for clearing things up Christophe!


On Tue, Feb 3, 2009 at 3:13 PM, Christophe Grand christo...@cgrand.netwrote:


 Stu Hood a écrit :
  I still think the
  ( (range 10))
  ... use case is really worthwhile though, and I don't see a way to
  accomplish it with reduce.

 reduce is not a good fit since you would want to short circuit the
 computation at the first false.
 but apply works very well for this use case: (apply  (range 10))
 and it stops as soon as it can:

 user=(apply  (map #(doto % println) (concat (range 10 20) (range 10
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 0
 false

 Christophe

 --
 Professional: http://cgrand.net/ (fr)
 On Clojure: http://clj-me.blogspot.com/ (en)



 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Synchronization Benchmarks

2009-01-17 Thread Stu Hood

I added a Clojure implementation based on an Atom instead of a Ref,
and re-ran the tests (this time on a quad core machine). I also fixed
the calculation of the percent change in both tests (ugh).

It looks like using an Atom is slightly more performant than a Ref if
you are making a single state change that is commutative/indempotent.
Also, RWDict fell apart on a quad core machine (independent of the
number of writes): I'll try with the alternative fairness setting like
you suggested.

Thanks,
Stu

On 1/16/09, Christian Vest Hansen karmazi...@gmail.com wrote:

 Another thing you might want to test is the fairness of the rw-lock in
 your RWDict, because even a couple of very active readers can easily
 starve out any number of writers when the rw-lock is non-fair. The
 reason is simple: readers can interleave but writers cannot, and
 writers can only get in when noone is reading :)

 On Fri, Jan 16, 2009 at 4:21 AM, Stu Hood stuh...@gmail.com wrote:
 Ah! but a mere hash table is not bi-directional :-)
 Right =)  I got the idea in a Channel 9 video about MS' efforts with STM:
 http://channel9.msdn.com/shows/Going+Deep/Software-Transactional-Memory-The-Current-State-of-the-Art/
 (which reminds me, the spin-lock approach they try is probably fairly
 close
 to using an Atom in Clojure).

 I made the changes that Christophe suggested, and added type hints for the
 HashMaps used in CLJDict, and the speed improvement is very impressive. To
 see the scalability of the different approaches, I graphed with various
 numbers of threads and read percentages:
 http://github.com/stuhood/clojure-conc/tree/master/results

 Two conclusions:
  1. The overhead for STM with low contention is very reasonable,
  2. Optimism + MVCC + persistence fall down when faced with a majority of
 writes. (see the 100% write case in the writes graph.)

 Thanks,
 Stu


 On Thu, Jan 15, 2009 at 2:52 PM, Christian Vest Hansen
 karmazi...@gmail.com wrote:

 On Thu, Jan 15, 2009 at 8:47 PM, Christian Vest Hansen
 karmazi...@gmail.com wrote:
  On Thu, Jan 15, 2009 at 8:35 PM, Mark H. mark.hoem...@gmail.com
  wrote:
  On Jan 15, 1:38 am, stuhood stuh...@gmail.com wrote:
  The benchmark contains 4 bi-directional dictionary implementations:
 ...
 
  Doesn't Java already have a more optimized thread-safe hash table that
  works by locking individual buckets, rather than the whole table?
  Maybe I'm just confused ;-P

 Ah! but a mere hash table is not bi-directional :-)


 --
 Venlig hilsen / Kind regards,
 Christian Vest Hansen.




 




 --
 Venlig hilsen / Kind regards,
 Christian Vest Hansen.

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Synchronization Benchmarks

2009-01-15 Thread Stu Hood
 Ah! but a mere hash table is not bi-directional :-)
Right =)  I got the idea in a Channel 9 video about MS' efforts with STM:
http://channel9.msdn.com/shows/Going+Deep/Software-Transactional-Memory-The-Current-State-of-the-Art/(which
reminds me, the spin-lock approach they try is probably fairly close
to using an Atom in Clojure).

I made the changes that Christophe suggested, and added type hints for the
HashMaps used in CLJDict, and the speed improvement is very impressive. To
see the scalability of the different approaches, I graphed with various
numbers of threads and read percentages:
http://github.com/stuhood/clojure-conc/tree/master/results

Two conclusions:
 1. The overhead for STM with low contention is very reasonable,
 2. Optimism + MVCC + persistence fall down when faced with a majority of
writes. (see the 100% write case in the writes graph.)

Thanks,
Stu


On Thu, Jan 15, 2009 at 2:52 PM, Christian Vest Hansen karmazi...@gmail.com
 wrote:


 On Thu, Jan 15, 2009 at 8:47 PM, Christian Vest Hansen
 karmazi...@gmail.com wrote:
  On Thu, Jan 15, 2009 at 8:35 PM, Mark H. mark.hoem...@gmail.com wrote:
  On Jan 15, 1:38 am, stuhood stuh...@gmail.com wrote:
  The benchmark contains 4 bi-directional dictionary implementations:
 ...
 
  Doesn't Java already have a more optimized thread-safe hash table that
  works by locking individual buckets, rather than the whole table?
  Maybe I'm just confused ;-P

 Ah! but a mere hash table is not bi-directional :-)


 --
 Venlig hilsen / Kind regards,
 Christian Vest Hansen.

 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: test-is reporting problem

2009-01-15 Thread Stu Hood
You do that.
-another Stuart


On Thu, Jan 15, 2009 at 10:32 PM, Stuart Sierra the.stuart.sie...@gmail.com
 wrote:


 I was afraid that would happen.  I'll fix it, probably tomorrow.
 -the other Stuart

 On Jan 15, 6:27 pm, Stuart Halloway stuart.hallo...@gmail.com wrote:
  The improved error reposting in test-is breaks some tests, e.g. from
  the book:
 
  (deftest test-lazy-index-of-any-with-match
(is (with-out-str (is (zero? (index-of-any zzabyycdxx #{\z \a}
Iterating overz\n)
(is (with-out-str (is (= 3 (index-of-any zzabyycdxx #{\b \y}
Iterating overz\nIterating over z\nIterating over a\n))
 
  The problem is that it tries to take the value of with-out-str, not
  realizing that it is a macro.
 
  Should I
 
  (1) rewrite the test to not use a macro?
  (2) take a stab at fixing this in test-is?
  (3) get out of the way and let another Stuart handle it?  :-)
 
  Stuart
 


--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
Clojure group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---