Re: [ANN] Clojure 1.9.0-alpha15 is now available

2017-03-14 Thread Dmitri
👍 <http://emojipedia.org/thumbs-up-sign/>
On Tuesday, March 14, 2017 at 1:45:13 PM UTC-4, Alex Miller wrote:
>
> Yes, this is a bad use of refer-clojure which fails with the new spec. It 
> has been fixed and a release job for core.async is waiting on the build box.
>
> On Tuesday, March 14, 2017 at 12:38:53 PM UTC-5, Dmitri wrote:
>>
>> looks like the latest core.async fails Spec validation with alpha15:
>>
>> Caused by: clojure.lang.ExceptionInfo: Call to clojure.core/refer-clojure 
>> did not conform to spec:
>> In: [2] val: (quote :as) fails at: [:args :exclude :op :spec] predicate: 
>> #{:exclude}
>> In: [2 1] val: :as fails at: [:args :exclude :op :quoted-spec :spec] 
>> predicate: #{:exclude}
>> In: [2] val: (quote :as) fails at: [:args :only :op :spec] predicate: 
>> #{:only}
>> In: [2 1] val: :as fails at: [:args :only :op :quoted-spec :spec] 
>> predicate: #{:only}
>> In: [2] val: (quote :as) fails at: [:args :rename :op :spec] predicate: 
>> #{:rename}
>> In: [2 1] val: :as fails at: [:args :rename :op :quoted-spec :spec] 
>> predicate: #{:rename}
>> :clojure.spec/args  ((quote :exclude) (quote [reduce transduce into merge 
>> map take partition partition-by bounded-count]) (quote :as) (quote core))
>>  {:clojure.spec/problems ({:path [:args :exclude :op :spec], :pred 
>> #{:exclude}, :val (quote :as), :via [], :in [2]} {:path [:args :exclude :op 
>> :quoted-spec :spec], :pred #{:exclude}, :val :as, :via [], :in [2 1]} 
>> {:path [:args :only :op :spec], :pred #{:only}, :val (quote :as), :via [], 
>> :in [2]} {:path [:args :only :op :quoted-spec :spec], :pred #{:only}, :val 
>> :as, :via [], :in [2 1]} {:path [:args :rename :op :spec], :pred 
>> #{:rename}, :val (quote :as), :via [], :in [2]} {:path [:args :rename :op 
>> :quoted-spec :spec], :pred #{:rename}, :val :as, :via [], :in [2 1]}), 
>> :clojure.spec/args ((quote :exclude) (quote [reduce transduce into merge 
>> map take partition partition-by bounded-count]) (quote :as) (quote core))}, 
>> compiling:(clojure/core/async.clj:9:1)
>>
>>
>> On Tuesday, March 14, 2017 at 12:39:35 PM UTC-4, Alex Miller wrote:
>>>
>>> Clojure 1.9.0-alpha15 is now available.
>>>
>>> Try it via
>>>
>>> - Download: 
>>> https://repo1.maven.org/maven2/org/clojure/clojure/1.9.0-alpha15
>>> - Leiningen: [org.clojure/clojure "1.9.0-alpha15"]
>>>
>>> 1.9.0-alpha15 includes the following changes since 1.9.0-alpha14:
>>>
>>> - CLJ-1793 - reducer instances hold onto the head of seqs (also applies 
>>> to a broader set of head-holding cases)
>>> - CLJ-2043 - s/form of conformer is broken
>>> - CLJ-2035 - s/form of collection specs are broken
>>> - CLJ-2100 - s/form of s/nilable should include the original spec, not 
>>> the resolved spec
>>>
>>> Specs:
>>>
>>> - CLJ-2062 - added specs for `import` and `refer-clojure`
>>> - CLJ-2114 - ::defn-args spec incorrectly parses map body as a prepost 
>>> rather than function body
>>> - CLJ-2055 - binding-form spec parses symbol-only maps incorrectly
>>>
>>> Infrastructure:
>>>
>>> - CLJ-2113 - Clojure maven build updated
>>>
>>

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

2017-03-14 Thread Dmitri
looks like the latest core.async fails Spec validation with alpha15:

Caused by: clojure.lang.ExceptionInfo: Call to clojure.core/refer-clojure 
did not conform to spec:
In: [2] val: (quote :as) fails at: [:args :exclude :op :spec] predicate: 
#{:exclude}
In: [2 1] val: :as fails at: [:args :exclude :op :quoted-spec :spec] 
predicate: #{:exclude}
In: [2] val: (quote :as) fails at: [:args :only :op :spec] predicate: 
#{:only}
In: [2 1] val: :as fails at: [:args :only :op :quoted-spec :spec] 
predicate: #{:only}
In: [2] val: (quote :as) fails at: [:args :rename :op :spec] predicate: 
#{:rename}
In: [2 1] val: :as fails at: [:args :rename :op :quoted-spec :spec] 
predicate: #{:rename}
:clojure.spec/args  ((quote :exclude) (quote [reduce transduce into merge 
map take partition partition-by bounded-count]) (quote :as) (quote core))
 {:clojure.spec/problems ({:path [:args :exclude :op :spec], :pred 
#{:exclude}, :val (quote :as), :via [], :in [2]} {:path [:args :exclude :op 
:quoted-spec :spec], :pred #{:exclude}, :val :as, :via [], :in [2 1]} 
{:path [:args :only :op :spec], :pred #{:only}, :val (quote :as), :via [], 
:in [2]} {:path [:args :only :op :quoted-spec :spec], :pred #{:only}, :val 
:as, :via [], :in [2 1]} {:path [:args :rename :op :spec], :pred 
#{:rename}, :val (quote :as), :via [], :in [2]} {:path [:args :rename :op 
:quoted-spec :spec], :pred #{:rename}, :val :as, :via [], :in [2 1]}), 
:clojure.spec/args ((quote :exclude) (quote [reduce transduce into merge 
map take partition partition-by bounded-count]) (quote :as) (quote core))}, 
compiling:(clojure/core/async.clj:9:1)


On Tuesday, March 14, 2017 at 12:39:35 PM UTC-4, Alex Miller wrote:
>
> Clojure 1.9.0-alpha15 is now available.
>
> Try it via
>
> - Download: 
> https://repo1.maven.org/maven2/org/clojure/clojure/1.9.0-alpha15
> - Leiningen: [org.clojure/clojure "1.9.0-alpha15"]
>
> 1.9.0-alpha15 includes the following changes since 1.9.0-alpha14:
>
> - CLJ-1793 - reducer instances hold onto the head of seqs (also applies to 
> a broader set of head-holding cases)
> - CLJ-2043 - s/form of conformer is broken
> - CLJ-2035 - s/form of collection specs are broken
> - CLJ-2100 - s/form of s/nilable should include the original spec, not the 
> resolved spec
>
> Specs:
>
> - CLJ-2062 - added specs for `import` and `refer-clojure`
> - CLJ-2114 - ::defn-args spec incorrectly parses map body as a prepost 
> rather than function body
> - CLJ-2055 - binding-form spec parses symbol-only maps incorrectly
>
> Infrastructure:
>
> - CLJ-2113 - Clojure maven build updated
>

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

2016-02-29 Thread Dmitri
Sounds fantastic!

On Monday, February 29, 2016 at 4:13:53 PM UTC-5, Jim Crossley wrote:
>
> Sounds good, Dmitri. I'll work up something on a fork in the next few 
> days and ping you. We can go from there. 
>
> Jim 
>
>
> On Mon, Feb 29, 2016 at 2:33 PM, Dmitri  > wrote: 
> > Hi Jim, 
> > 
> > I'm the author of Luminus, and I'd love tow work with you to tune up the 
> > performance. Feel free to ping me via email or on GitHub. 
> > 
> > 
> > On Sunday, February 28, 2016 at 8:17:13 PM UTC-5, Jim Crossley wrote: 
> >> 
> >> I just tried a few experiments and realized the :dispatch? option is 
> >> broken in the latest Immutant release. :( 
> >> 
> >> This is a result of some changes we made to better support WebSockets. 
> >> 
> >> We were already hoping to get a release out this week, so we'll add 
> that 
> >> to the list of fixes. 
> >> 
> >> Sorry about that, 
> >> Jim 
> >> 
> >> On Sunday, February 28, 2016 at 1:32:09 PM UTC-5, Jim Crossley wrote: 
> >>> 
> >>> Hi, 
> >>> 
> >>> Luminus uses Immutant, which uses Undertow, so it should be possible 
> >>> to tune the Luminus app to approach the performance of the TechEmpower 
> >>> Undertow app. The relevant options to immutant.web/run [1] are 
> >>> :dispatch?, :io-threads, and :worker-threads. 
> >>> 
> >>> The Undertow app sets IO threads here [2] and worker threads here [3], 
> >>> so you can easily set those same values in the Luminus app. 
> >>> 
> >>> But the real performance bump will come from the :dispatch? option. By 
> >>> default, :dispatch? is true, i.e. requests handled by threads in the 
> >>> IO pool are dispatched to a thread in the worker pool. For 
> >>> compute-bound tasks like the JSON serialization benchmark, that 
> >>> context switch is far more expensive than just having the IO thread 
> >>> return the response. So you'd want to set :dispatch? to false in that 
> >>> case. 
> >>> 
> >>> The tricky bit here is that the Luminus app defines all its routes in 
> >>> a single handler [4]. But for the more io-bound tasks, e.g. 
> >>> DbSqlHandler [5], you'll want the default true value of :dispatch?. So 
> >>> in order to get the best results for all the benchmarks, you'll need 
> >>> to re-organize that app to run two handlers: one that dispatches and 
> >>> one that doesn't. In Immutant, the simplest way to do this is to 
> >>> distinguish each handler with a unique :path option. 
> >>> 
> >>> I'm happy to assist whoever is maintaining that app with the tuning. 
> >>> 
> >>> Thanks, 
> >>> Jim 
> >>> 
> >>> [1] 
> >>> 
> http://immutant.org/documentation/current/apidoc/immutant.web.html#var-run 
> >>> [2] 
> >>> 
> https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/Java/undertow/src/main/java/hello/HelloWebServer.java#L122
>  
> >>> [3] 
> >>> 
> https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/Java/undertow/src/main/java/hello/HelloWebServer.java#L160
>  
> >>> [4] 
> >>> 
> https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/Clojure/luminus/hello/src/hello/routes/home.clj#L44
>  
> >>> [5] 
> >>> 
> https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/Java/undertow/src/main/java/hello/DbSqlHandler.java#L38
>  
> >>> 
> >>> On Sat, Feb 27, 2016 at 9:40 PM, gvim  wrote: 
> >>> > In the latest round of Techempower benchmarks: 
> >>> > 
> >>> > 
> >>> > 
> https://www.techempower.com/benchmarks/#section=data-r12&hw=peak&test=json 
> >>> > 
> >>> > ... I was surprised to find Luminus performing no better than Hapi 
> >>> > (Node) 
> >>> > and significantly worse than Java frameworks. Figures are 
> >>> > requests/second: 
> >>> > 
> >>> > FORTUNES 
> >>> > - Hapi: 1.9 
> >>> > - Luminus:   0.9 
> >>> > - Gemini:   55.5 
> >>> > 
> >>> > JSON SERIALISATION 
> >>> > - Hapi: 0.3  (Raw db) 
> >>> > - Luminus:   0.8 
> >>> > - Rapidoid: 78.4 
> >>> > 
&g

Re: Luminus in Techempower benchmarks

2016-02-29 Thread Dmitri
Hi Jim,

I'm the author of Luminus, and I'd love tow work with you to tune up the 
performance. Feel free to ping me via email or on GitHub.

On Sunday, February 28, 2016 at 8:17:13 PM UTC-5, Jim Crossley wrote:
>
> I just tried a few experiments and realized the :dispatch? option is 
> broken in the latest Immutant release. :(
>
> This is a result of some changes we made to better support WebSockets.
>
> We were already hoping to get a release out this week, so we'll add that 
> to the list of fixes.
>
> Sorry about that,
> Jim
>
> On Sunday, February 28, 2016 at 1:32:09 PM UTC-5, Jim Crossley wrote:
>>
>> Hi, 
>>
>> Luminus uses Immutant, which uses Undertow, so it should be possible 
>> to tune the Luminus app to approach the performance of the TechEmpower 
>> Undertow app. The relevant options to immutant.web/run [1] are 
>> :dispatch?, :io-threads, and :worker-threads. 
>>
>> The Undertow app sets IO threads here [2] and worker threads here [3], 
>> so you can easily set those same values in the Luminus app. 
>>
>> But the real performance bump will come from the :dispatch? option. By 
>> default, :dispatch? is true, i.e. requests handled by threads in the 
>> IO pool are dispatched to a thread in the worker pool. For 
>> compute-bound tasks like the JSON serialization benchmark, that 
>> context switch is far more expensive than just having the IO thread 
>> return the response. So you'd want to set :dispatch? to false in that 
>> case. 
>>
>> The tricky bit here is that the Luminus app defines all its routes in 
>> a single handler [4]. But for the more io-bound tasks, e.g. 
>> DbSqlHandler [5], you'll want the default true value of :dispatch?. So 
>> in order to get the best results for all the benchmarks, you'll need 
>> to re-organize that app to run two handlers: one that dispatches and 
>> one that doesn't. In Immutant, the simplest way to do this is to 
>> distinguish each handler with a unique :path option. 
>>
>> I'm happy to assist whoever is maintaining that app with the tuning. 
>>
>> Thanks, 
>> Jim 
>>
>> [1] 
>> http://immutant.org/documentation/current/apidoc/immutant.web.html#var-run 
>> [2] 
>> https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/Java/undertow/src/main/java/hello/HelloWebServer.java#L122
>>  
>> [3] 
>> https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/Java/undertow/src/main/java/hello/HelloWebServer.java#L160
>>  
>> [4] 
>> https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/Clojure/luminus/hello/src/hello/routes/home.clj#L44
>>  
>> [5] 
>> https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/Java/undertow/src/main/java/hello/DbSqlHandler.java#L38
>>  
>>
>> On Sat, Feb 27, 2016 at 9:40 PM, gvim  wrote: 
>> > In the latest round of Techempower benchmarks: 
>> > 
>> > 
>> https://www.techempower.com/benchmarks/#section=data-r12&hw=peak&test=json 
>> > 
>> > ... I was surprised to find Luminus performing no better than Hapi 
>> (Node) 
>> > and significantly worse than Java frameworks. Figures are 
>> requests/second: 
>> > 
>> > FORTUNES 
>> > - Hapi: 1.9 
>> > - Luminus:   0.9 
>> > - Gemini:   55.5 
>> > 
>> > JSON SERIALISATION 
>> > - Hapi: 0.3  (Raw db) 
>> > - Luminus:   0.8 
>> > - Rapidoid: 78.4 
>> > 
>> > 
>> > SINGLE QUERY 
>> > - Hapi: 2.9 
>> > - Luminus:   8.7 
>> > - Gemini:   75.8 
>> > 
>> > MULTI-QUERY 
>> > - Hapi:   33.0 
>> > - Luminus: 20.4 
>> > - Dropwizard: 65.8 
>> > 
>> > DATA UPDATES 
>> > - Hapi:20.9 
>> > - Luminus:  20.0 
>> > - Ninja:   54.7 
>> > 
>> > PLAINTEXT 
>> > - Hapi:0.7 
>> > - Luminus:  0.0 
>> > - Rapidoid:  100.0 
>> > 
>> > 
>> > 
>> > Any ideas? 
>> > 
>> > gvim 
>> > 
>> > 
>> > 
>> > 
>> > 
>> > 
>> > 
>> > 
>> > -- 
>> > You received this message because you are subscribed to the Google 
>> > Groups "Clojure" group. 
>> > To post to this group, send email to clo...@googlegroups.com 
>> > Note that posts from new members are moderated - please be patient with 
>> your 
>> > first post. 
>> > To unsubscribe from this group, send email to 
>> > clojure+u...@googlegroups.com 
>> > For more options, visit this group at 
>> > http://groups.google.com/group/clojure?hl=en 
>> > --- You received this message because you are subscribed to the Google 
>> > Groups "Clojure" group. 
>> > To unsubscribe from this group and stop receiving emails from it, send 
>> an 
>> > email to clojure+u...@googlegroups.com. 
>> > For more options, visit https://groups.google.com/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/clojur

Re: Streamlining dev environment startup

2015-12-11 Thread Dmitri
The recommended way to manage components in Luminus is using the mount 
library (https://github.com/tolitius/mount), it's much less intrusive than 
Component in my opinion and provides most of the same benefits without 
requiring you to structure your application around it. The latest version 
of mount has both Clojure and ClojureScript support as well. It's now 
included in the template by default in recent versions.

On Thursday, December 3, 2015 at 5:24:48 AM UTC-5, Sven Richter wrote:
>
> It definitly is compatible. It just takes some manual work. Like I said, I 
> started myself with the luminus template and implement components + other 
> stuff into it. 
> You can definitly do it and I also recommend it for the sole reason that a 
> change to the routes in compojure will lead to a restart of the repl. You 
> can circumvent that by reloading the code base. 
> It may have changed in the last two years, but then I am not up to date.
>
> Best Regards,
> Sven
>
> Am Mittwoch, 2. Dezember 2015 22:05:58 UTC+1 schrieb Webdev Tory Anderson:
>>
>> Maybe I spoke too soon when mentioning incompatibility between Luminus 
>> and Reloaded. I look forward to taking a closer look at your work!
>>
>> On Wednesday, December 2, 2015 at 1:49:20 AM UTC-7, Sven Richter wrote:
>>>
>>> Hi,
>>>
>>> I based a template on luminus myself and added some stuff. It also 
>>> contains predefined components so you don't have to add it yourself.
>>> You can look how its done here: 
>>> https://github.com/sveri/closp/tree/master/resources/leiningen/new/closp/clj/components
>>>
>>> Best Regards,
>>> Sven
>>>
>>> Am Dienstag, 1. Dezember 2015 17:43:41 UTC+1 schrieb Colin Yates:

 The general idea is to use the ‘reloaded’ pattern, so rather than `lein 
 run` you would have a function which starts and stop the system. You still 
 need to run figwheel and mongo (yay for document databases) as separate 
 processes, although I tend to do those in straight terminals rather than 
 emacs shells as they live longer than my emacs does.

 You can find more about the reloaded pattern and a prescripted approach 
 to structuring your app here: https://github.com/stuartsierra/component
 .

 I think it is fairly common to have:
  - your major building blocks as components
  - a specific dev namespace which is only on the :dev profile
  - fns in that namespace to start/stop components or the entire system

 There are some libraries which build on the component library: 
 https://github.com/danielsz/system for example.

 HTH.

 On 1 Dec 2015, at 16:26, Webdev Tory Anderson  
 wrote:

 I recently read something hinting at ways of streamlining the startup 
 process for the dev environment, so I'm hoping you good folks can give me 
 some tips. I'm developing a web app in Linux, Clojurescript/Clojure 
 (incidentally using the Luminus architecture). I use emacs (that part's 
 non-negotiable; sorry). The cumbersome startup process I usually have goes 
 like this:

 M-x shell
> mongod # start the mongo daemon
>
> M-x shell
> lein run # start the app and server
>
> M-x shell
> lein figwheel #start CLJS development
>
> (open a .clj file)
> C-c M-c  # (cider-connect)
> # insert localhost, port num, which proj. to connect to
>
>
 This is usually bearable since I only have to do it once or twice a 
 week, but it's definitely the sort of redundancy that would be nice to 
 eliminate. The "lein run" is good to have foregrounded because I can see 
 timbre statements and cleanly reboot when necessary. Figwheel, at the 
 moment, has to be foregrounded because that's where the figwheel prompt 
 ends up (I'd love to have that in Cider somehow, though). 

 Any recommendations on how to chop some of these steps off?



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

Re: [ANN] Let's make clojure.org better!

2015-11-10 Thread Dmitri
Just a note that the author of Cryogen is very responsive regarding 
discussions on improvements and pull requests for additional functionality. 
If there's a particular feature that's missing it might be worth creating 
an issue or opening a pr for it.

On Tuesday, November 10, 2015 at 10:57:45 AM UTC-5, Alex Miller wrote:
>
> Hi Hildeberto,
>
> I built spikes of the site in a number of technologies like Cryogen, 
> Stasis, Sphinx, Asciidoctor, and some of the other Ruby-based static 
> generators as well. In the end, I found that JBake was the best match for 
> our goals at this time. The site build architecture has been decided and 
> we're not interested in revisiting that at this time. At some point down 
> the road, based on experience and tool evolution, we may take another look, 
> but not soon. 
>
> Cryogen is a great tool and I would recommend it to others. One problem I 
> had with it was its flexibility with respect to the url structure. I 
> actually think for the purposes of creating a blog etc that is a dimension 
> that is good to remove, but it was a downside for our use. 
>
> We are working with a designer on the site look and feel and at some point 
> that will be visible. At the point where that is visible, I expect there 
> will be some evolution on front page, navigation structure, etc and would 
> be happy to get feedback on that.
>
> Right now, we are primarily looking for content ideas and would love 
> thoughts on that. Or if there is interest in enhancing existing pages, I 
> would also like to talk about those.
>
> Thanks,
> Alex
>
>
>
> On Tuesday, November 10, 2015 at 9:41:40 AM UTC-6, Hildeberto Mendonça 
> wrote:
>>
>> That's a great initiative! Thanks! But I'm just sad to see JBake instead 
>> of Cryogen (https://github.com/cryogen-project/cryogen-core) which is 
>> written in Clojure :-( Can we send a pull request replacing JBake by 
>> Cryogen or is JBake a final decision?
>>
>> -- 
>> Hildeberto Mendonça, Ph.D
>> Blog: http://www.hildeberto.com
>> Twitter: https://twitter.com/htmfilho
>>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread Dmitri
There are a number of options here depending on your workflow. You could 
override the dynamic var, create a separate connection for tests and pass 
it around explicitly in test code, or get the connection from the 
environment. The last option is what I tend to do, the profiles.clj will 
contain separate URLs for testing and dev databases:

{:profiles/dev  {:env {:database-url 
"jdbc:postgresql://localhost/myapp_dev?user=db_user_name_here&password=db_user_password_here"}}
 :profiles/test {:env {:database-url 
"jdbc:postgresql://localhost/myapp_test?user=db_user_name_here&password=db_user_password_here"}}}

The tests run in the test profile and so get the test database connection 
from the environment.



On Wednesday, August 5, 2015 at 2:34:31 PM UTC-4, James Reeves wrote:
>
> On 5 August 2015 at 18:04, Dmitri > 
> wrote:
>
>> I agree that wrapping the functions is a sensible approach. Using 
>> wrap-transaction is precisely how I ended up doing it with the conman yesql 
>> wrapper https://github.com/luminus-framework/conman
>>
>> The approach I took there is to have the generated functions use the 
>> connection atom, and have with-transaction rebind it to the transactional 
>> connection within its scope. However, the functions also accept an explicit 
>> connection, and with-transaction also provides explicit access to the 
>> transactional connection
>>
>
> So when you're testing, presumably you use a dynamic binding to override 
> the global connection to the test database?
>
> - James
>

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


Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread Dmitri
I agree that wrapping the functions is a sensible approach. Using 
wrap-transaction is precisely how I ended up doing it with the conman yesql 
wrapper https://github.com/luminus-framework/conman

The approach I took there is to have the generated functions use the 
connection atom, and have with-transaction rebind it to the transactional 
connection within its scope. However, the functions also accept an explicit 
connection, and with-transaction also provides explicit access to the 
transactional connection:

(with-transaction [t-conn conn]
  (jdbc/db-set-rollback-only! t-conn)
  (create-user!
{:id "foo"
 :first_name "Sam"
 :last_name  "Smith"
 :email  "sam.sm...@example.com"})
  (get-user {:id "foo"}))




This approach works for testing, since the connection can be passed 
explicitly, but I would argue that in practice it's better to use a 
separate test database instead of the dev instance.

On Wednesday, August 5, 2015 at 11:11:19 AM UTC-4, James Reeves wrote:
>
> On 5 August 2015 at 14:03, Dmitri > 
> wrote:
>
>> What I'm talking about is whether it's a better pattern to leave a 
>> repetitive and error prone task to the user or encapsulate it in a single 
>> place. The whole discussion boils down to following options.
>>
>> The first option is that we keep functions pure and the connection is 
>> passed as a parameter by the person writing the code (the user). With this 
>> approach the burden is squarely on the user to remember to pass the correct 
>> connection to the function. This becomes error prone for things like 
>> transactions where the developer has to pass the transaction connection as 
>> opposed to the normal database connection. The worst part in this scenario 
>> is that the code will run except it won't run transactionally. This is a 
>> bug that is difficult to catch as it only surfaces in cases where the 
>> transaction should be rolled back.
>>
>
> It's worth pointing out that you don't need to use dynamic or global vars 
> to avoid this scenario. You could just remove the original database 
> connection from scope:
>
>   (defn foobar* [tx]
> (foo tx)
> (bar tx))
>
>   (defn foobar [db]
> (sql/with-transaction [tx db] (foobar* tx))
>
> Or shadow the original binding:
>
>   (defn foobar [db]
> (sql/with-transaction [db db]
>   (foo db)
>   (bar db)))
>
> Ideally you also want a way of testing this behaviour, even with dynamic 
> or global scope. If it's critical to your application that database 
> operations run in a transaction, you should have a way of verifying that.
>
> For instance, you might use a protocol to factor out the operations on the 
> database:
>
>   (defprotocol Database
> (wrap-transaction [db f])
> (foo db)
> (bar db))
>
>   (defn foobar [db]
> (wrap-transaction db
>   (fn [tx]
> (foo tx)
> (bar tx
>
> This allows tests to be written to verify that foo and bar are called 
> within wrap-transaction, and to verify our production implementation of the 
> protocol correctly wraps the function f in a SQL transaction.
>
> If you're writing something that depends upon behaviour that can't be 
> verified, you're going to run into problems no matter how you structure 
> your application.
>  
>
>> The alternative is to encapsulate the database connection management in 
>> the initialization logic in the namespace managing the connection. This way 
>> the query functions can be context aware and ensure that the correct 
>> connection is used automatically.
>>
>
> Do you mean storing the database connection in a global var, not just a 
> dynamically scoped one?
>
> In such a case, how do you run tests without wiping the development 
> database? Do you run the tests in a separate process, or shut down the dev 
> server before running tests, or do you not mind if your development 
> database is cleared by your tests?
>
> - James
>

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


Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-05 Thread Dmitri
What I'm talking about is whether it's a better pattern to leave a 
repetitive and error prone task to the user or encapsulate it in a single 
place. The whole discussion boils down to following options.

The first option is that we keep functions pure and the connection is 
passed as a parameter by the person writing the code (the user). With this 
approach the burden is squarely on the user to remember to pass the correct 
connection to the function. This becomes error prone for things like 
transactions where the developer has to pass the transaction connection as 
opposed to the normal database connection. The worst part in this scenario 
is that the code will run except it won't run transactionally. This is a 
bug that is difficult to catch as it only surfaces in cases where the 
transaction should be rolled back.

The alternative is to encapsulate the database connection management in the 
initialization logic in the namespace managing the connection. This way the 
query functions can be context aware and ensure that the correct connection 
is used automatically.

I simply disagree that leaving repetitive and error prone tasks to the 
developer as opposed to encapsulating them centrally is a better pattern. I 
certainly don't see that as a feature.

On Wednesday, August 5, 2015 at 8:19:38 AM UTC-4, James Gatannah wrote:
>
>
>
> On Monday, August 3, 2015 at 10:21:09 PM UTC-5, Dmitri wrote:
>>
>> My understanding is that the problem is actually caused by the stateless 
>> nature of the functions.
>>
>
> You're talking about database interactions. By definition, those are not 
> stateless. The trick is to isolate this statefulness as much as possible. 
> Expanding it just compounds the problem. 
>
>  
>
>> Since the function accepts the connection as a parameter it's up to the 
>> user of the function to ensure that it's passed the correct connection.
>>
>
> That depends on what you mean by "user of the function." If I'm working on 
> the web server front-end, I shouldn't have any idea about the database 
> connection. I should describe what I
> want to happen. If I have any concept that multiple databases are involved 
> (I shouldn't, but abstractions leak), then, yes, I have to specify which 
> one I mean. This isn't
> complicated.
>
> It's up to the person writing the database back-end code (also possibly 
> me, if we're talking about a start-up, but then we aren't talking about the 
> 200 KLOC scenario) to turn that
> description into the side-effects.
>
>  
>
>> Every functional solution presented in this thread suffers from this same 
>> fundamental problem that the function is not aware of the context it's 
>> being run in.
>>
>
> That isn't a problem: it's a feature.
>
> It doesn't matter what language or programming paradigm you're using in 
> this context. This cuts across problem domains and architectures.
>
> The actual database interaction code should be as brain-dead simple (not 
> "easy") and bullet-proof as you can possibly make it. And it should be as
> isolated from the front-end code as you can get away with making it.
>
> That isn't a "right" answer. But it's a good rule of thumb. And you should 
> have very hefty reservations (and very good reasons) about violating it.
>
> Respectfully,
> James
>
>

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


Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread Dmitri
My understanding is that the problem is actually caused by the stateless 
nature of the functions. Since the function accepts the connection as a 
parameter it's up to the user of the function to ensure that it's passed 
the correct connection. Every functional solution presented in this thread 
suffers from this same fundamental problem that the function is not aware 
of the context it's being run in.

On Monday, August 3, 2015 at 10:16:28 PM UTC-4, Rob Lally wrote:
>
> Everything you say is true. And programming is always about picking the 
> right trade-offs at the right time, making this sort of conversation one 
> that can never come to a *right* answer.
>
> But… in this case Pablo was experiencing concrete problems: those problems 
> stemmed from how easy it was to make mistakes having both a global 
> connection pool and the option to pass around specific connections which 
> had transactions open. Having two conflicting ways of doing the same thing 
> was causing problems. Eliminating at least one of them is a solution. Pablo 
> felt that he might want to eliminate both and add a new mechanism. A number 
> of people (including me) felt that Pablo’s proposed solution would, 
> potentially, lead to new problems and that eliminating only one of the 
> original mechanisms would be sufficient to solve his problems.
>
> In a very real sense, the pragmatic solution and the most “pure” solution 
> seem - to me at least - to be the same.
>
>
> R.
>
>
> On 3 Aug 2015, at 18:19, Dmitri > 
> wrote:
>
> While I generally agree that purity is something to strive for, I think 
> it's also important to consider the problem that's being solved in each 
> particular scenario. While creating stateless database query functions and 
> passing the connection round explicitly achieves purity, it's not entirely 
> clear what practical problem that's addressing. However, the practical 
> disadvantages are that you end up with is additional variable being passed 
> around and more opportunities for user error as is the case with 
> transactions. While there is mental overhead in having to understand that 
> the functions use an implicit connection, there's conversely additional 
> mental overhead in having to remember what connection to use when with the 
> explicit approach.
>
> In some applications it might be valuable to pass the database around 
> explicitly. Yet, many of the applications in the wild tend to deal with a 
> single database instance where a connection is created when the application 
> is started and retained for the lifecycle of the application. Creating the 
> additional hoops for the user to jump through for purely theoretical 
> benefit seems unwarranted in this scenario. 
>
>
> On Monday, August 3, 2015 at 6:48:05 PM UTC-4, Rob Lally wrote:
>>
>> Hey Pablo,
>>
>> Sorry, you are completely correct: I accidentally typed transaction when 
>> I meant connection. My bad.
>>
>> I don’t understand what you mean by connections having to be global when 
>> dealing with an RDBMS. It is true that you normally want to pool them to 
>> conserve resources, and that pooling may be global in nature - but it also 
>> may not be. Quality of Service demands often necessitate multiple pools to 
>> the same data-source to be created and accessed independently. You also, 
>> sometimes, want to access different databases from the same application, 
>> that gets much harder - and your code becomes less general if you need to 
>> reference specific global connection-pools.
>>
>> I’m also a little confused by your suggestion that it would be impossible 
>> to enclose each test in a transaction. The article you point to shows one 
>> way. Another way I’ve used often is to declare a var holding a ref and in a 
>> fixture initialise/close a connection around the test. The test function 
>> then derefences the var holding the connection passing it into the function 
>> under test. This does make it impossible to run tests in parallel, but 
>> that’s not something I’ve ever tried. Creating tests that access shared 
>> resources is a little bit uglier than in a OO language where you could more 
>> easily reference an instance variable but it isn’t much worse, and a little 
>> macro-pixie dust can make it all go away.
>>
>> I will say that it has been my experience that you don’t find yourself 
>> passing database connection pools around everywhere. As your code grows you 
>> naturally extract components/protocols that wrap all that up. Your 
>> ring-handler doesn’t need a connection it needs some sort of data-access 
>> component. That component needs a connection/

Re: Using a dynamic var for my database connection for implicit connections+transactions

2015-08-03 Thread Dmitri
While I generally agree that purity is something to strive for, I think 
it's also important to consider the problem that's being solved in each 
particular scenario. While creating stateless database query functions and 
passing the connection round explicitly achieves purity, it's not entirely 
clear what practical problem that's addressing. However, the practical 
disadvantages are that you end up with is additional variable being passed 
around and more opportunities for user error as is the case with 
transactions. While there is mental overhead in having to understand that 
the functions use an implicit connection, there's conversely additional 
mental overhead in having to remember what connection to use when with the 
explicit approach.

In some applications it might be valuable to pass the database around 
explicitly. Yet, many of the applications in the wild tend to deal with a 
single database instance where a connection is created when the application 
is started and retained for the lifecycle of the application. Creating the 
additional hoops for the user to jump through for purely theoretical 
benefit seems unwarranted in this scenario. 


On Monday, August 3, 2015 at 6:48:05 PM UTC-4, Rob Lally wrote:
>
> Hey Pablo,
>
> Sorry, you are completely correct: I accidentally typed transaction when I 
> meant connection. My bad.
>
> I don’t understand what you mean by connections having to be global when 
> dealing with an RDBMS. It is true that you normally want to pool them to 
> conserve resources, and that pooling may be global in nature - but it also 
> may not be. Quality of Service demands often necessitate multiple pools to 
> the same data-source to be created and accessed independently. You also, 
> sometimes, want to access different databases from the same application, 
> that gets much harder - and your code becomes less general if you need to 
> reference specific global connection-pools.
>
> I’m also a little confused by your suggestion that it would be impossible 
> to enclose each test in a transaction. The article you point to shows one 
> way. Another way I’ve used often is to declare a var holding a ref and in a 
> fixture initialise/close a connection around the test. The test function 
> then derefences the var holding the connection passing it into the function 
> under test. This does make it impossible to run tests in parallel, but 
> that’s not something I’ve ever tried. Creating tests that access shared 
> resources is a little bit uglier than in a OO language where you could more 
> easily reference an instance variable but it isn’t much worse, and a little 
> macro-pixie dust can make it all go away.
>
> I will say that it has been my experience that you don’t find yourself 
> passing database connection pools around everywhere. As your code grows you 
> naturally extract components/protocols that wrap all that up. Your 
> ring-handler doesn’t need a connection it needs some sort of data-access 
> component. That component needs a connection/connection pool but that can 
> be passed in at construction time. I have feared the creation of functions 
> that need an ever increasing number of parameters that need to be passed 
> on, but it isn’t something I find happens in practice. Of course, YMMV.
>
> I would respectfully suggest that the solutions are not the same. My way 
> has no global state and functional purity-lite (those connections are 
> rarely idempotent): which are obviously only theoretical benefits. But it 
> does work when I do it; I like my code, I don’t have problems working with 
> it, and I genuinely don’t face any of the challenges you’re struggling with.
>
>
>
> R.
>
>
>
> On 3 Aug 2015, at 03:19, J. Pablo Fernández  > wrote:
>
> Rob,
>
> The transactions are not global, the transactions are local. Connections 
> are global and there's no way around it with the constraints of a 
> traditional RDBMs. Your idea of making the global connection unavailable 
> for code that's in the context of a transaction would prevent the errors 
> I'm trying to prevent but you would still required to pass the connection 
> around, which in a webapp, means that the whole chain of function calls, 
> pretty much everything, would have a database connection. That is ugly in 
> some cases, impossible in others.
>
> A piece of code that would be impossible is to enclose each test in a 
> transaction using clojure.test: 
> http://stackoverflow.com/questions/31735423/how-to-pass-a-value-from-a-fixture-to-a-test-with-clojure-test
>
> Furthermore, I don't think this solution gains you any purity, you still 
> have a global estate and you are hiding it away when starting a 
> transaction. My proposal was to make it work instead of hiding it. They are 
> rather equivalent from the complexity point of view.
>
>
>

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

Re: ANN: ClojureScript 0.0-3255 - pretty printer & latest Closure Compiler / Library

2015-05-10 Thread Dmitri
Is there possibly anything else missing in the package, figwheel doesn't 
appear to find the repl ns.

lein figwheel
Retrieving org/clojure/clojurescript/0.0-3269/clojurescript-0.0-3269.pom 
from central
Retrieving org/clojure/clojurescript/0.0-3269/clojurescript-0.0-3269.jar 
from central
Exception in thread "main" java.io.FileNotFoundException: Could not locate 
cljs/repl__init.class or cljs/repl.clj on classpath: , 
compiling:(figwheel_sidecar/repl.clj:1:1)



On Sunday, May 10, 2015 at 10:20:13 AM UTC-4, David Nolen wrote:
>
> Just cut 0.0-3269 which adds the missing analysis and source map bits back 
> into the artifacts. It also cleans up :libs support and fixes a related 
> regression with Closure compatible libraries that follow classpath 
> conventions (like transit-js). Both :libs Closure libraries and classpath 
> aware Closure compatible libraries now enjoy REPL support.
>
> David
>
> On Sun, May 10, 2015 at 9:41 AM, David Nolen  > wrote:
>
>> It appears there are still some important bits missing from the 
>> artifacts. Working through the issues and will cut a release soon.
>>
>> David
>>
>> On Sun, May 10, 2015 at 12:22 AM, Rangel Spasov > > wrote:
>>
>>> Hey guys,
>>>
>>> 0.0-3264 fails for me with:
>>>
>>> clojure.lang.ExceptionInfo: failed compiling 
>>> file:resources/public/js/compiled/out/cljs/core.cljs
>>>
>>>  at clojure.core$ex_info.invoke (core.clj:4591)
>>>
>>> Caused by: java.lang.IllegalArgumentException: No implementation of 
>>> method: :make-reader of protocol: #'clojure.java.io/IOFactory found for 
>>> class: nil
>>>
>>>  at clojure.core$_cache_protocol_fn.invoke (core_deftype.clj:554)
>>>
>>> 0.0-3255 seems fine. 
>>>
>>> @raspasov
>>>
>>> On Saturday, May 9, 2015 at 12:33:52 PM UTC-7, David Nolen wrote:

 Just released 0.0-3264, it fixes a critical issue where .js files were 
 missing from the artifacts due to the changed build. Also included are a 
 several fixes around the :libs feature, REPLs, and stack trace mapping.

 David

 On Fri, May 8, 2015 at 3:23 PM, David Nolen  
 wrote:

> ClojureScript, the Clojure compiler that emits JavaScript source code.
>
> README and source code: https://github.com/clojure/clojurescript
>
> Leiningen dependency information:
>
> [org.clojure/clojurescript "0.0-3255"]
>
> A big thanks goes out to Jonathan Boston and Shaun Lebron for this
> release. Thanks to their efforts ClojureScript now includes a full
> port of clojure.pprint under the cljs.pprint namespace. This was the
> last major namespace in need of porting to ClojureScript.
>
> The release also bumps several dependencies: Clojure 1.7.0-beta2,
> tools.reader 0.9.2, Closure Compiler v20150505, and Closure Library
> 0.0-20150505-021ed5b3.
>
> This release also fixes some regressions around async testing,
> docstring REPL support, arglist meta, and more.
>
> As always feedback welcome!
>
> ## 0.0-3255
>
> ### Changes
> * Update Closure Library dependency
> * CLJS-1252: Update Closure Compiler Dependency to v20150505
> * .clj -> .cljc for important analysis / compilation bits
> * add public cljs.compiler.api namespace
> * CLJS-1224: cljs.repl: Memoize stack frame mapping
> * depend on tools.reader 0.9.2
>
> ### Enhancements
> * add cljs.pprint/pp macro
> * CLJS-710: port clojure.pprint
> * CLJS-1178: Compiler does not know Math ns is not not-native
> * add getBasis methods to deftype and defrecord ctors a la Clojure JVM
> * support ^long and ^double type hints
>
> ### Fixes
> * fix cljs-1198 async testing regression
> * CLJS-1254: Update REPL browser agent detection CLJS-1253: Create/Use
>   new Closure Library Release
> * CLJS-1225: Variadic function with same name as parent function gives
>   runtime error in advanced compile mode.
> * CLJS-1246: Add cljs.core/record? predicate.
> * CLJS-1239: Make eduction variadic.
> * CLJS-1244: tagged-literal precondition check missing wrapping vector
> * CLJS-1243: Add TaggedLiteral type & related fns
> * CLJS-1240: Add cljs.core/var?
> * CLJS-1214: :arglists meta has needless quoting CLJS-1232: bad
>   arglists for doc, regression
> * CLJS-1212: Error in set ctor for > 8-entry map literal
> * CLJS-1218: Syntax quoting an alias created with :require-macros
>   throws ClassCastException
> * CLJS-1213: cljs.analyzer incorrectly marks all defs as tests when
>   eliding test metadata
> * CLJS-742: Compilation with :output-file option set fails
>
>
  -- 
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@googlegroups.com 
>>> 
>>> Note that posts from new members are moderated - please be patient with 
>>> your first post.
>>> To unsubscribe from this group, send email t

Re: Clojure needs a web framework with more momentum

2015-05-05 Thread Dmitri
One way I could see this working is having a more opinionated profile like 
+site or something that sets up an app with authentication, logins, a 
default model and so on. I would definitely support merging the efforts on 
this front. Ping me by email, and we can try figure out the details. :)

On Tuesday, May 5, 2015 at 1:27:21 AM UTC-4, Sven Richter wrote:
>
> Hi Dmitri,
>
> When I was building closp I was taking luminus as the base for it with 
> some minor adoptions. I just had a look at the website of luminus and saw 
> the massive amount of work you put into the documentation again. If that 
> sounds reasonable for you I'd like to try to move closp and closp-crud to 
> luminus as an opionated part of it.
> So if you call lein new luminus projectname +closp you will basically get 
> what you get now with closp. You can look here for the additions: 
> https://github.com/sveri/closp.
> I would like to maintain that "branch".
>
> I am not sure if that will work out the way I think, but I'd like to 
> evaluate it at least. It would be nice to have a common base and a common 
> documentation for it.
>
> Best Regards,
> Sven
>
> Am Dienstag, 5. Mai 2015 02:38:41 UTC+2 schrieb Dmitri:
>>
>> As others have pointed out the comparison isn't really valid. Luminus 
>> intentionally aims to leverage existing libraries that are maintained 
>> independently whenever possible. I've been doing web dev with Clojure for 
>> the past 4 years and overall I do prefer the approach of using composable 
>> libraries over monolithic frameworks. With the Clojure web stack it's much 
>> easier to tell what's actually happening during the request/response 
>> lifecycle as things tend to be explicit. With frameworks like Rails a lot 
>> of stuff happens implicitly and requires a lot of in depth knowledge to 
>> work with effectively.
>>
>> However, there are a some downsides to the libraries over frameworks 
>> approach as well. The biggest issue is that it's difficult to track what 
>> libraries are actively maintained and which ones play nicely together. 
>> Since most libraries are maintained by individuals it's common for them to 
>> become abandoned. Another problem is that each app becomes a unique 
>> snowflake since there aren't a lot of established patterns for structuring 
>> them. Finally, security is an issue for Clojure web apps as a lot of it 
>> done in rather ad hoc fashion. While this works great for people who are 
>> well versed in the Clojure web ecosystem it's a huge barrier for newcomers.
>>
>> I think that the best way to address the problem is via organizations 
>> where related projects are maintained by groups of contributors. This helps 
>> discovery of projects, and it helps spread the burden of maintenance for 
>> them. This approach is already working in the wild on GitHub with Ring, 
>> Reagent, and Luminus orgs. Meanwhile, Leiningen templates are a great way 
>> to provide reasonable defaults for different types of applications and can 
>> be used to address issues such as security.
>>
>> Also, I'm certainly open to contributions for Luminus. I moved it to an 
>> org recently and new members would be very welcome. :)
>>
>>
>> On Saturday, May 2, 2015 at 4:43:53 PM UTC-4, g vim wrote:
>>>
>>> I recently did some research into web frameworks on Github. Here's what 
>>> I found: 
>>>
>>>
>>> FRAMEWORK   LANG  CONTRIBUTORS COMMITS 
>>>
>>> LuminusClojure28678 
>>> CaribouClojure 2275 
>>>
>>> BeegoGolang991522 
>>>
>>> PhoenixElixir  1241949 
>>>
>>> YesodHaskell   1303722 
>>>
>>> LaravelPHP2684421 
>>>
>>> PlayScala   4176085 
>>>
>>> SymfonyPHP113020914 
>>>
>>> RailsRuby   269151000 
>>>
>>>
>>> One could conclude from this that the Clojure community isn't that 
>>> interested in web development but the last Clojure survey suggests 
>>> otherwise. Clojure's library composition approach to everything only 
>>> goes so far with large web applications, as Aaron Bedra reminded us in 
>>> March last year: www.youtube.com/watch?v=CBL59w7fXw4 . Less manpower 
>>> means less momentum and more bugs. Furtherm

Re: Clojure needs a web framework with more momentum

2015-05-05 Thread Dmitri
Luminus uses a minimal amount of generated code. It completely embraces the 
composable library approach. The difference from rolling your own each time 
is that it provides some structure and it's a curated set of libraries that 
are known to work well together.

On Tuesday, May 5, 2015 at 3:46:09 AM UTC-4, Dan Kersten wrote:
>
>
>
> On Monday, May 4, 2015 at 4:41:02 AM UTC-4, Sven Richter wrote:
>> One potential problem with this "web framework" as app template approach 
>> is upgrade-ability.  When 2.0 of your "framework" comes out, what happens 
>> to an app generated from 1.0 that wants to benefit from the new 
>> capabilities?
>>
>
> This is the reason I don't use Luminus or Modularity or others that rely 
> heavily on leiningen template-based codegen. Its very difficult to upgrade 
> the generated code, especially if you've had to add to or modify it. 
>
> I'm experimenting with an approach that would generate only the 
> project.clj file and directory structure (putting everything else into 
> libraries), but don't yet have anything to release (my code is currently 
> very targeted at my own use case, but in time I'd like to generalize it a 
> bit and let others at it).
>

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


Re: Clojure needs a web framework with more momentum

2015-05-04 Thread Dmitri
As others have pointed out the comparison isn't really valid. Luminus 
intentionally aims to leverage existing libraries that are maintained 
independently whenever possible. I've been doing web dev with Clojure for 
the past 4 years and overall I do prefer the approach of using composable 
libraries over monolithic frameworks. With the Clojure web stack it's much 
easier to tell what's actually happening during the request/response 
lifecycle as things tend to be explicit. With frameworks like Rails a lot 
of stuff happens implicitly and requires a lot of in depth knowledge to 
work with effectively.

However, there are a some downsides to the libraries over frameworks 
approach as well. The biggest issue is that it's difficult to track what 
libraries are actively maintained and which ones play nicely together. 
Since most libraries are maintained by individuals it's common for them to 
become abandoned. Another problem is that each app becomes a unique 
snowflake since there aren't a lot of established patterns for structuring 
them. Finally, security is an issue for Clojure web apps as a lot of it 
done in rather ad hoc fashion. While this works great for people who are 
well versed in the Clojure web ecosystem it's a huge barrier for newcomers.

I think that the best way to address the problem is via organizations where 
related projects are maintained by groups of contributors. This helps 
discovery of projects, and it helps spread the burden of maintenance for 
them. This approach is already working in the wild on GitHub with Ring, 
Reagent, and Luminus orgs. Meanwhile, Leiningen templates are a great way 
to provide reasonable defaults for different types of applications and can 
be used to address issues such as security.

Also, I'm certainly open to contributions for Luminus. I moved it to an org 
recently and new members would be very welcome. :)


On Saturday, May 2, 2015 at 4:43:53 PM UTC-4, g vim wrote:
>
> I recently did some research into web frameworks on Github. Here's what 
> I found: 
>
>
> FRAMEWORK   LANG  CONTRIBUTORS COMMITS 
>
> LuminusClojure28678 
> CaribouClojure 2275 
>
> BeegoGolang991522 
>
> PhoenixElixir  1241949 
>
> YesodHaskell   1303722 
>
> LaravelPHP2684421 
>
> PlayScala   4176085 
>
> SymfonyPHP113020914 
>
> RailsRuby   269151000 
>
>
> One could conclude from this that the Clojure community isn't that 
> interested in web development but the last Clojure survey suggests 
> otherwise. Clojure's library composition approach to everything only 
> goes so far with large web applications, as Aaron Bedra reminded us in 
> March last year: www.youtube.com/watch?v=CBL59w7fXw4 . Less manpower 
> means less momentum and more bugs. Furthermore, I have a hunch that 
> Clojure's poor adoption as indicated by Indeed.com maybe due to this 
> immaturity in the web framework sphere. Why is it that Elixir, with a 
> much smaller community and lifespan than Clojure's, has managed to put 4 
> times as much mindshare into its main web framework when its module 
> output, as measured by modulecounts.com, is a tiny fraction of Clojure's? 
>
> gvim 
>
>
>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: [ANN} Aleph 0.4.0 released, plus Manifold, Dirigiste, and a whole host of other libraries

2015-04-17 Thread Dmitri
Ah, you're right there is ring.middleware.reload middleware available and 
wrapping the handler with it in dev works perfectly.

On Friday, April 17, 2015 at 7:22:06 PM UTC-4, Zach Tellman wrote:
>
> Hey Dmitri,
>
> I haven't used any sort of dev-mode before (I just update stuff in the 
> REPL when necessary), but it seems like something like that belongs in 
> middleware, not the server.  The server is just calling a function, it 
> shouldn't care if something else is changing that function's behavior.
>
> If other servers have this behavior embedded, maybe it can be extracted 
> into a standalone library?
>
> Zach
>
> On Fri, Apr 17, 2015 at 3:47 PM, Dmitri  > wrote:
>
>> I'd like to add Aleph to the Luminus template and I was wondering if 
>> there's an equivalent of dev mode available for other servers where it 
>> watches for changes in source and reloads them. I did a cursory look but 
>> didn't spot anything like a -dev option.
>>
>> On Friday, April 17, 2015 at 5:06:30 PM UTC-4, Zach Tellman wrote:
>>
>>> Hey all,
>>>
>>> In preparation for Clojure/West, I'm formally releasing the latest Aleph 
>>> and the libraries that surround it.  Aleph 0.4.0 has been running in 
>>> production at Factual for half a year now, and across a variety of services 
>>> is handling at peak 600k HTTP requests/sec (spread across 15-20 machines).  
>>>
>>> Since the landscape of Clojure HTTP servers is pretty crowded these 
>>> days, it's worth taking some time to explain how Aleph differs.  To be 
>>> clear, most Clojure deployments likely use Jetty, and should continue to do 
>>> so.  However, Aleph has some unique properties:
>>>
>>> * It uses the Netty library, which is a high-performance and very 
>>> battle-tested network layer for the JVM
>>> * It is the only HTTP server that has *ubiquitous* asynchronous streams 
>>> wherever data can be received or sent (all other libraries can only 
>>> represent streaming requests using InputStreams, or like http-kit don't 
>>> support streaming HTTP requests at all)
>>> * It is the only server that has a WebSocket implementation with any 
>>> support for per-connection backpressure.  I won't make this post even 
>>> longer by going into why this is important, but this will be a central 
>>> theme of my talk at Clojure/West next week if you're interested in hearing 
>>> more.
>>> * It uses consistent abstractions to represent network connections over 
>>> a variety of protocols, which makes it straightforward to use the same 
>>> application logic for all of them.
>>>
>>> Again, none of these points mean you should immediately drop whatever 
>>> you're using and move over to Aleph instead.  However, I do feel it 
>>> represents the only (current) good option for using core.async or a similar 
>>> stream abstraction to represent network data, which is an idea a number of 
>>> people seem to be playing with lately.  Some examples of this can be found 
>>> at http://ideolalia.com/aleph/literate.html.
>>>
>>> A full list of the libraries:
>>>
>>> aleph - https://github.com/ztellman/aleph - uses the excellent Netty 
>>> library to expose HTTP, TCP, and UDP using a consistent asynchronous stream 
>>> representation.
>>>
>>> manifold - https://github.com/ztellman/manifold - an unopinionated 
>>> stream representation designed to cleanly interoperate with other stream 
>>> representations (Clojure's seqs, core.async channels, Java's 
>>> BlockingQueues, and others).  This is the base stream representation for 
>>> all network sources and sinks in Aleph.
>>>
>>> dirigiste -  https://github.com/ztellman/dirigiste - a pure-Java 
>>> library that provides instrumented, dynamically sized thread and object 
>>> pools.  This is used for thread pools in Aleph's HTTP server, and for 
>>> connection pools in Aleph's HTTP client.
>>>
>>> byte-streams -  https://github.com/ztellman/byte-streams - a means of 
>>> translating any byte representation into another.  Want to turn a 
>>> core.async channel that emits byte-arrays into an InputStream, or maybe the 
>>> other way around?  Look no further.  The library's conversion mechanism is 
>>> extensible, which is used in Aleph to make Netty's custom byte 
>>> representations interoperable with more familiar representations.
>>>
>>> byte-tran

Re: [ANN} Aleph 0.4.0 released, plus Manifold, Dirigiste, and a whole host of other libraries

2015-04-17 Thread Dmitri
I'd like to add Aleph to the Luminus template and I was wondering if 
there's an equivalent of dev mode available for other servers where it 
watches for changes in source and reloads them. I did a cursory look but 
didn't spot anything like a -dev option.

On Friday, April 17, 2015 at 5:06:30 PM UTC-4, Zach Tellman wrote:
>
> Hey all,
>
> In preparation for Clojure/West, I'm formally releasing the latest Aleph 
> and the libraries that surround it.  Aleph 0.4.0 has been running in 
> production at Factual for half a year now, and across a variety of services 
> is handling at peak 600k HTTP requests/sec (spread across 15-20 machines).  
>
> Since the landscape of Clojure HTTP servers is pretty crowded these days, 
> it's worth taking some time to explain how Aleph differs.  To be clear, 
> most Clojure deployments likely use Jetty, and should continue to do so. 
>  However, Aleph has some unique properties:
>
> * It uses the Netty library, which is a high-performance and very 
> battle-tested network layer for the JVM
> * It is the only HTTP server that has *ubiquitous* asynchronous streams 
> wherever data can be received or sent (all other libraries can only 
> represent streaming requests using InputStreams, or like http-kit don't 
> support streaming HTTP requests at all)
> * It is the only server that has a WebSocket implementation with any 
> support for per-connection backpressure.  I won't make this post even 
> longer by going into why this is important, but this will be a central 
> theme of my talk at Clojure/West next week if you're interested in hearing 
> more.
> * It uses consistent abstractions to represent network connections over a 
> variety of protocols, which makes it straightforward to use the same 
> application logic for all of them.
>
> Again, none of these points mean you should immediately drop whatever 
> you're using and move over to Aleph instead.  However, I do feel it 
> represents the only (current) good option for using core.async or a similar 
> stream abstraction to represent network data, which is an idea a number of 
> people seem to be playing with lately.  Some examples of this can be found 
> at http://ideolalia.com/aleph/literate.html.
>
> A full list of the libraries:
>
> aleph - https://github.com/ztellman/aleph - uses the excellent Netty 
> library to expose HTTP, TCP, and UDP using a consistent asynchronous stream 
> representation.
>
> manifold - https://github.com/ztellman/manifold - an unopinionated stream 
> representation designed to cleanly interoperate with other stream 
> representations (Clojure's seqs, core.async channels, Java's 
> BlockingQueues, and others).  This is the base stream representation for 
> all network sources and sinks in Aleph.
>
> dirigiste -  https://github.com/ztellman/dirigiste - a pure-Java library 
> that provides instrumented, dynamically sized thread and object pools. 
>  This is used for thread pools in Aleph's HTTP server, and for connection 
> pools in Aleph's HTTP client.
>
> byte-streams -  https://github.com/ztellman/byte-streams - a means of 
> translating any byte representation into another.  Want to turn a 
> core.async channel that emits byte-arrays into an InputStream, or maybe the 
> other way around?  Look no further.  The library's conversion mechanism is 
> extensible, which is used in Aleph to make Netty's custom byte 
> representations interoperable with more familiar representations.
>
> byte-transforms -  https://github.com/ztellman/byte-transforms - a 
> curated collection of byte compression, hashing, and encoding mechanisms, 
> which can work on anything byte-streams can convert.
>
> While all these libraries are used in concert to create Aleph, I've been 
> very careful to make sure any of them can be used by themselves.  If anyone 
> has questions about them, the best place to get my attention is the Aleph 
> mailing list: https://groups.google.com/forum/#!forum/aleph-lib.
>
> I will be mentioning some of these libraries at my upcoming Clojure/West 
> talk (http://clojurewest.org/speakers#ztellman), but I've also set aside 
> an Unsession for specifically discussing these libraries: 
> https://github.com/clojurewest/clojurewest2015/wiki/Unsessions.  If 
> you're interested, please add your name to the list.
>
> Zach
>

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

2014-12-09 Thread Dmitri
It really looks fantastic, I'll do the integration in Luminus this weekend 
and let you know how that goes. :)

On Tuesday, December 9, 2014 4:50:51 PM UTC-5, Andrey Antukh wrote:
>
>
>
> 2014-12-09 22:35 GMT+01:00 Dmitri >:
>
>> I'm definitely up for that, if I knew about buddy I wouldn't have started 
>> the lib in the first place. :) I found friend to be a bit too complex for 
>> what I needed in the apps I was writing as well. I originally added the 
>> access restriction logic to lib-noir, but recently I started considering 
>> deprecating it in favor of standalone libraries for all the functionality 
>> that it bundles. Buddy looks like a perfect solution for web app security.
>>
>
>> I only see a couple of small differences in functionality. Buddy requires 
>> a handler function, while I opted for allowing a static redirect URI as an 
>> alternative. I allow specifying a vector of uri patterns for each set of 
>> rules. I'm also using Clout (https://github.com/weavejester/clout) for 
>> request matching instead of plain regex. All of these are very minor 
>> differences however.
>>
>  
> Are minor differences but if them are useful, maybe them should be 
> implemented in buddy.
> I'll review in detail the implementation of your library and extract from 
> them that parts for buddy. I'll try to do it this weekend. Until weekend I 
> will stay very busy :( 
>
>
>> I think I'll be moving Luminus over to use Buddy instead lib-noir for 
>> security. :)
>>
>
> Oh, great notice! I'm repeating, if you find something missing, let me 
> know!
>
> Regards.
> Andrey.
>
>>
>> On Tuesday, December 9, 2014 4:13:44 PM UTC-5, Andrey Antukh wrote:
>>>
>>> Would be awesome join forces, and If you miss something that you library 
>>> is already support, let me know, and we can integrate it in buddy.
>>>
>>> I have made buddy because I'm little frustrate with friend approach (is 
>>> good but not convinced me).
>>>
>>> Regards.
>>> Andrey
>>>
>>> 2014-12-09 21:30 GMT+01:00 Dmitri :
>>>
>>> That does look rather similar actually, and it looks like buddy does a 
>>>> lot more as well. I guess that validates the approach, I'll have to see if 
>>>> it fits all my use cases. :)
>>>>
>>>> On Tuesday, December 9, 2014 2:43:42 PM UTC-5, Andrey Antukh wrote:
>>>>>
>>>>> Hi Dmitri!
>>>>>
>>>>> If I understand it well, is a very similar system already implemented 
>>>>> in buddy: http://niwibe.github.io/buddy/#_access_rules_system 
>>>>> <http://www.google.com/url?q=http%3A%2F%2Fniwibe.github.io%2Fbuddy%2F%23_access_rules_system&sa=D&sntz=1&usg=AFQjCNFhCj_anD1ohvV4MbWGgBmSj3OGng>
>>>>>  
>>>>>
>>>>> Regards.
>>>>> Andrey.
>>>>>
>>>>> 2014-12-09 19:11 GMT+01:00 Dmitri :
>>>>>
>>>>>> https://github.com/yogthos/ring-access-rules
>>>>>>
>>>>>> Friend is a great library, but it's definitely not easy to get into 
>>>>>> and I found it can actually make the workflow logic difficult to follow 
>>>>>> in 
>>>>>> some cases.
>>>>>>
>>>>>> My experience has been that for apps I work on all I want is to apply 
>>>>>> a decision function to a route to see if it should be accessible. The 
>>>>>> decision logic really tends to be application specific. It's easy to 
>>>>>> write 
>>>>>> a custom access control function for a specific scenario, but it's 
>>>>>> difficult to make a generic one that works well for any scenario. This 
>>>>>> library provides a simple way to associate access control functions with 
>>>>>> routes and leaves the workflow up to the user.
>>>>>>
>>>>>> -- 
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups "Clojure" group.
>>>>>> To post to this group, send email to clo...@googlegroups.com
>>>>>> Note that posts from new members are moderated - please be patient 
>>>>>> with your first post.
>>>>>> To unsubscribe from this group, send email to
>>>>>> clojure+u...@googlegroups.com
>>>>>> For more options, visit this 

Re: [ANN] ring-access-rules library

2014-12-09 Thread Dmitri
I'm definitely up for that, if I knew about buddy I wouldn't have started 
the lib in the first place. :) I found friend to be a bit too complex for 
what I needed in the apps I was writing as well. I originally added the 
access restriction logic to lib-noir, but recently I started considering 
deprecating it in favor of standalone libraries for all the functionality 
that it bundles. Buddy looks like a perfect solution for web app security.

I only see a couple of small differences in functionality. Buddy requires a 
handler function, while I opted for allowing a static redirect URI as an 
alternative. I allow specifying a vector of uri patterns for each set of 
rules. I'm also using Clout (https://github.com/weavejester/clout) for 
request matching instead of plain regex. All of these are very minor 
differences however.

I think I'll be moving Luminus over to use Buddy instead lib-noir for 
security. :)

On Tuesday, December 9, 2014 4:13:44 PM UTC-5, Andrey Antukh wrote:
>
> Would be awesome join forces, and If you miss something that you library 
> is already support, let me know, and we can integrate it in buddy.
>
> I have made buddy because I'm little frustrate with friend approach (is 
> good but not convinced me).
>
> Regards.
> Andrey
>
> 2014-12-09 21:30 GMT+01:00 Dmitri >:
>
>> That does look rather similar actually, and it looks like buddy does a 
>> lot more as well. I guess that validates the approach, I'll have to see if 
>> it fits all my use cases. :)
>>
>> On Tuesday, December 9, 2014 2:43:42 PM UTC-5, Andrey Antukh wrote:
>>>
>>> Hi Dmitri!
>>>
>>> If I understand it well, is a very similar system already implemented in 
>>> buddy: http://niwibe.github.io/buddy/#_access_rules_system 
>>> <http://www.google.com/url?q=http%3A%2F%2Fniwibe.github.io%2Fbuddy%2F%23_access_rules_system&sa=D&sntz=1&usg=AFQjCNFhCj_anD1ohvV4MbWGgBmSj3OGng>
>>>  
>>>
>>> Regards.
>>> Andrey.
>>>
>>> 2014-12-09 19:11 GMT+01:00 Dmitri :
>>>
>>>> https://github.com/yogthos/ring-access-rules
>>>>
>>>> Friend is a great library, but it's definitely not easy to get into and 
>>>> I found it can actually make the workflow logic difficult to follow in 
>>>> some 
>>>> cases.
>>>>
>>>> My experience has been that for apps I work on all I want is to apply a 
>>>> decision function to a route to see if it should be accessible. The 
>>>> decision logic really tends to be application specific. It's easy to write 
>>>> a custom access control function for a specific scenario, but it's 
>>>> difficult to make a generic one that works well for any scenario. This 
>>>> library provides a simple way to associate access control functions with 
>>>> routes and leaves the workflow up to the user.
>>>>
>>>> -- 
>>>> You received this message because you are subscribed to the Google
>>>> Groups "Clojure" group.
>>>> To post to this group, send email to clo...@googlegroups.com
>>>> Note that posts from new members are moderated - please be patient with 
>>>> your first post.
>>>> To unsubscribe from this group, send email to
>>>> clojure+u...@googlegroups.com
>>>> For more options, visit this group at
>>>> http://groups.google.com/group/clojure?hl=en
>>>> --- 
>>>> You received this message because you are subscribed to the Google 
>>>> Groups "Clojure" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>> an email to clojure+u...@googlegroups.com.
>>>> For more options, visit https://groups.google.com/d/optout.
>>>>
>>>
>>>
>>>
>>> -- 
>>> Andrey Antukh - Андрей Антух -  / <
>>> ni...@niwi.be>
>>> http://www.niwi.be <http://www.niwi.be/page/about/>
>>> https://github.com/niwibe
>>>  
>>  -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> 
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscr

Re: [ANN] ring-access-rules library

2014-12-09 Thread Dmitri
That does look rather similar actually, and it looks like buddy does a lot 
more as well. I guess that validates the approach, I'll have to see if it 
fits all my use cases. :)

On Tuesday, December 9, 2014 2:43:42 PM UTC-5, Andrey Antukh wrote:
>
> Hi Dmitri!
>
> If I understand it well, is a very similar system already implemented in 
> buddy: http://niwibe.github.io/buddy/#_access_rules_system 
> <http://www.google.com/url?q=http%3A%2F%2Fniwibe.github.io%2Fbuddy%2F%23_access_rules_system&sa=D&sntz=1&usg=AFQjCNFhCj_anD1ohvV4MbWGgBmSj3OGng>
>  
>
> Regards.
> Andrey.
>
> 2014-12-09 19:11 GMT+01:00 Dmitri >:
>
>> https://github.com/yogthos/ring-access-rules
>>
>> Friend is a great library, but it's definitely not easy to get into and I 
>> found it can actually make the workflow logic difficult to follow in some 
>> cases.
>>
>> My experience has been that for apps I work on all I want is to apply a 
>> decision function to a route to see if it should be accessible. The 
>> decision logic really tends to be application specific. It's easy to write 
>> a custom access control function for a specific scenario, but it's 
>> difficult to make a generic one that works well for any scenario. This 
>> library provides a simple way to associate access control functions with 
>> routes and leaves the workflow up to the user.
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> 
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>
>
> -- 
> Andrey Antukh - Андрей Антух - > / <
> ni...@niwi.be >
> http://www.niwi.be <http://www.niwi.be/page/about/>
> https://github.com/niwibe
>  

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


[ANN] ring-access-rules library

2014-12-09 Thread Dmitri
https://github.com/yogthos/ring-access-rules

Friend is a great library, but it's definitely not easy to get into and I 
found it can actually make the workflow logic difficult to follow in some 
cases.

My experience has been that for apps I work on all I want is to apply a 
decision function to a route to see if it should be accessible. The 
decision logic really tends to be application specific. It's easy to write 
a custom access control function for a specific scenario, but it's 
difficult to make a generic one that works well for any scenario. This 
library provides a simple way to associate access control functions with 
routes and leaves the workflow up to the user.

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

2013-11-13 Thread Dmitri
I notice you're using a fairly old version of markdown-clj [markdown-clj 
"0.9.19"]

The current version is [markdown-clj "0.9.35"] so that should address a lot 
of formatting issues. :)

On Wednesday, November 13, 2013 2:09:10 PM UTC-5, Ryan Spangler wrote:
>
> Brian,
>
> Thanks for the heads up!  I fixed some of the formatting issues I found, 
> I'll keep a lookout for this issue (using a md->html converter which 
> apparently requires spaces at the end of lines in lists?)
>
> And yes, data modeling is one of our main concerns.  All models are also 
> data, which means they can be manipulated like any other data structure. 
>  This is what enables us to generate the admin and api automatically!  (as 
> well as a host of other benefits)
>
> On Wednesday, November 13, 2013 8:07:52 AM UTC-8, Brian Craft wrote:
>>
>> Looks very cool. I'm happy to see that data modeling is taken seriously, 
>> which in my experience is the biggest piece lacking in other clojure web 
>> tools.
>>
>> The docs have a lot of layout problems with words running together, like 
>> so: "data from oneenvironment". Looks like a string joining operation 
>> that's not quite right.
>>
>> On Tuesday, November 12, 2013 3:52:10 PM UTC-8, Ryan Spangler wrote:
>>>
>>> Hello Clojure,
>>>
>>> Excited to announce today the release of Caribou!  
>>> http://let-caribou.in/
>>>
>>> We have been building web sites and web applications with it for over 
>>> two years now and improving it every day.  Currently we have four people 
>>> working on it and another ten using it to build things, so it is getting a 
>>> lot of real world testing.
>>>
>>> It has been designed as a collection of independent libraries that could 
>>> each be useful on their own, but which come together as a meaningful whole.
>>>
>>> We have been spending the last couple months getting it ready for a full 
>>> open source release, and I am happy to say it is finally ready.  Funded and 
>>> supported by Instrument in Portland, OR:  http://weareinstrument.com/ We 
>>> have four projects using it in production, and several more about to be 
>>> launched (as well as over a dozen internal things).
>>>
>>> Documentation is here:  
>>> http://caribou.github.io/caribou/docs/outline.html
>>>
>>> Source is here:  http://github.com/caribou/caribou (use this for 
>>> issues, you don't actually need the source as it is installed through a 
>>> lein template).
>>>
>>> Some of the independently useful libraries Caribou is built on are:
>>>
>>> * Polaris -- Routing with data (not macros) and reverse routing! :  
>>> https://github.com/caribou/polaris
>>> * Lichen -- Image resizing to and from s3 or on disk: 
>>> https://github.com/caribou/lichen
>>> * Schmetterling -- Debugging Clojure processes from the browser:  
>>> https://github.com/prismofeverything/schmetterling
>>> * Antlers -- Useful extensions to mustache templating (helpers and 
>>> blocks, among other things):  https://github.com/caribou/antlers
>>> * Groundhog -- Replay http requests: 
>>> https://github.com/noisesmith/groundhog
>>>
>>> And many others.
>>>
>>> Basically this is an Alpha release, and I am announcing it here first in 
>>> order to get as much feedback from the community as possible.  We have made 
>>> it as useful as we can for our purposes and recognize that for it to 
>>> improve from here, we really need as many people using it and building 
>>> things with it as possible.  The documentation also needs to be put through 
>>> its paces:  we need to see how well people are able to use it who know 
>>> nothing about it, based only on the existing docs.
>>>
>>> All feedback welcome!  
>>>
>>> Thanks for reading!  I hope you find it useful.
>>>
>>

-- 
-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Full stack Clojure web/REST framework - is there any mileage in it?

2013-01-11 Thread Dmitri
I think a lot of the issues can be addressed via a good template which sets 
up all the boiler plate, demonstrates idiomatic usage, and defaults to some 
common libraries. I'm actively working on filling this gap with the 
Luminus, 
which aims to make it easy to get rolling, and sets up all the basic things 
like sessions, static resources, packaging, etc.

On Friday, January 11, 2013 11:52:05 AM UTC-5, Paul Umbers wrote:
>
> I've been experimenting with Clojure web services recently, and posting 
> the work on GitHub  and my 
> blog
> .
>
> When putting this test app together, it occurred to me that most other 
> languages have a full-stack API available which makes life easier when it 
> comes to making decisions about which libraries/APIs/frameworks to use. It 
> also reduces the possibility of "impedance mismatch" between the libraries. 
> For Java, you can use Spring (or any one of a dozen or more other popular 
> frameworks), for Scala there's Typesafe, and so on. Clojure has Compojure, 
> Ring, several logging, validation and database libraries, and they can be 
> used together but they don't constitute a coordinated full stack - and that 
> creates issues.
>
> For example, the latest vesion of Compojure (1.1.3) uses Ring 1.1.5 and 
> not the latest version of Ring (1.1.6) which has significantly better util 
> functions available - but I can't use them until Compojure catches up. By 
> the time you add logging, validation, data access, etc the odds of a 
> mismatch between these libraries goes up dramatically.
>
> This is a concern, because these mismatches must be worked around in *my*code 
> and are likely to break as the libraries are upgraded in future 
> versions. So, I'm having to spend my time maintaining what are essentially 
> "patches" for third-party libraries just so that they work together.
>
> Now, it may not be the best decision to try to put together a true 
> full-stack framework from scratch, but is it worth choosing a bunch of 
> existing frameworks and coordinating their releases - in much the same way 
> as Eclipse coordinates plugin releases for major releases - so that putting 
> together a full-stack app becomes easier?
>
> Projects taking part in the "meta-project" will work together to harmonize 
> their functionality & APIs, and coordinate their development cycles & 
> releases so that the meta-framework remains consistent and easily usable.
>
> Is this another barrier to adoption the Clojure community can remove? Is 
> this even a barrier? Am I missing something?
>
> Thoughts?
>
> [Also posted to http://www.reddit.com/r/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

CDS tutorials

2012-10-10 Thread Dmitri
Hi,

I saw the new ClojureDocs site and I'd like to contribute some tutorials 
I've made on setting up the environment and making web apps.

I have a tutorial on using Eclipse and CounterClockwise at 
https://www.yogthos.net/blog/18-Setting+up+Eclipse+for+Clojure
and I've got an extensive Noir tutorial here 
https://www.yogthos.net/blog/22-Noir+tutorial+-+part+1

if they look useful I'd be glad to add them.

Cheers,
Dmitri

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

2012-06-11 Thread Dmitri

And it's been updated as per suggestion, thanks for the tip.

On 2012-06-11, at 01:45 , Baishampayan Ghose wrote: 
>
> > On Sun, Jun 10, 2012 at 10:16 PM, Dmitri  
> wrote: 
> >> The reason I'm using strings for values is to make it easier to work 
> with 
> >> deserialized JSON. Currently I have it running as a service that our 
> >> internal applications send a JSON request and get a PDF document back. 
> > 
> > Internally you can call `name` on the arguments, that way the user can 
> > pass in either a string or a keyword. 
> > 
> > Regards, 
> > BG 
> > 
> > -- 
> > Baishampayan Ghose 
> > b.ghose at gmail.com 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> > Groups "Clojure" group. 
> > To post to this group, send email to clojure@googlegroups.com 
> > Note that posts from new members are moderated - please be patient with 
> your first post. 
> > To unsubscribe from this group, send email to 
> > clojure+unsubscr...@googlegroups.com 
> > For more options, visit this group at 
> > http://groups.google.com/group/clojure?hl=en 
>
>

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

2012-06-11 Thread Dmitri Sotnikov
That's a good point, it would make the API more idiomatic I suppose.

On 2012-06-11, at 01:45 , Baishampayan Ghose wrote:

> On Sun, Jun 10, 2012 at 10:16 PM, Dmitri  wrote:
>> The reason I'm using strings for values is to make it easier to work with
>> deserialized JSON. Currently I have it running as a service that our
>> internal applications send a JSON request and get a PDF document back.
> 
> Internally you can call `name` on the arguments, that way the user can
> pass in either a string or a keyword.
> 
> Regards,
> BG
> 
> -- 
> Baishampayan Ghose
> b.ghose at gmail.com
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en

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

2012-06-10 Thread Dmitri
The reason I'm using strings for values is to make it easier to work with 
deserialized JSON. Currently I have it running as a service that our 
internal applications send a JSON request and get a PDF document back. 

On Sunday, June 10, 2012 12:25:39 PM UTC-4, Moritz Ulrich wrote:
>
> Looks cool! Unfortunately I currently don't have the time to have a 
> deep look at it. However, I have a small comment on the api: Many 
> parameters like 'style', 'size', 'orientation', etc. use strings for 
> their values. I think keywords would be a better fit there. 
>
> On Sun, Jun 10, 2012 at 5:59 PM, Dmitri  
> wrote: 
> > The goal of clj-pdf is to provide a straight forward way to generate 
> PDFs 
> > using markup similar to hiccup. It tries to do the right thing by 
> default, 
> > so all styling hints are optional. It's getting some production use at 
> the 
> > moment, and there don't appear to be any issues so far. 
> > 
> > https://github.com/yogthos/clj-pdf 
> > 
> > Any suggestions or feature requests are welcome. :) 
> > 
> > 
> > -- 
> > You received this message because you are subscribed to the Google 
> > Groups "Clojure" group. 
> > To post to this group, send email to clojure@googlegroups.com 
> > Note that posts from new members are moderated - please be patient with 
> your 
> > first post. 
> > To unsubscribe from this group, send email to 
> > clojure+unsubscr...@googlegroups.com 
> > For more options, visit this group at 
> > http://groups.google.com/group/clojure?hl=en 
>
>
>
> -- 
> Moritz Ulrich 
>

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

clj-pdf for declarative PDF generation (status update)

2012-06-10 Thread Dmitri
The goal of clj-pdf is to provide a straight forward way to generate PDFs 
using markup similar to hiccup. It tries to do the right thing by default, 
so all styling hints are optional. It's getting some production use at the 
moment, and there don't appear to be any issues so far. 

https://github.com/yogthos/clj-pdf

Any suggestions or feature requests are welcome. :)


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

Re: a library I'm working on for generating PDFs from Clojure

2012-04-19 Thread Dmitri
It should be pretty easy to map some basic Hiccup tags to this,
headings, paragraphs, lists, and tables, etc. I suspect it's probably
easier to go the hiccup->pdf route, as you could simply ignore the
html tags that aren't applicable.


On Apr 19, 4:45 am, David Jagoe  wrote:
> Hi Dmitri,
>
> This is great, thanks!
>
> I have a system where I need to render web reports to nicely formatted
> PDFs. Currently I maintain separate HTML and TeX templates for this
> purpose (in a Python system) but wanted to have a system that allows
> me to write hiccup once and have it output HTML & PDF reports. I see
> that you've used the hiccup syntax but obviously your "tags" are
> different because screen and print media have different nature. I
> suppose it would be possible for me to write HTML-hiccup and have a
> translator that writes pdf-hiccup subset that contains the same
> content. Or maybe the other way around - write pdf-hiccup and
> translate to html-hiccup. Do you have an idea of which would be
> better? I.e. which has richer semantics that could be dropped during
> translation?
>
> Thanks!
> David
>
> 2012/4/19 Vinzent :
>
>
>
>
>
>
>
>
>
> > Thank you, I was looking for something exactly like that! I'll give it a
> > try.
>
> > ÞÅÔ×ÅÒÇ, 19 ÁÐÒÅÌÑ 2012šÇ., 7:34:10 UTC+6 ÐÏÌØÚÏ×ÁÔÅÌØ Dmitri ÎÁÐÉÓÁÌ:
>
> >> I poked around and noticed that there aren't any libraries for
> >> creating PDFs, and as I needed to make one for work I decided to open
> >> source it. I tried to follow Hiccup syntax as I find it to be nice and
> >> flexible.
>
> >>https://github.com/yogthos/clj-pdf
>
> >> The library piggy backs on iText 2.1.7 (the last LGPL release) and
> >> JFreeChart, it's able to generate documents with text formatting,
> >> lists, tables, and charts.
>
> >> I've also made a proof of concept service which accepts JSON formatted
> >> text and serves up PDFs that's built on top of it.
>
> >>https://github.com/yogthos/instant-pdf
>
> >> Feedback and suggestions are welcome.
>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Clojure" group.
> > To post to this group, send email to clojure@googlegroups.com
> > Note that posts from new members are moderated - please be patient with your
> > first post.
> > To unsubscribe from this group, send email to
> > clojure+unsubscr...@googlegroups.com
> > For more options, visit this group at
> >http://groups.google.com/group/clojure?hl=en
>
> --
> David Jagoe
>
> davidja...@gmail.com
> +447535268218

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


a library I'm working on for generating PDFs from Clojure

2012-04-18 Thread Dmitri
I poked around and noticed that there aren't any libraries for
creating PDFs, and as I needed to make one for work I decided to open
source it. I tried to follow Hiccup syntax as I find it to be nice and
flexible.

https://github.com/yogthos/clj-pdf

The library piggy backs on iText 2.1.7 (the last LGPL release) and
JFreeChart, it's able to generate documents with text formatting,
lists, tables, and charts.

I've also made a proof of concept service which accepts JSON formatted
text and serves up PDFs that's built on top of it.

https://github.com/yogthos/instant-pdf

Feedback and suggestions are welcome.

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


Re: a convenience idea for test functions

2012-04-18 Thread Dmitri
That is an excellent point, and the macro is actually a very nice
approach, thanks for the help.


On Apr 18, 1:07 am, Sean Corfield  wrote:
> On Tue, Apr 17, 2012 at 9:16 PM, Dmitri  wrote:
> > (map? foo bar baz) would return bar if foo is a map and baz otherwise.
>
> To elaborate on Alan's response, consider:
>
> (if (map? foo) (/ bar 0) baz)
>
> If map? were 'merely' a variadic function, (map? foo (/ bar 0) baz)
> would fail because (/ bar 0) would be evaluated and then passed as an
> argument, along with foo and baz.
>
> So, no, the simple answer is that you can't just make the test
> functions variadic and get the same behavior as an if form (hence
> Alan's suggestion of a macro-generating macro to create new macros for
> the forms you want).
>
> (Apologies if I'm laboring the point here)
> --
> Sean A Corfield -- (904) 302-SEAN
> An Architect's View --http://corfield.org/
> World Singles, LLC. --http://worldsingles.com/
>
> "Perfection is the enemy of the good."
> -- Gustave Flaubert, French realist novelist (1821-1880)

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


a convenience idea for test functions

2012-04-17 Thread Dmitri
Often times I find myself writing code like the following

(if (map? foo) bar baz)

would it make sense to make test functions variadic, so if only passed
a single argument it would return true/false, but could also act as an
if when passed 3 arguments, eg:

(map? foo bar baz) would return bar if foo is a map and baz otherwise.

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

2010-10-11 Thread Dmitri
Thanks this does seem to solve the problem of the servlet being
reinitialized on every run.

On Oct 10, 11:10 pm, Adrian Cuthbertson 
wrote:
> Hi Dmitri,
>
> The problem is probably related to calling init with args. It requires
> that super() gets called - I can't remember where I saw the
> documentation, but here's an example of what works for me.
>
> The following is a generic servlet which gets passed a clojure
> namespace name as an init parameter at init time which is saved in an
> atom. Then on each service call, it parses the servlet path and uses
> the "ipath" (first component of the url after the context), along with
> the ns name from the atom to load a clj namespace (once) and call a
> function called  passing it the req and rsp. The clj fn cn then
> handle the method type, GET, POST, etc and has access to all the
> servlet stuff.
>
> This way you have a servlet as a gateway to a clj ns and the function
> called determined by the req url...
>
> (ns svlt.Svlt
>   (import (javax.servlet.http HttpServlet HttpServletRequest
>      HttpServletResponse HttpSession)
>     (javax.servlet ServletConfig)
>     )
>   (:gen-class :extends javax.servlet.http.HttpServlet
>        :state state :init clinit))
>
> (defn -clinit
>   []
>   [[] (atom (hash-map))])
>
> (defn -init-void
>   [this] ; NB - careful, must rather call init() (void) than with the cfg 
> args.
>            ; If with args, must call .super() which is problematic
>   (let [;cfg (.getServletConfig this)
>         ns-nm (.getInitParameter this "app-ns")]
>     (println :Svlt :init :ns-nm ns-nm)
>     (swap! (.state this) assoc :ns-nm ns-nm)))
>
> (defn -service
>   [this #^HttpServletRequest req #^HttpServletRequest rsp]
>   (let [cpath (.getContextPath req)
>         spath (.getServletPath req)
>         ipath (.getPathInfo req)
>         _ (println :Svlt :cpath cpath :spath spath :ipath ipath)
>         ns-nm (get @(.state this) :ns-nm)
>         _ (println :Svlt :ns-nm ns-nm)
>         _ (when (nil? ns-nm) (throw (java.io.IOException.
>               (str "No app-ns param found in Svlt config: " spath
>         ipath (if (or (nil? ipath) (= ipath "")) "root" ipath)
>         ipath (if (.startsWith ipath "/") (.substring ipath 1) ipath)
>         ns-sym (symbol ns-nm)
>         _ (println :ns-sym ns-sym :ipath-now ipath)
>         found-ns (find-ns ns-sym)
>         found-ns (if (nil? found-ns)
>                    (let [n (create-ns ns-sym)] (require ns-sym) n)
>                    found-ns)
>         _ (when (nil? found-ns) (throw (java.io.IOException.
>               (str  "Namespace not found for: " ns-sym
>         req-fn (get (ns-publics ns-sym) (symbol ipath))
>         ]
>     (req-fn req rsp)))
>
> -Hth, Adrian

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


Servlet question

2010-10-10 Thread Dmitri
I noticed an odd thing when making a servlet


(ns jms.myservlet
  (import (javax.servlet.http
HttpServlet
HttpServletRequest
HttpServletResponse))
  (:gen-class
:extends javax.servlet.http.HttpServlet))

(defn -init [& args]
  (println "+++ init ran with args: " args))

(defn -doGet [_
  #^HttpServletRequest request
  #^HttpServletResponse response]
  (println "+++" "in doGet")
  (.. response
(getWriter)
(println (str "hello"


I've deployed the above on glassfish, and every time the page is hit
the init is run:

[#|2010-10-10T14:50:20.116-0400|INFO|glassfish3.0.1|
javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|
_ThreadID=34;_ThreadName=Thread-1;|+++ init ran with args:
(# #)
|#]

[#|2010-10-10T14:50:20.116-0400|INFO|glassfish3.0.1|
javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|
_ThreadID=34;_ThreadName=Thread-1;|+++ in doGet
|#]

[#|2010-10-10T14:50:24.572-0400|INFO|glassfish3.0.1|
javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|
_ThreadID=34;_ThreadName=Thread-1;|+++ init ran with args:
(# #)
|#]

[#|2010-10-10T14:50:24.573-0400|INFO|glassfish3.0.1|
javax.enterprise.system.std.com.sun.enterprise.v3.services.impl|
_ThreadID=34;_ThreadName=Thread-1;|+++ in doGet
|#]

A servlet is supposed to be run once when the page is loaded and stick
around until destroy is called, which is the case with a Java servlet.
What am I doing wrong in implementing the servlet, so that the Clojure
one is reloaded every time it's accessed?

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

2010-09-04 Thread Dmitri
So I made a change which allows passing a map of deserializers instead
of having them initialized globally, it's more or less the same as the
previous version otherwise, let me know if you feel it makes the
reader too complex

http://gist.github.com/565764

here's sample usage with that approach

(defn write-date [date #^PrintWriter out]
  (.print out
(str "\""
  (.format
(new java.text.SimpleDateFormat
  "MMM dd,  hh:mm:ss a") date) "\"")))

(extend Date Write-JSON
  {:write-json write-date})

(def deserializers
  {:age
   #(.parse
  (new java.text.SimpleDateFormat
 "MMM dd,  hh:mm:ss a") %)})

(defn read-json-from-str [input]
  (read-json input true true nil deserializers))

(let [data {:name "John"
:age (new java.util.Date)
:address [:street "1 Bay"
:city "Toronto"]}
  encoded (json-str data)]
  (println "encoded" encoded)
  (println "decoded" (read-json-from-str encoded)))


output:

encoded {"name":"John","age":"Sep 05, 2010 01:04:02 AM","address":
["street","1 Bay","city","Toronto"]}
decoded {:name John, :age #, :address [street 1 Bay city Toronto]}


On Sep 3, 3:17 pm, Stuart Sierra  wrote:
> No. I'm talking about collisions when multiple deserialization
> functions are added from different sources.  It cannot be a global
> setting.
>
> -S
>
> On Sep 3, 1:28 pm, Dmitri  wrote:
>
>
>
>
>
>
>
> > The problem I was trying to avoid is having to do a second pass over
> > the data after it comes out of the parser, it's more expensive and
> > it's also ugly for nested data structures. Would using defonce- and
> > defmacro- from clojure-contrib address the problem with namespace
> > collisions?
>
> > On Sep 3, 12:01 pm, Stuart Sierra  wrote:
>
> > > You can already extend the Write-JSON protocol to any type. But it
> > > doesn't work in reverse. JSON has no standardized way to express types
> > > beyond Object/Array/String/Number, so any deserialization will always
> > > be application-specific.
>
> > > -S
>
> > > On Sep 3, 8:58 am, Baishampayan Ghose  wrote:
>
> > > > > Sorry, I can't accept any patch that modifies behavior globally. What
> > > > > happens when two different libraries try to parse JSON with different
> > > > > deserializers?
>
> > > > > The only thing I would consider is a function that is passed into 
> > > > > read-
> > > > > json and invoked in read-json-object. But even that seems like adding
> > > > > unnecessary complication to the library.
>
> > > > Just curious, but does using protocols in clojure.contrib.json help?
> > > > May be people can extend the protocol to their types and make them
> > > > serializable to JSON and vice versa?
>
> > > > Regards,
> > > > BG
>
> > > > --
> > > > Baishampayan Ghose
> > > > b.ghose at gmail.com

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


Re: date serialization in clojure-contrib json

2010-09-03 Thread Dmitri
That's a very good point, I can't think of a good way to address that
off top of my head, I agree that passing in a function isn't really
great either.

On Sep 3, 3:17 pm, Stuart Sierra  wrote:
> No. I'm talking about collisions when multiple deserialization
> functions are added from different sources.  It cannot be a global
> setting.
>
> -S
>
> On Sep 3, 1:28 pm, Dmitri  wrote:
>
>
>
> > The problem I was trying to avoid is having to do a second pass over
> > the data after it comes out of the parser, it's more expensive and
> > it's also ugly for nested data structures. Would using defonce- and
> > defmacro- from clojure-contrib address the problem with namespace
> > collisions?
>
> > On Sep 3, 12:01 pm, Stuart Sierra  wrote:
>
> > > You can already extend the Write-JSON protocol to any type. But it
> > > doesn't work in reverse. JSON has no standardized way to express types
> > > beyond Object/Array/String/Number, so any deserialization will always
> > > be application-specific.
>
> > > -S
>
> > > On Sep 3, 8:58 am, Baishampayan Ghose  wrote:
>
> > > > > Sorry, I can't accept any patch that modifies behavior globally. What
> > > > > happens when two different libraries try to parse JSON with different
> > > > > deserializers?
>
> > > > > The only thing I would consider is a function that is passed into 
> > > > > read-
> > > > > json and invoked in read-json-object. But even that seems like adding
> > > > > unnecessary complication to the library.
>
> > > > Just curious, but does using protocols in clojure.contrib.json help?
> > > > May be people can extend the protocol to their types and make them
> > > > serializable to JSON and vice versa?
>
> > > > Regards,
> > > > BG
>
> > > > --
> > > > Baishampayan Ghose
> > > > b.ghose at gmail.com

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


Re: date serialization in clojure-contrib json

2010-09-03 Thread Dmitri
The problem I was trying to avoid is having to do a second pass over
the data after it comes out of the parser, it's more expensive and
it's also ugly for nested data structures. Would using defonce- and
defmacro- from clojure-contrib address the problem with namespace
collisions?

On Sep 3, 12:01 pm, Stuart Sierra  wrote:
> You can already extend the Write-JSON protocol to any type. But it
> doesn't work in reverse. JSON has no standardized way to express types
> beyond Object/Array/String/Number, so any deserialization will always
> be application-specific.
>
> -S
>
> On Sep 3, 8:58 am, Baishampayan Ghose  wrote:
>
>
>
> > > Sorry, I can't accept any patch that modifies behavior globally. What
> > > happens when two different libraries try to parse JSON with different
> > > deserializers?
>
> > > The only thing I would consider is a function that is passed into read-
> > > json and invoked in read-json-object. But even that seems like adding
> > > unnecessary complication to the library.
>
> > Just curious, but does using protocols in clojure.contrib.json help?
> > May be people can extend the protocol to their types and make them
> > serializable to JSON and vice versa?
>
> > Regards,
> > BG
>
> > --
> > Baishampayan Ghose
> > b.ghose at gmail.com

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


Re: date serialization in clojure-contrib json

2010-08-25 Thread Dmitri
I posted the complete file on github here http://gist.github.com/549771

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

2010-08-25 Thread Dmitri
I added the *deserializers* atom, converted read-json-object to a
macro

(def *deserializers* (atom {}))

(defn add-deserializer [k deserializer]
  (swap! *deserializers* #(assoc % k deserializer)))

(defn remove-deserializer [k]
  (swap! *deserializers* #(dissoc % k)))

(defmacro get-object-reader []
  (let [store  '(recur (.read stream) nil
  (assoc! result (if keywordize? (keyword key) key)
element))
deserialize-store '(let [elm-key (if keywordize? (keyword key)
key)
 deserializer (get @*deserializers*
elm-key)]
 (recur (.read stream) nil
   (assoc! result elm-key
 (if deserializer
   (deserializer element) element
store-and-recur (if (empty? @*deserializers*) deserialize-
store store)]

`(fn [#^PushbackReader ~'stream ~'keywordize?]
   ;; Expects to be called with the head of the stream AFTER the
   ;; opening bracket.
   (loop [~'i (.read ~'stream), ~'key nil, ~'result (transient
{})]
 (let [~'c (char ~'i)]
   (cond
  (= ~'i -1) (throw (EOFException. "JSON error (end-of-
file inside object)"))

  (Character/isWhitespace ~'c) (recur (.read ~'stream)
~'key ~'result)

  (= ~'c \,) (recur (.read ~'stream) nil ~'result)

  (= ~'c \:) (recur (.read ~'stream) ~'key ~'result)

  (= ~'c \}) (if (nil? ~'key)
 (persistent! ~'result)
 (throw (Exception. "JSON error (key missing
value in object)")))

  :else (do (.unread ~'stream ~'i)
  (let [~'element (read-json-reader ~'stream
~'keywordize? true nil)]
(if (nil? ~'key)
  (if (string? ~'element)
(recur (.read ~'stream) ~'element
~'result)
(throw (Exception. "JSON error (non-string
key in object)")))
  ~store-and-recur)


and changed read-json-reader to use get-object-reader at the start of
the loop

(defn- read-json-reader
  ([#^PushbackReader stream keywordize? eof-error? eof-value]
 (loop [i (.read stream)
object-reader (get-object-reader)]
   (let [c (char i)]
 (cond
  ;; Handle end-of-stream
  (= i -1) (if eof-error?
 (throw (EOFException. "JSON error (end-of-
file)"))
 eof-value)

  ;; Ignore whitespace
  (Character/isWhitespace c) (recur (.read stream) object-
reader)

these are the only changes that are needed and should preserve the
default case, while allowing to extend object reader with custom
deserializers, would this solution be acceptable?

On Aug 24, 8:21 pm, Dmitri  wrote:
> I understand the desire to keep the parser clean, but at the same time
> the ability to register custom data deserializers would be very
> convenient. Would something like the following help with the
> performance issue, since if no deserializers were registered there
> would only be a one time penalty for selecting the object reader?
>
> (defn- read-json-reader
>   ([#^PushbackReader stream keywordize? eof-error? eof-value]
>      (loop [i (.read stream)
>             object-reader (if (empty? @*deserializers*)  read-json-
> object read-json-object-and-deserialize)]
>
> On Aug 24, 6:51 pm, Stuart Sierra  wrote:
>
>
>
> > On Aug 23, 9:03 pm, Dmitri  wrote:
>
> > > Would there be an issue with adding something like that to the
> > > contrib?
>
> > I don't want to add anything that impacts performance in the plain
> > parsing case.
>
> > -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: date serialization in clojure-contrib json

2010-08-24 Thread Dmitri
I understand the desire to keep the parser clean, but at the same time
the ability to register custom data deserializers would be very
convenient. Would something like the following help with the
performance issue, since if no deserializers were registered there
would only be a one time penalty for selecting the object reader?

(defn- read-json-reader
  ([#^PushbackReader stream keywordize? eof-error? eof-value]
 (loop [i (.read stream)
object-reader (if (empty? @*deserializers*)  read-json-
object read-json-object-and-deserialize)]




On Aug 24, 6:51 pm, Stuart Sierra  wrote:
> On Aug 23, 9:03 pm, Dmitri  wrote:
>
> > Would there be an issue with adding something like that to the
> > contrib?
>
> I don't want to add anything that impacts performance in the plain
> parsing case.
>
> -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: date serialization in clojure-contrib json

2010-08-23 Thread Dmitri
Transforming the data after it comes out of the parser can be
cumbersome with complex data structures though, it would be nice to
have a way for the parser to return the data in the desired format.

I updated clojure.contrib.json with the ability to add custom
deserializers:

(def *deserializers* (atom {}))

(defn add-deserializer [k deserializer]
  (swap! *deserializers* #(assoc % k deserializer)))

(defn remove-deserializer [k]
  (swap! *deserializers* #(dissoc % k)))


(defn- read-json-object [#^PushbackReader stream keywordize?]
  ;; Expects to be called with the head of the stream AFTER the
  ;; opening bracket.
  (loop [i (.read stream), key nil, result (transient {})]
(let [c (char i)]
  (cond
   (= i -1) (throw (EOFException. "JSON error (end-of-file inside
object)"))

   (Character/isWhitespace c) (recur (.read stream) key result)

   (= c \,) (recur (.read stream) nil result)

   (= c \:) (recur (.read stream) key result)

   (= c \}) (if (nil? key)
  (persistent! result)
  (throw (Exception. "JSON error (key missing value in
object)")))

   :else (do (.unread stream i)
 (let [element (read-json-reader stream keywordize?
true nil)]
   (if (nil? key)
 (if (string? element)
   (recur (.read stream) element result)
   (throw (Exception. "JSON error (non-string key
in object)")))

 (let [elm-key (if keywordize? (keyword key) key)
   deserializer (get @*deserializers* elm-
key)]
   (recur (.read stream) nil
 (assoc! result elm-key
   (if deserializer
 (deserializer element) element)))


all I had to change was the part where the key and value are put in
the map to first check if there is a deserializer registered and use
it instead of storing the data directly, then I can use it as follows

(defn write-date [date #^PrintWriter out]
  (.print out
(str "\"" (.format (new java.text.SimpleDateFormat "MMM dd, 
hh:mm:ss a") date) "\"")))

(extend Date Write-JSON
  {:write-json write-date})

(add-deserializer :age #(.parse (new java.text.SimpleDateFormat "MMM
dd,  hh:mm:ss a") %))

(let [data {:name "John" :age (new java.util.Date) :address [:street
"1 Bay" :city "Toronto"]}
  encoded (json-str data)]
  (println encoded)
  (println "decoded" (read-json encoded)))


Would there be an issue with adding something like that to the
contrib?



On Aug 21, 1:52 pm, Stuart Sierra  wrote:
> I suppose one could override the (private) read-json-object function
> to transform maps after they are read, based on the presence of
> certain keys.  But that would seriously complicate the reader.  It's
> probably easier to transform the data after it comes back from the
> JSON parser.
>
> -S
>
> On Aug 20, 5:06 pm, Dmitri  wrote:
>
>
>
>
>
>
>
> > My concern is more to do with the reader, I think extending writer
> > works quite well, it would be nice if it was possible to do the same
> > thing with the reader, so you could specify how to deserialize
> > specific types of data. Right now it seems to be baked into read-json-
> > reader and there's no easy way to extend it.
>
> > Maybe it could be possible to specify how to deserialize data based on
> > the key names, then if the reader hits a key with the given name it
> > would try to deserialize it with the given function or something?
>
> > On Aug 20, 3:32 pm, Stuart Sierra  wrote:
>
> > > Since there is no standard for how to represent dates in JSON, it is
> > > unlikely to be built in.  But you can extend the writer with
> > > application-specific date formats.
> > > -S
>
> > > On Aug 20, 2:15 pm, Dmitri  wrote:
>
> > > > I'm currently using Dan Larkin's clojure-json, and it provides a way
> > > > to serialize and deserialize dates, it also provides the option to
> > > > specify custom serializers, eg:
>
> > > > (defn date-encoder
> > > >         [date writer pad current-indent start-token-indent indent-
> > > > size]
> > > >         (.append writer (str start-token-indent \" date \")))
>
> > > > I was looking at switching to using the json implementation in clojure-
> > > > contrib, but noticed that it doesn't handle dates nor does it provide
> > > > a way to register custom serializers, is there a plan to implement
> > > > that in the future, or is the proper approach to simply extend Write-
> > > >

Re: date serialization in clojure-contrib json

2010-08-20 Thread Dmitri
My concern is more to do with the reader, I think extending writer
works quite well, it would be nice if it was possible to do the same
thing with the reader, so you could specify how to deserialize
specific types of data. Right now it seems to be baked into read-json-
reader and there's no easy way to extend it.

Maybe it could be possible to specify how to deserialize data based on
the key names, then if the reader hits a key with the given name it
would try to deserialize it with the given function or something?

On Aug 20, 3:32 pm, Stuart Sierra  wrote:
> Since there is no standard for how to represent dates in JSON, it is
> unlikely to be built in.  But you can extend the writer with
> application-specific date formats.
> -S
>
> On Aug 20, 2:15 pm, Dmitri  wrote:
>
>
>
> > I'm currently using Dan Larkin's clojure-json, and it provides a way
> > to serialize and deserialize dates, it also provides the option to
> > specify custom serializers, eg:
>
> > (defn date-encoder
> >         [date writer pad current-indent start-token-indent indent-
> > size]
> >         (.append writer (str start-token-indent \" date \")))
>
> > I was looking at switching to using the json implementation in clojure-
> > contrib, but noticed that it doesn't handle dates nor does it provide
> > a way to register custom serializers, is there a plan to implement
> > that in the future, or is the proper approach to simply extend Write-
> > JSON whenever a custom serializer/deserializer is needed.

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


Re: date serialization in clojure-contrib json

2010-08-20 Thread Dmitri
Extending the writer is pretty trivial

(defn write-date [date]
  (.format (new java.text.SimpleDateFormat "MMM dd,  hh:mm:ss a")
date))

(extend Date Write-JSON
  {:write-json write-date})

but it seems like deserializing a date wouldn't be quite so trivial.

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


date serialization in clojure-contrib json

2010-08-20 Thread Dmitri
I'm currently using Dan Larkin's clojure-json, and it provides a way
to serialize and deserialize dates, it also provides the option to
specify custom serializers, eg:

(defn date-encoder
[date writer pad current-indent start-token-indent indent-
size]
(.append writer (str start-token-indent \" date \")))

I was looking at switching to using the json implementation in clojure-
contrib, but noticed that it doesn't handle dates nor does it provide
a way to register custom serializers, is there a plan to implement
that in the future, or is the proper approach to simply extend Write-
JSON whenever a custom serializer/deserializer is needed.

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


Re: sequence manipulation question

2009-10-19 Thread Dmitri

ah thanks for the clarification, makes perfect sense, didn't notice
into.

On Oct 20, 1:25 am, Alex Osborne  wrote:
> Dmitri wrote:
>
>  > I notice that certain sequence operations such as concat and cons will
>  > not retain the original type of sequence, for example if you combine
>  > two vectors together a list will be returned:
>  >
>  > user=> (concat [1 2] [3 4])
>  > (1 2 3 4)
>  >
>  > is this intentional behavior, and would it not be more consistent for
>  > concat to retain the original type of the data structures, when both
>  > data structures that were passed in are of the same type.
>
> It's because concat returns a lazy sequence, the concatenation only
> happens when you ask for relevant elements (which has the benefit that
> it doesn't need to do any copying, saving both time and memory).  If you
> want to concatenate two vectors eagerly (so returning another vector)
> you could use 'into' instead:
>
> user=> (into [1 2] [3 4])
> [1 2 3 4]
>
>  > Also, why
>  > does cons behave differently from conj:
>  >
>  > user=> (conj [1 2] 3)
>  > [1 2 3]
>  >
>  > user=> (cons 2  [1 2])
>  > (2 1 2)
>
> Because cons always creates a list (which construct at the front), while
> conj "adds" it in the natural (ie fastest) way for that collection type,
> vectors "add" at the end.
>
> user> (conj '(1 2) 3)
> (3 1 2)
> user> (conj [1 2] 3)
> [1 2 3]
> user> (conj #{1 2} 3)
> #{1 2 3}
>
> user> (cons 3 '(1 2))
> (3 1 2)
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



sequence manipulation question

2009-10-19 Thread Dmitri

I notice that certain sequence operations such as concat and cons will
not retain the original type of sequence, for example if you combine
two vectors together a list will be returned:

user=> (concat [1 2] [3 4])
(1 2 3 4)

is this intentional behavior, and would it not be more consistent for
concat to retain the original type of the data structures, when both
data structures that were passed in are of the same type. Also, why
does cons behave differently from conj:

user=> (conj [1 2] 3)
[1 2 3]

user=> (cons 2  [1 2])
(2 1 2)

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

2009-04-02 Thread Dmitri

yeah I definitely agree that it would be nice if constants could be
used without the parens.

On Apr 2, 11:48 am, Paul Stadig  wrote:
> Yeah that works the same as defining a function, just more explicit. I was
> looking for a way to define a constant and just use it as "my-const" without
> having to use the parens to call a function or a macro. I guess that would
> be something like a symbol macro in CL?
>
> Paul
>
> On Thu, Apr 2, 2009 at 11:08 AM, MikeM wrote:
>
>
>
> > There is definline which seems appropriate in place of the constant
> > macros.
>
> > (definline my-const [] 1)
> > (my-const) ;= 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
To unsubscribe from 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: speed question

2009-04-02 Thread Dmitri

nifty :)

On Apr 2, 5:10 pm, Raffael Cavallaro 
wrote:
> If you change the color constructor you can get some nice color
> effects:
>
> (. setColor (let [scaled (Math/round (* value color-scale))]
>                      (Color.   255 (- 255 scaled) scaled)))
>
> will give you yellow and magenta for example
--~--~-~--~~~---~--~~
You 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: speed question

2009-04-02 Thread Dmitri

Thanks a lot, that's really helpful. I never thought of using a macro
to define constants
like that, it's definitely a good trick and it does seem to result in
the biggest performance
gain.

On Apr 2, 7:25 am, Paul Stadig  wrote:
> I got it down to about 3 seconds. I did what William said, but the biggest
> improvement was from changing the way *width*, *height*, and *max-steps*
> were defined. I noticed that in the Java version they are constants, but in
> the Clojure version they are Vars which means that inside your tight inner
> loops you are dereferencing the vars multiple times. Vars are for thread
> local values, but these values are not expected to change. I'm not sure the
> best way to make these vars into constants, but I changed them into macros:
>
> (defmacro *width* [] (float 640))
>
> Then replaced instances of *width* with (*width*). The macros will get
> compiled down to floats instead of resulting in multiple Var.deref calls
> (and probably Number.floatValue calls) per loop iteration.
>
> Here is the code:
>
> (ns main
>  (:import (java.awt Color Container Graphics Canvas Dimension)
>           (javax.swing JPanel JFrame)
>           (java.awt.image BufferedImage BufferStrategy)))
>
> (set! *warn-on-reflection* true)
>
> (defmacro *width* [] (float 640))
> (defmacro *height* [] (float 640))
> (defmacro *max-steps* [] (float 32))
>
> (defn on-thread [#^Runnable f] (doto (new Thread f) (.start)))
>
> (defn check-bounds [x y]
>    (loop [px (float x)
>           py (float y)
>           zx (float 0.0)
>           zy (float 0.0)
>           zx2 (float 0.0)
>           zy2 (float 0.0)
>           value (float 0)]
>       (if (and (< value (*max-steps*)) (< (+ zx2 zy2) (float 4.0)))
>            (let [new-zy (float (+ (* (float 2.0) zx zy) py))
>                  new-zx (float (+ (- zx2 zy2) px))
>                  new-zx2 (float (* new-zx new-zx))
>                  new-zy2 (float (* new-zy new-zy))]
>                  (recur px py new-zx new-zy new-zx2 new-zy2 (inc value)))
>            (if (== value (*max-steps*)) 0 value
>
> (defn draw-line [#^Graphics g y]
>    (let [dy (- 1.25 (* 2.5 (/ y (*height*]
>      (doseq [x (range 0 (*width*))]
>        (let [dx (- (* 2.5 (/ x (*width*))) 2.0)]
>                (let [value (check-bounds dx dy)]
>                    (if (> value  0)
>                        (doto g
>                            (. setColor (Color. (* value (/ 255
> (*max-steps*)
>                            (. drawRect x y 0 0
>
> (defn draw-lines
>    ([buffer g] (draw-lines buffer g (*height*)))
>    ([#^BufferStrategy buffer g y]
>          (doseq [y (range 0 y)]
>             (draw-line g y)
>             ;(on-thread (draw-line g y))
>             (. buffer show
>
> (defn draw [#^Canvas canvas]
>    (let [buffer (. canvas getBufferStrategy)
>          g        (. buffer getDrawGraphics)]
>          (draw-lines buffer g)))
>
> (defn main []
>
>  (let [panel (JPanel.)
>        canvas (Canvas.)
>        frame (JFrame. "Mandelbrot")]
>
>    (doto panel
>      (.setPreferredSize (Dimension. (*width*) (*height*)))
>      (.setLayout nil)
>      (.add canvas))
>
>    (doto frame
>      (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
>      (.setBounds 0,0,(*width*) (*height*))
>      (.setResizable false)
>      (.add panel)
>      (.setVisible true))
>
>    (doto canvas
>      (.setBounds 0,0,(*width*) (*height*))
>      (.setBackground (Color/BLACK))
>      (.createBufferStrategy 2)
>      (.requestFocus))
>
>    (draw canvas)))
>
> (time (main))
>
> ~$ clojure /tmp/mandelbrot.clj
> "Elapsed time: 3577.128587 msecs"
>
> Paul
--~--~-~--~~~---~--~~
You 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: speed question

2009-04-02 Thread Dmitri

like Paul said earlier changing the globals to macros makes seems to
make a huge impact.
and the check-bounds and draw-line get called for each line on the
screen so it makes sense
that optimizations there will make a big impact.

On Apr 2, 8:05 am, MikeM  wrote:
> Starting with your version, I got about a 2x improvement with the
> following:
>
> (defn check-bounds [x y]
>    (let [f2 (float 2.0)
>          f4 (float 4.0)]
>    (loop [px (float x)
>           py (float y)
>           zx (float 0.0)
>           zy (float 0.0)
>           zx2 (float 0.0)
>           zy2 (float 0.0)
>           value (float 0)]
>       (if (and (< value (*max-steps*)) (< (+ zx2 zy2) f4))
>            (let [new-zy (float (+ (* (* f2 zx) zy) py))
>                  new-zx (float (+ (- zx2 zy2) px))
>                  new-zx2 (float (* new-zx new-zx))
>                  new-zy2 (float (* new-zy new-zy))]
>                  (recur px py new-zx new-zy new-zx2 new-zy2 (inc
> value)))
>            (if (== value (*max-steps*)) 0 value)
>
> f2 and f4 didn't do much, most improvement seems to come from (* (* f2
> zx) zy) in place of (* f2 zx zy). Using the arity 2 multiply results
> in the multiply being inlined.
--~--~-~--~~~---~--~~
You 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: speed question

2009-04-02 Thread Dmitri

thanks a lot, that's really helpful.

On Apr 2, 7:25 am, Paul Stadig  wrote:
> I got it down to about 3 seconds. I did what William said, but the biggest
> improvement was from changing the way *width*, *height*, and *max-steps*
> were defined. I noticed that in the Java version they are constants, but in
> the Clojure version they are Vars which means that inside your tight inner
> loops you are dereferencing the vars multiple times. Vars are for thread
> local values, but these values are not expected to change. I'm not sure the
> best way to make these vars into constants, but I changed them into macros:
>
> (defmacro *width* [] (float 640))
>
> Then replaced instances of *width* with (*width*). The macros will get
> compiled down to floats instead of resulting in multiple Var.deref calls
> (and probably Number.floatValue calls) per loop iteration.
>
> Here is the code:
>
> (ns main
>  (:import (java.awt Color Container Graphics Canvas Dimension)
>           (javax.swing JPanel JFrame)
>           (java.awt.image BufferedImage BufferStrategy)))
>
> (set! *warn-on-reflection* true)
>
> (defmacro *width* [] (float 640))
> (defmacro *height* [] (float 640))
> (defmacro *max-steps* [] (float 32))
>
> (defn on-thread [#^Runnable f] (doto (new Thread f) (.start)))
>
> (defn check-bounds [x y]
>    (loop [px (float x)
>           py (float y)
>           zx (float 0.0)
>           zy (float 0.0)
>           zx2 (float 0.0)
>           zy2 (float 0.0)
>           value (float 0)]
>       (if (and (< value (*max-steps*)) (< (+ zx2 zy2) (float 4.0)))
>            (let [new-zy (float (+ (* (float 2.0) zx zy) py))
>                  new-zx (float (+ (- zx2 zy2) px))
>                  new-zx2 (float (* new-zx new-zx))
>                  new-zy2 (float (* new-zy new-zy))]
>                  (recur px py new-zx new-zy new-zx2 new-zy2 (inc value)))
>            (if (== value (*max-steps*)) 0 value
>
> (defn draw-line [#^Graphics g y]
>    (let [dy (- 1.25 (* 2.5 (/ y (*height*]
>      (doseq [x (range 0 (*width*))]
>        (let [dx (- (* 2.5 (/ x (*width*))) 2.0)]
>                (let [value (check-bounds dx dy)]
>                    (if (> value  0)
>                        (doto g
>                            (. setColor (Color. (* value (/ 255
> (*max-steps*)
>                            (. drawRect x y 0 0
>
> (defn draw-lines
>    ([buffer g] (draw-lines buffer g (*height*)))
>    ([#^BufferStrategy buffer g y]
>          (doseq [y (range 0 y)]
>             (draw-line g y)
>             ;(on-thread (draw-line g y))
>             (. buffer show
>
> (defn draw [#^Canvas canvas]
>    (let [buffer (. canvas getBufferStrategy)
>          g        (. buffer getDrawGraphics)]
>          (draw-lines buffer g)))
>
> (defn main []
>
>  (let [panel (JPanel.)
>        canvas (Canvas.)
>        frame (JFrame. "Mandelbrot")]
>
>    (doto panel
>      (.setPreferredSize (Dimension. (*width*) (*height*)))
>      (.setLayout nil)
>      (.add canvas))
>
>    (doto frame
>      (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
>      (.setBounds 0,0,(*width*) (*height*))
>      (.setResizable false)
>      (.add panel)
>      (.setVisible true))
>
>    (doto canvas
>      (.setBounds 0,0,(*width*) (*height*))
>      (.setBackground (Color/BLACK))
>      (.createBufferStrategy 2)
>      (.requestFocus))
>
>    (draw canvas)))
>
> (time (main))
>
> ~$ clojure /tmp/mandelbrot.clj
> "Elapsed time: 3577.128587 msecs"
>
> Paul
--~--~-~--~~~---~--~~
You 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: speed question

2009-04-01 Thread Dmitri

I'm running it as a script with:
java -server -cp clojure.jar clojure.lang.Script  mandelbrot.clj

as I mentioned earlier, I did try forcing all the primitives, but
didn't notice much of a difference, I also did try running the draw
function repeatedly to make sure it wasn't just the startup times
causing it to run slow.

(main []
...

(time (draw canvas))
(time (draw canvas))
(time (draw canvas


as a note I also tried a jython version and it runs about twice as
fast for me, which I think is comparable, and it could just mean that
there is a
hit on performance over java that only so much can be done about.

I'm mostly curious if I made any newbie mistakes that would cause it
to perform a lot worse than it should. I do expect pure java to run
faster in the end.

On Apr 1, 10:49 pm, Stuart Sierra  wrote:
> On Apr 1, 9:40 pm, Dmitri  wrote:
>
> > I've been playing around with rendering a mandelbrot set, and using
> > pure java it renders about 2 seconds on my machine, however it runs
> > about 10 times as slow in clojure, I was curious if I'm doing anything
> > obviously wrong, or if it's just life :) I do run it with the -server
> > flag, which does improve it a bit. I've got the java and clojure
> > source below:
>
> Are you running the Clojure source as a script on the command line?
> Some of the delay may be Clojure starting up and parsing the script.
>
> You should also try using primitive types in the loops.  See this
> thread for 
> details:http://groups.google.com/group/clojure/browse_thread/thread/61f236e83...
>
> -Stuart Sierra
--~--~-~--~~~---~--~~
You 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: speed question

2009-04-01 Thread Dmitri

I'm running it as a script with:
java -server -cp clojure.jar clojure.lang.Script  mandelbrot.clj

as I mentioned earlier, I did try forcing all the primitives, but
didn't notice
much of a difference, I did try running the draw method repeatedly to
make sure it wasn't just the startup times causing it to run slow.

as a note I also tried a jython version and it runs about twice as
fast for me,
which I think is comparable, and it could just mean that there is a
hit on performance
over java that only so much can be done about.

I'm mostly curious if I made any newbie mistakes that would cause it
to perform a
lot worse than it should. I do expect pure java to run faster in the
end.

On Apr 1, 10:49 pm, Stuart Sierra  wrote:
> On Apr 1, 9:40 pm, Dmitri  wrote:
>
> > I've been playing around with rendering a mandelbrot set, and using
> > pure java it renders about 2 seconds on my machine, however it runs
> > about 10 times as slow in clojure, I was curious if I'm doing anything
> > obviously wrong, or if it's just life :) I do run it with the -server
> > flag, which does improve it a bit. I've got the java and clojure
> > source below:
>
> Are you running the Clojure source as a script on the command line?
> Some of the delay may be Clojure starting up and parsing the script.
>
> You should also try using primitive types in the loops.  See this
> thread for 
> details:http://groups.google.com/group/clojure/browse_thread/thread/61f236e83...
>
> -Stuart Sierra
--~--~-~--~~~---~--~~
You 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: speed question

2009-04-01 Thread Dmitri

I actually tried forcing the type hints and didn't really see a
noticeable improvement, just made the code hard to read for the most
part.

On Apr 1, 9:57 pm, CuppoJava  wrote:
> From a quick glance, I think the lack of type hints is what's slowing
> down your Clojure code.
> You can set the global variable *warn-on-reflection* to true, to get a
> sense of where to add your type hints.
>   -Patrick
--~--~-~--~~~---~--~~
You 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
-~--~~~~--~~--~--~---



speed question

2009-04-01 Thread Dmitri

I've been playing around with rendering a mandelbrot set, and using
pure java it renders about 2 seconds on my machine, however it runs
about 10 times as slow in clojure, I was curious if I'm doing anything
obviously wrong, or if it's just life :) I do run it with the -server
flag, which does improve it a bit. I've got the java and clojure
source below:

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.ImageObserver;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Mandelbrot extends Canvas  implements ImageObserver {

public static final int WIDTH = 640;
public static final int HEIGHT = 640;
private static int BAILOUT = 4;
private static int MAX_ITERATIONS = 32;

public BufferStrategy strategy;

public Mandelbrot () {
setBounds(0,0,WIDTH,HEIGHT);
setBackground(Color.BLACK);

JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
panel.setLayout(null);

panel.add(this);

JFrame frame = new JFrame("Mandelbrot");
frame.add(panel);

frame.setBounds(0,0,WIDTH, HEIGHT);
frame.setResizable(false);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

//create a double buffer
createBufferStrategy(2);
strategy = getBufferStrategy();
requestFocus();
}

private int checkBounds(float x, float y) {
float cr = x;
float ci = y;
float zi = 0.0f;
float zr = 0.0f;
int i = 0;

while (true) {
i++;
float temp = zr * zi;
float zr2 = zr * zr;
float zi2 = zi * zi;
zr = zr2 - zi2 + cr;
zi = temp + temp + ci;
if (zi2 + zr2 > BAILOUT)
return i;
if (i > MAX_ITERATIONS)
return 0;
}
}

private void draw() {
float x = -2.1f, y = -1.5f, z = 3.0f;
int i, j;

Graphics g = strategy.getDrawGraphics();
g.clearRect(0, 0, getWidth(), getHeight());
for (i =  0; i < HEIGHT; i++) {
for (j = 0; j < WIDTH; j++) {

int value = checkBounds((x + 
z*(i/(float)WIDTH)), (y + z*(j/(float)
HEIGHT)));

if (value > 0) {
g.setColor(new 
Color(value*255/MAX_ITERATIONS));
g.drawRect(i, j, 0, 0);
}
}
strategy.show();
}
strategy.show();
}

public static void main(String args[]) {

Mandelbrot m = new Mandelbrot();
long startTime = System.currentTimeMillis();
m.draw();
System.out.println((System.currentTimeMillis() - 
startTime)/1000);
}
}

Clojure:

(ns main
  (:import (java.awt Color Container Graphics Canvas Dimension)
   (javax.swing JPanel JFrame)
   (java.awt.image BufferedImage BufferStrategy)))

(def *width* 640)
(def *height* 640)
(def *max-steps* 32)

(defn on-thread [f] (doto (new Thread f) (.start)))

(defn check-bounds [x y]
(loop [px x
   py y
   zx 0.0
   zy 0.0
   zx2 0.0
   zy2 0.0
   value 0]
   (if (and (< value *max-steps*) (< (+ zx2 zy2)
4.0))
(let [new-zy (+ (* 2.0 zx zy) py)
  new-zx (+ (- zx2 zy2) px)
  new-zx2 (* new-zx new-zx)
  new-zy2 (* new-zy new-zy)]
  (recur px py new-zx new-zy new-zx2 new-zy2 (inc
value)))
(if (== value *max-steps*) 0 value

(defn draw-line [g y]
(let [dy (- 1.25 (* 2.5 (/ y *height*)))]
  (doseq [x (range 0 *width*)]
(let [dx (- (* 2.5 (/ x *width*)) 2.0)]
(let [value (check-bounds dx dy)]
(if (> value  0)
(doto g
(. setColor (Color. (* value (/ 255 *max-
steps*
(. drawRect x y 0 0

(defn draw-lines
([buffer g] (draw-lines buffer g *height*))
([buffer g y]
  (doseq [y (range 0 y)]
 (draw-line g y)
 ;(on-thread (draw-line g y))
 (. buffer show


(defn draw [canvas]
(let [buffer (. canvas getBufferStrategy)
  g(. buffer getDrawGra

is there a replace-at function

2009-01-25 Thread Dmitri

I ran into a situation where I needed to replace an element in a
collection at a specific position, I ended up writing the following:

(defn replace-at [coll pos value]
  "replaces an element in collection at pos with the value"
  (let [parts (split-at pos coll)]
(concat (first parts) (cons value (rest (second parts))

I was wondering if there's a standard function to do this
--~--~-~--~~~---~--~~
You 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: sort behavior question

2009-01-08 Thread Dmitri

I think the main issue is that sort should behave consistently.
Possibly sort could check if the elements implement Comparable before
attempting to sort them? I also don't see a reason as to why the lists
shouldn't implement Comparable.


On Jan 8, 4:17 pm, "Mark Engelberg"  wrote:
> Lists are not comparable (i.e., you can't do something like (< '(1 2
> 3) '(4 5 6))).  So you can't sort a collection of lists, but you can
> sort a collection of vectors (provided the vectors contain comparable
> things).  This is always the case; there is no inconsistency.
>
> The reason you are sometimes not getting an error is that when you
> randomly generate small collections of vectors, often the first
> element will be enough to sort the collection, so it never tries to
> compare the second elements, which in this case are lists.
>
> I'm not sure why lists don't implement comparable.  Offhand I can't
> think of a reason why they wouldn't, but perhaps there is a reason.
--~--~-~--~~~---~--~~
You 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: sort behavior question

2009-01-08 Thread Dmitri

I tried this again with the latest build from svn, and it seems that
lists may be running into a race condition due to their lazy nature:

Exception in thread "main" java.lang.RuntimeException:
java.lang.ClassCastException: clojure.lang.LazyCons cannot be cast to
java.lang.Comparable

On Jan 8, 2:11 pm, "Stephen C. Gilardi"  wrote:
> On Jan 8, 2009, at 1:55 PM, Dmitri wrote:
>
> > There are two issues here that I'm seeing, first is that the list and
> > vector have different behavior, my understanding is that they are both
> > sequences and one should be able to perform the same operations on
> > them.
>
> I don't know more about the underlying issue, but there's a  
> distinction between *being* a seq and being "seq-able".
>
> Something is a seq if it implements the ISeq interface. Lists are  
> seqs, vectors are not seqs.
>
>         user=> (instance? clojure.lang.ISeq '(1 2 3))
>         true
>         user=> (instance? clojure.lang.ISeq '[1 2 3])
>         false
>
> Something is seq-able if one can create a seq through which its  
> contents can be viewed sequentially by calling calling "seq" on it.  
> Lists and vectors are both seq-able.
>
>         user=> (instance? clojure.lang.ISeq (seq '(1 2 3)))
>         true
>         user=> (instance? clojure.lang.ISeq (seq '[1 2 3]))
>         true
>
> The distinction is often blurred because most functions that accept a  
> seq automatically call "seq" on the subset of their arguments that  
> they expect to use as seqs.
>
> You may have hit on a situation where the distinction matters.
>
> --Steve
>
>  smime.p7s
> 3KViewDownload
--~--~-~--~~~---~--~~
You 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: sort behavior question

2009-01-08 Thread Dmitri

There are two issues here that I'm seeing, first is that the list and
vector have different behavior, my understanding is that they are both
sequences and one should be able to perform the same operations on
them.

Second issue is that the behavior is inconsistent, if it is not
possible to sort tuples with a list as a second element, then it
should never work, as opposed to working sometimes on some data sets.
The inconsistency of the behavior is troubling.

On Jan 7, 11:47 pm, ".Bill Smith"  wrote:
> I wonder if the root cause might be clearer if you were to review the
> documentation for the sort function and then apply what it says to a
> smaller dataset, e.g. a pair of lists.
>
> Bill
--~--~-~--~~~---~--~~
You 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
-~--~~~~--~~--~--~---



sort behavior question

2009-01-07 Thread Dmitri

I noticed strange behavior in the sort function, I was sorting key
value tuples and ran into the following:

when sorting 2 item vectors such as [1 [1 2 3]] sort works fine:
(println
(sort
(map
   (fn [x] [(int (* (Math/random) 10)) x]) (for [x (range 4)]
[1 2 3]

output:
([6 [1 2 3]] [6 [1 2 3]] [6 [1 2 3]] [6 [1 2 3]])

however, if the second item is a list, e.g:
(println
(sort
(map
   (fn [x] [(int (* (Math/random) 10)) x]) (for [x (range
100)] `(1 2 3)

the following exception can occur, this happens more frequently for
larger ranges, for range of 4, it may or may run and produce the
result, however with a range of 100 the exception occurs consistently:

Exception in thread "main" java.lang.RuntimeException:
java.lang.ClassCastException: clojure.lang.LazyCons (gen.clj:60)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:2684)
at clojure.lang.Compiler.compile(Compiler.java:4564)
at clojure.lang.RT.compile(RT.java:362)
at clojure.lang.RT.load(RT.java:404)
at clojure.lang.RT.load(RT.java:376)




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



Re: performance question

2008-12-13 Thread Dmitri

thanks for pointing this out, and I absolutely appreciate the example.
I'm still new to functional approach and I always like to see how
things are done properly.

On Dec 13, 1:15 pm, Chouser  wrote:
> On Sat, Dec 13, 2008 at 10:41 AM, Dmitri  wrote:
>
> > I wrote a simple word counter described herehttp://ptrace.fefe.de/wp/
> > it reads stdin and counts the occurrences of words, however I notice
> > that it runs significantly slower than the java version in the link.
>
> There are several differences that could be factors.  For example, the
> Java version uses StreamTokenizer, while your Clojure version uses
> String.split with a regex that gets recompiled for each line read.
>
> > I've also noticed that there is a significant speed difference between
> > conj and assoc, why is that?
> > If I understand correctly both should only create the delta of the new
> > elements and the old structure, however  assoc appears to perform much
> > better.
>
> user=> (let [c 100 p [1 1]] (time (reduce #(conj % [%2 %2]) {}
> (range c))) (time (reduce #(assoc % %2 %2) {} (range c))) nil)
> "Elapsed time: 1544.180472 msecs"
> "Elapsed time: 1894.318809 msecs"
> nil
> user=> (let [c 100 p [1 1]] (time (reduce #(conj % [%2 %2]) {}
> (range c))) (time (reduce #(assoc % %2 %2) {} (range c))) nil)
> "Elapsed time: 1549.159812 msecs"
> "Elapsed time: 1594.18912 msecs"
>
> That's a million items added to a hash-map each way in about 1.5
> seconds -- not too shabby.  And the speeds for conj vs. assoc seem
> very close, though I'm actually seeing a slight advantage for conj.
>
> And I'm sorry for what follows -- it's like a compulsion for me, and I
> hope it doesn't put you off.  Each of these functions takes the same
> input and produces the same output as your original code, but each is
> implemented a bit more succinctly:
>
> (import '(java.io BufferedReader InputStreamReader))
>
> (defn inc-count [words word]
>   (if (seq word)
>     (assoc words word (inc (words word 0)))
>     words))
>
> (defn sort-words [words]
>  (reverse (sort (map (fn [[k v]] [v k]) words
>
> (defn print-words [words]
>   (doseq [head words]
>     (println head)))
>
> (defn read-words [words line]
>   (reduce inc-count words line))
>
> (defn read-input []
>   (with-open [buf (BufferedReader. (InputStreamReader. System/in))]
>     (let [words (for [line (line-seq buf)] (.split line " "))]
>       (print-words (sort-words (reduce read-words {} words))
>
> (time (read-input))
>
> --Chouser
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: performance question

2008-12-13 Thread Dmitri

To give an example, I tried running through the Iliad from project
gutenberg, it's roughly 1MB of text http://www.gutenberg.org/files/6130/6130.txt

and the program takes ~4600 ms to run, if I comment out printing of
results it runs in ~3700 ms.
By contrast a java version runs in ~560ms.

Now, obviously I could just use the mutable java hash map, but I'm
curious if there's a functional approach which would be efficient.

On Dec 13, 12:38 pm, Jeremy Dunck  wrote:
> On Dec 13, 9:41 am, Dmitri  wrote:
> ...
>
> > The slowdown seems to occur in the inc-count
> > function, where it "updates" the map using the assoc. Is this not a
> > proper way to approach this in clojure?
>
>             (recur (time (inc-count words head)) tail
>
> You're pretty tightly looping here-- are you sure the overhead isn't
> in this extra (time) call rather than (inc-count) itself?
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to 
clojure+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: performance question

2008-12-13 Thread Dmitri

I added the time call later on to find what was taking up the cycles,
I also checked the reverse, it's impact is minimal, the print-words
part of the program runs fast, but the read-words takes the majority
of the time.

On Dec 13, 12:38 pm, Jeremy Dunck  wrote:
> On Dec 13, 9:41 am, Dmitri  wrote:
> ...
>
> > The slowdown seems to occur in the inc-count
> > function, where it "updates" the map using the assoc. Is this not a
> > proper way to approach this in clojure?
>
>             (recur (time (inc-count words head)) tail
>
> You're pretty tightly looping here-- are you sure the overhead isn't
> in this extra (time) call rather than (inc-count) itself?
--~--~-~--~~~---~--~~
You 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
-~--~~~~--~~--~--~---



performance question

2008-12-13 Thread Dmitri

I wrote a simple word counter described here http://ptrace.fefe.de/wp/
it reads stdin and counts the occurrences of words, however I notice
that it runs significantly slower than the java version in the link.

I was wondering why there is such a dramatic difference. The approach
I took was to create a map keyed on words and use the occurrence count
as the value. When each line is read from input it's tokenized and the
word counts are updated. The slowdown seems to occur in the inc-count
function, where it "updates" the map using the assoc. Is this not a
proper way to approach this in clojure?

I've also noticed that there is a significant speed difference between
conj and assoc, why is that?
If I understand correctly both should only create the delta of the new
elements and the old structure, however  assoc appears to perform much
better.

(import '(java.io BufferedReader InputStreamReader))

(defn inc-count [words word]
  (if (= (. word (length)) 0)
words
(let [cnt (get words word)]
(if cnt (assoc words word (inc cnt))
(assoc words word 1)

(defn sort-words [words]
  (reverse (sort-by (fn [x] (first x))
 (map (fn [x] [(get words x) x])
 (keys words)

(defn print-words [words]
(let [head (first words) tail (rest words)]
  (if head
(do
(println head)
(recur tail)

(defn read-words [words line]
  (let [head (first line) tail (rest line)]
  (if (nil? tail) words
(recur (time (inc-count words head)) tail

(defn read-input []
(with-open [stream (System/in)]
(let [buf (BufferedReader. (InputStreamReader. stream))]
  (loop [line (. buf (readLine)) words {}]
(if (nil? line)
  (print-words (sort-words words))
  (recur (. buf (readLine)) (read-words words (. line (split "
")

(time (read-input))
--~--~-~--~~~---~--~~
You 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: infix operators

2008-11-30 Thread Dmitri

I agree that the consistency that the s-expressions provide is
valuable, and hence it would be counter productive to allow different
kinds of syntax. However, it makes sense to have an explicit way to do
infix notation. As Johan points out above, Haskell has a very elegant
way of infixing functions eg:

div a b
can be written as
a `div` b

And it seems that using a macro which accepts arguments in infix
notation would allow the code to be more expressive and readable. The
formula example Jeff provides is quite readable without requiring any
additional language features.

A general version which does not check operator precedence would
provide a way to use infix notation to make the code more readable.


On Nov 30, 10:20 am, Randall R Schulz <[EMAIL PROTECTED]> wrote:
> On Sunday 30 November 2008 07:06, Daniel Renfer wrote:
>
> > Since it's pretty much the topic, has anyone ever seen this:
>
> >http://www.dwheeler.com/readable/
>
> One thing I'll say is that I can't see myself _ever_ getting behind a
> notation where white-space is significant. The so-called "semicolon
> inference" in Groovy bugs me endlessly (in real-life programming, not
> just 'cause I'm aware it's there). And there have been complaints about
> the Scala counterpart on its mailing lists. Wasn't FORTRAN lesson
> enough about the mistake of giving syntactic significance to blanks
> beyond being simple token separators?
>
> Frankly, I don't see the problem with S-Expressions as we've known them
> for so long. I think they're beautiful. All non-trivial programs are
> complex and require tool support for their creation and even more for
> later comprehension. Once you accept that, then you realize that a
> uniform notation like the S-Expression is just something that requires
> support from the authoring and analysis tools.
>
> Randall Schulz
--~--~-~--~~~---~--~~
You 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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: infix operators

2008-11-30 Thread Dmitri

Thanks for the example, the macro is exactly the solution was looking
for.

On Nov 30, 1:11 am, Jeff Bester <[EMAIL PROTECTED]> wrote:
> On Nov 28, 11:11 pm, Dmitri <[EMAIL PROTECTED]> wrote:
>
> > Thanks for the comments, the prefix notation may indeed be something
> > that one gets used to. I find it just fine for most cases, just not
> > for mathematical expressions. The example function was not meant as a
> > complete solution, but rather as an example of how trivial it is to
> > switch between the two notations. I do see how the formatting makes it
> > more readable, thanks for pointing that out. It does sound that it's
> > largely a matter of what you're used to.
>
> If you are translating formulas it might be worth investing the time
> to
> create a macro to convert from infix to prefix with precedence rules,
> as
> well as, creating new operators.  I think Peter Norvig covers
> something
> akin to this in PAIP.  This is where any lisp truly shines; that is
> using
> macros to express Domain Specific Languages.  That is at compile/load
> time
>  morph the code to allow new syntax in the language.
>
> See the following for an example implementation
>
> user> (formula (3 + 4 * 2) / 3)
> 11/3
>
> = Example code 
>
> ;; used for order of evaluation table and for valid infix operators
> (def +precedence+
>      {'rem 5,
>       '* 4,
>       '/ 3,
>       '+ 2,
>       '- 1})
>
> ;; highest level of precedence
> (def +highest-precedence+ (apply max (map val +precedence+)))
>
> (defn- operator?
>   "Check if is valid operator"
>   ([sym]
>      (not (nil? (get +precedence+ sym)
>
> (defn- find-lowest-precedence
>   "find the operator with lowest precedence; search from left to
> right"
>   ([seq]
>      ;; loop through terms in the sequence
>      (loop [idx 0
>             seq seq
>             lowest-idx nil
>             lowest-prec +highest-precedence+]
>        ;; nothing left to process
>        (if (empty? seq)
>          ;; return lowest found
>          lowest-idx
>          ;; otherwise check if current term is lower
>          (let [prec (get +precedence+ (first seq))]
>            ;; is of lower or equal precedence
>            (if (and prec (<= prec lowest-prec))
>              (recur (inc idx) (rest seq)
>                     idx prec)
>              ;; is of high precedence therefore skip for now
>              (recur (inc idx) (rest seq)
>                     lowest-idx lowest-prec)))
>
> (defn- infix-to-prefix
>   "Convert from infix notation to prefix notation"
>   ([seq]
>      (cond
>       ;; handle term only
>       (not (seq? seq)) seq
>       ;; handle sequence containing one term (i.e. handle parens)
>       (= (count seq) 1) (infix-to-prefix (first seq))
>       ;; handle all other cases
>       true (let [lowest (find-lowest-precedence seq)]
>              (if (nil? lowest) ;; nothing to split
>                seq
>                ;; (a b c) bind a to hd, c to tl, and b to op
>                (let [[hd tl] (split-at lowest seq)
>                      op (first tl)
>                      tl (rest tl)]
>                  ;; recurse
>                  (list op (infix-to-prefix hd) (infix-to-prefix tl
>
> (defmacro formula
>   "Formula macro translates from infix to prefix"
>   ([& equation]
>      (infix-to-prefix equation))
--~--~-~--~~~---~--~~
You 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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: infix operators

2008-11-28 Thread Dmitri

Thanks for the comments, the prefix notation may indeed be something
that one gets used to. I find it just fine for most cases, just not
for mathematical expressions. The example function was not meant as a
complete solution, but rather as an example of how trivial it is to
switch between the two notations. I do see how the formatting makes it
more readable, thanks for pointing that out. It does sound that it's
largely a matter of what you're used to.


--~--~-~--~~~---~--~~
You 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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



infix operators

2008-11-28 Thread Dmitri

First of I'd like to say that I find Clojure to be an excellent
language, however I find the lack of infix operators makes reading
equations somewhat unnatural, eg:

(+ (- (* x x) (* y y)) a)

I ended up writing a simple function to handle infix notation

(defn infix [arg1 func arg2 & args]
(let [result (func arg1 arg2)]
(if (= args nil) result (recur result (first args) (second
args) (rrest args)

using that I find makes the code more readable:

(infix (infix x * x) - (infix y * y) + a)

I was wondering if there is a more elegant way to do this, and if it
could be added as a standard or contrib 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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Clojure, Emacs and Slime on Windows

2008-11-11 Thread Dmitri P

Does your clojure.bat start from command line without errors?


On Nov 11, 10:21 am, "Kyle R. Burton" <[EMAIL PROTECTED]> wrote:
> I've followed the straightforward instructions that BC put together:
>
>  http://bc.tech.coop/blog/081023.html
>
> It worked flawlessly under Linux.  I have lispbox installed on a
> windows machine and have been trying to get it to work on that
> platform as well.  Emacs + slime + clisp does work.
>
> I created a clojure.bat
>
> --
> @set CLOJURE_JAR=c:\Documents and
> Settings\kburton\personal\projects\clojure-svn\clojure\trunk\clojure.jar
> @set CONTRIB_JAR=c:\Documents and
> Settings\kburton\personal\projects\clojure-svn\clojure-contrib\trunk\clojure-contrib.jar
> @set CLASSPATH=%CLOJURE_JAR%;%CONTRIB_JAR%;.
> @java -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=
> -server -cp "%CLASSPATH%" clojure.lang.Repl %*
> --
>
> and put it into C:\WINDOWS so it was on the PATH.  I then updated my
> dot emacs file:
>
> --
> (add-to-list 'load-path "C:\\Documents and
> Settings\\kburton\\personal\\projects\\clojure-svn\\clojure-mode")
> (add-to-list 'load-path "C:\\Documents and
> Settings\\kburton\\personal\\projects\\clojure-svn\\swank-clojure")
> (setq swank-clojure-binary "C:\\WINDOWS\\clojure.bat")
> ; (file-exists-p "C:\\WINDOWS\\clojure.bat")
> ; (setq swank-clojure-binary "C:\\Documents and
> Settings\\kburton\\bin\\clojure")
>
> (require 'clojure-auto)
> (require 'swank-clojure-autoload)
> --
>
> Running M-- M-slime clojure^M executes the batch file, so things are
> close, but I get the following in the *inferior-lisp* buffer:
>
> --
> (clojure/add-classpath "file:///c:/Documents and
> Settings/kburton/personal/projects/clojure-svn/swank-clojure/")
>
> (clojure/require (quote swank))
>
> nil
>
> (swank/start-server "c:/DOCUME~1/kburton/LOCALS~1/Temp/slime.15196"
> :encoding "iso-latin-1-unix")
>
> Listening for transport dt_socket at address: 
> Clojure
> user=> java.lang.Exception: No such namespace: clojure (NO_SOURCE_FILE:1)
> user=> java.lang.Exception: No such namespace: clojure (NO_SOURCE_FILE:3)
> user=> nil
> user=> java.lang.Exception: No such namespace: swank (NO_SOURCE_FILE:7)
> user=>
> user=> (resolve 'map)
> #'clojure.core/map
> user=>
> --
>
> Resolve finds a standard name, but it finds it in clojure.core.  I'm
> not sure what to try next, this implies to me that the Repl is active,
> but somehow didn't get bootstrapped?
>
> Any help, advice, questions or suggestions are appreciated.
>
> Regards,
>
> Kyle R. Burton
>
> --
> --
> Wisdom and Compassion are inseparable.
> -- Christmas Humphreys
> [EMAIL PROTECTED]http://asymmetrical-view.com/
> --
--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To post to this group, send email to clojure@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: What Windows IDE are you using?

2008-10-15 Thread Dmitri P

I followed Hans's instructions and was able to use compojure's repl
script as swank-clojure-binary. Also, I don't use jline on windows
because cmd provides sufficient editing facilities. I found that swing
JFrame displayed through setVisible hangs slime, it probably needs a
thread wrapper.


On Oct 13, 2:33 am, "Hans Huebner" <[EMAIL PROTECTED]> wrote:
> On Sat, Oct 11, 2008 at 20:34, CuppoJava <[EMAIL PROTECTED]> wrote:
> > If anyone is using Windows, please share what environment you're using
> > to program in.
>
> I am using Emacs and Slime, and that works rather well.
>
> Emacs for Windows:http://ourcomments.org/cgi-bin/emacsw32-dl-latest.pl
> Slime:http://common-lisp.net/project/slime/
> Emacs Clojure mode and Slime for Clojure:http://clojure.codestuffs.com/
>
> My .emacs contains the following Clojure specific Slime setup code.
> The paths need to be modified, and I use swank-clojure-binary instead
> of the Jar method that is described as first choice in the
> swank-clojure documentation.
>
> ;; clojure
> (add-to-list 'load-path "h:/clojure/clojure-mode")
>
> (require 'clojure-auto)
> (load-library "clojure-mode")
>
> (add-to-list 'load-path "h:/clojure/swank-clojure")
> (setq swank-clojure-binary "h:/clojure/clojure.sh")
> (require 'swank-clojure-autoload)
>
> Hope this helps,
> Hans
--~--~-~--~~~---~--~~
You 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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



"if" small syntax change proposal

2008-10-09 Thread Dmitri P

Allow cond-like specification of expression pairs and allow odd number
of expressions. Let odd expressions in last position serve as default
return value. There will be no impact on previous reading/writing of
"if". Stolen from Paul Graham's Arc.

(defmacro myif
([x] x)
([x y] (if x y))
([x y & z] (if x y `(myif [EMAIL PROTECTED]

--~--~-~--~~~---~--~~
You 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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Clojure Poll 09/2008

2008-09-12 Thread Dmitri P

Doing: learning, deciding whether clojure is appropriate for my
company projects

Would like:
1) up to date documentation. Online docs are so far behind SVN it's
not funny. Yes yes, SVN is not release, but in the beginning stages of
the project as it is things happen very fast and sticking with release
is shooting yourself in the foot.

2) more examples in online docs, especially where there are no
examples at all.

3) more syntax tricks, like defining partials with arbitrary argument
positions.

Otherwise, clojure is already good, because it's lispy, does macros
and talks with java.


On Sep 10, 2:40 pm, Rich Hickey <[EMAIL PROTECTED]> wrote:
> As we rapidly approach 500 members on the group (!) I thought it would
> be a good time to conduct another poll:
>
> What are you doing with Clojure?
>
> What 3 features would you most like to see added next?
>
> Thanks,
>
> Rich

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



Re: Bug: self require -> stack overflow

2008-09-09 Thread Dmitri P

Whatever you do, don't kill Clojure while trying to save us from
ourselves.

--~--~-~--~~~---~--~~
You 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 [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---