Re: (finally) got all class signature changes w/gen-class reloading at runtime

2011-02-10 Thread Robert Campbell
Hi George,

That's correct. I briefly mention the JVM's standard "hot swapping"
capabilities when running in debug mode. Unfortunately this hot
swapping is mostly limited to changing method bodies and not class
signatures (add/remove method, etc).

Normally this is not even a problem because - as you mentioned -
Clojure compiles _new_ classes on the fly, and these can be loaded
fine. The problem is limited to gen-class development when stub
classes are generated. During interactive development you'll probably
be adding/removing methods or otherwise changing the class signature.
This is a problem because the stub was already generated the first
time you called (compile) and loaded. Subsequent compiles - which
include the class sig changes - don't get reloaded due to JVM
limitations. This specific issue is solved via JRebel.

Rob



On Thu, Feb 10, 2011 at 12:21 AM, George Jahad
 wrote:
> I studied it a bit more and noticed that the jdi redefineClasses
> method can't add new methods, (as you imply in your blog.)  That's
> what's special about what JRebel offers.
>
> The redefineClasses method is described here:
> http://download.oracle.com/javase/6/docs/jdk/api/jpda/jdi/com/sun/jdi/VirtualMachine.html#redefineClasses(java.util.Map)
>
>
> On Feb 9, 12:38 pm, George Jahad  wrote:
>> so i think most java debuggers, even jdb, are capable of reloading
>> classes aren't they?
>>
>> i haven't tried your example, but in the cdt, you use
>> the .redefineClasses method to reload a java class
>>
>> For example, I can hack on one of the classes in  clojure compiler and
>> reload it, without restarting, like so:
>>
>> (.redefineClasses
>>  (vm)
>>  {(first (find-classes #"clojure.lang.Compiler\$DefExpr\$Parser"))
>>   (to-byte-array
>>    (java.io.File.
>>     "/Users/georgejahad/incoming/clojure/classes/clojure/lang/Compiler
>> $DefExpr$Parser.class"))})
>>
>> is that what you are talking about, or am i missing something?
>>
>> On Feb 9, 12:49 am, Robert Campbell  wrote:
>>
>> > Back in January I found myself writing some gen-class to connect my
>> > Clojure library to my Java project. Until now I'd been spoiled by
>> > Clojure's dynamic, interactive nature, so running up against the whole
>> > "stub class signature can't change w/out jvm reboot" thing hurt a bit.
>>
>> > I found a partial solution via JRebel, but it only worked with
>> > invocations lacking type information and compiled to use reflection.
>> > It failed on any invocation with enough type information present in
>> > the sexpr to use invokevirtual. I actually met Jevgeni (CTO of ZT)
>> > last week and he mentioned he might have some of their guys take a
>> > look at the problem. Lo and behold, their latest nightly build fixes
>> > the issue and it now seems that everything is working.
>>
>> > Here's how to set it up:http://blog.robert-campbell.com/post/2760935713
>>
>> > The company behind JRebel, ZeroTurnaround, gives out free licenses to
>> > OSS and Scala developers. When I spoke with Jevgeni he seemed open to
>> > the idea of adding Clojure development to that list provided there was
>> > enough demand. While gen-class is a relatively rare/minor part of most
>> > Clojure development, I think this tool allows us to smooth out one
>> > rough patch in the dev 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

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


(finally) got all class signature changes w/gen-class reloading at runtime

2011-02-09 Thread Robert Campbell
Back in January I found myself writing some gen-class to connect my
Clojure library to my Java project. Until now I'd been spoiled by
Clojure's dynamic, interactive nature, so running up against the whole
"stub class signature can't change w/out jvm reboot" thing hurt a bit.

I found a partial solution via JRebel, but it only worked with
invocations lacking type information and compiled to use reflection.
It failed on any invocation with enough type information present in
the sexpr to use invokevirtual. I actually met Jevgeni (CTO of ZT)
last week and he mentioned he might have some of their guys take a
look at the problem. Lo and behold, their latest nightly build fixes
the issue and it now seems that everything is working.

Here's how to set it up: http://blog.robert-campbell.com/post/2760935713

The company behind JRebel, ZeroTurnaround, gives out free licenses to
OSS and Scala developers. When I spoke with Jevgeni he seemed open to
the idea of adding Clojure development to that list provided there was
enough demand. While gen-class is a relatively rare/minor part of most
Clojure development, I think this tool allows us to smooth out one
rough patch in the dev 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: Clojure/JVM languages internal presentation

2011-01-19 Thread Robert Campbell
Hi Shantanu,

Good questions.

> Can you share some details about the language selection process? Was it based 
> on developers consensus or it was a purely management decision? Was the 
> presence or absence of enough number of Clojure/Scala experts in the team 
> influential on the eventual decision?

This was completely developer driven; management was mildly resistant
to the idea from the beginning. I made my case for Clojure to the
other tech/team leads and we all agreed to allow it on a case by case
basis. Once the development organization was in agreement, it was run
by management who pushed back due to staffing concerns. I negotiated a
compromise (Scala) which (mostly) alleviated the staffing concern, but
maintained many of the same benefits. This negotiation is partly
reflected in the language selection slides, where number of
books/training, developer acceptance/momentum, syntax were all used as
selection criteria.

> To help me understand, would you like to share how was this conclusion 
> derived ("Clojure - being a Lisp dialect - has a steeper learning curve due 
> to its syntax and more purely functional nature.")?

When I show a typical Java developer some Clojure code, they
immediately have to swim across two rivers: S expressions and
functional concepts. We can agree that taking the plunge is incredibly
rewarding, but we shouldn't deny that they present real obstacles to
many developers. In contrast, when I show them some imperative-style
Scala, they can immediately recognize syntax and patterns already
familiar to them. This allows them to get up and running quickly,
dipping their toe into functional concepts at their own rate. I do,
however, agree that Clojure is simpler to use once you've crossed
those rivers, helped deeply by its smaller, more consistent syntax.

Clojure and Scala are both great languages that provide concrete
improvements over vanilla Java. With this presentation I try to
highlight two of those improvements that I found most compelling.

Rob


On Tue, Jan 18, 2011 at 7:21 PM, Shantanu Kumar
 wrote:
> Rob, thanks for sharing this and congratulations on having IDC (your
> employer IIUC) adopting an alternate JVM language. Can you share some
> details about the language selection process? Was it based on
> developers consensus or it was a purely management decision? Was the
> presence or absence of enough number of Clojure/Scala experts in the
> team influential on the eventual decision? Finally, from your notes on
> slide #25:
>
>
> "Clojure - being a Lisp dialect - has a steeper learning curve due to
> its syntax and more purely functional nature.
> Since Scala is instead a hybrid language, both object oriented and
> functional, it’s completely possible to write imperative, Java-style
> Scala.
> This allows developers to slowly ease into the language, adding more
> powerful functional techniques as they become more comfortable.
> So when management asks, “Where am I gonna find Scala programmers?”,
> we can answer,
>   “The same places you find Java programmers: throughout IDC and the
> greater market,” almost honestly..."
>
>
> To help me understand, would you like to share how was this conclusion
> derived ("Clojure - being a Lisp dialect - has a steeper learning
> curve due to its syntax and more purely functional nature.")? Scala
> has more syntax/semantics than Clojure AFAICT. Was it familiarity with
> the Java syntax?
>
> Regards,
> Shantanu
>
> On Jan 18, 4:33 am, Robert Campbell  wrote:
>> Hey guys,
>>
>> This past summer I gave a presentation on JVM langauges at our
>> company's worldwide developer summit. I tried to get approval for
>> Clojure but had to settle for Scala because its syntax didn't frighten
>> management. I figured I'd share it in case any of the slides can be of
>> use elsewhere.
>>
>> open in browser (no 
>> notes):http://public.iwork.com/document/?d=JVM_Languages.key&a=p1045023190
>>
>> src:https://github.com/rcampbell/jvm-languages
>>
>> The talk (w/notes in github .key file) was very important and the
>> slides don't make much sense without it, but it generally went like:
>>
>> -Topic is JVM languages, what they are, why we should care about them
>> -We (as a mostly Java house) have two big problems: bloat and concurrency
>> -Show bloat with examples, try to illustrate a trend
>> -Why are these other languages so concise?
>> -Go back over the examples pulling out a single language feature from
>> each (in bold), explain how it leads to more concise code
>> -Talk a bit about concurrency, No free lunch (R), Ghz wall, cores increasing
>> -Java's answer to concurrency is difficult to work with
>> -Make a token e

Clojure/JVM languages internal presentation

2011-01-17 Thread Robert Campbell
Hey guys,

This past summer I gave a presentation on JVM langauges at our
company's worldwide developer summit. I tried to get approval for
Clojure but had to settle for Scala because its syntax didn't frighten
management. I figured I'd share it in case any of the slides can be of
use elsewhere.

open in browser (no notes):
http://public.iwork.com/document/?d=JVM_Languages.key&a=p1045023190

src: https://github.com/rcampbell/jvm-languages

The talk (w/notes in github .key file) was very important and the
slides don't make much sense without it, but it generally went like:

-Topic is JVM languages, what they are, why we should care about them
-We (as a mostly Java house) have two big problems: bloat and concurrency
-Show bloat with examples, try to illustrate a trend
-Why are these other languages so concise?
-Go back over the examples pulling out a single language feature from
each (in bold), explain how it leads to more concise code
-Talk a bit about concurrency, No free lunch (R), Ghz wall, cores increasing
-Java's answer to concurrency is difficult to work with
-Make a token effort to select a JVM language based on books,
perceived momentum/maturity/community, etc
-Select Clojure and Scala, end with Scala example since that's the one
that was approved (replace slide here :-)

Rob

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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 (.foo (new Bar)) use a different method invocation mechanism than (def bar (new Bar)) (.foo bar)?

2011-01-16 Thread Robert Campbell
Thank you for the explanation Rasmus. I tried (.foo ^Bar bar) and it
behaved exactly like (.foo (new Bar)) as you suggested.

So method invocation via reflection works, while invokevirtual does
not. As a sanity check I compared the bytecode of an AOT'd (working)
invocation of a method compiled and loaded before the JRebel reload
with a failing invocation after the reload. As expected they both
contain the exact same code:

  71c71
  <10:  invokevirtual   #32; //Method 
foo/core/Bar.sayAhoj:()Ljava/lang/String;
  ---
  >10:  invokevirtual   #32; //Method
foo/core/Bar.sayHello:()Ljava/lang/String;

The only difference I've been able to spot so far between the vanilla
method invocations (pre JRebel reloading) and the freshly added and
reloaded method invocations is in the object expression:

  InstanceMethodExpr for sayAhoj (newly reloaded JRebel, broken):
  method.clazz = class foo.core.Bar$$M$8e38ee87
  method.parameterTypes = java.lang.Class[1], [0] = [class foo.core.Bar]

  InstanceMethodExpr for sayHello (loaded initially, working):
  method.clazz = class foo.core.Bar
  method.parameterTypes = java.lang.Class[0]

This mostly makes sense since I'm assuming JRebel has to load a new
class and perform some behind the scenes magic to write it up to look
like the original. The extra parameter looks like the [this] from the
function. I tried setting these values to match the sayHello versions,
but it didn't help.

Those differences don't seem to actually matter since at the end of
the day the compiled bytecode is twi identical invokevirtuals.

Rob



On Sun, Jan 16, 2011 at 7:22 PM, Rasmus Svensson  wrote:
> 2011/1/16 Robert Campbell :
>> The second form - (.foo bar), expanded to (. bar foo) - eventually
>> calls Reflector.invokeNoArgInstanceMember.
>
> For that form, the clojure compiler cannot infer the type of bar, and
> does not know which exact method (class + type signature) .foo
> represents. Due to this, a runtime lookup that uses the reflector is
> inserted, since a method invocation in java byte code must be
> statically typed (at least currently).
>
>> The first form - (.foo (new Bar)), expanded to (. (new Bar) foo) -
>> doesn't seem to use any Reflector _invocation_ methods. I also added a
>> breakpoint to java.lang.reflect.Method.invoke() and it never hits that
>> breakpoint.
>
> This is because the compiler knows the type of the arg to .foo, and
> can emit bytecode for a plain old (statically typed) method
> invocation.
>
> Since reflective method invocations are pretty slow, you often try to
> add type hints so that it can be avoided: (.foo ^Bar bar) The
> generated bytecode for this method invocation should be very similar
> (if not identical) to the bytecode for (.foo (new Bar))
>
> // raek
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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


Why does (.foo (new Bar)) use a different method invocation mechanism than (def bar (new Bar)) (.foo bar)?

2011-01-16 Thread Robert Campbell
I've been trying to understand exactly how these two statements are
evaluated by tracing execution through Compiler.java, Reflector.java,
etc of tag 1.2.0.

The second form - (.foo bar), expanded to (. bar foo) - eventually
calls Reflector.invokeNoArgInstanceMember.

The first form - (.foo (new Bar)), expanded to (. (new Bar) foo) -
doesn't seem to use any Reflector _invocation_ methods. I also added a
breakpoint to java.lang.reflect.Method.invoke() and it never hits that
breakpoint.

It seems that Reflector.getMethods is actually used to resolve Methods
for placement in the object expression "ObjExpr fexpr" on line 5421 of
Compiler.java. After that poing I'm unable to trace where the actual
invocation takes place.

I am trying to understand how the first form gets evaluated because I
have a case where JRebel instrumentation causes this to work:

(def bar (new foo.core.Bar))
#'user/bar
(.sayAhoj bar)
"Ahoj!"

but this to fail:

(.sayAhoj (new foo.core.Bar))
java.lang.NoSuchMethodError: foo.core.Bar.sayAhojLjava/lang/String;
(NO_SOURCE_FILE:0)

even though the method appears in the stub and can be invoked fine via
reflection. More information here:

http://blog.robert-campbell.com/post/2760935713/clojures-gen-class-and-jrebel

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

2010-06-23 Thread Robert Campbell
I'd like to resurrect this thread, because I have the exact same
requirement Laurent had and I'm hoping there's been some additional
progress in this area.

I'm set to give a Clojure presentation to our company's Java
developers, and I'm looking for a way to excite the audience about FP
concepts in general and Clojure in particular.

This audience will only care about one thing: how does this improve
productivity / help do our job better?

Thoughts? What convinced you?



On Sat, Apr 24, 2010 at 1:54 AM, Laurent PETIT  wrote:
> Thanks for the "food for thought". I'm concerned with the short
> introduction not being too much "goal oriented" (and more "tutorial
> oriented"), I'll continue think about it in "background mode".
>
> Cheers,
>
> --
> Laurent
>
> 2010/4/23 cburroughs :
>> What I did when I needed to give a shorter talk was to base it on some
>> of the well known presentations and just cut out a lot. I don't think
>> Stuart's intro or Rich's "for Java people" talk assumes people are
>> already enthusiastic about functional programming.
>>
>> [1] http://github.com/stuarthalloway/clojure-presentations/ or those
>> attached to the file section
>>
>> On Apr 21, 8:14 am, Laurent PETIT  wrote:
>>> Hello,
>>>
>>> I've consulted a lot of already made presentations of clojure.
>>> They are great, but I guess they may not suit my needs because it
>>> seems to me that either:
>>>   * they are more 1 1/2 to 2 hours talks than 45 minutes
>>>   * they assume the "public" will not be relunctant to some terms like
>>> "Lisp", "Functional Programming" and directly present these as
>>> advantages
>>>
>>> My goal is to raise interest into clojure in the mind of a public of
>>> people having used java for a long time. They may have Scala already
>>> in their "radar", but not clojure, or may have seen it and immediately
>>> dismissed it for what seemed to them good reasons (mainly aversion for
>>> lisp syntax), though we all know this is not true after the "normal"
>>> adaptation period.
>>>
>>> Say this presentation could be the presentation that leads people, at
>>> its end, asking you for giving all those great other presentations
>>> already available that I mentioned before ...
>>>
>>> Any references I missed that already solve my problem ? :-)
>>>
>>> Thanks in advance,
>>>
>>> --
>>> Laurent
>>>
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with your 
>> first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group 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

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

2010-03-23 Thread Robert Campbell
I love the Little/Seasoned Schemer books. They feel lightweight, both
physically and in content, and I managed to work through them fairly
quickly. It was surprisingly fun. SICP/HTDP/PAIP, on the other hand,
have more of the textbook feel which has so far kept me from working
through them.

The only thing that's kind of bitten me in the ass is that when I
started Clojure, I wrote a lot "lower level" fns, in the style of the
book. By this I mean lots of explicit recursion with cons cells,
accumulators, etc. when in fact there were already much higher level
constructs (map/reduce/filter/etc) I should have been using. Still,
you quickly learn, and it's nice knowing the plumbing.

Rob


On Tue, Mar 23, 2010 at 6:45 PM, cody koeninger  wrote:
>
>
> On Mar 23, 10:37 am, Sean Devlin  wrote:
>> Hey folks,
>> I'm looking to add to my bookshelf.  I was wondering what this groups
>> experience with the Schemer series of books is?
>>
>> Sean
>
>
> Little, seasoned, + the little MLer are awesome, only thing that comes
> close in terms of pedagogical quality is How To Design Programs.
> Haven't read reasoned.  A little java isn't that great, that style
> doesn't really mesh well with java.
>
> The little schemer may be very basic, but given some of the job
> applicants I've seen, we'd all be better off if every programmer had
> read it at least once.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
>
> To unsubscribe from this group, send email to 
> clojure+unsubscribegooglegroups.com or reply to this email with the words 
> "REMOVE ME" as the subject.
>

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

To unsubscribe from this group, send email to 
clojure+unsubscribegooglegroups.com or reply to this email with the words 
"REMOVE ME" as the subject.


Re: Leaning about VM's, JVM in particular

2010-02-16 Thread Robert Campbell
"Some good books that we recommend to get you on your way [to
understanding the JVM/runtime] are: "Java Reflection in Action"
by Ira R. Forman and Nate Forman. "The Java Virtual Machine
Specification" 2nd edition by Tim Lindholm.
"Effective Java" 2nd edition and "Java Puzzlers" by Joshua Bloch. And
"Inside The Java Virtual Machine" 2nd
edition by Bill Venners."

- The Joy of Clojure, by Michael Fogus and Chris Houser who are both
active on IRC and this mailing list.

http://www.manning.com/fogus/



On Tue, Feb 16, 2010 at 5:29 PM, Andrey Fedorov  wrote:
> Hi all,
>
> I'm looking for approaches to learn about VM's, the JVM in particular.
> I noticed some local university courses use Virtual Machines (Smith,
> Nair) [1]. I'm planning on getting it, but would rather query you guys
> for opinions first, and recommendations on other books/resources?
>
> Cheers,
> Andrey
>
>
> 1. http://www.amazon.com/gp/product/1558609105/
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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: iterator-seq runs over

2010-02-16 Thread Robert Campbell
Hi Stuart,

That fixes the problem, thank you.

When I ran the result-set through (type), it showed me that the
instance was actually a ResultSetStream. While the Jena ResultSet
interface doesn't act as a closable resource, perhaps the stream was
being closed once the owning QueryExecution obj was closed via
with-open.

Rob



On Tue, Feb 16, 2010 at 9:55 AM, Stuart Halloway
 wrote:
> Hi Rob,
>
> map is lazy, count and butlast are not lazy. Does adding a doall around your
> call to map fix this problem?
>
> Stu
>
>> (map handler (iterator-seq result-set)) always throws a
>> NoSuchElementException
>>
>> (map handler (butlast (iterator-seq result-set))) always works.
>>
>> (count (iterator-seq result-set)) is returning the correct number of
>> elements. Calls to first, second, nth, also work correctly.
>>
>> When I manually test a result-set of three elements,
>> [(handler (.next result-set))
>> (handler (.next result-set))
>> (handler (.next result-set))]
>> evaluates correctly, while adding one more .next call results in the
>> same NoSuchElementException.
>>
>> Using butlast fixes the problem, but then I obviously lose the last
>> element in the result set. This code is replacing vanilla Java code
>> which used .hasNext() and .next() without problem for a couple of
>> months, so I doubt it's the class (com.hp.hpl.jena.query.ResultSet)
>> incorrectly implementing Iterator.
>>
>> Has anyone else seen this type of behavior?
>>
>> Rob
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group 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

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


iterator-seq runs over

2010-02-15 Thread Robert Campbell
(map handler (iterator-seq result-set)) always throws a NoSuchElementException

(map handler (butlast (iterator-seq result-set))) always works.

(count (iterator-seq result-set)) is returning the correct number of
elements. Calls to first, second, nth, also work correctly.

When I manually test a result-set of three elements,
[(handler (.next result-set))
 (handler (.next result-set))
 (handler (.next result-set))]
evaluates correctly, while adding one more .next call results in the
same NoSuchElementException.

Using butlast fixes the problem, but then I obviously lose the last
element in the result set. This code is replacing vanilla Java code
which used .hasNext() and .next() without problem for a couple of
months, so I doubt it's the class (com.hp.hpl.jena.query.ResultSet)
incorrectly implementing Iterator.

Has anyone else seen this type of behavior?

Rob

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

2010-02-07 Thread Robert Campbell
Hi Michał,

That works perfectly and is much simpler, thank you.


On Sun, Feb 7, 2010 at 4:23 PM, Michał Marczyk  wrote:
> Ouch, sorry, I misread your specs... Use this instead:
>
> (map #(zipmap (keys coordinates) %)
>  (apply cartesian-product (vals coordinates)))
>
> With coordinates bound to your example map, this produces
>
> ({"baz" true, "bar" \a, "foo" 1}
>  {"baz" false, "bar" \a, "foo" 1}
>  ...)
>
> (which is your example output with the keys ordered differently in the
> small maps).
>
> Sincerely,
> Michał
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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: Dutch Clojure users

2010-02-07 Thread Robert Campbell
I'm only 1.5hr flight away in Prague. I'd be happy to host any Clojure
users to trade notes over our famous beer.


On Sat, Feb 6, 2010 at 12:26 PM, Joop Kiefte  wrote:
> Hello folks!
> I am from the Netherlands and I am learning Clojure now, using it at work,
> and loving it so far. Are there any more dutch Clojure programmers on this
> list so we can meet? I am also interested to know about Clojure-programmers
> from any country in a reasonable distance from Strasbourg.
> Joop Kiefte
> --
> Communication is essential. So we need decent tools when communication is
> lacking, when language capability is hard to acquire...
>
> - http://esperanto.net  - http://esperanto-jongeren.nl
>
> Linux-user #496644 (http://counter.li.org) - first touch of linux in 2004
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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


Cartesian product of map pairs w/labels

2010-02-07 Thread Robert Campbell
Imagine a map m {
   "foo" [1 2 3 4]
   "bar" [\a \b \c]
   "baz" [true false]
}

How could I transform that into a seq s (
   {"foo" 1 "bar" \a "baz" true}
   {"foo" 1 "bar" \a "baz" false}
   {"foo" 1 "bar" \b "baz" true}
   {"foo" 1 "bar" \b "baz" false}
   {"foo" 1 "bar" \c "baz" true}
   {"foo" 1 "bar" \c "baz" false}
   {"foo" 2 "bar" \a "baz" true}
   ...
)

I've made a macro to expand the map over a for:
(defmacro cartesian-map [m]
  `(for ~(vec (reduce #(concat %1 %2) (map #(identity [(symbol %)
(list 'coordinates %)]) (keys coordinates
 ~(apply hash-map (flatten (map #(identity [% (symbol %)]) (keys
coordinates))

and expands correctly:
(clojure.core/for [foo (coordinates "foo") bar (coordinates "bar") baz
(coordinates "baz")] {"foo" foo, "bar" bar, "baz" baz})

but when I run it, I only get (), which doesn't make any sense because
if I run the expansion against the map m, it performs correctly.

Why would the macro expand correctly, but no run correctly in the
REPL? Also, are there any ways to simplify my macro?

Rob

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

2009-12-30 Thread Robert Campbell
I think anything which lowers the impedance mismatch between Clojure
data structures and a persistent store is worth investigating. I'd
love to find an ACID, transactional store which accepts native
structures. Right now I'm using CouchDB, and while JSON is close
enough, it still requires a mapping between the Clojure and Couch
worlds. Not supporting set, and not allowing fields with dashes
(JavaScript thinks it's a minus) are some of the annoyances.


On Wed, Dec 30, 2009 at 12:52 PM, Gabi  wrote:
> On first look, Redis and Clojure seems to be a perfect match. They
> both handle sets and maps efficiently. If one could find an easy way
> to store and retrieve Clojure data structures to Redis (even a small
> subset- just a list or a set), a distributed clojure app could be very
> easy (and effective?) thing to do - The stateless Clojure nodes would
> share and operate on the same central data structure which is stored
> in Redis). What do you thing ? Is it worth investigating further?
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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: Help with my vec matching function

2009-12-28 Thread Robert Campbell
That makes sense. I updated the function to:

(defn closest-match
  "Returns the closest matches of needle in the haystack"
  [#^IPersistentVector needle #^IPersistentVector haystack]
  (letfn [(matching [candidate]
(println ">> checking " candidate)
(reduce + (map #(if (= %1 %2) 1 0) needle candidate)))
  (closest [v1s v2]
   (cond (empty? v1s) [v2]
 (and (= (matching (first v1s)) (matching v2))
  (= (count (first v1s)) (count v2))) (conj v1s v2)
 (or (> (matching (first v1s)) (matching v2))
 (and (= (matching (first v1s)) (matching v2))
  (< (count (first v1s)) (count v2 v1s
 :else [v2]))]
(reduce #(closest %1 %2) [] haystack)))

This does work now:

(closest-match [1 2 3] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5]})
[[1 2 3 4 5]]

(closest-match [1 2] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5]})
[[1 2 \b] [1 2 \c] [1 2 \a]]

(closest-match [2 1 3] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5]})
[[2 1]]

One place I'm going to try to improve upon is how it reacts when there
are no matches. Right now, it will return the smallest candidate
because the third cond predicate will be true:
(and (= (matching (first v1s)) (matching v2))  ; (= 0 0)
   (< (count (first v1s)) (count v2 v1s  ; basically finds the
smallest candidate

(closest-match [\a \b] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5]})
[[1]]

(closest-match [\a \b] #{[1 2 \a] [1 2 \b] [2 1] [1] [1 2 \c] [1 2 3 4 5] []})
[[]]

I think when matches = 0, or there is literally no intersection
between the needle and the candidates, I will just return [].

Rob




On Mon, Dec 28, 2009 at 6:28 PM, ajuc  wrote:
>
>
> On 28 Gru, 20:57, Robert Campbell  wrote:
>> How might I add a third and final condition, where those candidates
>> with equal scores AND equal counts are all returned together?
>
> Reduce can work with functions like
> f : x * y -> x
>
> So we can modify function closest to be like that (untested):
>
> (closest [ v1s v2]
>          (if  (empty v1s)
>                   v2
>                   (cond
>                     (and (= (matching (first v1s)) (matching v2))
>                          (= (count (first v1s)) (count v2))) (into
> v1s v2))
>                     (or (> (matching (first v1s)) (matching v2))
>                         (and (= (matching (first v1s)) (matching v2))
>                              (< (count (first v1s)) (count v2
> [v1]
>                     :else [v2])))
>
> Also, we use matching on the same arguments a lot, so it would be good
> to memoize that 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

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

2009-12-28 Thread Robert Campbell
How might I add a third and final condition, where those candidates
with equal scores AND equal counts are all returned together?

A first try was this:

(defn closest-match
  "Searches the haystack vecs for the closest match to the needle vec"
  [#^IPersistentVector needle #^IPersistentVector haystack]
  (letfn [(matching [candidate]
(reduce + (map #(if (= %1 %2) 1 0) needle candidate)))
  (closest [v1 v2]
   (cond
 (and (= (matching v1) (matching v2))
  (= (count v1) (count v2))) [v1 v2]
 (or (> (matching v1) (matching v2))
 (and (= (matching v1) (matching v2))
  (< (count v1) (count v2 v1
 :else v2))]
(reduce #(closest %1 %2) [] haystack)))

(closest-match [1 2] #{[1 2 \a] [1 2 \b] [2 1]})
[[1 2 \b] [1 2 \a]]
(closest-match [1 2] #{[1 2] [1 2 \a] [1 2 \b] [2 1]})
[1 2]

It looks good at first, but I quickly noticed that I broke the whole
reduction by introducing a pair where we expend only a vec:

(closest-match [1 2] #{[1 2 \a] [1 2 \b] [2 1] [1 2 \c]})
[1 2 \a]

What we should be getting [[1 2 \a] [1 2 \b] [1 2 \c]] since each of
them is equally close to [1 2 3]




On Mon, Dec 28, 2009 at 5:20 PM, Robert Campbell  wrote:
> Thanks ajuc.
>
> I updated the implementation to match your algorithm:
>
> (defn closest-match
>  "Searches the haystack vecs for the closest match to the needle vec"
>  [#^IPersistentVector needle #^IPersistentVector haystack]
>  (letfn [(matching [candidate]
>                    (reduce + (map #(if (= %1 %2) 1 0) needle candidate)))
>          (closest [v1 v2]
>                   (if (or (> (matching v1) (matching v2))
>                           (and (= (matching v1) (matching v2))
>                                (< (count v1) (count v2 v1 v2))]
>    (reduce #(closest %1 %2) [] haystack)))
>
> It now factors in the second step, taking the shortest candidate.
>
> (closest-match [1 2 3] #{[1 2 3] [9 8 3] [1 2] [1] [1 0 3 4] [1 2 3 4 5]})
>
> now correctly returns [1 2 3] instead of [1 2 3 4 5]
>
>
>
>
> On Mon, Dec 28, 2009 at 4:23 PM, ajuc  wrote:
>> I don't know if I understan correctly the requirements, but this is my
>> try.
>>
>>
>> (def v #{[1 2 3]   [9 8 3]   [1 2]   [1]   [1 0 3 4]   [1 2 3 4 5]} )
>>
>> (defn matching [p v]
>>  (reduce + (map #(if (= %1 %2) 1 0) p v)))
>>
>> (defn better-match [p v1 v2]
>>  (if
>>    (or
>>      (> (matching p v1) (matching p v2))
>>      (and
>>         (= (matching p v1) (matching p v2)) (< (count v1) (count
>> v2
>>    v1
>>    v2))
>>
>> (reduce #(better-match [1 2 4 4 5] %1 %2) [] v)
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with your 
>> first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group 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: Help with my vec matching function

2009-12-28 Thread Robert Campbell
Thanks ajuc.

I updated the implementation to match your algorithm:

(defn closest-match
  "Searches the haystack vecs for the closest match to the needle vec"
  [#^IPersistentVector needle #^IPersistentVector haystack]
  (letfn [(matching [candidate]
(reduce + (map #(if (= %1 %2) 1 0) needle candidate)))
  (closest [v1 v2]
   (if (or (> (matching v1) (matching v2))
   (and (= (matching v1) (matching v2))
(< (count v1) (count v2 v1 v2))]
(reduce #(closest %1 %2) [] haystack)))

It now factors in the second step, taking the shortest candidate.

(closest-match [1 2 3] #{[1 2 3] [9 8 3] [1 2] [1] [1 0 3 4] [1 2 3 4 5]})

now correctly returns [1 2 3] instead of [1 2 3 4 5]




On Mon, Dec 28, 2009 at 4:23 PM, ajuc  wrote:
> I don't know if I understan correctly the requirements, but this is my
> try.
>
>
> (def v #{[1 2 3]   [9 8 3]   [1 2]   [1]   [1 0 3 4]   [1 2 3 4 5]} )
>
> (defn matching [p v]
>  (reduce + (map #(if (= %1 %2) 1 0) p v)))
>
> (defn better-match [p v1 v2]
>  (if
>    (or
>      (> (matching p v1) (matching p v2))
>      (and
>         (= (matching p v1) (matching p v2)) (< (count v1) (count
> v2
>    v1
>    v2))
>
> (reduce #(better-match [1 2 4 4 5] %1 %2) [] v)
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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


Help with my vec matching function

2009-12-28 Thread Robert Campbell
When given the following set of vecs

#{[1 2 3]   [9 8 3]   [1 2]   [1]   [1 0 3 4]   [1 2 3 4 5]}

find the closest match to [1 2 3]

(defn closest-match
  "Searches the haystack vecs for the closest match to the needle vec"
  [#^IPersistentVector needle #^IPersistentVector haystack]
  (second
   (last
(apply sorted-map
   (apply concat
  (map (fn [candidate]
 [(reduce + (map #(if (= %1 %2) 1 0) needle candidate)) 
candidate])
   haystack))

I wanted a three-step process:

1) Count the number of matching elements for each candidate
*2) When counts are equal, select the shortest candidate, discarding
the rest  <-- help!
3) Return the candidate with the highest count

Stepping through the execution,

  (map (fn [candidate]
 [(reduce + (map #(if (= %1 %2) 1 0) needle candidate)) 
candidate])
   haystack)
  ; returns ([1 [1]] [2 [1 0 3 4]] [3 [1 2 3]] [3 [1 2 3 4 5]] 
[2 [1
2]] [1 [9 8 3]]), a vec matching counts to candidates

   (apply concat ...
   ; returns (1 [1] 2 [1 0 3 4] 3 [1 2 3] 3 [1 2 3 4 5] 2 [1
2] 1 [9 8 3]) for consumption by "apply assoc {}" or "apply
sorted-map"

(apply sorted-map
; returns {1 [9 8 3], 2 [1 2], 3 [1 2 3 4 5]} <-- here is where
things get screwed up

When I apply the sorted-map, it will just take the last candidate for
matching counts. In other words, given (3 [1 2 3] 3 [1 2 3 4 5]) it
will return [1 2 3 4 5]. I'd instead like it to take the shorted
candidate, which in this case is [1 2 3].

What are some ways I could simplify/improve this function? How might I
implement my missing 2nd step so that it correctly picks the closest
match?

Rob

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

2009-12-13 Thread Robert Campbell
>> We have talked about adding a run task;
>> if you're interested we could even get it in for the 1.0.0 release.

I'd definitely like to see that. Right now my deployment sequence looks like:

lein compile
lein uberjar
java -jar myapp-standalone.jar

I imagine "lein run" should be able to execute the -main method in the
:main namespace or an executable jar.

It would also be nice if you could chain the targets/tasks together
like in Maven:

lein compile uberjar run




On Sun, Dec 13, 2009 at 2:54 PM, mac  wrote:
> On Dec 6, 12:40 am, Phil Hagelberg  wrote:
>> Zach Tellman  writes:
>> > If that's what it takes, great.  Someone just needs to define what a
>> > multi-platform JNI package looks like. I'm willing to go along with
>> > whatever is decided upon by technomancy et al.
>>
>> I don't think this is necessarily within the scope ofleiningen
>> itself; it should be able to be implemented within a plugin. I'm happy
>> to provide support for how to write a plugin, but since I'm pretty
>> ignorant of the challenges of native code I'm not sure my input is all
>> that helpful.
>>
>> -Phil
>
> I looked at the code of the swank plugin and some other I found but it
> seems like plugins are just new tasks?
> In order to AOT compile some clojure code that uses native libraries
> (e.g. penumbra) they need to be on the java.library.path at compile
> time (because the native libs are loaded in static blocks so simply
> importing their java classes causes them to be linked in), which means
> that the compile task needs to know about java.library.path.
> I've made a rather ham-fisted attempt at adding this functionality to
> leiningen. The result can be viewed here:
> http://github.com/bagucode/leiningen
> However, when trying to build penumbra with it, it still fails with an
> UnsatisfiedLinkError. It seems like setting the java.library.path
> property in the ant task in eval-in-project is ignored..?
>
> /Mac
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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: FileNotFoundException (Access is denied)

2009-11-26 Thread Robert Campbell
Thank you, that was the problem.

I wonder if Stuart should change this line:

(defn clojure-source? [file] (.endsWith (.toString file) ".clj" ))

to this:

(defn clojure-source? [file] (and (.isFile file) (.endsWith (.toString
file) ".clj" )))

just to make sure directories like "myproj.clj" don't throw an error.
I suppose that's being excessively safe for what's meant to be a
simple example.



On Thu, Nov 26, 2009 at 9:43 AM, Rob Wolfe  wrote:
>
>
> Robert Campbell napisał(a):
>> I'm trying to write a file scanner very similar to the one on page 131
>> of Stuart's book:
>>
>> (ns user
>>   (:use [clojure.contrib.duck-streams :only [reader]]))
>>
>> (defn scan [dir]
>>   (for [file (file-seq dir)]
>>     (with-open [rdr (reader file)]
>>       (count (filter #(re-find #"foobar" %) (line-seq rdr))
>>
>> user> (scan (java.io.File. "C:/SomeValidDir"))
>>
>> java.lang.RuntimeException: java.io.FileNotFoundException:
>> C:\publishing\cosmos\trunk\web (Access is denied) (NO_SOURCE_FILE:0)
>>
>> The strange part:
>>
>> user> (file-seq (java.io.File. "C:/SomeValidDir"))
>> ( # #)
>> and so on, properly listing the entire contents of the directory.
>>
>> user> (for [file (file-seq (java.io.File.
>> "C:/publishing/cosmos/trunk/web"))] nil)
>> (nil nil) and so on, again working properly.
>>
>> user> (for [file (file-seq (java.io.File.
>> "C:/publishing/cosmos/trunk/web"))] (with-open [rdr (reader file)]
>> nil))
>> ; Evaluation aborted. (this one finally fails with the same error)
>>
>> So "with-open [rdr (reader file)]" is the problem, but why?
>
> I guess "reader" does not work for directories. Try to change your
> "for" loop like this:
> (for [file (file-seq dir) :when (.isFile file)]
>
> HTH,
> Rob
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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: Question about future

2009-11-25 Thread Robert Campbell
If you have this:

user> (def f (future (Thread/sleep 2) :done))
#'user/f
user> @f  ; this immediate deref blocks for 20 sec, finally returning :block
:done
user> @f  ; returns immediately
:done

What is actually happening when you call the first @f? You are waiting
for the function to finish executing and return a value? Or are you
waiting for a return value to appear in the ref slot?

Is there any way to check if there is a value ready or if the function
has returned w/out blocking?



On Thu, Nov 26, 2009 at 12:32 AM, Hong Jiang  wrote:
> Thanks. Yeah, after adding a call to shutdown-agents, the process no
> longer hangs.
>
> On Nov 25, 1:15 pm, Kevin Downey  wrote:
>> future also uses the same threadpool as agents, so once you call
>> future the threadpool spins up, and just sort of sits around for a
>> while before the jvm decides to exit, which is why the program would
>> sit around for 50 seconds
>>
>>
>>
>> On Wed, Nov 25, 2009 at 10:30 AM, Hong Jiang  wrote:
>> > Thanks for your replies David and Sean. Yes, I made a mistake thinking
>> > that future takes a function and its arguments, so the function was
>> > never called in my program.
>>
>> > On Nov 25, 8:21 am, David Brown  wrote:
>> >> On Tue, Nov 24, 2009 at 09:04:38PM -0800, Hong Jiang wrote:
>> >> >Hi all,
>>
>> >> >I'm new to Clojure and playing with small programs. Today I wrote a
>> >> >snippet to figure out how future works:
>>
>> >> >(defn testf []
>> >> >  (let [f (future #(do
>> >> >                     (Thread/sleep 5000)
>> >> >                     %)
>> >> >                  5)
>> >> >        g 7]
>> >> >    (+ g @f)))
>>
>> >> You don't ever evaluate the function containing the sleep, you just
>> >> create it, and then immediately return 5.
>>
>> >> Future contains an explicit do, so you can just do the steps in the
>> >> future:
>>
>> >>      [f (future
>> >>           (Thread/sleep 5000)
>> >>          5)
>> >>          ...
>>
>> >> Or, if you want to get the function call in, you'll need to call it:
>>
>> >>      [f (future (#(do (Thread/sleep 5000) %) 5)) ...]
>>
>> >> David
>>
>> > --
>> > You received this message because you are subscribed to the Google
>> > Groups "Clojure" group.
>> > To post to this group, send email to clojure@googlegroups.com
>> > Note that posts from new members are moderated - please be patient with 
>> > your first post.
>> > To unsubscribe from this group, send email to
>> > clojure+unsubscr...@googlegroups.com
>> > For more options, visit this group at
>> >http://groups.google.com/group/clojure?hl=en
>>
>> --
>> And what is good, Phaedrus,
>> And what is not good—
>> Need we ask anyone to tell us these things?
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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: FileNotFoundException (Access is denied)

2009-11-25 Thread Robert Campbell
Forgot to mention: running Clojure 1.0.0- and Clojure-Contrib
1.0-SNAPSHOT according to the pom..


On Thu, Nov 26, 2009 at 7:38 AM, Robert Campbell  wrote:
> I'm trying to write a file scanner very similar to the one on page 131
> of Stuart's book:
>
> (ns user
>  (:use [clojure.contrib.duck-streams :only [reader]]))
>
> (defn scan [dir]
>  (for [file (file-seq dir)]
>    (with-open [rdr (reader file)]
>      (count (filter #(re-find #"foobar" %) (line-seq rdr))
>
> user> (scan (java.io.File. "C:/SomeValidDir"))
>
> java.lang.RuntimeException: java.io.FileNotFoundException:
> C:\publishing\cosmos\trunk\web (Access is denied) (NO_SOURCE_FILE:0)
>
> The strange part:
>
> user> (file-seq (java.io.File. "C:/SomeValidDir"))
> ( # #)
> and so on, properly listing the entire contents of the directory.
>
> user> (for [file (file-seq (java.io.File.
> "C:/publishing/cosmos/trunk/web"))] nil)
> (nil nil) and so on, again working properly.
>
> user> (for [file (file-seq (java.io.File.
> "C:/publishing/cosmos/trunk/web"))] (with-open [rdr (reader file)]
> nil))
> ; Evaluation aborted. (this one finally fails with the same error)
>
> So "with-open [rdr (reader file)]" is the problem, but why?
>

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


FileNotFoundException (Access is denied)

2009-11-25 Thread Robert Campbell
I'm trying to write a file scanner very similar to the one on page 131
of Stuart's book:

(ns user
  (:use [clojure.contrib.duck-streams :only [reader]]))

(defn scan [dir]
  (for [file (file-seq dir)]
(with-open [rdr (reader file)]
  (count (filter #(re-find #"foobar" %) (line-seq rdr))

user> (scan (java.io.File. "C:/SomeValidDir"))

java.lang.RuntimeException: java.io.FileNotFoundException:
C:\publishing\cosmos\trunk\web (Access is denied) (NO_SOURCE_FILE:0)

The strange part:

user> (file-seq (java.io.File. "C:/SomeValidDir"))
( # #)
and so on, properly listing the entire contents of the directory.

user> (for [file (file-seq (java.io.File.
"C:/publishing/cosmos/trunk/web"))] nil)
(nil nil) and so on, again working properly.

user> (for [file (file-seq (java.io.File.
"C:/publishing/cosmos/trunk/web"))] (with-open [rdr (reader file)]
nil))
; Evaluation aborted. (this one finally fails with the same error)

So "with-open [rdr (reader file)]" is the problem, but why?

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

2009-11-24 Thread Robert Campbell
I've deployed two small mashup apps which combine OpenCalais and our
content repository to annotate documents with metadata (named
entities, relationships, etc) and expose the results over the web.
Good experiences all around, including with the clojure-http-client
and saxon wrapper libs + Compojure.

I did miss having a nice Clojure RDF lib, so maybe I'll make a Jena
wrapper in the future. Parsing the XML-RDF as pure XML w/xpath was
enough for my purposes.


On Tue, Nov 24, 2009 at 6:06 AM, John Harrop  wrote:
> On Mon, Nov 23, 2009 at 9:47 PM, Richard Newman  wrote:
>>>
>>> 1- We have this license server, used to control the use of a
>>> professional software (this one written using delphi).
>>
>> What are the ethics of using an open source product like Clojure to
>> implement DRM restrictions for some other product? Seems there might be
>> something a bit iffy there -- if not legally, perhaps morally.
>>
>> I don't agree. So long as they abide by the Clojure license, everything is
>> A-OK… and the Clojure license doesn't impose restrictions on its use for
>> this purpose.
>
> Hence my "if not legally".
>
>>
>> This use of Clojure is internally consistent, and so I suspect that you're
>> simply slightly offended by the idea of someone making money by using
>> open-source software. In that case, I'd suggest you look first at Red Hat
>> (market cap: $5.09B), and the Linux community's attitude towards them
>> (generally positive).
>
> Oh, I have no problem with making money by using open source software, when
> it's done in the manner that companies like Red Hat do it. It's the use to
> lock down some piece of proprietary software even more than it already is
> that seems, at the very least, ironic.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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


Transforming a Seq to a Map

2009-11-18 Thread Robert Campbell
Hey guys,

I'm having some trouble finding a nice way to perform a map
transformation I need. I need to transform this:

[ {:a 1 :b 2 :c 3} {:a 4 :b 5 :c 6} {:a 7 :b 8 :c 9} ]

into this:

{ {:a 1 :b 2} 3 {:a 4 :b 5} 6 {:a 7 :b 8} 9 }

I wanted to use map, but each f in map only returns one value, so I
couldn't figure it out. Here is what I have now:

(def result (ref {}))
(for [item coll]
(dosync (alter result assoc (dissoc item :c) (item :c
; result should now have correct value

I also wrote a recursive version to build the map without using a ref,
but I feel like I'm missing a simpler 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: Strange behavior seen when ints have leading zeros

2009-11-12 Thread Robert Campbell
Oh, that's pretty neat. Thanks!


On Thu, Nov 12, 2009 at 2:36 PM, Fogus  wrote:
>> Why does Clojure hate 8's? :-)
>
> It doesn't.  By adding a leading zero you're telling Clojure that you
> want octal numbers.  There is no number 08 in octal, instead to write
> the base-10 number 8 you would use 010 in octal.
>
> -m
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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


Strange behavior seen when ints have leading zeros

2009-11-12 Thread Robert Campbell
C:\dev\clojure>java -cp clojure.jar clojure.lang.Repl
Clojure 1.1.0-alpha-SNAPSHOT
user=> (def grid1 [01 02 03 04 05 06 07])
#'user/grid1
user=> grid1
[1 2 3 4 5 6 7]
user=> (def grid2 [01 02 03 04 05 06 07 08])
java.lang.NumberFormatException: Invalid number: 08
java.lang.Exception: Unmatched delimiter: ]
java.lang.Exception: Unmatched delimiter: )
user=>

Why does Clojure hate 8's? :-)

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


Re: Converting to TCO

2009-11-08 Thread Robert Campbell

Mark: that looks a lot like the "collector" I learned about in The
Little Schemer. I actually do have How to Design Programs, but I
wanted to finish Seasoned Schemer first. I was poking around in SICP
because of a Project Euler problem. Thanks for the tip!

John: good catch. Can you confirm the difference between my original
defn and your letfn? Both work, but as I understand it from the
documentation, defn would actually define that local function
globally, while letfn actually does bind it locally to all the expr
which follow in the body..


On Sun, Nov 8, 2009 at 7:01 PM, John Harrop  wrote:
> You have a bug:
> (defn exp-mod [base exp m]
>   (cond
>     (zero? exp) 1
>     (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
>     :else (mod (* base (exp-mod base (inc exp) m)) m)))
> should be
> (defn exp-mod [base exp m]
>   (cond
>     (zero? exp) 1
>     (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
>     :else (mod (* base (exp-mod base (dec exp) m)) m)))
> The recursion depth is logarithmic in exp so TCO is probably unnecessary
> here. But with the bug, it gets locked into a cycle of exp being alternately
> 2 and 1 and never reaching zero, the base case, so the recursion continues
> until the stack blows up.
> Meanwhile,
> (defn fermat-test [n]
>   (defn try-it [a]
>     (= (exp-mod a n n) a))
>  (try-it (inc (rand-int (dec n)
> should really be
> (defn fermat-test [n]
>   (letfn [(try-it [a]
>            (= (exp-mod a n n) a))]
>    (try-it (inc (rand-int (dec n))
> in Clojure, or even
> (defn fermat-test
>   "Performs the Fermat test on n with a, if specified, or with a random
> value from 2 to n."
>   ([n a]
>     (= (exp-mod a n n) a))
>   ([n]
>     (fermat-test n (inc (rand-int (dec n))
>
> >
>

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

2009-11-08 Thread Robert Campbell

One correction: after playing with the functions a bit I noticed I
screwed up, putting sqrt where I needed square.


On Sun, Nov 8, 2009 at 4:43 PM, Robert Campbell  wrote:
> I've started reading SICP and I came across the Fermat primality test
> implemented an Scheme. I reimplemented it in Clojure and was able to
> switch the recursive call in fast-prime to TCO/recur, but I was unable
> to do the same for the exp-mod function.
>
> (defn exp-mod [base exp m]
>  (cond
>    (zero? exp) 1
>    (even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
>    :else (mod (* base (exp-mod base (inc exp) m)) m)))
>
> (defn fermat-test [n]
>  (defn try-it [a]
>    (= (exp-mod a n n) a))
>  (try-it (inc (rand-int (dec n)
>
> (defn fast-prime? [n times]
>  (cond
>    (zero? times) true
>    (fermat-test n) (recur n (dec times))
>    :else false))
>
> Calling (fast-prime? 5 3) blows the stack. How can I change exp-mod to use 
> TCO?
>

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



Converting to TCO

2009-11-08 Thread Robert Campbell

I've started reading SICP and I came across the Fermat primality test
implemented an Scheme. I reimplemented it in Clojure and was able to
switch the recursive call in fast-prime to TCO/recur, but I was unable
to do the same for the exp-mod function.

(defn exp-mod [base exp m]
  (cond
(zero? exp) 1
(even? exp) (mod (Math/sqrt (exp-mod base (/ exp 2) m)) m)
:else (mod (* base (exp-mod base (inc exp) m)) m)))

(defn fermat-test [n]
  (defn try-it [a]
(= (exp-mod a n n) a))
  (try-it (inc (rand-int (dec n)

(defn fast-prime? [n times]
  (cond
(zero? times) true
(fermat-test n) (recur n (dec times))
:else false))

Calling (fast-prime? 5 3) blows the stack. How can I change exp-mod to use TCO?

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

2009-10-27 Thread Robert Campbell

Wow, thank you very much. That's definitely a lot simpler. I'm going
to try reimplementing it via your suggestions and see how it goes.

I like your idea about not maintaining cart state on the server,
because it would make my functions easier to test and debug (no need
to setup & teardown a fake session) but I'm not sure it would work
well in practice. If a user is browsing Amazon, for example, they
might add something to their cart, then visit 10 random pages before
they go to checkout. I would need to embed the cart in each of these
pages and resubmit the cart to the server for each request. The
purpose of sessions are to avoid exactly this hairy situation.

I wrapped cart in a Ref in case multiple browser windows are open and
there is a concurrent "add to cart" click.


On Tue, Oct 27, 2009 at 12:41 PM, Timothy Pratley
 wrote:
>
> Hi Robert
>
> On Oct 27, 9:48 pm, Robert Campbell  wrote:
>> Hey guys, I'm looking for _any_ feedback/thoughts on this Clojure code
>> I wrote. I just feel like the entire thing is way too complex, but I'm
>> not sure about how to simplify it. I wanted to try something "real
>> world" so I made a simple shopping cart ref to put in a session:
>
> Great, an open invitation!
>
> structs are really no different from maps except as a performance
> optimisation (and not a huge one). So dropping the structs would
> remove some boilerplate if simplicity is your goal. Also why not make
> the cart a map of products to qty and forget about subtotal...
> subtotal and total are easily calculated by separate functions for
> view or checkout... something like (untested at all):
>
> (defn add-to-cart [product qty]
>  (if (pos? qty)
>    (dosync (alter cart update-in [product] #(+ qty (if % % 0)
>
> (defn update-cart [product qty]
>  (dosync (alter cart assoc product qty)))
>
> (defn remove [product]
>  (dosync (alter cart dissoc product)))
>
> (defn subtotal [product]
>  (* (@cart product) (price product)))
>
> (defn total []
>  (reduce + (map subtotal @cart)))
>
> But in a real-world example I'm not sure a ref would be the best way
> to deal with the state... wouldn't you have the cart sent up in the
> request and a new cart returned? ie: you wouldn't need to maintain a
> ref on the server, just provide the hooks for building a cart and
> checking out. So the functions might be better if they take a cart as
> input and return a cart. Doing that pretty much makes them empty
> functions:
> (defn remove [cart product]
>  (dissoc cart product))
> So do you even need a remove function? Maybe not.
>
> Just some thoughts - I'm no web-shop programmer so disclaimer
> attached.
>
>
> Regards,
> Tim.
>
>
>
> Regards,
> Tim.
>
> >
>

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



feedback on this code

2009-10-27 Thread Robert Campbell

Hey guys, I'm looking for _any_ feedback/thoughts on this Clojure code
I wrote. I just feel like the entire thing is way too complex, but I'm
not sure about how to simplify it. I wanted to try something "real
world" so I made a simple shopping cart ref to put in a session:


(defstruct cart :line-items :total)
(defstruct line-item :product :qty :subtotal)


(defn create-line-item [product qty]
  (struct line-item product qty (* qty (product :price

(defn add-line-item [cart line-item]
  (assoc cart
:line-items (conj (cart :line-items) line-item)
:total (+ (cart :total) (line-item :subtotal

(defn update-line-item [line-items product qty]
  (cond
(empty? line-items) ()
(= ((first line-items) :product) product)
(cons
(assoc (first line-items)
:qty qty
:subtotal (* qty (((first line-items) :product) :price)))
(rest line-items))
:else
(cons (first line-items)
(update-line-item (rest line-items) product qty

(defn remove-line-item [cart line-item]
  (assoc cart
:line-items (remove #{line-item} (cart :line-items))
:total (- (cart :total) (line-item :subtotal



(defn add-to-cart [product qty cart]
  (dosync
   (let [li (create-line-item product qty)]
 (alter cart add-line-item li

(defn update-cart-helper [cart product qty]
  (let [uli (update-line-item (cart :line-items) product qty)]
  (assoc cart
:line-items uli
:total (reduce + (map #(% :subtotal) uli)

(defn update-cart [product qty cart]
  (dosync
   (alter cart update-cart-helper product qty)))

(defn remove-from-cart [line-item cart]
  (dosync
   (alter cart remove-line-item line-item)))

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



Tricks for transforming a DB ResultSet into XLM?

2009-09-11 Thread Robert Campbell

I am using clojure.contrib.sql which gives me the typical Clojure
ResultSet: a set of maps. Are there any tricks you've used in the past
to transform this into XML? I was looking at Enlive since I've used it
- and loved it - for HTML transformations in the past, but examples
are few and I don't see how I'd use it.

Thanks!

Rob

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

2009-07-13 Thread Robert Campbell

Thanks guys, that makes perfect sense to me. I have another Enlive question:

I need the _exact_ functionality of the "sniptest" function (which
appears to have been removed) in production code. I am trying to
create a decorator in compojure that will accept a response body and
modify the styling in various ways. I can just use the old sniptest
definition:

(apply str (emit* ((transformation [:h1] (content "hey")) (html-src
(:body response)

but is there a better way? I'm also not sure what emit* does exactly.
Is it breaking :content values out of lists so they stand alone as
strings?

BTW, I want to thank you Christophe for making this library. It's
everything xslt-driven views were supposed to be, but elegant instead
of evil. It's also going to be much nicer for the designers than all
the custom tags/embedded code frameworks I've used in the past.

Rob


On Mon, Jul 13, 2009 at 12:37 AM, Christophe Grand wrote:
> Hi !
>
> On Sat, Jul 11, 2009 at 7:31 PM, Jarkko Oranen  wrote:
>>
>> On Jul 11, 6:01 pm, Robert Campbell  wrote:
>> > Hey guys,
>> >
>> > I'm just curious why Christophe chose to return seq instead of a str
>> > for Enlive for his template functions.
>>
>> Most likely Enlive generates each of those fragments separately;
>> Forcing them into a single string at the end would wasteful in case
>> the user intends to write the output into a stream (which can be done
>> a fragment at a time.) Thus, leaving the choice to the user seems like
>> a good decision.
>
> Yes you are spot on: most of the time the resulting html is wrote into a
> stream (disk/network/pipe).
> This is also why I modified Ring to accept a seq of string as the body of a
> http response.
>
> Christophe
>
>
> --
> Professional: http://cgrand.net/ (fr)
> On Clojure: http://clj-me.blogspot.com/ (en)
>
> >
>

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

2009-07-11 Thread Robert Campbell

Hey guys,

I'm just curious why Christophe chose to return seq instead of a str
for Enlive for his template functions.

Example:

(deftemplate my-page-transformation "index.html" [message style]
  [:style] (content style)
  [:h1] (content message))

orchid> (my-page-transformation "my wonderful header" "h1 { color: blue }")
("" "\n\t" "" "\n\t\t" "" "h1 { color: blue }"
"" "\n\t" "" "\n\t" "" "\n\t\t" "" "test"
"" "\n\t" "" "\n" "")

It's trivial to call (apply str (my-page..)) but I'm just curious
about the thinking behind using a seq. Is it related to xml-seq and
traversing the tree?

Thanks,

Rob

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

2009-07-08 Thread Robert Campbell

> Wherever the files goes after C-x C-f ~/.emacs and then C-x C-s is where
> emacs thinks your home directory is. I would just go with that. It's
> normally in %appdata%, but it won't be there until you create it and save
> it.

yes, this is better than my #2

> Robert? Is that all you have in your .emacs? I am looking to create
> one from scratch.

Here is my entire .emacs file, which is extremely basic but got me up
and running at least:

--

(setq swank-clojure-extra-classpaths
  '())  
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure Box/clojure/clojure.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure
Box/clojure-contrib/target/clojure-contrib-1.0-SNAPSHOT.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure Box/compojure/deps/jetty-6.1.16.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure 
Box/compojure/deps/jetty-util-6.1.16.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure
Box/compojure/deps/servlet-api-2.5-20081211.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure 
Box/compojure/deps/commons-codec-1.3.jar")   
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure
Box/compojure/deps/commons-fileupload-1.2.1.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure Box/compojure/deps/commons-io-1.4.jar")  

(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure Box/compojure/compojure.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Dev/user/libs/postgresql-8.3-604.jdbc4.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Dev/technomancy-clojure-http-client/src")  

(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(cua-mode t nil (cua-base))
 '(show-paren-mode t))
(custom-set-faces
  ;; custom-set-faces was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 )

--

You'll notice the paths are different (I changed it during my first
post) but obviously they aren't relevant. A big problem I had was
getting versions of Clojure, Contrib, Compojure, Enlive, HttpClient,
etc. that all play well with each other. I'd frequently have a version
of Compojure/Enlive/HttpClient that was dependent on one or another
Contrib version, etc.  A quick trick I learned was to just check out
Compojure from git, run the ant deps which downloads the dependencies
compatible with that version, and just use those because James of
Compojure has done the work syncing them all up, so:

(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure Box/compojure/compojure.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure Box/compojure/deps/clojure.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Program Files/Clojure Box/compojure/deps/clojure-contrib.jar")

But with 1.0 out now I haven't had as many issues.

Rob


On Thu, Jul 9, 2009 at 5:35 AM, Shawn Hoover wrote:
>
> On Wed, Jul 8, 2009 at 2:56 PM, Mani  wrote:
>>
>> Thanks Shawn, Robert.
>> From Robert's post, I am bit confused here. I also read that .emacs is
>> in %appdata% folder (vista), but all I see is .emacs.d folder (which I
>> guess is for the emacs server). I tried creating one "C-x C-f
>> ~/.emacs" - under my home-directory (C:\emacs). Should i just create
>> a .emacs under %appdata%/.emacs.d  OR right under %appdata%?
>
> Wherever the files goes after C-x C-f ~/.emacs and then C-x C-s is where
> emacs thinks your home directory is. I would just go with that. It's
> normally in %appdata%, but it won't be there until you create it and save
> it.
>
> For ideas for a .emacs from scratch, you can look at
> http://bitbucket.org/shoover/emacs/src/tip/init.el.
>
> Shawn
>
> >
>

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

2009-07-08 Thread Robert Campbell

1. Here is my .emacs I use for Clojure Box to load the Jars and add
the proper paths to your classpath:

(setq swank-clojure-extra-classpaths
  '())
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Dev/clojure/clojure.jar")  
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Dev/clojure-contrib/target/clojure-contrib-1.0-SNAPSHOT.jar")  

(add-to-list 'swank-clojure-extra-classpaths
 "C:/Dev/compojure/deps/jetty-6.1.16.jar")
(add-to-list 'swank-clojure-extra-classpaths
 "C:/Dev/technomancy-clojure-http-client/src")

etc... just add directories and jars as needed

2. Your .emacs file would be here: C:\Documents and Settings\${your
username}\Application Data

3. I don't know about this one, but I had problems setting my home
directory. Even though I did it, it was still looking in C:\Documents
and Settings\${your username}\Application Data. Files there would load
fine.


On Wed, Jul 8, 2009 at 8:02 PM, Shawn Hoover wrote:
>
> On Wed, Jul 8, 2009 at 2:55 AM, dumb me  wrote:
>>
>> Hi All,
>>
>> I am a dumb around here. my first post among many to come :)
>>
>> I setup clojurebox to work thru the book. I am a newbie to emacs and
>> to clojure. I don't mind the learning curve to emacs.
>>
>> I am completely blank  about configuring Clojurebox.
>> Here's what I want to do:
>>
>> 1) load all the code-examples and the related jar-files of the book -
>> when I load ClojureBox.
>
> This requires putting the example source directly and all the jars into the
> Emacs Lisp variable swank-clojure-extra-classpaths (or writing some code to
> scoop them all up and generate a value to put in a variable). See the
> Customization section of the README.rtf that installs with Clojure Box.
> There should be a shortcut in the Start menu.
>
>>
>> 2) Where do I find the .emacs for Clojure Box? As I understand that I
>> will have to modify this file to include the libraries/folder-path. I
>> don't see one...
>
> "C-x C-f ~/.emacs". More info in the Customization section of the README.rtf
> that installs with Clojure Box.
>
>>
>> 3) I have been trying to do (load-file
>> "code.examples.introduction.clj") [my home directory being c:\emacs
>> and the code folder inside the emacs folder.] and I always get the
>> File-not-found exception.
>
> Once the classpath is set up correctly using the above techniques, in the
> REPL you can type (use 'code.examples.introduction) or leave off code. or
> code.examples. depending on what part you actually put on your classpath.
>
> Shawn
>
> >
>

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

2009-07-08 Thread Robert Campbell

Phil - got it. It wouldn't be hard at all to write a script to monitor
a directory, and any jar you throw in there gets exploded to the
classpath dir like you use. That would make it pretty painless.

> For the record, this is usually termed "dribbling" in the Lisp world.
> It's very handy for debugging customer interaction -- just tell them
> to turn on dribble, and have them send you the file rather than
> copying and pasting:

I hate to go completely off topic, but could you explain what advices
are in Lisp? When I was reading a post by Steve Yegge he wrote

"As far as I know, Lisp had it first, and it's called advice in Lisp.
Advice is a mini-framework that provides before, around, and after
hooks by which you can programmatically modify the behavior of some
action or function call in the system."
http://steve-yegge.blogspot.com/2007/01/pinocchio-problem.html

Searching turns up some pretty thin results, maybe the better one
being details on Emacs Lisp advices:
http://www.delorie.com/gnu/docs/elisp-manual-21/elisp_212.html

Does Clojure support something like this? I didn't come across it in
Stuart's book, website, etc. and AOP certainly helps manage complexity
in Java



On Wed, Jul 8, 2009 at 7:34 PM, Richard Newman wrote:
>
>> Perhaps instead of saving an image, it should be able to save a
>> transcript
>> of the REPL inputs? Then you could rescue code from this, or find
>> any cruft
>> your image had become dependent on, or whatever.
>
> For the record, this is usually termed "dribbling" in the Lisp world.
> It's very handy for debugging customer interaction -- just tell them
> to turn on dribble, and have them send you the file rather than
> copying and pasting:
>
> http://www.franz.com/support/documentation/8.1/doc/introduction.htm#reporting-bugs-1
>
> >
>

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

2009-07-08 Thread Robert Campbell

That's it, that's exactly what I needed to complete this example. I'm
pretty pumped because you guys have shown me a way to do it without
macros and without manually managing a quoted tree structure.

If it's okay, could somebody explain the difference between what's
happening here:

user> (def my-func (list + 1 2))
#'user/my-func
user> (my-func)
; Evaluation aborted.

and here:

user> (def my-func (list + 1 2))
#'user/my-func
user> (eval my-func)
3

I don't really understand how:
user>(my-func) is NOT eval on my-func in the REPL. My understanding is
the first item in the list is treated as a function, with the rest of
the list passed as arguments. Wouldn't the REPL just be calling eval
internally on everything you type in?



On Wed, Jul 8, 2009 at 7:22 PM, Richard Newman wrote:
>
>> That looks like what I'm after. When I run a test, however, it doesn't
>> behave properly:
>
> You'll want to either eval the expression, or apply the first item in
> the list to the rest:
>
> user=> (eval (list + 1 2))
> 3
> user=> (let [form (list + 1 2)]
>   (when (not (empty? form))
>     (apply (first form) (rest form
> 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: Save current namespace like a Smalltalk image

2009-07-08 Thread Robert Campbell

>> Unfortunately this is impossible due to the way the classloaders in
>> the
>> JVM work; you can't modify your classpath at runtime and have it work
>> consistently.

Doesn't this seem a little crazy though? My day job is Java dev in
Eclipse and a little IntelliJ and both IDEs allow you to modify
classpath at any time. It seems like it would be a basic requirement
for any IDE. Think of how often you do this. If I had to reboot
Eclipse every time I'd go crazy. Then throw in the lack of image
support and it becomes a real obstacle.

Does anyone know exactly when the JVM is booted for the REPL? Is it
from swank or clojure-mode or one of these systems? Couldn't there be
a way to reboot this subsystem instead of all Emacs?

Maybe from the command line you could execute the (add-to-list
'swank-clojure-extra-classpaths "/whatever") then reboot the subsystem
which invokes the JVM? Or modify the .emacs file and just reboot the
subsystem?

It's tough because I'm completely new to Emacs and I'm not clear on
how all the pieces fit together yet.


On Wed, Jul 8, 2009 at 7:14 PM,
mccraigmccraig wrote:
>
> what's the problem with adding urls to the current ClassLoader ?
>
> i've seen remarks to the effect that it doesn't work well, but i don't
> understand why...
>
> c
>
> On 8 Jul 2009, at 17:37, Phil Hagelberg wrote:
>
>>
>> Robert Campbell  writes:
>>
>>> The main reason this is an issue for me is during development I
>>> sometimes find I need another library added to my classpath. Right
>>> now
>>> the only way I know how to modify the classpath in Emacs is to change
>>> the .emacs file with an add-to-list 'swank-clojure-extra-classpaths
>>> and reboot. I think my looking for an image solution might be a
>>> cop-out itself; I need to learn Emacs better so I can figure out how
>>> to modify the classpath without rebooting.
>>
>> Unfortunately this is impossible due to the way the classloaders in
>> the
>> JVM work; you can't modify your classpath at runtime and have it work
>> consistently.
>>
>> The solution I've settled on is to have a static classpath; no matter
>> what the project is, my classpath is always the same:
>> src/:target/dependency/:target/classes/:test/
>>
>> When you need to add a new library, instead of putting the jar on the
>> classpath, just unpack the jar in the target/dependency directory.
>> Then
>> you can access it without restarting the JVM.
>>
>> -Phil
>>
>> >
>
>
> >
>

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



Re: Save current namespace like a Smalltalk image

2009-07-08 Thread Robert Campbell

> Perhaps instead of saving an image, it should be able to save a transcript
> of the REPL inputs? Then you could rescue code from this, or find any cruft
> your image had become dependent on, or whatever.

The only problem I see with this approach is that you leave it up to
the user (me) to sort though this transcript and try to reproduce the
latest version of the image. A function may be redefined many times
and the only version I'd _usually_ care about is the latest. This is
typically because the latest definition encompasses the latest
understanding of the problem or solution.

Having said that, it's better than nothing. There are certainly times
when I need to backtrack to previous definitions when I've down down
the wrong path. Having a transcript is better than where I'm at today.




On Wed, Jul 8, 2009 at 12:00 PM, John Harrop wrote:
> On Wed, Jul 8, 2009 at 5:14 AM, Robert Campbell  wrote:
>>
>> Thanks Daniel, that makes perfect sense, especially about having
>> random - and forgotten - code in the image. I have a lot of this
>> during my exploration sessions.
>
> Perhaps instead of saving an image, it should be able to save a transcript
> of the REPL inputs? Then you could rescue code from this, or find any cruft
> your image had become dependent on, or whatever.
> >
>

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

2009-07-08 Thread Robert Campbell

> It seems to me you want:
> user=> (list + 1 2)
> (# 1 2)

That looks like what I'm after. When I run a test, however, it doesn't
behave properly:

user> (def my-func (list + 1 2))
#'user/my-func
user> (my-func)
; Evaluation aborted.
clojure.lang.PersistentList cannot be cast to clojure.lang.IFn




On Wed, Jul 8, 2009 at 6:06 AM, Timothy Pratley wrote:
>
> It seems to me you want:
> user=> (list + 1 2)
> (# 1 2)
>
> As opposed to:
> user=> '(+ 1 2)
> (+ 1 2)
>
> Regarding examining a function, contrib has some helpers written by
> Chris
> user=> (use 'clojure.contrib.repl-utils)
> (source func)
> (show func)
> In your case source wont be useful as the function is generated not
> read from source. The output from show is a bit opaque to me so not
> sure if it is useful to you.
>
> I think once it is compiled a function is not easy to examine... so as
> you alluded to the best alternative would be to keep the AST?
>
> Regards,
> Tim.
>
> On Jul 7, 10:18 pm, Robert Campbell  wrote:
>> I'm trying to write the first basic GP example in this free 
>> book:http://www.lulu.com/items/volume_63/2167000/2167025/2/print/book.pdf
>>
>> I've gotten a lot of the suppor methods working correctly (like
>> fitness) but I'm having problem convering the pseudocode on page 14
>> for generating random expressions to make up my initial population.
>> Here's what I have so far:
>>
>> (defn gen-rand-expr [functions terminals max-depth arity method]
>>         (if (or (= max-depth 0) (and (= method :grow) (< (rand) (/ (count
>> terminals) (+ (count terminals) (count functions))
>>           (rand-element terminals)
>>           (let [arg1 (gen-rand-expr functions terminals (- max-depth 1) 
>> arity method)
>>                 arg2 (gen-rand-expr functions terminals (- max-depth 1) 
>> arity method)
>>                 func (rand-element functions)]
>>             (func arg1 arg2
>>
>> First, how can I print out the definition of a function in clojure?
>> For example, if I do (defn add [x y] (+ x y)) how can inspect this
>> definition, like (show-def add) -> (defn add [x y] (+ x y)). This
>> would help a lot in debugging the random programs I'm trying to
>> generate.
>>
>> Second, I believe the last line is the problem in my code. Let's
>> assume the function randomly selected was +, it will run (+ 1 2) and
>> the entire function returns 3 instead of a randomly generated syntax
>> tree like I need. I then tried '(func arg1 arg2) hoping it would
>> prevent evaluation, but then it will always just return (func arg1
>> arg2) which isn't what I need either. I need it to actually return a
>> syntax tree made up of expressions like (+ 1 2) but unevaluated.
>>
>> I am guessing I need to start reading and using macros at this point?
>>
>> Rob
> >
>

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

2009-07-08 Thread Robert Campbell

Hi Jurjen,

That wrapper for defn is something I was looking for in another post;
I previously asked how I can inspect the definitions of my functions
on the REPL. When I'm exploring stuff I'll be redefining many
functions many times and sometimes I lose track things. I basically
have to scroll around searching my REPL for the last definition. It
sounds like you have a solution to this problem. It seems strange to
me that Clojure doesn't support this concept natively. At some point
the function definition is compiled into bytecode to run on the JVM,
why not just automatically safe the original definition in metadata
when this is done? Have you should about adding your wrapper code to
Contrib?

Rob




On Wed, Jul 8, 2009 at 12:30 PM, Jurjen wrote:
>
> I had the same thought (as posted in the other thread) and haven't
> come to a final solution yet. The main reason I wanted to achieve it
> was that I do my developing / tinkering / brainstorming spread over
> several work boxes spread out through several locations, and a clojure
> REPL is cheap and easy, whereas maintaining several IDEs in synch (3
> locations at work, 2 at home) can be a bit of a nightmare.
>
> The compromise I've got at the moment is that I've made a custom
> wrapper around [defn] that records the code used to create the
> instance, and stores it in the metadata of the var that points to the
> function. I can then cycle through the namespace definitions using ns-
> interns / ns-publics and see the definition of each function, and can
> save it to a file.
>
> I tried to create a print-dup method so that the entire contents of a
> namespace could be dumped to a file, but as chouser pointed out, print-
> dup works on the function itself, whereas the code is stored in the
> metadata of the var that points to the function (and there's no back-
> link from the function to the var), so now it is a multi-stage process
> to port current code in its entirety, but as I'm generally only
> working on fairly limited areas of code it isn't a huge deal.
> Also, any closures are not captured by capturing the source, so
> there's still issues there, but for me the function definition is
> generally good enough. Still have to implement it for macros as well,
> but haven't needed that as much.
>
> Incidentally, I find the easiest way to port my code around is to
> print it to the repl, then cut-and-paste it to etherpad, which I can
> then access from anywhere (without having to save). Now if only there
> was a hosted REPL that integrated an IDE nicely I would really be set.
> Lord-of-all-repls comes close, but is not pure clojure or JVM.
>
> Jurjen
>
> On Jul 8, 8:13 pm, Robert Campbell  wrote:
>> Hello,
>>
>> Sometimes I have pretty long REPL sessions where I'm trying to flesh
>> out some ideas. When I close my instance of Clojure Box (Emacs based)
>> I lose all the definitions I had worked out over time. Is there any
>> way to dump namespace(s) to an image? It would be great to be able to
>> load up some workspace image and pick up where I left off.
>>
>> Rob
> >
>

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

2009-07-08 Thread Robert Campbell

Thanks Daniel, that makes perfect sense, especially about having
random - and forgotten - code in the image. I have a lot of this
during my exploration sessions.

The main reason this is an issue for me is during development I
sometimes find I need another library added to my classpath. Right now
the only way I know how to modify the classpath in Emacs is to change
the .emacs file with an add-to-list 'swank-clojure-extra-classpaths
and reboot. I think my looking for an image solution might be a
cop-out itself; I need to learn Emacs better so I can figure out how
to modify the classpath without rebooting. Then I wouldn't be
rebooting so often and I wouldn't need to be making images to save
I'm-in-the-middle-of-a-thought state


On Wed, Jul 8, 2009 at 10:57 AM, Daniel Lyons wrote:
>
> Robert,
>
> On Jul 8, 2009, at 2:13 AM, Robert Campbell wrote:
>
>> Sometimes I have pretty long REPL sessions where I'm trying to flesh
>> out some ideas. When I close my instance of Clojure Box (Emacs based)
>> I lose all the definitions I had worked out over time. Is there any
>> way to dump namespace(s) to an image? It would be great to be able to
>> load up some workspace image and pick up where I left off.
>
> Something similar was discussed recently but didn't come to a solid
> conclusion: 
> http://groups.google.com/group/clojure/browse_thread/thread/4efaee2e67a272c6/f24578bfa06e6b9c?lnk=gst&q=printing+and+reading+a+function#f24578bfa06e6b9c
>
> This is kind of a cop-out, but in general my advice would be to work
> from a file. Get your Clojure and Emacs set up so that you can compile
> your stuff pretty easily and your files are in the namespace-
> appropriate folder underneath your classpath. For example, I keep my
> Clojure code in ~/Projects/Languages/Clojure and my Emacs config looks
> like this:
>
> (setq swank-clojure-extra-classpaths
>       (cons "/Users/fusion/Projects/Languages/Clojure/classes"
>            (cons "/Users/fusion/Projects/Languages/Clojure"
>                  (directory-files "~/.clojure" t "\.jar$"
> (eval-after-load 'clojure-mode '(clojure-slime-config))
> (setq swank-clojure-extra-vm-args '("-Dclojure.compile.path=/Users/
> fusion/Projects/Languages/Clojure/classes"))
>
> Now if I want to load or compile a Clojure file, it just works.
>
> Next, when I start doodling I make a file in the aforementioned
> directory and put my stuff in there and open up a slime session in
> another window. C-c C-c sends the current form over Slime to the
> running session. Then I do my interactive testing and exploration in
> the slime session. Whenever I hit on a form I want to keep, I copy and
> paste it over to the file and make it into a function over there. I
> might make a function with a dumb name like demo or test and put a
> bunch of forms in there, and eventually they get refactored into unit
> tests (or not). If I close Emacs and reopen it on a file that doesn't
> yet have a namespace and whatnot, I select the stuff I want to
> evaluate and do C-c C-r to evaluate the region. It's handy, if less
> transparent.
>
> The main advantage to this, apart from keeping the code clean, is that
> you avoid the dirty image problem that can happen with Common Lisp or
> (I assume) Smalltalk, where the code seems to work but accidentally
> depends on cruft in the image that never made it into the source file.
> I've had this happen in CL and found it very frustrating. I had a
> tumblog which I tried to make faster by saving images and found one
> day to my surprise that I couldn't make a fresh image on my server,
> which was running a different architecture, because the only reason it
> was able to make images on my box was because the first image had some
> crap in it that never made it to the source file. Maybe this problem
> isn't as prevalent in Smalltalk; maybe the JVM can circumvent this by
> being cross-platform, but it's happened more than once in CL. IIRC,
> CMU CL for a long time was self-hosting to such a degree it couldn't
> be built at all without a running binary of a previous version. That
> kind of thing makes porting to new architectures quite difficult.
>
> Just my $0.02,
>
> —
> Daniel Lyons
>
>
> >
>

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



Save current namespace like a Smalltalk image

2009-07-08 Thread Robert Campbell

Hello,

Sometimes I have pretty long REPL sessions where I'm trying to flesh
out some ideas. When I close my instance of Clojure Box (Emacs based)
I lose all the definitions I had worked out over time. Is there any
way to dump namespace(s) to an image? It would be great to be able to
load up some workspace image and pick up where I left off.

Rob

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



Help with example from "A Field Guide to Genetic Programming"

2009-07-07 Thread Robert Campbell

I'm trying to write the first basic GP example in this free book:
http://www.lulu.com/items/volume_63/2167000/2167025/2/print/book.pdf

I've gotten a lot of the suppor methods working correctly (like
fitness) but I'm having problem convering the pseudocode on page 14
for generating random expressions to make up my initial population.
Here's what I have so far:

(defn gen-rand-expr [functions terminals max-depth arity method]
(if (or (= max-depth 0) (and (= method :grow) (< (rand) (/ (count
terminals) (+ (count terminals) (count functions))
  (rand-element terminals)
  (let [arg1 (gen-rand-expr functions terminals (- max-depth 1) arity 
method)
arg2 (gen-rand-expr functions terminals (- max-depth 1) arity 
method)
func (rand-element functions)]
(func arg1 arg2

First, how can I print out the definition of a function in clojure?
For example, if I do (defn add [x y] (+ x y)) how can inspect this
definition, like (show-def add) -> (defn add [x y] (+ x y)). This
would help a lot in debugging the random programs I'm trying to
generate.

Second, I believe the last line is the problem in my code. Let's
assume the function randomly selected was +, it will run (+ 1 2) and
the entire function returns 3 instead of a randomly generated syntax
tree like I need. I then tried '(func arg1 arg2) hoping it would
prevent evaluation, but then it will always just return (func arg1
arg2) which isn't what I need either. I need it to actually return a
syntax tree made up of expressions like (+ 1 2) but unevaluated.

I am guessing I need to start reading and using macros at this point?

Rob

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

2009-06-06 Thread Robert Campbell

Talk about bad timing - reading the "Silly question from Programming
Clojure" it looks like a book thread already got started there. Here
were some additional mentions:

Laurent PETIT: OOSC: Object Oriented Software Construction, but this
is OOP so I'm disinclined to include it for this specific list
Paul Stadig: Concepts of Programming Languages by Sebesta, suggested
as more general than SICP


On Sat, Jun 6, 2009 at 1:12 PM, Robert Campbell wrote:
> Going beyond the language-specific Programming Clojure book, what
> other books have best helped you make the (sometimes mind-bending)
> transition from OOP thinking to FP thinking? My bookshelf is piled
> high with OOP books like Design Patterns, Domain Driven Design,
> Analysis Patterns, etc. I've recently ordered:
>
> - Concepts, Techniques, and Models of Computer Programming (mentioned
> on this/compojure's list)
> - Structure and Interpretation of Computer Programs (highly
> recommended on Stackoverflow, lectures posted online)
>
> Any others?
>

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



What books have helped you wrap your brain around FP and Clojure?

2009-06-06 Thread Robert Campbell

Going beyond the language-specific Programming Clojure book, what
other books have best helped you make the (sometimes mind-bending)
transition from OOP thinking to FP thinking? My bookshelf is piled
high with OOP books like Design Patterns, Domain Driven Design,
Analysis Patterns, etc. I've recently ordered:

- Concepts, Techniques, and Models of Computer Programming (mentioned
on this/compojure's list)
- Structure and Interpretation of Computer Programs (highly
recommended on Stackoverflow, lectures posted online)

Any others?

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



STM & Resource transactions

2009-06-02 Thread Robert Campbell

I've been looking at using the clojure.set functions to create a
simple in-memory database cache. Basically when the app boost up, load
entire db into memory, work with it through the basic relational
algebra functions provided. Any mutations (create/update/delete) would
be wrapped in a simple function that 1) updates the cache and 2)
persists to the database in order to add the "D" to STM's "ACI". So
for example, you could have:

(defn insert-product [product]
 (dosync (alter products conj product))
 (with-connection db (transaction (insert-values XXXstuff hereXXX)))

The dosync will run the alter within an STM transaction.
The transaction will run the insert within a local resource (database)
transaction.

In Java, if you have two transactional systems, you can bridge them
with JTA. STM, however, is a different beast. Has anyone done anything
towards bridging STM and resource transactions?

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



Re: clojure-contrib build error

2009-04-30 Thread Robert Campbell

If you're on Windows, please take a look at Clojure Box:

http://clojure.bighugh.com/

It comes with an installer which sets you up with an Emac environment
running Clojure + contrib.

It's everything you need to get up in running in minutes. This is the
path I took when I faced similar difficulties as you.

Let me know later if you need help adding in more depedencies like
Compojure or DB drivers, as I had to struggle through that a tiny bit.

Rob



On Thu, Apr 30, 2009 at 12:08 PM, Hubert Iwaniuk  wrote:
> Hi All,
>
> I'm newcomer to clojure.
>
> Downloaded clojure.jar.
> Decided to go with VimClojure.
> So I need clojure-contrib.
> svn co clojure-contrib, and failed to build.
> svn co clojure, build fine retried building clojure-contrib, went fine.
>
> It's fine by me, but I believe that is not really a good user experience to
> need to build from sources just to start playing around.
>
> It might be good to have clojure-contrib released as clojure is released.
>
> Cheers,
>    Hubert.
>
> >
>

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



Re: AppEngine in Atlanta this week

2009-04-27 Thread Robert Campbell

Is there any way you could record the presentation and post it on your site?


On Mon, Apr 27, 2009 at 1:36 PM, slc  wrote:
>
> If you are interested in Google AppEngine and live in the Atlanta
> area ...
> 
> Tuesday - Clojure
>
>    * Who: John Hume
>    * What: Clojure on Google AppEngine
>    * When: Tuesday, April 28th at 7pm
>    * Where:  Norcross Group — 135 Technology Parkway, Suite 200,
> Norcross, GA 30092.
>
> For more details see Atlanta Clojure User Group (atlclj.org) .
> 
> Wednesday - Groovy
>
>    * Who: Vincent Stoessel
>    * What: Google AppEngine and Groovy
>    * When: Wednesday April 29, 2009 - 6:30PM
>    * Where: Matrix Resources, 115 Perimeter Center Place NE, Suite
> 250, Atlanta, GA
>
> PLEASE SIGN UP on the gg-members mail list: gg-members-
> requ...@www.ajug.org
> 
>
> Sari Connard
>
>
> >
>

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