Re: Why does (= [] (range)) not terminate?

2012-02-17 Thread Michael Gardner
On Feb 17, 2012, at 2:29 PM, Alan Malloy wrote:

> Lazy sequences implement java.util.List, which has a .size method.
> clojure.lang.APersistentVector/doEquiv (and doEquals) attempts to
> optimize when it sees it is being compared to something with a .size
> or .count method, by comparing sizes before doing the hard work of
> comparing elements. But this is not much of an optimization when
> the .size method is infinitely slow! Perhaps an additional test for
> lazy sequences should be added to these methods, but I'm certain the
> issue is more complicated than it appears after my cursory
> exploration, so that may well have other issues.

Thanks for the explanation; I guessed it might be something like that. It seems 
a dubious optimization to do an initial size check on collections for which 
size/count are O(n), even when n isn't infinite!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 does (= [] (range)) not terminate?

2012-02-17 Thread Michael Gardner
On Feb 17, 2012, at 12:32 PM, Bill Smith wrote:

> It might help to know that (= (range) (range)) does not terminate either.

Of course, since a pairwise sequential comparison (what I assume is going on 
under the hood) will never find a non-matching pair.

> It appears that the = operator wants to fully evaluate the second argument 
> before comparing to the first.  Since (range) is infinite, it hangs.

Yes, that is what appears to be happening. The question is: why? Why does it 
only do this to the second argument? Why does (= v s) for any vector `v' and 
any infinite lazy sequence `s' not terminate, while (= s v) does?

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


Why does (= [] (range)) not terminate?

2012-02-17 Thread Michael Gardner
I came across something interesting while working on some code posted in 
another thread: it seems (= [] (range)) does not terminate, while (= (range) 
[]) does. Why is that?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 be lazy…

2012-02-16 Thread Michael Gardner
On Feb 16, 2012, at 11:08 AM, Wolodja Wentland wrote:

> Thanks for the explanation. What would be a good way to ensure that the
> subseqeuence are lazy too?

I can't think of a good way to do this with higher-order functions, so you'll 
probably have to write a recursive function that "manually" iterates over the 
collection, looking ahead as necessary to figure out when to split. To make the 
result lazy, just wrap your function's body in a call to lazy-seq.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 be lazy…

2012-02-16 Thread Michael Gardner
partition-by is lazy in that it only splits its argument into as many subseqs 
as requested; the subseqs themselves are not lazy. So when you partition-by the 
result of (replace-subseq-with-sentinel [1 2] sentinel (range)) and then 
request the infinite third subseq thereof, partition-by won't terminate.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: stack overflow vs scheme

2011-12-01 Thread Michael Gardner
Try increasing the JVM's stack size with -Xss.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: need help eliminating ordinary recursion/thinking the Clojure way

2011-11-11 Thread Michael Gardner
Since you're given a sorted list of intervals, you don't actually need to 
restart the whole merging process from the start after each merge; you can just 
replace the last interval in your output with the new, merged interval and 
continue from there. So `reduce' is the perfect tool for the job; my solution 
is below.

I used 2-vectors for ranges since they're easier to type and read. Note that 
reduce-intervals builds its result in reverse, since seqs like to be 
manipulated from the head.

(defn intervals-intersect? [s1 s2]
(not (or
(> (s1 0) (s2 1))
(> (s2 0) (s1 1)

(defn join-intervals [s1 s2]
[(min (s1 0) (s2 0)) (max (s1 1) (s2 1))])

(defn reduce-intervals [reduced s]
(let [[s-prev & more] reduced]
(if (and s-prev (intervals-intersect? s-prev s))
(cons (join-intervals s-prev s) more)
(cons s reduced

(defn merge-intervals [intervals]
(reverse
(reduce reduce-intervals []
intervals)))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: anyone interested in a small game?

2011-10-31 Thread Michael Gardner
On Oct 31, 2011, at 2:03 PM, Timothy Baldridge wrote:

> This is what Clojure excels at...de-coupling, or as Rich put it in his
> recent talk "Simple made Easy": don't assume things about your code.
> Don't assume that all models will always fit into the concept of a
> polygon...don't assume that you'll always want to represent your
> models via Java2D.

It's impossible to make zero assumptions about your code; the trick is figuring 
out which are the appropriate ones. Making too many assumptions leads to 
brittle and hard-to-extend code, but making too few leads to over-generalized, 
ponderous code that does way more than it's ever likely to be used for.

In a case like this game, it should be easy to refactor away from the 
"everything is a polygon" model if and when the game outgrows it, so I'd argue 
against introducing the extra complexity of per-entity renderers until it's 
actually necessary.

That's a strength of dynamic, expressive languages like Clojure, IMO: because 
there's so much less code, refactoring is much easier. So instead of trying to 
predict all future requirements and possibly ending up with over-generalized 
code, you can make assumptions based on current/near-term requirements and 
refactor when those assumptions no longer apply.

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


Re: When to use mutable state

2011-10-14 Thread Michael Gardner
On Oct 14, 2011, at 8:48 AM, Timothy Baldridge wrote:

> On Fri, Oct 14, 2011 at 7:58 AM, pistacchio  wrote:
>> I'm implementing a litte "game" thing in Clojure. So far I'm passing
>> around a "world status" object among functions. It is very
>> "functional" and I can simulate any moment of the game my simply
>> feeding the system with a made-up world state.
> 
> 
> Well you're going to get a slight performance boost by going to a
> controlled mutable state as you won't have to modify your entire state
> tree whenever any object changes, you'll only have to modify the part
> that changes. But what I see as the biggest benefit to using mutable
> state, is being able multi-thread your program. Running everything on
> one thread is s 20th century. ;-)

Clojure's data structures are designed to support efficient creation of 
modified versions via structural sharing; e.g. a map created via assoc shares 
much of the same memory as the map from which it was created. So unless you're 
building the entire game state from scratch each time, you don't have to worry 
about modifying the "entire" state tree as opposed to a small portion of it.

Not saying you won't get any performance boost from using mutation, just that 
the performance of the functional solution is not nearly as bad as you might 
think. As always, profiling trumps guessing about performance bottlenecks.

On Oct 14, 2011, at 7:58 AM, pistacchio wrote:

> Since Clojure has a very sophisticate system for managing state
> (references, atoms...) I wanted to know what is the more idiomatic way
> of programming Clojure, whether to use its system or to stick to a
> more functional approach.

Don't feel you have to just use atoms etc just because they're there. Clojure 
is basically a functional language; mutability is limited to a few specific 
constructs precisely because idiomatic Clojure code is expected to be nearly 
all functional, with mutability used only as necessary. Performance might be 
one reason to use mutability (though see above); another might be that some 
framework you're using more-or-les requires it.

For example, Java's Swing has you provide a callback function that is supposed 
to know how to draw your app's content. But Swing can't pass your current world 
state to your callback, so the callback needs to be able to access the world 
state in some other way. A "global" atom holding the world state is a pretty 
natural solution in that case.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Spread work onto multiple threads (in pure Clojure)

2011-10-11 Thread Michael Gardner
Just to throw in my two cents here: it would really be a shame for Clojure's 
pmap to continue to languish in the state it's currently in (i.e. nearly 
useless). Even though implementing an alternative using thread pools isn't too 
hard, it hurts the Clojure concurrency sales pitch-- I can't tell people "and 
often you can parallelize simple programs just by changing a single character 
(map -> pmap)" without adding the caveat "but pmap kind of sucks for most 
purposes, so you'll probably have to roll your own or use a library".

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: suggestion for clojure development

2011-09-28 Thread Michael Gardner
On Sep 28, 2011, at 7:20 PM, Arthur Edelstein wrote:

> So what's the plan for the future? Are there plans to make clojure
> stable at some point so that backward compatibility can be expected?
> Otherwise I am going to have difficulty continuing to advocate clojure
> to my colleagues. In other words, when will the library ecosystem be
> considered important enough not to break?

I don't think there will (nor should) ever be a declaration by the core team 
that "from this point onward, we will never break backwards compatibility." 
There's always a trade-off between maintaining backwards compatibility and 
making improvements to the language. Naturally, as the language matures the 
tradeoff will shift towards compatibility, but in my opinion it would be 
foolish to set anything in stone. I don't think the lack of any such promise 
has hurt Python, for example; and while the transition to 3.0 certainly seems 
to have been slow and painful, I don't doubt the language will survive.

> I think a statement of the policies of the Clojure/Core team (perhaps
> spelled out on the website) concerning stability and backward
> compatibility would really help those of us who want to be able to
> rely on Clojure.

I think the absence of such a statement makes it clear that although breaking 
backwards compatibility is obviously bad, the core team is making no 
hard-and-fast promises. This seems consistent with what other dynamic languages 
are doing, and is a Good Thing for the language in my view.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Randomly select an element from a sorted-set (rand-nth (sorted-set ..))

2011-09-26 Thread Michael Gardner
On Sep 26, 2011, at 8:12 AM, Paul Richards wrote:

> How can I efficiently pick a random element from a sorted-set?

If your sorted set is densely packed (if most possible values do appear in the 
set), then you could just pick a random value, see if it's in the set, and 
repeat until you find a match.

Otherwise, you could use a sorted-vector. I don't know if there's a good 
implementation out there, though, so you might have to roll your own.

Or you could use a sorted-set that can do a "random binary search", where it 
chooses between the first and second halves at random rather than by comparison 
with a particular value. Maybe you could subclass the Clojure sorted-set to do 
this, though I'm guessing it's not made for subclassing.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 expressions in macro are not evaluated?

2011-09-14 Thread Michael Gardner
On Sep 13, 2011, at 2:39 AM, jingguo wrote:

> I get a_message printed twice if I paste the code in a clojure REPL.
> But I save the code into a file called foo.clj and use "clj foo.clj"
> to run it. I get nothing in stdout. It seems that (printf "a_message
> \n")
> is not evaluated. Can anybody explain this behavior? Thanks.

`for' yields a lazy sequence, whose elements are not actually evaluated until 
they are used. The REPL automatically prints the result of each expression you 
evaluate, which is the only thing that's causing those printfs to get 
evaluated. Try using `doseq' instead.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: puzzlement over lazy sequences

2011-09-12 Thread Michael Gardner
On Sep 12, 2011, at 11:28 PM, Ken Wesson wrote:

> But if, as you say, take, drop, etc. work for larger n, it should be
> easy to make nth work with larger n and non-random-access seqs, just
> by changing the non-random-access case to (first (drop n the-seq)).

I'd be rather surprised if nth suddenly started giving linear performance on 
arrays for large values of n. If nth can't be made to work in constant time on 
arrays for n > 2**31, then I'd favor the IllegalArgumentException approach. One 
can always do (first (drop …)) manually if linear performance is acceptable.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: lambda function returning a constant?

2011-09-06 Thread Michael Gardner
On Sep 6, 2011, at 10:43 PM, Armando Blancas wrote:

> For something like "=> true" try:
> user=> (defmacro => [expr] `(fn [] ~expr))
> #'user/=> (macroexpand-1 '(=> true))
> (clojure.core/fn [] true)

Alternatively: (constantly true)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Question regarding structural sharing, records, and maps

2011-07-29 Thread Michael Gardner
On Jul 28, 2011, at 10:59 PM, Trenton Strong wrote:

> So far, I
> have settled on just using a single ref wrapping the root node of the
> tree with all update functions acting on that ref via dosync.

An atom would be more appropriate, unless you're coordinating updates to the 
tree with updates to some other ref.

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


Re: Code structure/design problems

2011-07-29 Thread Michael Gardner
On Jul 29, 2011, at 1:50 AM, Laurent PETIT wrote:

> Without too much thinking about it, I would have thought monsters, players, 
> etc. need to be changed in a same "transaction", so would have by default 
> implemented them as refs instead of atoms.
> 
> Could you elaborate more on the choice of atoms as design decisions ?

Not to hijack the question, but in my game I used a single atom containing the 
state of the entire game world as a hash. This is not too inefficient thanks to 
Clojure's structure-sharing, and has certain advantages: saving or printing the 
world state becomes trivial, and you can simplify argument lists for functions 
that need to use multiple world objects (though some would object to passing 
the entire world to a function that uses only certain parts of 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


Re: Code structure/design problems

2011-07-28 Thread Michael Gardner
On Jul 28, 2011, at 1:44 AM, Oskar wrote:

> I have a hard time coming up reasons why this would be better. My
> function that I wanted that checks if two characters are close enough
> to each other is just a very small part of my game. And I could make
> just that function fuctional and my list of benefits would be nil.
> Sure, immutable data structures is great, for example, but in this
> case, I don't see how making the game purely functional would make the
> code better. But I could be wrong of course. It's kind of hard to
> imagine. If enough people say "Yes, do it!" I might try it.

I'd say "yes" if only for the experience of writing a "purely functional" game 
(minus the I/O, of course). I wrote a Pong clone in a similar way, though I 
don't share that author's dislike for passing the whole world to each "mover" 
function. That lets you do neat things like:

(reduce
(fn [world mover]
(merge world (mover world dt))) 
[world
move-players
move-ball   
collide-player
collide-wall
collide-goal])

where each of the "mover" functions returns an updated partial world hash. One 
advantage to this approach is that you can see exactly what changes to the 
world each function is making, which is great for testing and debugging. Of 
course you can use an atom in much the same way, but to me passing a "world" 
argument around my program isn't a big deal.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Alright, fess up, who's unhappy with clojurescript?

2011-07-24 Thread Michael Gardner
On Jul 24, 2011, at 2:08 PM, James Keats wrote:

> On Jul 24, 7:24 pm, Michael Gardner  wrote:
>> The functional parts of Javascript are far different from those of Clojure 
>> (and not in a good way).
> 
> How so? javasript, while not as functional as clojure, is far more
> functional than java ( first class functions, closures, anonymous
> functions etc.

Javascript is simply painful to use functionally. The verbosity of anonymous 
functions, the lack of crucial HOFs like map/filter/reduce, the lack of 
functional data structures, the lack of macros (not strictly a "functional" 
feature, but especially useful with functional code)... You can fix these to 
varying degrees with libraries; but in any case the overall superiority of 
Clojure syntax and data structures must be obvious to anyone interested in 
ClojureScript, since those are the sole advantages it provides over Javascript.

> A small subset of clojure would mirror and could expand
> on a small subset of javascript); it's been called a "Lisp in C's
> Clothing", and Brendan Eich famously and repeatedly said "As I’ve
> often said, and as others at Netscape can confirm, I was recruited to
> Netscape with the promise of “doing Scheme” in the browser" Back at
> Netscape "doing a scheme in the browser" was botched a bit by a deal
> with Sun and "the diktat from upper engineering management was that
> the language must “look like Java”."[1], and whereas clojure/
> clojurescript now had an opportunity to correct that, instead it's
> piling on the Java-ism with gClosure.

Why should we care what kind of Javascript ClojureScript generates, as long as 
it's correct and performant? The whole point of the project is to allow us to 
write Clojure rather than Javascript!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Alright, fess up, who's unhappy with clojurescript?

2011-07-24 Thread Michael Gardner
On Jul 24, 2011, at 1:11 PM, James Keats wrote:

>> Restricting yourself to a functional subset of JavaScript can't fix
>> JavaScript. The functional subset stinks, Javascript notaries be damned.
> 
> If so where does this leave clojure itself and its advocacy of
> functional programming, then; see last paragraph of my reply to Mark.

You can't draw any inference along those lines from David's observation. The 
functional parts of Javascript are far different from those of Clojure (and not 
in a good 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


Re: Question on eliminating recur

2011-07-09 Thread Michael Gardner
On Jul 9, 2011, at 8:47 AM, Brian Hurt wrote:

> If there is an obvious way to rewrite the code using doseq or fold (or reduce 
> or map or etc), then yes- you should do it.  However, if this way to rewrite 
> the code isn't obvious in 10 seconds of thought, don't worry about it. Use 
> loop/recur.  The goal is clear, concise code- not blind obedience to 
> aphorisms.

I think Christian wanted to know *why* one "should" eliminate recur. I can't 
think of a reason to avoid it myself, though I also don't recall hearing any 
recommendations against using recur.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Clojure for variadic functions with optional leading arguments?

2011-07-09 Thread Michael Gardner
On Jul 9, 2011, at 6:16 PM, Sean Corfield wrote:

> If I need a function to have something like the following signatures,
> what's the most idiomatic way to do it:
> 
> ([fn-arg str-arg vec-arg & others] ...)
> ([str-arg vec-arg & others] ...)
> 
> Background: several functions in clojure.java.jdbc are already
> variadic but as part of JDBC-6 I want to enable users to pass in an
> optional function to tweak the PreparedStatement before it is
> executed. My options seem to be ugly code to test types at the start
> of the argument lists or to add in optional keyword arguments at the
> end of the argument list (which still means processing the arguments
> and doing sort of type testing but which feels a bit cleaner).

Keywords args are a viable option, and they don't necessarily have to come at 
the end of the varargs. Type-testing feels really ugly and Perlish to me.

The only other options I see are to wrap the varargs in a vector, or to create 
two functions with different names. I don't think there's one "idiomatic" way 
to do it; it depends on your constraints and preferences.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Applying Java functions

2011-06-17 Thread Michael Gardner
On Jun 17, 2011, at 3:44 AM, Konrad Hinsen wrote:

> Java methods aren't even first-class objects (nor, in fact, objects at all) 
> in the Java world. Clojure can hardly do better than Java in unifying things 
> at the JVM level. The one thing that you can do with a method in Java is call 
> it, and the same limitation applies in Clojure.

Why would it have to be done at the JVM level? Couldn't the Clojure compiler 
generate an anonymous function whenever it sees a Java method? I presume it 
currently doesn't do this for performance reasons.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Your favorite utility function or macro.

2011-03-25 Thread Michael Gardner
This comes in handy for me when I'm dealing with side-effects but can't use 
doto:

(defmacro do-with [[binding-form init-expr] & body]
"Evaluates body with binding-form bound to the value of init-expr, then 
yields that same value."
`(let [~binding-form ~init-expr]
~@body
~binding-form))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Jesus, how the heck to do anything?

2011-03-23 Thread Michael Gardner
On Mar 23, 2011, at 7:26 PM, Armando Blancas wrote:

> But there's no question that to use Clojure
> you need a good grasp of java, the language and infrastructure, no way
> around that.

I don't know about that. I've been teaching a young'un Clojure without ever 
mentioning anything about Java. Knowing a bit about the JVM and .jar files and 
such might be helpful in setting things up initially, and certainly Java 
libraries (both standard and third-party) can come in handy to solve certain 
kinds of problems; but even for that you don't really need to know Java the 
language.

Then again, maybe I'm underestimating how hard it would be to read Java API 
docs without knowing the language...

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 read this sample code?

2011-03-16 Thread Michael Gardner
On Mar 15, 2011, at 5:28 PM, Christian wrote:

> Secondly, what is happening inside the for structure? [idx elt] are
> being bound to vector returned by indexed, but that assignment only
> happens when pred == elt. Finally, we return the vector idx. Is this
> correct?

[idx elt] is destructuring-bound to each element in (indexed coll), one after 
another, except that those elements for which (pred elt) returns false or nil 
are skipped (pred is being called as a function on elt, not compared to it). 
The result of the for loop is the sequence of values given by the expression in 
its body (in this case the indexes whose values in coll satisfied pred). That 
for loop would be equivalent to this map + filter:

(map first
  (filter (fn [[idx elt]] (pred elt))
(indexed coll)))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: The horrors of setting up a decent OpenGL clojure environment.

2011-02-21 Thread Michael Gardner
On Feb 21, 2011, at 8:24 AM, Timothy Baldridge wrote:

> Finally I found out that the "best" was was to use lein. So I
> installed lein, and after several hours finally got it to download and
> install Clojure. I added penumbra to my project.clj, and told lein to
> get the deps. It downloaded dozens of packages then said it completed.
> Oh! but penumbra also requires a Java OpenGL interop package that
> isn't on clojars!

Do you have lwjgl in your project's :native-dependencies? In any case, you 
might have better luck asking the Leiningen mailing list.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Get digits of a number

2011-02-17 Thread Michael Gardner
On Feb 17, 2011, at 1:36 PM, Mike Meyer wrote:

> My turn...
> 
> (defn to-digits
>  "Create a seq of digits from a number."
>  [i]
>  ^{:user/comment "For Euler Problems (Specifically 16)"}
>  (map {\0 0 \1 1 \2 2 \3 3 \4 4 \5 5 \6 6 \7 7 \8 8 \9 9}
>   (str  i)))
> 
> No assumption about representation here. But my Python background is
> showing - Pythons dictionaries are used *everywhere* in the language,
> and hence tuned as tightly as possible and thus blasted fast.

Why not use Character/digit, as Saul suggested?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Anyone want to take a crack at making the fasta shootout program faster?

2011-02-12 Thread Michael Gardner
On Feb 12, 2011, at 3:38 PM, Isaac Gouy wrote:

> On Feb 12, 1:28 pm, Michael Gardner  wrote:
>> That's why this kind of competition is not interesting to me. As it only 
>> compares the fastest programs, there's every incentive to submit 
>> horrifically complex, optimized-to-the-hilt solutions that would almost 
>> never get used in the real world.
>> 
>> Rather than ask "what's the fastest this can be done in language X?", we 
>> should ask "how fast are the idiomatic ways of doing this in language X" and 
>> possibly "how hard is it to do it faster, when those are not good enough?".
> 
> 
> Looking at the benchmarks game web page showing the "fasta" programs:
> - 4 different Clojure programs are shown
> - 2 different Java programs are shown
> - 4 different C programs are shown
> etc
> 
> 
> http://shootout.alioth.debian.org/u32/performance.php?test=fasta
> 
> 
>> Possibly just including code size/complexity with the performance metric 
>> would do the trick, though measuring that cross-language is a challenge all 
>> its own.
> 
> There is a column showing compressed source code size for each
> program.
> 
> 
> And then there's 
> http://shootout.alioth.debian.org/u32/code-used-time-used-shapes.php

Those are all good, but how many people actually look at anything beyond the 
fastest implementation for a given language? To some extent this is their 
problem, sure, but it's not helped by the prominence the shootout site gives to 
the fastest implementations in various places.

In the first place, I'm not even sure what the purpose of all that data is. 
What do people do with it? Is it purely for entertainment, or do people 
actually use it to decide what language to use for a project? If it's just for 
entertainment (as the word "game" seems to imply), won't people just skim the 
numbers for the fastest programs and walk away with wrong impressions?

In my opinion, it's simply not meaningful nor interesting to compare the 
fastest implementations across different languages. But by presenting those 
comparisons prominently (even when it also provides other more meaningful 
comparisons elsewhere), the shootout site does disservice to its users and the 
programming community by providing a convenient yet misleading focus point.

Perhaps each language could have one "best" implementation selected by the 
community or by a panel of judges; then the default or most prominent 
comparisons could use these "best" implementations rather than the fastest 
ones. Either way, it would be good to remove those fastest-vs-fastest 
comparisons altogether, or at least reduce their prominence significantly.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Anyone want to take a crack at making the fasta shootout program faster?

2011-02-12 Thread Michael Gardner
On Feb 12, 2011, at 3:12 PM, Isaac Gouy wrote:

> Yeah but it's not too hard to see why the Lisp programmer Juho
> Snellman opined on HN "the [sic program] implementations seem to have
> totally dived off the deep end of complexity".

That's why this kind of competition is not interesting to me. As it only 
compares the fastest programs, there's every incentive to submit horrifically 
complex, optimized-to-the-hilt solutions that would almost never get used in 
the real world.

Rather than ask "what's the fastest this can be done in language X?", we should 
ask "how fast are the idiomatic ways of doing this in language X" and possibly 
"how hard is it to do it faster, when those are not good enough?".

Possibly just including code size/complexity with the performance metric would 
do the trick, though measuring that cross-language is a challenge all its own.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 does pmap partition its work?

2011-01-27 Thread Michael Gardner
On Jan 27, 2011, at 7:24 AM, Rasmus Svensson wrote:

> If you simply want all tasks to be performed as quickly as possible,
> one alternative could be to use an ExecutorService (perhaps one
> created with newFixedThreadPool) with its invokeAll method. invokeAll
> takes a collection of callables (in clojure terms: you can pass it a
> seq of zero-arg functions) and returns a collection of futures. An
> ExecutorService could perhaps give you fine-grained control.
> 
> I recently wrote a blog post on this; you might find it interesting:
> http://blog.raek.se/2011/01/24/executors-in-clojure/

Thanks for the tip. By coincidence, I just stumbled across ExecutorService 
yesterday via the example at http://clojure.org/concurrent_programming. I'm 
never thrilled about having to use Java APIs directly, but in this case an 
ExecutorService does what I want much better than pmap, and isn't too difficult 
to use.

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


Re: What is the difference between a tail-recursive function and a recursive function using recur?

2011-01-26 Thread Michael Gardner
Tail-recursive just means the recursive call occurs in tail position: the 
result of the recursive call gets returned as-is rather than having some 
additional computations done to it first. This means the compiler *could* 
optimize the recursive call to not consume any additional stack space, by 
replacing the current stack frame rather than pushing a new one.

However, the JVM does not support tail-call optimization. Apparently Clojure 
can't support implicit TCO without support from the JVM, so it requires that 
you use the explicit 'recur' construct to allow it to simulate TCO in the 
self-recursive case. Recur can only occur in tail position, and Clojure will 
give you an error if you try to use it elsewhere.

On Jan 26, 2011, at 9:04 AM, Harrison Maseko wrote:

> Hi all,
> I need some help in understanding some basic concept. The book
> Programming Clojure on pages 134 - 136 deals with tail recursion and
> self-recursion using recur. The tail recursive example blows the stack
> while the self-recursive function using recur presented on page 135
> does not. On page 136 the book says that "the critical difference
> between tail-fibo (tail recursion) and recur-fibo (self-recursion
> using recur) is on line 7, where recur replaces the call to fib." Why
> does recur make such a difference in the way the function consumes
> resources? What really is the difference between a tail-recursive
> function and a recursive function using recur?
> Thanks for your help.
> -h.
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=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
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 does pmap partition its work?

2011-01-25 Thread Michael Gardner
On Jan 25, 2011, at 12:13 PM, Andy Fingerhut wrote:

> In my original message describing pmap's behavior, there was a little 
> "gotcha" near the end:
> 
> "Note: Sometimes working at odds with pmap's "Don't work too far ahead" 
> approach is if the input sequence to pmap is chunked.  When a chunk is 
> reached, all elements in that chunk have threads start in parallel, so the 
> number of parallel threads can easily exceed (availableProcessors+2) during 
> those times."
> 
> 
> (range n) produces heavily chunked sequences.  Chunks are an optimization on 
> time and memory when representing large sequences, but they do cause pmap as 
> written today to suddenly fire off all futures in the chunk as parallel 
> threads when it reaches the chunk.

Interesting! Sorry I missed this gotcha from your original email; I hadn't run 
across this problem at the time and thus the info didn't stick in my head. 
Thanks for the link to modified-pmap, too.

This seems like undesirable behavior from pmap to me (and/or unwanted 
chunking-induced behavior[1]). At the least I would like to see pmap adopt an 
optional extra argument that works like your modified-pmap's num-threads 
argument, and possibly also the arrival of Clojure's promised de-chunking 
interface.

[1] http://disclojure.org/documents/clojure-1-1-0-rc1-release-notes/ (section 
2.3: "Please share any use cases where chunked processing has resulted in 
behavioral differences that matter to you on the Clojure google group.")

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 does pmap partition its work?

2011-01-25 Thread Michael Gardner
On Jan 25, 2011, at 9:33 AM, Ken Wesson wrote:

> Well, that's weird, because the documentation *I* read says it
> composits the arguments together into a command line and hands off to
> Runtime/exec. And the documentation of *that* says it returns a
> Process object and the process it launches runs asynchronously.

That doesn't necessarily contradict what I observed. The way I read the docs[1] 
is that sh does indeed use Runtime.exec(), but then waits for the sub-process 
to complete and returns a map of its exit status, etc. That's not explicitly 
stated, but it's the only explanation consistent with what I observe. For 
comparison, what behavior do you observe with (do (clojure.java.shell/sh 
"sleep" "10") nil)?

> If that were the case, though, your pmap should indeed only be running
> cores+2 instances at once. Which is not what you observed.
> 
> Something's hinky here.

Indeed. According to a previous thread[2], something similar happens with 
Thread/sleep; my guess is that sh sleeps (or something similar) while it waits 
for the sub-process to finish and thus suffers from the same issue.

[1] 
http://clojure.github.com/clojure/clojure.java.shell-api.html#clojure.java.shell/sh
[2] http://groups.google.com/group/clojure/browse_thread/thread/9b3581d9f4b4afd6

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 does pmap partition its work?

2011-01-25 Thread Michael Gardner
On Jan 25, 2011, at 9:06 AM, Ken Wesson wrote:

> sh is asynchronous. It calls Runtime/exec, which launches the sleep as
> a separate process and immediately returns a Process object (which
> your pmap should be returning a seq of). It may produce n+2 Process
> objects at a time but it produces them all before the first of the
> asynchronous sleep processes finishes, so for a while all of the
> latter are running at the same time.

Really? The documentation for sh claims to return a map, which is what I 
observe. And the call to sh doesn't return until the sub-process has finished, 
even if I discard its return value (so it can't be the case that the resulting 
"map" is actually some lazy thing that blocks when I try to access its 
contents).

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 does pmap partition its work?

2011-01-25 Thread Michael Gardner
I have run across something else I don't understand about pmap. Why does the 
following:

(pmap (fn [_] (clojure.java.shell/sh "sleep" "10")) (range 32))

result in all 32 "sleep" processes being run at once? I thought pmap used n+2 
threads, where n is the number of processors/cores available (I have two cores).

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Calling .close() on resources -- with-open macro

2011-01-24 Thread Michael Gardner
On Jan 24, 2011, at 1:54 PM, Laurent PETIT wrote:

> That's interesting. Indeed, it seems to me that the .close() call
> should be wrapped by a try / catch with an empty catch.

Why would client code want an exception thrown by .close() to get swallowed? Is 
that not unexpected behavior in most cases?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: [ANN] fs - file system utilities for Clojure

2011-01-24 Thread Michael Gardner
On Jan 19, 2011, at 11:32 AM, Miki wrote:

> I'd appreciate some comments about need functionality, bugs, code reviews and 
> such.

Thanks for this useful library. Some suggestions:

-I'd rather (copy-tree src dest) worked like "cp -R src dest" (including when 
dest doesn't exist) rather than "cp -R src/* dest/".

-It would be nice if functions that create files or dirs (like mkdir and touch) 
returned the new object's path, to allow chaining.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 does pmap partition its work?

2011-01-24 Thread Michael Gardner
On Jan 23, 2011, at 10:56 PM, Ken Wesson wrote:

> I've managed to make this more efficient, by making each agent send
> process a larger portion of the job than one single item:
> 
> (defn eager-pmap [f & colls]
>  (let [cores (.. Runtime getRuntime availableProcessors)
>agents (cycle (for [_ (range cores)] (agent nil)))
>ccolls (map (partial partition 16 16 []) colls)
>promises (apply map (fn [& _] (promise)) ccolls)]
>(doall
>  (apply map (fn [a p & chunks]
>   (send a
> (fn [_]
>   (deliver p
> (apply map f chunks)
>agents promises ccolls))
>(mapcat deref promises)))
> 
> This is much faster than either of the other eager-pmaps I posted to
> this thread, and yet it's only using 60% CPU on my dual-core box. That
> means there's still another x1.6 or so speedup possible(!) but I'm not
> sure how.
> 
> Raising the size of the partitions from 16 all the way to 1024 makes
> no noticeable difference.

Thanks for the work, Ken. Clojure's multi-threaded performance can be 
mysterious indeed, which is a shame when one of the major benefits of 
functional code is that it's easily parallelizable. Anyway, for now I will 
probably just stick with pmap + shuffle, since it's dead-simple and should be 
enough my purposes.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 does pmap partition its work?

2011-01-23 Thread Michael Gardner
On Jan 23, 2011, at 8:34 PM, Andy Fingerhut wrote:

> No, you cannot rely on pmap to do that.


Thanks for the detailed and informative answer. I'll probably settle for 
shuffling the list of inputs before passing them to pmap, and just accept that 
there may be some inefficiency in the distribution of work.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 does pmap partition its work?

2011-01-23 Thread Michael Gardner
Suppose I have a sequence of tasks I'd like to parallelize using pmap. The 
amount of CPU time these tasks require varies greatly; in particular, many of 
them will require virtually no work. Can I rely on pmap to divide the work 
efficiently even if there is some pattern to the distribution of easy tasks 
(e.g. clumped at the beginning, or every nth)? Assume it's not possible to 
identify the easy tasks beforehand.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Help with java conversion

2011-01-21 Thread Michael Gardner
On Jan 21, 2011, at 10:35 AM, Laurent PETIT wrote:

> As far as possible, the equivalent of a java anArray[anIndex] expression will 
> be of not using an index in the first place in Clojure (*).

Expanding on Laurent's answer: to transform one list into another, use 'map'. 
In this case you can think of transforming the integers [0 .. n), expressed in 
Clojure as (range n), into a list of image strips.

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


Re: Code Review of my first stab

2011-01-18 Thread Michael Gardner
On Jan 18, 2011, at 10:59 AM, Tim Visher wrote:

> I'd love to have the code torn apart a little bit and get some
> suggestions for improvements.
> 
> It's located at https://gist.github.com/784744


It took me a few tries to figure out what to-wallpaper-name was doing. Maybe 
you should write a helper called split-filename or such, which you could use 
like (let [[base extension] (split-filename name)] ...). Also, why bother to 
negate the result of the name-has-resolution? test when you're going to do 
something in both cases anyway?

Why are you constructing your wallpaper structs in two steps (first creating 
without-destination-file and then assoc-ing the destination file to it)?

I'd chop the "to-" prefix off the front of most of your function names, as it 
feels redundant to me.

I'd also use map instead of for in wallpaper-resolutions, since it reads better 
to me with the list of resolutions coming at the end:

(map (partial apply struct resolution)
[[1280 1024] [1920 1080] [2560 1600] [1920 1200] [1680 1050] [1440 900] 
[1280 800]])

Actually, you might consider just using 2-vectors for resolutions instead of 
structs/records. Besides being simpler, it would allow you to do things like 
(clojure.string/join "x" my-resolution).

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Enhanced Primitive Support Syntax

2011-01-15 Thread Michael Gardner
On Jan 15, 2011, at 4:04 PM, Stuart Halloway wrote:

> I'll make a documentation update higher priority; hopefully that will help.

This should help. I feel like the discussion is going in circles because 
there's no single, official source that summarizes exactly what is happening 
with numerics in 1.3. (I know about 
http://www.assembla.com/wiki/show/clojure/Enhanced_Primitive_Support, but it's 
terse and a bit confusing.)

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


Re: Clojure job scheduler

2011-01-07 Thread Michael Gardner
On Jan 7, 2011, at 9:19 PM, Ken Wesson wrote:

> On the other hand, running a job scheduler from outside Clojure
> results in cranking up a big, slow to start up, expensive JVM process
> every single time a task needs to run, each of which runs one task
> once, and the scheduling itself must be done in an icky language like
> shell or cron's idiosyncratic "crontab" files with icky error
> reporting (e.g., need to run a local mail *server* to receive error
> notifications).

If you care about startup times, you can use nailgun. But that shouldn't matter 
unless you're running the job every minute or something.

As for scheduling, crontabs are really not hard to figure out. If you need more 
complex scheduling, you can do that from your Clojure script (essentially using 
cron to set the polling interval).

And what kinds of error reporting could you do from a persistent daemon that 
you couldn't also do from a cron job? Besides, most systems that have cron also 
come with postfix (though it's disabled by default on Mac OS X), so all you 
have to do is add your email address to /etc/aliases. Email-based error 
reporting for background tasks is really nice because you don't have to 
remember to check some log file or other task-specific status indicator 
periodically (which has burned me in the past).

But this is all somewhat beside the point. What Trevor said sounded as though 
the specific types of tasks he mentioned (sending emails and checking some kind 
of status via web app) were particularly unsuited to scheduled jobs; I was 
asking what it was about those tasks in particular that made him lean towards a 
daemon instead.

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


Re: Clojure job scheduler

2011-01-07 Thread Michael Gardner
On Jan 7, 2011, at 11:13 AM, Trevor wrote:

> 3. I could set a job-schedule using the OS to run a clojure script.
> I'd rather not, I would like to do things like send emails / check
> status via web app (making option 1 more appealing).

Could you elaborate on why a scheduled job to run a Clojure script would be 
inappropriate for those kinds of tasks? Anything you can do from a daemon, you 
should be able to do from a cron job.

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


Re: Let's see how fast we can make this

2010-12-24 Thread Michael Gardner
On Dec 24, 2010, at 8:19 PM, David Nolen wrote:

> ((long double) end-start) / 1000.0

I don't think this math is correct. The units for the values returned by 
mach_absolute_time() are CPU-dependent: 
http://developer.apple.com/library/mac/#qa/qa2004/qa1398.html

Using gettimeofday() on my 2.0 GHz Core 2 Duo Macbook, I get minima of ~3400 
microseconds for unoptimized C, ~800 microseconds for -O2.

#include 
#include 

unsigned count_chars(char const * s) {
unsigned count = 0;
while (*s++)
if (*s != ' ')
++count;
return count;
}

int main(int argc, char** argv) {
char const * s = "This is a really long stringThis is a really long 
stringThis is a really long stringThis is a really long stringThis is a really 
long stringThis is a really long stringThis is a really long stringThis is a 
really long stringThis is a really long stringThis is a really long stringThis 
is a really long stringThis is a really long stringThis is a really long 
stringThis is a really long stringThis is a really long stringThis is a really 
long stringThis is a really long stringThis is a really long stringThis is a 
really long stringThis is a really long string";
unsigned i, j;
struct timeval start, end;

for (j = 0; j < 10; ++j) {
gettimeofday(&start, 0);
for (i = 0; i < 1000; ++i)
count_chars(s);
gettimeofday(&end, 0);
printf("%u us\n", (unsigned)(100 * (end.tv_sec - start.tv_sec) + 
(end.tv_usec - start.tv_usec)));
}

return(0);
}

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


Re: Clojure 1.3 Alpha 4

2010-12-14 Thread Michael Gardner
On Dec 14, 2010, at 11:22 PM, Ken Wesson wrote:

> On Tue, Dec 14, 2010 at 10:37 PM, Michael Gardner  wrote:
>> That's what archives are for
> 
> Are you honestly suggesting I search the archives for every word of
> every thought that it ever occurs to me to post here?
> 
> I don't have that kind of time and I doubt anyone else does. If anyone
> started to actually enforce such a rule, participation here would drop
> to practically zero overnight.

That's a mighty fine straw man you have there. And how deftly you knock it down!

>> Are you saying that simplifying existing code provides no benefit?
> 
> If it breaks existing client code then yes. Simplifying internals
> without altering API semantics is generally a good thing; when the API
> semantics start changing, though, an unequivocal improvement becomes a
> tradeoff that might tip either way.
> 
> Changing the behavior of arithmetic operators that are found in
> virtually every extant source file is going to have a very big
> downside in broken backward compatibility. If there's an upside, it
> would have to be staggeringly enormous to make such a change
> worthwhile.

The claim I responded to was: "it cannot logically ever be a point against 
keeping current behavior". You are now arguing a much weaker claim, that the 
upside of simplifying existing code is unlikely to outweigh the drawbacks of 
breaking existing code.

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


Re: Clojure 1.3 Alpha 4

2010-12-14 Thread Michael Gardner
On Dec 14, 2010, at 9:26 PM, Ken Wesson wrote:

> On Tue, Dec 14, 2010 at 10:02 PM, Brian Goslinga
>  wrote:
>> This topic has been discussed to death before on this group.
> 
> If so, it was before I joined.

That's what archives are for:

http://groups.google.com/group/clojure/search?group=clojure&q=primitive+math

See in particular the threads "Enhanced primitive support" and "Enhanced 
primitive support - redux".

>> Doing the right thing is actually harder than you might first think
> 
> But it's also already being done by Clojure 1.2 so I don't see how
> that's relevant. If someone proposed a novel behavior, it being
> "harder than you might first think" would be a point against that
> proposal. However it cannot logically ever be a point against keeping
> current behavior.

Are you saying that simplifying existing code provides no benefit?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: String-friendly first/rest?

2010-12-08 Thread Michael Gardner
On Dec 8, 2010, at 4:05 PM, Surgo wrote:

> That's a fair criticism. I suppose that I'm not necessarily looking
> for specifically String manipulation abstractions (I can just do a
> (.substr "abc" 1) to get "bc" as a String after all), but rather
> looking for an abstraction that takes something that's addressable as
> a sequence and returns it in the same format or type instead of a seq.

So something like an inverse to (seq)? You could write such a thing, though it 
would have to know about each type (seq) knows about. More importantly, it 
would have to somehow know what type the thing originally was, since there's no 
difference between e.g. (seq "abc") and (seq [\a \b \c]). You'd either have to 
store the type when calling (seq) and manually pass it when calling the inverse 
function, or else I suppose you could write a wrapper for (seq) that adds 
metadata about what type the thing originally was.

Incidentally, while testing this last idea, I was surprised to find that :type 
metadata is treated specially:

=> (with-meta '() {:type (type [])})
[]

I assume this means :type is used internally by Clojure somehow. I notice 
clojure.org says that metadata "is used to convey information to the compiler 
about types", but ought there be a list of "reserved" metadata?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: parameters destructuring & sets?

2010-12-06 Thread Michael Gardner
On Dec 6, 2010, at 9:02 PM, Ken Wesson wrote:

> I'll try this one more time. You suggested the innards, and with them
> the seq order of the elements, might get rearranged.

I suggested no such thing; perhaps you are confusing me with Mike Meyer? I 
referred more generally to the possibility of two different calls to (seq) on 
the same collection returning the items in different orders. This might happen 
if e.g. the underlying collection picks a starting point for the iterators it 
returns non-deterministically. I'm not saying this is likely to be done in 
practice, mind you, just that there are conceivable cases where an immutable 
collection would not want to provide that kind of ordering guarantee.

>> It's not just about (nth) giving consistent results. It's also about forcing 
>> the programmer to make his intentions explicit, per Rich's quote.
> 
> We may just have to agree to disagree about that. It seems to me that
> calling nth, or first, or seq, or anything like that makes the
> programmer's intentions explicit, as those are all clearly treating
> the structure as a sequence. It's calling (foo coll) where foo calls
> (nth (seq coll)) or somesuch under the hood that doesn't make the
> programmer's intentions (as) explicit; they're calling some function
> on, say, a map and it may not be especially obvious that that function
> treats the map (and anything else passed to it) as a sequence.
> 
> Anyway, you can't legislate code clarity at the language level. They
> tried that with Java and look where it got them. Annotations,
> generics, and checked exceptions, oh my!

I don't actually have a strong opinion one way or the other on this, though I 
can see how it would appear otherwise from what I wrote. I was just giving what 
I understood to be one of the "official" reasons for the decision.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: parameters destructuring & sets?

2010-12-06 Thread Michael Gardner
On Dec 6, 2010, at 5:35 PM, Ken Wesson wrote:

> Who was relying on the order? If you merely relied on seeing 5 or 6,
> or on not seeing 3 or 4 twice, you were screwed.

Ah, I misunderstood what you wrote. Obviously (seq) should hand you each item 
in the collection exactly once, but that's at a weaker guarantee than that 
different calls to (seq) on the same collection should always hand them to you 
in the same order.

> The point was that you can't even rely on seeing all of the elements,
> once each, in *some* order, unless the seq is a copy instead of a view
> backed by the other data structure.

I don't see how this follows. It seems like you're making some unstated 
assumptions about how (seq) gets items from the underlying collection.

> And if it's a copy, it is
> expensive to produce. And if it is expensive to produce, it can be
> cached once produced. And if it can be cached once produced, nth can
> give consistent results by consulting the cached seq.

It's not just about (nth) giving consistent results. It's also about forcing 
the programmer to make his intentions explicit, per Rich's quote.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: parameters destructuring & sets?

2010-12-06 Thread Michael Gardner
On Dec 6, 2010, at 4:07 PM, Ken Wesson wrote:

> Perhaps. But under those circumstances seq itself has the same problem
> you're using to excuse not supporting nth, yet seq is supported. And
> so is (nth (seq x)) on these things; if the implementation changed its
> innards while you were walking the seq (even with map! Nevermind using
> nth) this could trip up. You might have a set #{1 2 3 4 5 6} and seq
> would produce (1 3 4 5 2 6) and then someone makes another set from it
> with disj and the structure rearranges, so seq would now produce (1 5
> 6 2 4 3). Meanwhile, another thread has produced a seq and is
> traversing it at the time and gets (1 3 4 2 4 3). Oops.


Why is this a problem? Why would you rely on the order in which (seq) hands you 
items from an unordered collection in the first place? If you care about order, 
use an ordered collection. Besides that, it's really uncommon in my experience 
to traverse the same collection twice while caring about the ordering.

The point of requiring a manual call to (seq) is to make it explicit that you 
are viewing this thing as a seq, with all that implies. To quote Rich from the 
previously-referenced thread:

"If in some situation it makes sense to treat a map as sequential (it might 
make some sense with array maps or sorted maps), just use (seq m), which will 
serve as an indicator of that special point of view."

Given the reasoning above, I'd argue that the fact that (first), (rest), and 
(next) work on unordered collections is actually a bug.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: range with decimal values

2010-12-04 Thread Michael Gardner
On Dec 4, 2010, at 8:42 AM, Glen Rubin wrote:

> If I use the range fn with a decimal number for step I get back
> something like this:
> 
> (range 0.05 0.16 0.01)
> 
> user> (0.05 0.060005 0.07 0.08 0.09 0.0
> 0.10999 0.11998 0.12998
> 0.13999 0.15)
> 
> Really I want output more like i get from the following fn:
> 
> (map float (range 5/100 16/100 1/100))
> 
> user> (0.05 0.06 0.07 0.08 0.09 0.1 0.11 0.12 0.13 0.14 0.15)

Perhaps (map (partial * 0.01) (range 5 16))?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: discussing Clojure with non-CS types

2010-11-25 Thread Michael Gardner
On Nov 24, 2010, at 7:47 PM, CuppoJava wrote:

> The other reason is that Clojure emphasizes functional programming and
> discourages mutation. This is fine, as I believe well-written code is
> usually functional anyway. The problem is that bad code is usually
> easier to write in an imperative way than a functional way, and the
> ability to write bad code is important I think. It's usually a lot
> quicker to whip up a mutative hack than think through the problem and
> factor out components and be functional about the whole thing. And
> usually, in the very very early stages of programming something, when
> you don't clearly know what it is you're programming, it's nice to be
> able to whip out a quick and dirty mutative hack. And then make it
> nice and elegant and functional later on, but Clojure makes doing that
> difficult for me.

I think this is a matter of mindset. Like learning a new human language: it 
takes a while to begin thinking in the new language. Until then, you have to 
think in your native language and translate on-the-fly, which makes certain 
things awkward to express.

Similarly with functional programming: once you begin to "think functionally", 
the functional solutions are the ones that come to mind first, rather than the 
imperative ones.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 of seq on empty collections

2010-11-14 Thread Michael Gardner
On Nov 14, 2010, at 4:04 PM, Ken Wesson wrote:

> Interestingly, (= (count v) 0) is relatively fast (900 msec); (seq v)
> is slower (2s); (empty? v) is even slower (3s); and (= v []) is
> slowest (16s).

Strange. Here are the timings I get for 1e8 iterations:

(zero? (count v)): ~3600 msecs
(seq v): ~2300 msecs
(empty? v): ~3100 msecs
(= v []): ~460 msecs

(= 0 (count v)) is even slower than (zero? (count v)). I'm running Clojure 1.2 
on a MacBook (Core 2 Duo, 2GHz).

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Collapse some functions? (was Re: clojure.core function decision tree)

2010-11-10 Thread Michael Gardner
On Nov 10, 2010, at 5:48 PM, Alan wrote:

> I guess you stay backwards-compatible by putting it in the docstring,
> but isn't it more general, clean, and programmatic to put these useful
> bits of information into new entries in (meta f)?

That's pretty much what I was trying to get at with "structured fields", though 
I was thinking more about the web documentation. I didn't know that Clojure's 
core functions all have nice metadata. Neat!

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Collapse some functions? (was Re: clojure.core function decision tree)

2010-11-10 Thread Michael Gardner
On Nov 10, 2010, at 12:40 PM, Michael Gardner wrote:

> The docstring for reverse does say "not lazy", which implies at least O(n).

In the general case, that is. As Meikel mentioned, reverse works on any seq, so 
this is the best guarantee it can provide in general.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Collapse some functions? (was Re: clojure.core function decision tree)

2010-11-10 Thread Michael Gardner
On Nov 10, 2010, at 11:36 AM, Carson wrote:

>> rseq O(1), reverse O(n).
>> peek O(1), last O(n).
>> pop O(1), butlast O(n).
>> get O(1), nth O(n).
> 
> I don't see that in the documentation...  If these functions aren't
> "collapsed", then it's better if at least (doc reverse) says something
> about O(n) and "see rseq".

The docstring for reverse does say "not lazy", which implies at least O(n).

But perhaps it should be more clear. What if there were some additional 
structured fields for each doc entry, like "performance guarantees" and "see 
also"?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 isn't there a fold-right?

2010-11-07 Thread Michael Gardner
On Nov 5, 2010, at 9:03 PM, Yang Dong wrote:

> Maybe because Clojure has a vector, and conj conjoins new elements to
> the end of the vector, so there's mere little use of fold-right. But,
> fold-right is an abstraction tool, missing it in the core is kind of
> pity.

What's wrong with just using reverse?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Constructing Nested Trees and Memory Consumption

2010-11-03 Thread Michael Gardner
On Nov 3, 2010, at 8:31 PM, Andy Fingerhut wrote:

> I'd recommend changing your code to use Java chars instead of single-char 
> Java strings.  That plus the change Paul suggests below should reduce memory 
> consumption significantly.

Another option is to .intern() the strings. You'll still create lots of garbage 
while reading the input file, though.

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


Re: Clojure on Javascript

2010-10-29 Thread Michael Gardner
On Oct 29, 2010, at 11:09 PM, David Nolen wrote:

> JS brought me to Lisp, I would love to see the Clojure community bring Lisp 
> back to JS. However I fail to see what advantage JS gives on the server side. 
> From what I've seen the V8 GC and Node.js have a considerable number of years 
> to go before they are serious contenders against the JVM for non-trivial 
> projects, evented or no.

Agreed. What is the point of Javascript on the server side? Familiarity? 
Consistency with client-side code?

> More interesting would be something along the lines of CoffeeScript (like 
> ClojureScript) that takes a reasonable subset Clojure and compiles into 
> efficient JS, allowing Clojure programmers to send Clojure code to clients.

Yes! Writing Javascript makes me want to throw things. Client-side Clojure 
would be fantastic.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: to macro or not?

2010-10-28 Thread Michael Gardner
On Oct 28, 2010, at 2:55 PM, Raoul Duke wrote:

> not looking to stir up a pot, looking to learn from people's
> experience. i've heard that in CL land, one is told to avoid macros as
> long as possible. i've heard other folks in the Clojure world say that
> if you aren't using macros, then sorta why bother use a Lisp since you
> are missing out on one of the most powerful differentiators. then
> reading about Conj it sounds like some folks say stay away from macros
> if you can.
> 
> any way of teasing out when macros are ok? :-) i mean, are they only
> ok for the internals of the Clojure system?


Use a macro iff you can't do what you want with a function.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: First function

2010-10-21 Thread Michael Gardner
On Oct 21, 2010, at 3:28 AM, Brody Berg wrote:

>(if (== (nth m_list m_left) target)

Forgot to mention: you should use = instead of == unless you're sure you will 
only ever get numeric arguments *and* profiling tells you that = is a 
performance bottleneck.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: First function

2010-10-21 Thread Michael Gardner
On Oct 21, 2010, at 3:28 AM, Brody Berg wrote:

>(if (empty? m_list)
>false
>(binary-search m_list 0 (- (count m_list) 1) target))

Assuming that returning nil is OK in case of the target not being present, you 
can replace this with (when (seq m_list) (binary-search ...)).

>(if (== (nth m_list m_left) target)
>(nth m_list m_left)
>false

Can similarly replace with (when (== (nth m_list m_left) target) target). But 
why are you returning the target value on success? Presumably the caller knows 
what that value is, and it makes your function awkward to use if target is 
false or nil. Why not return either the target's index, or just 'true' if you 
don't need that?

Also, can you assume m_list is a vector, or if not, make it into one in your 
helper body? That would let you write (m-list n) instead of (nth m-list n), and 
would guarantee constant-time performance when you do it.

> (- middle 1)
> (+ middle 1)

Can replace with (dec middle) and (inc middle), respectively.

Lastly, as a matter of style: Lisp users generally hate trailing parentheses. 
It's extremely common to simply collapse them onto the previous line. Your 
editor should be able to do the grunt-work of helping you balance them, and 
they pretty much disappear after a while.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Newbie - Map to String

2010-10-08 Thread Michael Gardner
On Oct 8, 2010, at 5:09 PM, Paul wrote:

> I'm trying to parse a map unto a URI string, e.g:
> 
> {:apple "green", :cherry "red", :banana "yellow"} into
> "apple=green&cherry=red&banana=yellow"

(use 'clojure.string)
(def kvs {:apple "green", :cherry "red", :banana "yellow"})

(join "&"
(map
(fn [[k v]]
(format "%s=%s" (name k) v))
kvs))

(format) is great for building strings out of a mix of bare string values and 
other expressions.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Is This Function Idiomatic Clojure?

2010-10-06 Thread Michael Gardner
On Oct 7, 2010, at 1:29 AM, Stefan Rohlfing wrote:

> Following an Enlive tutorial I wanted to implement a function 'd-map'
> that takes an arbitrary number of [:key (list of values)] parameters
> like this:
> 
> (d-map [:headline ["this" "is" "me"] ]
>   [:points [1 2 3] ]
>   [:comments [10 20 30] ])
> 
> 
> and returns a collection of [:key value] vectors where each value is
> grouped with its respective key:
> 
> [ [:headline "this"] [:headline "is"] [:headline "me"]
>  [:points 1] [:points 2] [:points 3]
>  [:comments 10] [:comments 20] [:comments 30] ]

I'd do something like:

(defn d-map [& kvs]
(apply concat
(map
(fn [[key vals]]
(map (partial vector key) vals))
kvs)))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Build String or Simply Use StringBuilder

2010-10-01 Thread Michael Gardner
On Sep 30, 2010, at 10:37 PM, HiHeelHottie wrote:

> (ns test-test.parse
>  (:use [clojure.contrib.string :only (split)]))
> 
> (defn parse-char [m c]
>  (condp = (:state m)
>  :degree (cond
>   (Character/isDigit c) (assoc m :degree (+ (* (:degree
> m) 10) (Character/digit c 10)))
>   (Character/isWhitespace c) (assoc
> m :state :whitespace :buf (conj (:buf m) (:degree m) " ") :degree 0))
>  :whitespace (cond
>   (Character/isDigit c) (assoc
> m :state :degree :degree (+ (* (:degree m) 10) (Character/digit c
> 10)))
>   (Character/isWhitespace c) m)))
> 
> (defn parse [s]
>  (let [m (reduce parse-char {:state :degree :degree 0 :buf []} (str s
> " "))]
>(apply str (:buf m
> 
> (println (parse "1 2   33"))

One minor improvement would be to use clojure.string/join instead of str. That 
way you won't have to manually append a space after each number in :buf (nor 
use apply).

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Build String or Simply Use StringBuilder

2010-09-29 Thread Michael Gardner
On Sep 29, 2010, at 11:01 PM, HiHeelHottie wrote:

> What if you are appending over different lines of code?

Could you give an example of what you're trying to do? Mutable strings are 
almost never necessary, in my experience.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Build String or Simply Use StringBuilder

2010-09-29 Thread Michael Gardner
On Sep 29, 2010, at 10:32 PM, Stuart Campbell wrote:

> I would just use (str) - it uses a StringBuilder when given more than one 
> argument:

There's also (format), which I find helpful for building more complex strings.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: An Emacs command to close the various balanced expressions in Clojure

2010-09-28 Thread Michael Gardner
On Sep 26, 2010, at 6:51 PM, blais wrote:

> Writing Clojure code tends to require a larger mix of "()",
> "[]" and "{}" characters than other LISPs I use. This
> sometimes makes it a bit tiring to write those balanced
> expressions.

For outer expressions I tend to use the verbose forms (hash-map ...) and 
(vector ...) for aesthetic reasons, so {} and [] mostly occur around innermost 
expressions in my code. Then balancing the remaining parens is just a matter of 
hitting ')' until Vim highlights the outermost paren for me. But I might find a 
feature like yours useful; does anybody know of an equivalent for Vim?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: finding value nearest x

2010-09-27 Thread Michael Gardner
On Sep 27, 2010, at 9:59 AM, Glen Rubin wrote:

> yes correct.  but i can write a fn to determine the index of the
> minimum distance in my new list?
> 
> that index applied to my original list will give me the value back.
> and this still would involve fewer calculations i think.

Do you have a particular reason to be concerned about performance here? Don't 
worry about it unless profiling tells you it's a bottleneck for your program.

And I doubt it will actually give better performance anyway, even with min-key 
evaluating f more times than is necessary, because your f is so inexpensive to 
calculate.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: return index of a value

2010-09-27 Thread Michael Gardner
On Sep 27, 2010, at 9:45 AM, Glen Rubin wrote:

> I have a vector of numbers
> 
> [0 99 3334 53 2 5 99 2 55 63]
> 
> I'd like to find the first index of a particular value.  For example
> if the value was 99 then I want to return 1, b/c the index of 99 is
> 1.  I can do this with a loop/recur structure comparing each value in
> the list to my desired value, however am wondering if there isn't a
> built-in for doing so??  thanks again!


In general, 'some' is used for linear searches. Given a vector 'v':

(some #(and (= 99 (v %)) %) (range 0 (count v)))

This is awkward because you're asking for the index and not the value itself. 
Index-based array manipulation is not often used in Clojure.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: finding value nearest x

2010-09-27 Thread Michael Gardner
On Sep 27, 2010, at 9:28 AM, Glen Rubin wrote:

> It occurs to me that another way of doing this is to map a new list
> and then use the min fn.  something like:
> 
> (apply min (map #(Math/abs (- % 136)) xs))
> 
> maybe this is better and involves less calculations?

That gives you the minimum distance from 136, not the value itself. You can't 
get back the original value afterwards either, because you don't know whether 
to subtract or add the distance from 136.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: simplest graphics?

2010-09-16 Thread Michael Gardner
On Sep 15, 2010, at 10:15 PM, Lee Spector wrote:

> Also, this would have a smaller impact but I'm curious about it: is there a 
> way to treat method names as data and then make calls to them, as one can 
> with clojure functions? Then I could pass things like fillRect, or map rect 
> to fillRect, etc. This would make things slightly simpler here but be handy 
> in other cases... but I don't see how to do it.

As you've discovered, Java method names are unfortunately not first-class 
functions in Clojure. You have to wrap them with memfn or a lambda like 
#(.fillRect %).

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: trouble using nested map fn

2010-08-23 Thread Michael Gardner
On Aug 23, 2010, at 11:13 AM, Luka Stojanovic wrote:

> On Mon, 23 Aug 2010 18:01:13 +0200, Joop Kiefte  wrote:
> 
>> bad example =/
>> 
>> Yes, it is
>> 
>> but you get the gist I hope
>> 
>> better example: #(first (sort %)) ;)
>> 
> 
> (comp first sort)
> 
> and #(some-fn x %) can be written as
> (partial some-fn x)
> 
> which leaves #(some-fn % x) as case not trivial with other syntax
> 
> again (fn [y] (some-fn y x)) is about 8 chars longer, so I guess #() form 
> really is not something that should be used that often

I don't know about you, but I find #(= 2 (count %)) much nicer and easier to 
read than (comp (partial = 2) count).

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


Re: What is the reason Lisp code is not written with closing parenthesis on new lines?

2010-08-18 Thread Michael Gardner
On Aug 18, 2010, at 2:49 PM, Greg wrote:

> On Aug 18, 2010, at 12:07 PM, Michael Gardner wrote:
> 
>> On Aug 18, 2010, at 1:38 PM, Greg wrote:
>> 
>>> http://gregslepak.posterous.com/on-lisps-readability
>> 
>> That article is dishonest.
> 
> Speaking as the author, I'm a bit offended.

Too bad. If you wanted to focus on the trailing-parens (which you clearly did 
in that article), you should have kept everything else the same between your 
examples.

If you wanted to comment on indentation as well, you should have (a) given it 
equal prominence in your discussion, (b) used separate code examples for 
trailing-parens vs indentation, and/or (c) made a separate post.

Closing the comments after people started to question you on this wasn't a good 
move, either (otherwise I'd be commenting there rather than 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


Re: What is the reason Lisp code is not written with closing parenthesis on new lines?

2010-08-18 Thread Michael Gardner
On Aug 18, 2010, at 1:38 PM, Greg wrote:

> http://gregslepak.posterous.com/on-lisps-readability

That article is dishonest. The author changes indentation widths between 
examples, while focusing entirely on the trailing-parens. He claims in a 
comment that "the post is not solely about trailing parenthesis", but there's 
only one passing remark about 2-space indentation in the whole article. (I 
personally use 4-space indents precisely because they make code easy to parse 
at a glance.)

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Installing Clojure on OS X

2010-08-17 Thread Michael Gardner
On Aug 17, 2010, at 10:17 AM, Saul Hazledine wrote:

> On Aug 17, 3:59 pm, HB  wrote:
>> Hey,
>> How to install Clojure on Mac OS X?
>> I googled the web, some use MacPorts, others write some shell scripts.
>> Is there a -standard- way to install Clojure on OS X (if possible,
>> please don't refer me to MacPorts)?
>> Thanks all for help and time.
> 
> I used a Mac in the past and I understand your frustration with
> MacPorts.

What's wrong with MacPorts? I've used it to install Clojure (and many other 
things) on my Mac, without much trouble.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: two announcements: a new Clojure article, and a new site for beginners

2010-08-14 Thread Michael Gardner
On Aug 14, 2010, at 12:58 AM, Gregg Williams wrote:

> ** Second announcement: GettingClojure.com, a collaborative site for
> Clojure beginners

gettingclojure.com currently redirects to www.wikidot.com.

www.gettingclojure.com is fine, though.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Please help! Really simple function not working.

2010-08-09 Thread Michael Gardner
On Aug 9, 2010, at 7:24 PM, Carlos Torres wrote:

> I'm trying to create a function that takes a simple list and returns the 
> number of zeros in the list.

user=> (count (filter zero? [0 1 2 3 0 4 5 6 0 7 8 9]))
3

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: looking for a simpler implementation of a function I'm using

2010-08-07 Thread Michael Gardner
On Aug 7, 2010, at 8:48 PM, Michael Gardner wrote:

> On Aug 7, 2010, at 8:39 PM, gary ng wrote:
> 
>> nice, why do I need the gensym ?
> 
> The gensym was just a cheesy way of generating a unique value.

To elaborate a bit more on my failure, I was reading the docs for partition-by 
thinking that "new value" meant a value not before seen, not simply a different 
value from the previous one. Then I accidentally hit 'send' before I could test 
it and realize my mistake.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: looking for a simpler implementation of a function I'm using

2010-08-07 Thread Michael Gardner
On Aug 7, 2010, at 8:35 PM, Michael Gardner wrote:

> (partition-by #(when (even? %) (gensym))

Whoops, hit 'send' too soon. And it doesn't actually work, since it splits 
before and after the even values.

On Aug 7, 2010, at 8:39 PM, gary ng wrote:

> nice, why do I need the gensym ?

The gensym was just a cheesy way of generating a unique value.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: looking for a simpler implementation of a function I'm using

2010-08-07 Thread Michael Gardner
(partition-by #(when (even? %) (gensym))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: randomizing a vector

2010-07-21 Thread Michael Gardner
On Jul 21, 2010, at 12:44 PM, Michał Marczyk wrote:

> The biggest problem with the code is that it reconstructs the entire
> `ordered-ips` vector minus the last entry picked at each iteration. It
> would be simpler and *much* more performant to do
> 
> (shuffle ordered-ips)
> 
> Also note that Clojure 1.2 provides an `rand-nth` function for doing
> 
> (let [i (count xs)] (get xs (rand-int i)))

I believe shuffle is only in clojure.core as of 1.2. Before that, you'd find it 
in clojure.contrib.seq.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Response

2010-07-18 Thread Michael Gardner
On Jul 17, 2010, at 9:46 PM, Isaac Hodes wrote:

> I did check out your response: it's rather fast on my machine. it's
> not really functional, though, as you use the `let` macro as a way of
> procedurally executing a lot of functions. This isn't bad at all, but
> you're not composing functions.

'Functional' means simply avoiding mutation and side-effects. How the code is 
organized is a separate issue.

In case you're interested, I made a small change to the code I posted before 
that makes it significantly faster. I don't know what you consider 'slow', but 
it takes 2-3x as long as your imperative Python version on my hardware (less if 
I replace the outermost map with pmap, depending on the input sizes). I think 
that's quite acceptable, especially given Clojure's relative youth as a 
language.

(defn convolve-indices [i max-m max-n]
"Lists all index pairs adding up to i, where the first index is less than 
max-m and the second is less than max-n."
(map #(vector % (- i %))
(range
(max 0 (inc (- i max-n)))
(min (inc i) max-m

(defn convolve-1 [i ms ns]
"Returns the ith value of the convolution of ms with ns."
(reduce +
(map (fn [[m n]] (* (ms m) (ns n)))
(convolve-indices i (count ms) (count ns)

(defn convolve [ms ns]
"Convolves ms with ns."
(map #(convolve-1 % ms ns)
(range (dec (+ (count ms) (count ns))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Response

2010-07-17 Thread Michael Gardner
On Jul 17, 2010, at 3:43 PM, Isaac Hodes wrote:

> It's just a shame, it seems to me, that there is such a nice way to
> represent the procedure in Python or even C, yet Clojure (or any Lisp
> really) struggles to idiomatically answer this question of
> convolution.

No, it's pretty easy to do convolution idiomatically, as demonstrated by some 
of the replies you got. What makes it seem difficult is that the literature is 
all written with imperative languages in mind.

What Clojure does "struggle" with is performance, in that the obvious way of 
writing something often results in poor performance, especially for heavy 
numeric code. This applies to most (all?) dynamic languages, though; you'd be 
better off with C if high-performance numerics are your top priority.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: A functional, efficient, convolution function. Is imperitive-style the answer?

2010-07-16 Thread Michael Gardner
I'm assuming the StackOverflow link you refer to is 
http://stackoverflow.com/questions/3259825/trouble-with-lazy-convolution-fn-in-clojure.

I would think about the problem this way: to compute the value at index i in 
the output list, you multiply together each pair of values in the input lists 
whose indices add up to i, then add them all together. So I would first write a 
small helper function to return a list of such index pairs for a given output 
index, then use it with map to compute each output value in one go.

(defn convolve-indices [i max-m max-n]
"Lists all index pairs adding up to i, where the first index is less than 
max-m and the second is less than max-n."
(filter #(< (first %) max-m)
(filter #(< (second %) max-n)
(map #(vector % (- i %))
(range (inc i))

(defn convolve-1 [i ms ns]
"Returns the ith value of the convolution of ms with ns."
(reduce +
(map #(* (ms (first %)) (ns (second %)))
(convolve-indices i (count ms) (count ns)

(defn convolve [ms ns]
"Convolves ms with ns."
(map #(convolve-1 % ms ns)
(range (dec (+ (count ms) (count ns))

I would expect this to be much slower than the imperative approach, due to all 
the temporary objects and the lack of type hints. There should be a much less 
wasteful way to write convolve-indices, for instance. On the plus side, you may 
be able to use pmap to parallelize the work with little effort.

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


Re: clojure.contrib.sql does not protect table names?

2010-07-14 Thread Michael Gardner
On Jul 14, 2010, at 11:41 AM, Tim McCormack wrote:

> On Jul 14, 11:56 am, Michael Wood  wrote:
>> AFAIK backticks are MySQL-specific.  PostgreSQL uses double quotes.  I
>> imagine there is a proper JDBC way of handing this, though.
> 
> OK, so there is enough variation between RDBMSs that a simple solution
> won't work. Seems like clojure.contrib.sql's job should be to even out
> those differences by quoting and escaping as appropriate to the chosen
> database. :-/

Actually, you can also use double quotes with MySQL if you turn on ANSI_QUOTES:

http://dev.mysql.com/doc/refman/5.5/en/server-sql-mode.html#sqlmode_ansi_quotes

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: DSL with a grammar

2010-07-08 Thread Michael Gardner
On Jul 8, 2010, at 2:34 PM, Nicolas Oury wrote:

> Sorry, that's why I had quote around my parse.
> 
> I meant, use clojure reader to take a sequence in a macro and then "parse" it 
> for my own DSL.
> So I shouldn't need any help from the reader (even if having some metas with 
> line and character attached to thing would help)
> 
> I do not want to go the parser generator way because I want the DSL to be 
> tightly integrated with Clojure.

In that case, what about treating the symbols in your given sequence as tokens, 
and using a Java-based parser generator from your macro to build up a parse 
tree out of Clojure objects? Maybe overkill, but since you get to skip the 
tokenization step, it should actually be pretty easy to implement.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: DSL with a grammar

2010-07-08 Thread Michael Gardner
On Jul 8, 2010, at 1:52 PM, Nicolas Oury wrote:

> I am trying to write a small Domain Specific Language using macro, and I want 
> the syntax of the args of the macro to be somehow "parsed" and transformed.
> 
> So, I have two questions:
> 
> - Does anybody else does that? (except the infix calculus) Is there a generic 
> method for doing it? Or even better a library?

The generic way to create parsers is with a parser generator. You describe your 
grammar (usually in something like Backus-Naur Form), and it creates code that 
will parse strings using that grammar.

But (somebody correct me if I'm wrong here) to do something like you describe 
would require a custom reader macro, which Clojure doesn't currently support.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 Clojure namespace names

2010-07-07 Thread Michael Gardner
On Jul 7, 2010, at 8:53 PM, j-g-faustus wrote:

> The disadvantage is of course that you end up with names like
> org.apache.http.client.params.ClientPNames/
> CONNECTION_MANAGER_FACTORY_CLASS_NAME
> which gets old really quick if you have to type it a lot :)

Why would you ever type that more than once? Just use :as.

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


Re: --> macro proposal

2010-07-06 Thread Michael Gardner
On Jul 6, 2010, at 3:16 PM, Greg wrote:

>> Have you checked for those?
> 
> No, sorry, I think that's a rather unreasonable request. I'm not going to 
> spend hours sifting through the core and contrib just to jerk out examples 
> for you.
> 
> I'd rather use logic and reason to make my case.

It's not unreasonable when you are arguing (rather vehemently) for its 
inclusion in clojure.core, for which there is a high bar. And logic alone isn't 
likely to be able to answer the question of whether enough people would use 
this macro to make its inclusion worthwhile.

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


Re: Clojure / Common Lisp Question

2010-06-26 Thread Michael Gardner
On Jun 26, 2010, at 12:37 AM, rob levy wrote:

>> Rich Hickey's insightful videos have caused me to stop
>> writing loops whenever possible. For me this is the same
>> level of "thinking-change" that happened when I moved to
>> using "Structured Programming" rather than GOTO (in Fortran).
>> Rich needs to write a paper called
>>  "Loops considered harmful"
>> 
> 
> That is a great thing, I like that about both Common Lisp and Clojure.  
> Compare with Perl or even Python; you can use map/grep, list comprehensions 
> etc some of the time but not all of the time.  I Lisp it's always possible to 
> that in a neat way I think.  I know there is a loop macro in CL, which I'm 
> sure can cause many people to just write in some other language's idiom 
> instead of the native one.

You can use Perl's map/grep pretty much anywhere, though they're not as nice to 
use because the language is a mess (albeit more functional than Python). I, 
too, have found myself using fewer and fewer explicit loops as time goes on, 
starting with a revelation about the versatility of map while I was still 
living in Perlistan. I haven't used a single loop statement yet in Clojure, and 
I doubt I will ever do so except for performance reasons.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: cond formatting

2010-06-22 Thread Michael Gardner
On Jun 22, 2010, at 3:55 PM, cageface wrote:

> This looks nice but requires more hand-indenting, right? I really like
> being able to select a block in emacs and hit indent-region and get
> predictably tidy code. (The failure of emacs to do this 100% with
> scala code is a pet peeve).

Can't help you there, as I never use auto-indenting (nor 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


Re: cond formatting

2010-06-22 Thread Michael Gardner
On Jun 22, 2010, at 3:27 PM, cageface wrote:

> In this case it takes some visual parsing to see what the predicates
> and results are and if you break them up onto individual lines you
> have to count evens to figure out what the results are. The extra
> level of indentation in the CL case makes it a lot easier. The only
> easy solution I've considered for this is to add an extra blank line
> between each clause, but this looks weird.
> 
> Any thoughts on this or other approaches?

Try this:

(defn compare-row [a b]
  ;; compare null rows as > to advance cursor
  (cond
(and (nil? a) (nil? b))
  [0,0]
(and (nil? a) (not= b nil))
  [1, 0]
(and (not= a nil) (nil? b))
  [-1, 0]
true
  (loop [col 0 a a b b]
 (let [cmp (compare-fields (first a) (first b))]
   (if (and (< col (count a)) (= cmp 0))
 (recur (+ 1 col) (rest a) (rest b))
 [cmp,col])

I do this with multi-line lets and hash-map initializations too:

(let [
foo
  (calculate-foo arg1)
bar
  (calculate-bar arg2)
extra-long-name
  (calculate-extra-long-name arg3)]
  (do-stuff))

(hash-map
  :foo
(calculate-foo arg1)
  :bar
(calculate-bar arg2)
  :extra-long-name
(calculate-extra-long-name arg3))

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Hash-map destructuring

2010-06-16 Thread Michael Gardner
On Jun 16, 2010, at 7:07 PM, ataggart wrote:

> There's a disconnect between the function definition and the
> datastructures used by the caller.
> 
> Either fix the data structure:
> (def args [:bar 2 :baz [:quux]])
> then use apply
> 
> Or change the function definition to take a map:
> (defn foo [x {:keys [bar baz]}]
>  ...)

That's a pretty flippant answer. I have run into this same issue; it's not 
always desirable to have your function take a map, and if you get the data 
structure from elsewhere (say loaded from a config file), then you have to 
resort to either re-building the arg list manually or doing (apply concat ...).

Regarding Brian's original question: as far as I know, there is no built-in 
version of apply that works with keyword args contained in a map. But note that 
you can eliminate the call to seq, since (apply concat args) works the same as 
(apply concat (seq args)).

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: review the clojure.string code

2010-06-03 Thread Michael Gardner
On Jun 3, 2010, at 2:31 AM, Laurent PETIT wrote:

>   * why ltrim / rtrim , but upper-case / lower-case ? Why not ltrim / rtrim + 
> ucase / lcase , or left-trim right-trim + upper-case / lower-case ? Will 
> left-trim/right-trim be so often used that they must be shortened to 
> ltrim/rtrim (especially compared to upper-case / lower-case) ? Oh and also, 
> with some IDEs, having left-trim enables the possibility to write l-t and 
> then have autocomplete  work by expanding to left-trim (so it's more 
> readable, and it's even faster to write with the right tools :-) ).

Someone suggested triml/trimr instead of ltrim/rtrim, which I like. I would 
also accept trim-left/trim-right.

How about case-up/case-down?

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: (apply interleave [[1 2]])

2010-05-29 Thread Michael Gardner
On May 29, 2010, at 5:07 AM, Paul Hobbs wrote:

> What code would this make simpler?  Are you constantly having to check this 
> special case?  If not, I don't see a reason to include it.

I haven't run across this particular issue, but I have many times written code 
that may end up calling a function with "degenerate" arguments in corner cases. 
I much prefer functions that handle such degenerate arguments gracefully when 
it makes sense to do so, which it absolutely does for interleave.

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Elegant way to replace a few words in string

2010-05-28 Thread Michael Gardner
On May 28, 2010, at 12:42 PM, Laurent PETIT wrote:

> The rule should really always be: no warning at all (with 
> *warn-on-reflection* set to true, of course).

I strongly disagree. Why should you care about those sorts of warnings unless 
you've already identified a bottleneck that needs elimination? IMO the "rule" 
should be: write it the simplest way you can first, then optimize only what 
your benchmarks tell you needs optimizing.

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


<    1   2   3   >