Re: Having trouble doing what I want using macros, is there a better way?

2016-06-10 Thread Nate Young
You can "capture" symbols from the surrounding context, making them 
available to the body of your macros, the "tilde tick trick" is what 
you're looking for there:



(defmacro deftransducer
  [body]
  `(fn [reducing-fn#]
 (fn
   ([] (reducing-fn#))
   ([result#] (reducing-fn# result#))
   ([[~'guid-state ~'processed-events :as ~'result] ~'event]
~@body


now your macro's body has some implicitly defined variables available to 
it called `guid-state` `processed-events` `result` and `event`


If you'd like to avoid the tilde trick and name your own variables, a 
common pattern in Clojure is to pass in the binding form yourself as 
part of the macro like so (assuming you don't care much about the first 
two arities):



(defmacro deftransducer
  [params body]
  `(fn [reducing-fn#]
 (fn
   ([] (reducing-fn#))
   ([result#] (reducing-fn# result#))
   (~params ~@body


Now you can use this without being restricted to the same names every time:

-
(deftransducer [[my-state already-processed :as result] next-event]
  ...body goes here...)


Macros are great and lots of fun to write! But I think I'd echo what's 
already been thrown out on this thread and suggest that you try to 
recast your logic in terms of existing transducers or write a 
higher-order function: something that takes a processing function and 
returns a transducer.



Travis Daudelin 
June 10, 2016 at 1:06 PMvia Postbox 


Hi all!

I'm current working on a project where I am ingesting events off a 
stream and processing them. There are many many steps involved in the 
processing component, so I am choosing to write the steps as a series 
of transducers (because, hey, they're super cool!). Here's the problem 
though, after writing the first 2 processing steps I'm noticing that 
all of them are going to look very similar:


||
(defn a-step-transducer
[]
(fn [reducing-fn]
(fn
([](reducing-fn))
([result](reducing-fn result))
([[guid-state processed-events :asresult]event]
;;step-specific logic


Given how many steps I am planning to write, this is a ton of 
boilerplate! So, my first thought was to use a macro to abstract away 
all this boilerplate. Now, I have to admit that Clojure is my first 
Lisp, so I'm really not sure I fully understand when or why to use 
macros to do things. My current understanding is that macros are a 
kind of "template" for code, so something like this where I don't want 
to write the same function structure over and over seems like a decent 
use case for macros (feel free to correct me if I'm totally off on 
this). Here is my first attempt:


||
(defmacro deftransducer
[body]
`(fn [reducing-fn]
   (fn
 ([] (reducing-fn))
 ([result] (reducing-fn result))
 ([[guid-state processed-events :as result] event]
  ~@body

The idea here being that in body I can reference the variables defined 
by the macro like reducing-fn, result, event, etc. Of course, I 
quickly found out that this doesn't work:


||
storm-etl.entry-processing>(deftransducer "something")
CompilerExceptionjava.lang.RuntimeException:Can't use qualified name 
as parameter: storm-etl.entry-processing/reducing-function


Some quick googling tells me that the solution to this is to use 
gensyms for these variable names, but that would defeat the whole 
purpose of this because I want to be able to reference those variables 
from within the code that I pass to my macro. Is this an appropriate 
use case for macros or am I way off base? Is there an alternative 
approach that would be recommended?

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient 
with your first post.

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

For more options, visit https://groups.google.com/d/optout.


--
Sent from Postbox 



--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be

Re: How to Keep Clojure Server From Quitting

2016-06-09 Thread Nate Young
oh, perfect. aleph.netty/wait-for-close looks like exactly the kind of 
thing I wanted. thanks!


Andrea Richiardi wrote:


I do the following in my code (where system/http is a mount var, the
eval result of start-server):

(ns ...
(:require [aleph.netty :as netty])

(defn -main
[& args]
(mount/start args)
(netty/wait-for-close server/http))


On Wednesday, June 8, 2016 at 7:53:25 AM UTC-7, Nate Young wrote:

Good morning (at least from my part of the globe),

I spent a good chunk of time last night wondering why this chunk
of code
kept exiting about a minute after being run:


(ns narcoleptic.server
(:require [aleph.http :as http]
[compojure.core :as compojure :refer [GET]]
[compojure.route :as route]
[ring.middleware.params :as params]))

(def handler
(params/wrap-params
(compojure/routes
(GET "/" [] "Hello World!")
(route/not-found "Not Found"

(def server (agent nil))

(defn -main []
(send-off server #(or % (http/start-server handler {:port
9000}


until I found
http://tech.puredanger.com/2010/06/08/clojure-agent-thread-pools/
<http://tech.puredanger.com/2010/06/08/clojure-agent-thread-pools/> which

explains that send-off pools die after a minute. Additionally, it
looks
like all of the thread pools that aleph creates are marked as daemon
threads, so the main thread dies after the send-off, the send-off
thread
dies after a minute and that leaves no non-daemon threads running, so
the JVM exits. Cool.

My question, then, is this: Is there a best practice for keeping a
thread open forever so that my server won't ever exit? I'd like to
`lein
run -m narcoleptic.server` and see that it stays up as long as
possible.

I've tried two solutions, but the first feels ike an awful lot of
typing
for a language that usually has the right tools close at hand and the
second feels like a hack and doesn't play as nicely in a REPL
environment (but they both work):

(1)

(defn wait-until-stopped []
(let [stopped (promise)]
(add-watch server :stop-wait
(fn [key server old-state new-state]
(when (= new-state :stopped)
(remove-watch server :stop-wait)
(deliver stopped :ok
@stopped))


(2)

;; removed the agents code
(def stopped (promise))
(defn -main []
(http/start-server handler {:port 9000})
@stopped)


Am I super off in the woods here? Any help/pointers/sage advice
appreciated. Thanks!


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


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

To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Question about "attempt" parser in parsatron

2014-01-28 Thread Nate Young
On Tue, Jan 28, 2014 at 8:31 AM, Kashyap CK  wrote:
> The attempt parser does not work as expected for me. Perhaps my
> understanding is not correct. I the following code I was hoping that
> parsatron would attempt to parser "hello" and fail.

This is actually exactly what happened, but The Parsatron gave you an
atrocious error message that probably clouded that fact. By
complaining about 'w' I imagine that you thought the parser had
proceeded past `helloParser` and was currently working on parsing the
"world" part of the input.

What actually happened, was that the (p/attempt (helloParser)) failed,
which failed the entire outer `let->>` form, since The Parsatron won't
continue to parse sequentially combined parsers unless all succeed

Since I think you mentioned elsewhere that you've watched the talk,
this is the the 'ok' part of the [consumed/empty] x [ok/err] matrix.
`attempt` turns (consumed x err) into (empty x err) which means it has
still failed, but has rewound itself back to where it started to fail
so that another parser might take a crack at parsing it successfully.

You might consider something like this instead:

(p/defparser optional [p default-value]
  (p/either (p/attempt p) (p/always default-value)))

(p/defparser p []
  (p/let->> [h (optional (helloParser) nil)
     w (worldParser)]
(p/always [h w])))

Hope that helps.

Nate Young

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


Re: why is "get" not giving me a default value?

2012-10-18 Thread Nate Young
On Thu, Oct 18, 2012 at 10:16 AM, larry google groups
 wrote:
> Okay, this is very confusing to me. If I try this:
>
>   (defn add-to-logged-in-registry [this-users-params]
>
>   (let [right-now (. (Date.) getTime)
> new-user-entry (conj this-users-params { "updated" right-now })]
> (swap! registry (fn [map-of-user-maps]
>  (conj map-of-user-maps {:hi new-user-entry})
I think you want to use assoc here instead of conj

(assoc map-of-user-maps :hi new-user-entry)

and conveniently, swap! will pass the map to assoc for you, so no need
for the anonymous function

(swap! registry assoc :hi new-user-entry)

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

2012-08-29 Thread Nate Young
On Wed, Aug 29, 2012 at 4:03 PM, Erlis Vidal  wrote:
> If yes, how can I do a recursive call when passing the function as a
> parameter to another function, like in this case with mapcat?
You could use `lazy-seq`. Something like this:

(defn my-flatten [x]
  (lazy-seq
(if (coll? x)
  (mapcat my-flatten x)
  [x])))

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

2012-08-28 Thread Nate Young
On Thu, Aug 23, 2012 at 11:22 AM, Alexsandro Soares
 wrote:
> Can you provide the code for this?
Certainly.

The parser's current source position is stored in the InputState
record's `pos` field. That field is a SourcePos record consisting of
the current line and column position. Most parsers, however don't deal
directly with the raw InputState and SourcePositions, so we must write
a low-level function to examine those records, and return the value
we're interested in without consuming any input. The function would
look like this:

(defn lineno []
  (fn [state _ _ eok _]
(bounce eok (:line (:pos state)) state)))

The first line defines the name of the fn we can use in let->>
statements to get the current line number.
The second line is the standard parser interface, a function that
takes the state and 4 continutation functions, of which we're only
interested in the one that doesn't consume any input and doesn't
produce an error.
The last line pulls the current line number from the state, and passes
it along with the unchanged state to the `eok` continuation (`bounce`
is the function we use to ensure that no stack is consumed in the
process).

Now, you can treat `lineno` just like any other parser (in truth, it
is very close in spirit to the `always` parser except that it operates
on the parsers current state).

(let->> [current-line (lineno)]
  (do-something-with current-line))

Hope this was helpful.

Nate

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

2012-08-23 Thread Nate Young
On Thu, Aug 23, 2012 at 9:24 AM, Alexsandro Soares
 wrote:
> Ok. Thanks for the answer.
>
> Is there any way to get the line and column?
The Parsatron doesn't have any builtin facilities for extracting line
numbers from tokens, you'd have to keep track of the number of newline
characters your parser has seen through some manually-implemented
manner.

Nate

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

2012-04-18 Thread Nate Young
On Thu, Apr 12, 2012 at 10:10 AM, rahulpilani  wrote:
> Hi,
> I am trying to use the parsatron library
> (https://github.com/youngnh/parsatron) to parse a simple list of digits. I
> am not able to get it to parse correctly, I was wondering what I was
> missing.

Hi! Thanks for giving The Parsatron a whirl and I apologize for the
late, late reply but here's what I'd try.

When dealing with whitespace, I like to use a `tok` parser to handle
the consuming of any leading whitespace. That way all other parsers I
write can assume that they can immediately start parsing the thing
itself, and not worry that there might be spaces or tabs on the front.
Also, this allows for a single place to define what whitespace is.
Something like:

(defparser ws []
  (either (char \space) (char \,)))

(defparser tok [token-parser]
  (many (ws))
  token-parser)

The `array-item` parser I would define like this:

(defparser array-item []
  (let->> [digit-chars (many1 (digit))]
(always (read-string (apply str digit-chars)

Which brings us to the hard part, `arr`. Its tempting to write:

(defparser arr []
  (between (char LPAREN) (char RPAREN)
   (many (tok (array-item)

and it'll even work for a number of inputs:

(run (arr) "()")
(run (arr) "(1)")
(run (arr) "(1, 2, 3)")
(run (arr) "( 1, 2, 3)")

will all work, but if there is trailing whitespace after the last
array item, the `(tok (array-item))` will consume it, and not find a
number, but a RPAREN and you'll get an error: "Unexpected token ')' at
line: 1 column: 11"

(run (arr) "(1, 2, 3, )") ;; => RuntimeException

The root of this problem is that The Parsatron doesn't implement
backtracking by default (a decision that as more users ask questions,
I'm rapidly rethinking), and instead relies on the programmer to
implement backtracking using constructs like `lookahead` and
`attempt`.

I think you'll find that wrapping the `(tok (array-item))` in an
`attempt` and then making the closing paren a `tok` will get you the
list-parser you're looking for:

    (defparser arr []
  (between (char LPAREN) (tok (char RPAREN))
   (many (attempt (tok (array-item))

Cheers,
Nate Young

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

2011-11-15 Thread Nate Young
There's also ABCL, the Common Lisp implementation that maintains the
inalienable right to arm bears, written in Java and supporting interop
between both Java and Lisp.

http://common-lisp.net/project/armedbear/doc/abcl-user.html

On 11/15/2011 09:13 AM, Dennis Crenshaw wrote:
> I haven't dealt with CL in quite a while, but there is this (which I was
> involved with in my undergrad at CofC):
> 
> http://clforjava.org/
> 
> CLforJava may be helpful since it is, "a totally new version of the
> Common Lisp language that runs on the Java Virtual Machine and is
> intertwined with the Java language in such a way that users of Lisp can
> directly access Java libraries and vice versa."
> 
> Sounds familliar? :)
> 
> Clojure <-> Java <-> CLforJava
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group 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: Dynamic test creation?

2011-11-09 Thread Nate Young
On 11/08/2011 12:44 PM, AndyK wrote:
> I finally had a chance to try this out and it fails with
> 
> error: java.lang.ClassCastException: java.lang.String cannot be cast
> to clojure.lang.IObj
> Compilation failed.
I think I fat-fingered my deftest-form definition:

I originally wrote:
(defn testdef-form [n [expected actual]]
  `(deftest ~(str "testfromline" n)
 (is (= ~expected ~actual

But it should probably be:
(defn testdef-form [n [expected actual]]
  `(deftest ~(symbol (str "testfromline" n))
 (is (= ~expected ~actual

The original, wrong, function would have produced something like this:
(deftest "testfromline27"
  (is (= 5 2)))

Which is probably what's giving you the error message you're seeing.
That string should be a symbol:
(deftest testfromline27
  (is (= 5 2)))

> When I substituted in something like this...
> 
> (defn prn-form [n scenario]
>   `(prn ~(str "foo" n) (prn ~(str n " :: " scenario
> 
> the file did compile.
I'd have to see the rest of your code to comment on what's going on here.

> Is the fact that deftest is also a macro going to cause a problem with
> the original idea?
Macros certainly have composability issues, but its certainly safe to
write a macro that produces some other macro form. In fact, lots of
clojure.core macros use this to great effect (affect?), see ->, cond,
or, and .. to name a few.

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

2011-11-02 Thread Nate Young
On 11/01/2011 03:05 PM, AndyK wrote:
> How would (run-tests 'my-namespace) know to run all those dynamic
> tests? I thought that it parsed the namespace for 'my-namespace when
> you call it. Or is it that the call to defcsvtests sets off a chain of
> macro resolutions before run-tests can even do its thing (so that it

Right. Its that the macro-expansion phase actually reads from the csv
file in order to create a number of deftest forms, and each one then
gets evaluated, so after you've evaluated (defcsvtests), then
(run-tests) will be able to find a number of tests to run.

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

2011-10-31 Thread Nate Young
On 10/28/2011 09:42 AM, AndyK wrote:
> I am setting up tests with clojure.test that are driven by a CSV where
> each line represents one test case. Right now, there is a single
> deftest function that runs all the assertions. That's ok but creates
> reporting like 1 test was run with 1000s of assertions. Clojure being
> so dynamic, is it possible to create tests on-the-fly and run them
> where each dynamic test represents each row so that the reporting says
> X tests (where X == number of CSV rows).
> 
> I'm fairly new to clojure and quite unfamiliar with the ins-and-outs
> of clojure.test.
> Any pointers here would be appreciated.
> 
> Thank you
> 
It absolutely would be possible, and furthermore this is an area where
macros really shine.

I would choose macros because from what you describe, it sounds like
you'd like to write a program that generates a bunch of deftest forms,
and then runs those tests. But you need language facilities like reading
from a csv file in order to do so. Clojure (and indeed all lisps) give
you this ability.

You could write a macro that reads in the CSV file and for each line,
generates a deftest form. Below is a quick sketch of what it might look
like if your CSV file consisted of two columns of values that were
supposed to be equal to each other.

(use 'clojure.test)
(require '[clojure.java.io :as io]
 '[clojure.data.csv :as csv])

(defn testdef-form [n [expected actual]]
  `(deftest ~(str "testfromline" n)
 (is (= ~expected ~actual

(defmacro defcsvtests [filename]
  (with-open [in-file (io/reader "in-file.csv")]
(let [testdefs (csv/read-csv in-file)]
  `(do ~@(map testdef-form (iterate inc 1) testdefs)

(defcsvtests "test-cases.csv")

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

2011-06-24 Thread Nate Young
> This creates a classes/midje/ directory full of class files. (QUESTION: Why 
> create a bunch of class files when Midje is in lib/ as a jar file?)
leiningen's compile task calls clojure.core/compile for every
namespace you specify in your project.clj.  clojure.core/compile sets
the *compile-files* var to true, and then sets about loading
everything your namespace needs to load properly. Any namespace loaded
while *compile-files* is set to true gets written to *compile-path*.
A bit of a hack would be to:

;; load your ns and it's dependencies
(require 'midje.aot)

;; reload your ns, only its class files get written to *compile-path*
;; as the others are already loaded
(binding [*compile-files* true]
  (require 'midje.aot :reload))

I'm not sure how this stands up to more complex projects, and large
dependency trees, though.
Nor am I sure it solves the require-dilemma you mention later in the email.

Hope that was helpful,
  Nate

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

2010-12-21 Thread Nate Young
On 12/17/2010 09:54 AM, Trevor wrote:
> 2. Is there a form for anonymous macros?
> 
> i.e. I know I can do : (fn[x](do x)), but can I not do: (macro[x](let
> [x# x] `(do x)))   ?
> 
> Thanks!
> 

A little tardy, but Konrad Hinsen has written a handful of CL-like
functions for symbol macros and macrolet in clojure.contrib.macro-utils:

http://clojure.github.com/clojure-contrib/macro-utils-api.html

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

2010-08-17 Thread Nate Young

On 08/16/2010 04:12 PM, leo wrote:

I am trying to understand how efficient it would be to use Clojure to
develop an asynchronous http client for my webapp instead of using
Java.  Is there any specific way one can be better than the other?

Bradford Cross of FlightCaster just wrote an excellent article on a 
framework he put together to make parallel HTTP requests: 
http://measuringmeasures.com/blog/2010/8/16/clojure-workers-and-large-scale-http-fetching.html


The first part of the post does a nice job of outlining existing http 
libraries in Clojure.


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


Re: Defining a namespace inside a let

2010-04-28 Thread Nate Young
On Apr 26, 5:25 pm, David McNeil  wrote:
> I am experimenting with clojure.test and I encountered the following
> situation which I cannot explain.
>
> This code:
>
> (println (do
>            (ns ns01
>              (:use clojure.test))
>            (deftest test1 nil)
>            (run-tests)))
>
> Produces the expected result (note: it runs one test):
This is actually NOT what I'm seeing.  At least when I run it, it
appears to run exactly zero tests.

> [snip]
>
> (println (let []
>            (do
>              (ns ns02
>                (:use clojure.test))
>              (deftest test1 nil)
>              (run-tests
>
> Then I get the unexpected result that no tests are executed:
The let here is, I believe a red herring.  Again, with what I'm
seeing, this form executes the same way as the above and runs exactly
zero tests.

> Seems there is something going on with namespaces that I do not
> understand and I hope that somewhere here can explain it.
I think I can explain the above behavior and suggest a way to obtain
the behavior you want.
I don't think it has as much to do with namespaces as it does with the
evaluation rule and it's relationship to def.

You've defined a do, which will execute each of the forms in turn, but
the deftest (a macro which expands to a def form) creates it's test
function in the namespace that the do was executed in, not the
namespace created and switched to just previously.

In fact, if you check your namespace, you should see that test1 is
defined not in ns01/ns02, but in user (or whichever namespace you
executed the do from).

What I can't sufficiently explain is why def doesn't see the binding
of *ns* but run-tests obviously does, as it tries to find all tests
defined in ns01/ns02 (of which there are none).
(println (do
   (ns ns03
 (:use clojure.test))
   (binding [*ns* (find-ns 'ns03)]
 (deftest test3 nil))
   (run-tests)))

Now, when the do evaluates the second form, it uses the namespace that
was created by the first form.

Hope this helps.

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