Re: Curious behaviour when requiring clojure.tools.cli

2021-06-14 Thread Thomas Heller
clojure.string/starts-with? was added in Clojure 1.8.0, I see 1.7.0 in the 
project.clj?

See 
https://github.com/clojure/clojure/blob/b1b88dd25373a86e41310a525a21b497799dbbf2/src/clj/clojure/string.clj#L362

What exactly else is going on I don't know but it all starts from the wrong 
Clojure version.

HTH

On Monday, June 14, 2021 at 2:21:04 PM UTC+2 Simon Brooke wrote:

>
> I've discovered a weird behaviour which I don't understand and can't seem 
> to fix - it's probably some obvious mistake of my own.
>
> Brief background, I'm trying to integrate cloverage with codox, so that I 
> can show test coverage reports on my documentation pages. Both of these are 
> established, solid, well written packages by respected members of the 
> community.
>
> Cloverage (1.3.0-SNAPSHOT) depends on clojure.tools.cli version 0.4.2. 
> When you start a repl within the cloverage/cloverage directory and attempt 
> to use clojure.tools.cli, no problem:
>
> cloverage.coverage=> (use 'clojure.tools.cli)
> nil
>
> Codox 0.10.7 does not depend on clojure.tools.cli, but my mildly modified 
> version of codox does depend on cloverage 1.3.0-SNAPSHOT (that is literally 
> the only change to the codox project.clj). When you start a repl within the 
> codox/codox directory, and attempt to use clojure.tools.cli, you get:
>
> user=> (use 'clojure.tools.cli)
> CompilerException java.lang.RuntimeException: No such var: 
> s/starts-with?, compiling:(clojure/tools/cli.cljc:97:8) 
>
> OK, so, it's picking up clojure.tools.cli at all presumably via the 
> dependency on cloverage, which is good. but clojure.tools.cli requires 
> clojure.string as `s`, see
>
> https://github.com/clojure/tools.cli/blob/master/src/main/clojure/clojure/tools/cli.cljc#L12
>  
> so you would have thought this would all work fine.
>
> So what happens if I require clojure.string as `s` in the repl? Well, I 
> get a different error:
>
> user=> (require '[clojure.string :as s])
> nil
> user=> (use 'clojure.tools.cli)
> CompilerException java.lang.Exception: namespace 'clojure.tools.cli' 
> not found, compiling:(/tmp/form-init1843820122884430414.clj:1:1) 
>
> So, can anyone explain what is going on here, and how I fix it? it matters 
> to me, because it prevents my code from compiling:
>
> user=> (use 'codox.cloverage-integration.runner :reload)
> CompilerException java.lang.RuntimeException: No such var: 
> s/starts-with?, compiling:(clojure/tools/cli.cljc:97:8) 
>
> In case anyone's interested, my current diff with respect to weavejester's 
> current codox is here: 
> https://github.com/simon-brooke/codox/commit/ef4ba70659c768f1aab4bfbf32efdaa48e9c43a8
>
> Thanks in advance for any help or thoughts!
>
>
>

-- 
You 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/67ca8def-3a52-4126-a969-b92577942c53n%40googlegroups.com.


Re: Classpath bug re Clojure 1.10.1.645 when using Figwheel.Main

2020-08-12 Thread Thomas Heller

>
> None of these libraries are broken. They just include resources. Also, I 
> don't think it is realistic to tell library authors to please move certain 
> files out of the way because my build tool randomizes my classpath. That is 
> not going to happen. People will keep including things like 
> log4j.properties that are in potential conflict with a local file or files 
> in other JAR paths.
>

These packages should be cleaned up. They contain files they shouldn't 
contain. It mostly goes unnoticed and library authors often aren't even 
aware this is happening. I have reported this to a couple CLJS libraries 
over the years and all of them were fixed pretty much immediately, since it 
was always accidental. The burden is probably on the community to make 
people aware of this. Heck I'd even say all tools used for building library 
.jar files should even complain about certain files from the outset. While 
it is mostly harmless and usually goes unnoticed it is also a potential 
security risk. I don't know anyone that audits their dependencies properly 
and often people just serve "public" resources straight over HTTP. That 
means any dependency you don't audit may contain 
"public/some-exploit/foo.html" which then is often automatically available 
under "https://your-domain.com/some-exploit/foo.html;. Probably not 
something you want to have on your domain.

Regardless :paths should be first, just because of the options it enables I 
outlined earlier. IMHO dependencies otherwise can stay unordered since 
everything should be namespaced properly and unique anyways so order 
shouldn't matter.

-- 
You 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/16ea6172-1d5c-4ac5-976c-3e5223aeee66o%40googlegroups.com.


Re: Classpath bug re Clojure 1.10.1.645 when using Figwheel.Main

2020-08-11 Thread Thomas Heller
This might be a good incentive for people to keep their published .jar 
files clean. Unfortunately many published CLJS libs contain the rather 
common "public" folder with "public/index.html" and often compiled .js 
artifacts which aren't actually ever used.

I do however think that it is useful to always have :paths first since it 
provides and easy way to "patch" libraries. You can just easily replace one 
namespace from a library and provide custom implementations without going 
through the entire forking process. This is used by many CLJS users as well 
since on older reagent versions it was required to stub out the reagent.dom 
[1] namepace in react-native builds. None of this is very pretty but having 
:paths first (just like lein :source-paths) at least gives you the option 
of doing this when the alternatives may be much more work.

[1] 
https://github.com/thheller/reagent-react-native/blob/master/src/main/reagent/dom.cljs

On Tuesday, August 11, 2020 at 6:08:00 AM UTC+2, Alex Miller wrote:
>
> Bunch of things here...
>
> Clojure maintains its own brew tap and a "stable" release that you can 
> obtain with `brew install clojure/tools/clojure` (the brew conventions 
> automatically find the prior repo based on that). That tap also includes 
> prerelease unstable versions that can be obtained with "@version" - more on 
> that is doc'ed in the readme for that repo. The current stable version is 
> 1.10.1.561.
>
> Homebrew core is what you are pulling from if you just do `brew install 
> clojure`. The formula there is no longer maintained by the Clojure team as 
> anyone can update it (and have, with changes we did not agree with). There 
> is no "ownership" model in homebrew-core. I would happily remove it from 
> there but they said they would not accept that PR. Recently, the 
> homebrew-core formula has been updated by members of the homebrew team to 
> newer prerelease (not yet stable) versions of clj. There is not really 
> anything we can do about this.
>
> The classpath difference is interesting. The classpath is a set of path 
> roots and in general the files in these paths should be mutually exclusive. 
> If the roots are mutually exclusive, then the classpath order is 
> unimportant (as the JVM will always find the same class/clj/resource file 
> regardless). Roots that include the same file are nearly always trouble and 
> the source of "jar hell" style problems. clj and deps.edn provide features 
> to cover most of the scenarios where users are typically tempted to use 
> ordering for replacement (:override-deps, :classpath-overrides, etc).
>
> Based on this, we did knowingly make a change since the last stable 
> release that effectively made the classpath unordered (all the roots go 
> through keys of a map at one point). To date, I had not seen any issues 
> with that, so this is a useful data point we can take into consideration. I 
> assume you're getting an index.html out of some library that's either 
> unimportant or accidentally included. For now, I'd recommend that you 
> continue using the latest stable version from the official Clojure homebrew 
> tap.
>
> Re the version - you can see the version with either `clj -h` (first line) 
> or `clj -Sdescribe`. 
>
> Relevant links:
>
> * Clojure homebrew tap - https://github.com/clojure/homebrew-tools
> * Official clj stable formula - 
> https://github.com/clojure/homebrew-tools/blob/master/Formula/clojure.rb 
> (what you get with `brew install clojure/tools/clojure`)
> * Getting started/install doc - https://clojure.org/guides/getting_started
> * Homebrew core - https://github.com/Homebrew/homebrew-core
> * clj reference - https://clojure.org/reference/deps_and_cli (or see `clj 
> -h` or `man clj`)
>
>
> On Monday, August 10, 2020 at 7:04:40 PM UTC-5 cloo...@gmail.com wrote:
>
>> P.S.  There seems to be no *`clojure --version`* flag.  Should this be 
>> added to the command line tool?
>>
>>
>> On Mon, Aug 10, 2020 at 4:58 PM Alan Thompson  wrote:
>>
>>> Hi.  Just helped a colleague debug a vexing problem on a CLJS project 
>>> using Figwheel.Main.
>>>
>>> If we do *`brew install clojure/tools/clojure`*, it works:
>>>
>>> ~/work/tmp810/xanadu > clj --help
>>> Version: *1.10.1.561*
>>>
>>> Usage: clojure [dep-opt*] [--] [init-opt*] [main-opt] [arg*]
>>>clj [dep-opt*] [--] [init-opt*] [main-opt] [arg*]
>>>
>>> The clojure script is a runner for Clojure. clj is a wrapper
>>> for interactive repl use. These scripts ultimately construct and
>>> 
>>>
>>>
>>> Note that local ./resources etc are at the beginning of the classpath
>>>
>>> ~/work/tmp810/xanadu > clj -Spath
>>> *resources:target:src/clj:src/cljc:src/cljs:test/cljs:test-figwheel-main*
>>> 

[JOB] Clojure Developer | Presien | Sydney

2019-10-17 Thread Thomas Sesselmann
Hi Everyone,

We're hiring a Clojure developer for our AI startup based in Sydney. We're 
using object detection and machine learning to improve worker safety on 
construction sites and we need a hand building out our Dashboard and 
Analytics platform which is forked from Metabase 
.

Join our growing team of developers, researchers and engineers in a fun and 
casual startup environment and work on a project that is already making a 
difference on real work sites to save lives all across Australia.

Other desirable skills: React, Docker, PostgreSQL, AWS

Salary is negotiable.

Get in touch at tom.sesselm...@presien.com

Cheers,

Tom Sesselmann

-- 
You 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/dc99b56a-25d7-4bb6-84bf-42d88d0267ca%40googlegroups.com.


Re: Custom test assertions in ClojureScript

2019-09-29 Thread Thomas Heller
Self-hosted should work the same way but it does require compiling the 
macro namespace in an extra step (ie. the $macros ns is created 
separately). I don't know how this is done for regular self-hosted. 
shadow-cljs has an extra build step for this that should take care of 
creating everything.

-- 
You 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/4c3edc2b-fb40-494c-a1e9-4ec071af722c%40googlegroups.com.


Re: Custom test assertions in ClojureScript

2019-09-28 Thread Thomas Heller
Hey,

cljs.test/assert-expr is part of the CLJ macro side so it can't be extended 
from a CLJS REPL. You can write it in a .clj file and use (require-macros 
'that.ns) from the CLJS REPL or use :require-macros in the ns form that 
uses the new assert-expr.

HTH,
Thomas

On Thursday, September 26, 2019 at 9:43:19 PM UTC+2, jvshahid wrote:
>
> Hi all, 
>
> I am trying to implement custom assertions in ClojureScript.  I tried to 
> use defmethod but got the following error: 
>
> > clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version 
> "1.10.520"}}}' -m cljs.main --repl --repl-env node 
> > cljs.user=> (require '[cljs.test]) 
> > nil 
> > cljs.user=> (defmethod cljs.test/assert-expr 'foo [& arg]) 
> > WARNING: Use of undeclared Var cljs.test/assert-expr at line 1  repl> 
> > Execution error (Error) at (:1). 
> > No protocol method IMultiFn.-add-method defined for type undefined: 
> > 
> > cljs.user=> cljs.test/assert-expr 
> > WARNING: Use of undeclared Var cljs.test/assert-expr at line 1  repl> 
> > nil 
>
> What am I doing wrong? 
>
> Thanks, 
>
> JS 
>

-- 
You 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/69293a74-493f-4cf4-b7f9-e0dfc1050b2f%40googlegroups.com.


Re: [ANN] seancorfield/next.jdbc 1.0.0

2019-06-13 Thread Thomas
Thank you for all the hard work you put into this Sean!!! Great to see new 
libraries being written for Clojure!!!

Thomas

On Thursday, 13 June 2019 07:51:56 UTC+2, Sean Corfield wrote:
>
> The first “gold” release of the next generation of clojure.java.jdbc – a 
> new low-level Clojure wrapper for JDBC-based access to databases!
>
>  
>
> https://github.com/seancorfield/next-jdbc
>
>  
>
> Compared to the release candidate, this contains just a couple of 
> usability additions. The API has been stable since Beta 1 and only 
> accretive/fixative changes will be made. Read more about the release: 
> https://clojureverse.org/t/next-jdbc-1-0-0-the-gold-release/4379
>
>  
>
> Official documentation on the excellent cljdoc.org: 
> https://cljdoc.org/d/seancorfield/next.jdbc
>
>  
>
> A longer blog post about the library’s journey to 1.0.0 will come at some 
> point. We are using next.jdbc in production at World Singles Networks (of 
> course!) so I hope you will feel comfortable doing the same!
>
>  
>
> Sean Corfield -- (904) 302-SEAN
> An Architect's View -- http://corfield.org/
>
> "If you're not annoying somebody, you're not really alive."
> -- Margaret Atwood
>
>  
>

-- 
You 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/a58c0314-d300-4309-a533-cbaadc7bcdc2%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Blocking behavior of >!! ?

2019-05-20 Thread Thomas Heller
The (go (!! c 42) will 
use that pending take and immediately fulfill it without checking the 
buffer (there is none).

I really can't explain this very well so I'd recommend watching some of the 
talks on core.async instead. All the topics are covered

- https://vimeo.com/100518968
- https://www.youtube.com/watch?v=enwIIGzhahw
- https://www.youtube.com/watch?v=096pIlA3GDo

On Monday, May 20, 2019 at 3:18:17 PM UTC+2, Brian Beckman wrote:
>
> Thanks, Thomas. I shouldn't have included the quoted code about ( my question because it distracts from what I really want to know, and what 
> I want to know is all about how (go ( so that (>!! c 42) doesn't block. 
>
> The following is an attempt to clarify my question. I first (go ( and give the name d to the result, which is a channel that I am going 
> read-from later. Channel d is "connected to" or "relayed from" c. I then 
> (>!! c 42), and then ( works. I wasted your attention by writing some code that would block ( c) if it weren't quoted.
>
> Here is the part I don't understand: the documentation says that (>!! c 
> 42) will block "if there is no buffer space available," and the 
> documentation does not specify any other conditions. Well, I created c with 
> no buffer space, so, (>!! c 42) must block unless something else "makes 
> buffer space available," assuming the documentation is correct. The only 
> other interaction with c that could possibly be alive at the time when I do 
> (>!! c 42), is (go ( available," assuming the documentation is correct. My understanding of ( c) (and I am suspicious of my understanding), is that ( rendezvous available, not a buffer. If that understanding is correct, then 
> (>!! c 42) should block because there is no buffer available. 
>
> On Sunday, May 19, 2019 at 1:48:16 PM UTC-7, Thomas Heller wrote:
>>
>> (> by the first go (running in a different thread). So it is blocking until 
>> something puts another value into c. Since nothing ever does your program 
>> hangs.
>>
>> If it helps you can read "go" as "please run this somewhere else, 
>> possibly at a different time" and let the current thread continue after the 
>> go.
>>
>> I can't explain this very well but the documentation aspect is accurate.
>>
>> On Sunday, May 19, 2019 at 7:33:07 PM UTC+2, Brian Beckman wrote:
>>>
>>> The documentation for >!! reads:
>>>
>>> -
>>> clojure.core.async/>!!
>>> ([port val])
>>>   puts a val into port. nil values are not allowed. Will block if no
>>>   buffer space is available. Returns true unless port is already closed.
>>>
>>>
>>> I have a case where I believe that the channel has no buffer, I park a 
>>> "pseudothread" in a go block reading off that channel via >> (lexically, not temporally), put to the unbuffered channel via >!!:
>>>
>>> (let [c (chan) ;; NO BUFFER!
>>>   d (go (>>   e (>!! c 42)] ;; blocking write to c, will unpark c's pseudothread
>>> (println {:c-coughs-up '(this will hang (>>   :d-coughs-up (>>   :what's-ee})
>>> (close! c) (close! d))
>>>
>>> {:c-coughs-up (this will hang (>>
>>>
>>> This case leads me to wonder whether the documentation might read
>>>
>>>  >!! will block if there is no buffer space available *and* if there is 
>>> no *rendezvous *available, that is, no pseudothread parked waiting for 
>>> >>
>>> but it's more likely that I completely misunderstand core.async because 
>>> I just made up the notion of a pseudothread in my struggle to understand!
>>>
>>>
>>>
>>>

-- 
You 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/568ddcbe-2e3a-4e6b-a97e-c060e3b7fb37%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Blocking behavior of >!! ?

2019-05-19 Thread Thomas Heller
(
> The documentation for >!! reads:
>
> -
> clojure.core.async/>!!
> ([port val])
>   puts a val into port. nil values are not allowed. Will block if no
>   buffer space is available. Returns true unless port is already closed.
>
>
> I have a case where I believe that the channel has no buffer, I park a 
> "pseudothread" in a go block reading off that channel via  (lexically, not temporally), put to the unbuffered channel via >!!:
>
> (let [c (chan) ;; NO BUFFER!
>   d (go (   e (>!! c 42)] ;; blocking write to c, will unpark c's pseudothread
> (println {:c-coughs-up '(this will hang (   :d-coughs-up (   :what's-ee})
> (close! c) (close! d))
>
> {:c-coughs-up (this will hang (
>
> This case leads me to wonder whether the documentation might read
>
>  >!! will block if there is no buffer space available *and* if there is 
> no *rendezvous *available, that is, no pseudothread parked waiting for 
> but it's more likely that I completely misunderstand core.async because I 
> just made up the notion of a pseudothread in my struggle to understand!
>
>
>
>

-- 
You 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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/clojure/8c187aad-b746-490a-b6f8-3abfcdaa7533%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [Q] Deploying two artefacts/jars with same group/artefactid via Leiningen

2019-03-28 Thread Thomas Heller
I'm doing this in shadow-cljs deploying a normal jar and one with aot. I'm 
not exactly sure how you'd do that for an uberjar though.

https://github.com/thheller/shadow-cljs/blob/master/project.clj#L96-L103

On Thursday, March 28, 2019 at 7:05:39 PM UTC+1, henrik42 wrote:
>
> Hi,
>
> I have an uberjar that I want to deploy to clojars. Part of
> building the uberjar is building the "standard" lib-jar of the
> same project.
>
> Now I'd like to release/deploy both with the same group/artefactid to
> clojars. The uberjar should get the :classifier "app".
>
> So after that people could lein depend on the lib-jar and can download
> the "app" via browser/wget/etc.
>
> I've tried different things (e.g. lein-package) with no luck.
>
> The problem is that deploying them "one at a time" re-deploys pom.xml and 
> that fails. 
> So deployen two jars must be aware of this and deploy pom.xml only once.
>
> Any idea?
>
> -- Henrik
>
>

-- 
You 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: Invalid-token when dereferencing namespaced keywords.

2019-01-30 Thread Thomas Heller
To expand on what Alex already mentioned. There is no such thing as 
double-colon keywords. Double-colon is a reader alias mechanism that let 
the reader resolve them so you can type less.

(ns foo.bar.xyz)

::hello

this is resolved at read-time and identical to actually writing

:foo.bar.xyz/hello

:: without a slash will use the current namespace as the namespace for the 
keyword.

If you have a require for another namespace and use :: with a slash you can 
use it to resolve your require alias.

(ns some.thing
  (:require [foo.bar.xyz :as x]))

::x/hello

again becomes

:foo.bar.xyz/hello

in your actual program. Nothing :: will ever exist at runtime.

So if you want you can always use the fully qualified keyword directly or 
you can let the require resolve them based on your ns require's. That means 
you'll get an error if there is no alias to resolve

(ns user2)

::user1/foo

This is invalid because user2 does not have an alias to user1, instead it 
is an actual full namespace.

:user1/foo

would be fine in this case (and identical to ::foo in user1). Or

(ns user2
  (:require [user1 :as u1]))

::u1/foo

Hope that makes things clearer. 

Cheers,
Thomas

-- 
You 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.10 has been released!

2018-12-18 Thread Thomas
Thank you for this release and all the hard work everyone has put into 
this!!!

Thomas

On Monday, 17 December 2018 18:30:01 UTC+1, Alex Miller wrote:
>
> Clojure 1.10 focuses on two major areas: improved error reporting and Java 
> compatibility.
>
>
> Error reporting at the REPL now categorizes 
> <https://clojure.org/reference/repl_and_main#_error_printing> errors 
> based on their phase of execution (read, macroexpand, compile, etc). Errors 
> carry additional information about location and context as data, and 
> present phase-specific error messages with better location reporting. This 
> functionality is built into the clojure.main REPL, but the functionality is 
> also available to other REPLs and tools with the ability to use and/or 
> modify the data to produce better error messages.
>
>
> Clojure 1.10 now requires Java 8 or above and has been updated 
> particularly for compatibility with Java 8 and Java 11. Changes included 
> bytecode-related bug fixes, removed use of deprecated APIs, and updates 
> related to the module system introduced in Java 9.
>
>
> See the change log 
> <https://github.com/clojure/clojure/blob/master/changes.md#changes-to-clojure-in-version-110>
>  
> for a complete list of all fixes, enhancements, and new features in Clojure 
> 1.10.
>
>
> Thanks to all of the community members who contributed patches to Clojure 
> 1.10 (first time contributors in bold):
>
>
>- 
> *Alexander Kiel *
>- *Ben Bader*
>- Bruce Adams
>- *Cezary Kosko*
>- Erik Assum
>- *Eugene Kostenko*
>- Ghadi Shayban
>- *Gijs Stuurman*
>- Jozef Wagner
>- 
> *Kwang Yul Seo *
>- *Matthew Gilliard*
>- Michał Marczyk
>- Nicola Mometto
>- Nikita Prokopov
>- 
> *Sean Corfield *
>- *Sebastien Martel*
>- Shogo Ohta
>- 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
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: downloading of files from Dropbox using cli-http

2018-06-26 Thread Thomas
I have no idea what could be wrong here... sorry.

Thomas

On Monday, 25 June 2018 14:38:12 UTC+2, Johannes wrote:
>
> Hi,
>
> I am trying to download a file from Dropbox which I can get with the Http 
> request:
>
> POST /2/files/download Host: https://content.dropboxapi.com User-Agent: 
> api-explorer-client Authorization: Bearer QfCCK... Dropbox-API-Arg: 
> {"path":"/log.txt"}
>
> or the curl request looks like that:
>
> curl -X POST https://content.dropboxapi.com/2/files/download \ --header 
> 'Authorization: 
> Bearer QfCCK...' \ --header 'Dropbox-API-Arg: {"path":"/log.txt"}'
>
> If I try the following using cli-http in a Clojurescript repl:
>
> (go (let [response ( https://content/dropboxapi.com/2/files/download; {:headers 
> {"authorization" "Bearer QfCCK..." "Dropbox-API-Arg" 
> "{\"path\":\"/log.txt\"}"} }))] (println response)))
>
> I get
>
> #object[*cljs.core.async.impl.channels.ManyToManyChannel*]
>
> {:status 0, :success false, :body , :headers {}, :trace-redirects [
> https://content/dropboxapi.com/2/files/download 
> https://content/dropboxapi.com/2/files/download], :error-code 
> :http-error, :error-text  [0]}
>
>
> I cannot figure out where my mistake is. Any help?
>
>
> Johannes
>

-- 
You 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: downloading of files from Dropbox using cli-http

2018-06-25 Thread Thomas
try and do a curl -v and see what it really does under the covers as there 
might be a redirect

Good luck,
Thomas

On Monday, 25 June 2018 14:38:12 UTC+2, Johannes wrote:
>
> Hi,
>
> I am trying to download a file from Dropbox which I can get with the Http 
> request:
>
> POST /2/files/download Host: https://content.dropboxapi.com User-Agent: 
> api-explorer-client Authorization: Bearer QfCCK... Dropbox-API-Arg: 
> {"path":"/log.txt"}
>
> or the curl request looks like that:
>
> curl -X POST https://content.dropboxapi.com/2/files/download \ --header 
> 'Authorization: 
> Bearer QfCCK...' \ --header 'Dropbox-API-Arg: {"path":"/log.txt"}'
>
> If I try the following using cli-http in a Clojurescript repl:
>
> (go (let [response ( https://content/dropboxapi.com/2/files/download; {:headers 
> {"authorization" "Bearer QfCCK..." "Dropbox-API-Arg" 
> "{\"path\":\"/log.txt\"}"} }))] (println response)))
>
> I get
>
> #object[*cljs.core.async.impl.channels.ManyToManyChannel*]
>
> {:status 0, :success false, :body , :headers {}, :trace-redirects [
> https://content/dropboxapi.com/2/files/download 
> https://content/dropboxapi.com/2/files/download], :error-code 
> :http-error, :error-text  [0]}
>
>
> I cannot figure out where my mistake is. Any help?
>
>
> Johannes
>

-- 
You 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: try catch leaking exception

2018-02-14 Thread Thomas Heller
lazy-seq is the short answer.

You are constructing the seq inside the try/catch but it is realized 
outside of that so no exceptions will be caught.

(defn gen-ym-list [from to]
  (try
(->> (p/periodic-seq (f/parse ym-fmt from) (t/months 1))
 (take-while #(not (t/after? % (f/parse ym-fmt to
 (into [])
(catch Exception _ nil)))

This forces the seq inside the try/catch.

HTH,
Thomas

On Wednesday, February 14, 2018 at 11:46:58 AM UTC+1, icamts wrote:
>
> Hi all,
> I found an unexpected behavior of (try ... (catch ...)) special form. Can 
> someone help me understand it better?
>
> These are project.clj and core.clj of my test project. The test project 
> zip file is provided as an attachment.
>
> (defproject try-try "0.0.0"
>   :description "unexpected try beahvior"
>   :url "http://example.com/FIXME;
>   :license {:name "Eclipse Public License"
> :url "http://www.eclipse.org/legal/epl-v10.html"}
>   :dependencies [[org.clojure/clojure "1.8.0"]
>  [org.clojure/tools.cli "0.3.5"]
>  [clj-time "0.14.0"]
>  [joda-time/joda-time "2.9.7"]])
>
> (ns try-try.core
>   (:require [clj-time.core :as t]
> [clj-time.format :as f]
> [clj-time.periodic :as p]))
>
> (def ym-fmt (f/formatter "MM"))
>
> (defn gen-ym-list [from to]
>   (try
> (->> (p/periodic-seq (f/parse ym-fmt from) (t/months 1))
>  (take-while #(not (t/after? % (f/parse ym-fmt to)
> (catch Exception _ nil)))
>
> (defn gen-ym-list* [from to]
>   (try
>(let [ym-from (f/parse ym-fmt from)
>  ym-to (f/parse ym-fmt to)]
>  (->> (p/periodic-seq ym-from (t/months 1))
>   (take-while #(not (t/after? % ym-to)
>(catch Exception _ nil)))
>
> (gen-ym-list "2017" "201802"); returns nil as expected
>
> (gen-ym-list "201712" "2018"); throws unexpected exception
>
> (gen-ym-list* "2017" "201802"); returns nil as expected
>
> (gen-ym-list* "201712" "2018"); returns nil as expected
>
> (use 'clojure.walk)
>
> (macroexpand-all
>  `(try
> (->> (p/periodic-seq (f/parse ym-fmt from) (t/months 1))
>  (take-while #(not (t/after? % (f/parse ym-fmt to)
> (catch Exception _ nil)))
>
> (macroexpand-all
>  `(try
> (let [date-from (f/parse ym-fmt from)
>   date-to (f/parse ym-fmt to)]
>   (->> (p/periodic-seq date-from (t/months 1))
>(take-while #(not (t/after? % date-to)
> (catch Exception _ nil)))
>
> gen-ym-list doesn't catch IllegalArgumentException thrown when to 
> argument is malformed. It catches the same exception thrown when from is 
> malformed.
>
> gen-ym-list* with arguments parsing in an initial let form works as 
> expected.
>
> From macro expansion I can see the to is parsed inside a fn*. Is this a 
> known limit in try-catch special form? Or a bug? Thanks in advance for your 
> help.
>
> Cheers,
> Luca
>
>
>

-- 
You 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: :npm-deps and transitive dependencies

2018-01-16 Thread Thomas Heller
You can create a deps.cljs in the root of your classpath for Y and declare 
:npm-deps there

;; src/deps.cljs
{:npm-deps {"the-thing" "version"}}

This way the compiler can pick up your npm dependency and install it.

On Monday, January 15, 2018 at 9:01:55 AM UTC+1, Lucas Wiener wrote:
>
> Hi,
>
> I have the following clojurescript project dependency setup: X -> Y (X has 
> stated Y in :dependencies). Now, I would like Y to depend on a npm 
> javascript library Z. Following the guides, I added :npm-deps to one of the 
> builds specified in Y. When I build and run Y, everything works fine with 
> the new Z dependency. However, building/running project X now fails since 
> the dependency Z cannot be found. From what I currently know, there are two 
> approaches to get X running again:
>
> 1) Specify Z as an :npm-deps also in the project X builds. This is not 
> very elegant since the union of all dependencies now cascade to the top 
> level projects. Also, this approach would fail when transitive dependencies 
> need different versions of the same dependency.
> 2) Compile Y into a bundle. Then X would depend on the prebuilt bundle of 
> Y (which already includes Z). This is not perfect since it requires an 
> extra processing step in Y, making lein checkouts a bit more troublesome 
> etc. Also, my intuition tells me that this might affect code splitting, 
> compilation optimizations, dead code elimination, etc. in a negative way.
>
> Am I missing something?
>

-- 
You 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: [Violation] Parser was blocked due to document.write(

2017-11-05 Thread Thomas Heller
This is only an issue in unoptimized code, ie. :none.

Without optimizations all code is in separate files which are loaded in 
dependency order. The default debug loader will load them by appending a 
script tag to the document. This has pretty terrible performance 
characteristics but is OK during development. You can pretty much ignore 
the chrome warning during development. You can turn off the "Verbose" log 
level and you won't see them again.

For everything non-development you should optimize the code with either 
:simple or :advanced settings, which will combine all the separate files 
into one (or more via :modules). This will not use the the debug loader and 
the warnings go away.

HTH

On Monday, November 6, 2017 at 12:28:36 AM UTC+1, ajlo...@gmail.com wrote:
>
> Sorry - very basic... I am trying the Clojurescript quickstart guide, and 
> have followed the instruction in detail.  When trying to view the 
> index.html in Chrome, I get this error in the console:
>
> "[Violation] Parser was blocked due to 

Re: Entity–component–system and Clojure

2017-08-16 Thread Thomas
If I am not mistaken Lightable uses it as well. There is also a plug in for 
it which helps with the ECS.

Hope that helps.

Thomas

On Wednesday, 16 August 2017 02:52:38 UTC+2, Didier wrote:
>
> I recently stumbled upon the entity-component-system design pattern which 
> is popular in game engine design: 
> https://en.wikipedia.org/wiki/Entity%E2%80%93component%E2%80%93system, 
> and really liked what I saw, thought it could be a good fit for Clojure.
>
> Basically, it has three concepts:
>
> 1) Components are pure data grouped together as per a given domain. In a 
> game engine that would be for example the 3D positional data related to 
> positioning of objects in the 3D scene. So one component would be 
> PositionComponent and it would have :X, :Y.
>
> 2) Entities are collections of Components with a unique ID.
>
> 3) Systems are processing functions that take an entity, transforming 
> their components' data, or performing side effects from them.
>
> Generally, in games, they inverse the entities, so instead of having 
> entities contain components, they have components stored in an array with 
> the index being the entity ID, and another array which contains the set of 
> components for the entity at that index. All of this is kept track of by a 
> world container.
>
> (def world
>   {:entities []
>:comp1 []
>:comp2 []
>...})
>
>
> So say you want to create an entity which is composed of comp1 and comp2, 
> you would just add to the world :entities at index 0 a set #{:comp1 
> :comp2}, and to the world :comp1 and :comp2 vectors at index 0 an initial 
> component1 and component2 data structure. In games, for performance, they 
> use a bitmask instead of a set for the entry of :entities.
>
>
> I'm not sure this structure is necessary if trying to use the pattern not 
> for game, but it doesn't hurt either I think.
>
> What I like about this, is I'm thinking its possible to use it to do 
> data-driven functional object modeling in Clojure. A problem I face, and I 
> feel other faces in Clojure, is how do you model entities without OOP? I 
> find this creates a kind of OO that is functional and data driven.
>
> You would spec a bunch of component, they're pure data. Then you'd define 
> systems (aka functions) which take an entity, and operate on the entity's 
> components (aka its data). At first glance, this appears to just be OOP, 
> but there's no inheritance here, and functions that operate or related data 
> are decoupled from the data. Systems are implicitly mapped to components, 
> based on what they work on. So you can extend all entities with more 
> functionality easily. You can also create entities from components on the 
> fly.
>
> On second glance, I wonder what's different about this from just functions 
> operating over data. I think its just a more rigid means to do so when you 
> need the concept of entities. In a way, entities act as a class, in that 
> they're a template of data. A system works over that template.
>
> Has anyone experimented with this in Clojure?
>

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

2017-02-27 Thread Thomas Heller

>
> ​What is the best way to determine the right value for this? I remember 
> that in the past I had a lot of little Java​
>  
> ​programs running and got a much better performance by limiting memory 
> usage.
>


That is not an easy question to answer. If you make it too small your 
process may crash with OutOfMemory errors, if you give it just enough it 
will constantly be running running garbage collections making your program 
slower. So "just right" is very dependent on your program and also on what 
else is happening on the machine running it. You can use tools like 
JVisualVM or Java Mission Control to better understand your system but that 
takes a lot of time and effort.

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

2017-02-27 Thread Thomas Heller
Last thing I can come up with is your environment variables or something in 
your ~/.lein/* folder. Beyond that I'm out of ideas.

On Monday, February 27, 2017 at 2:15:18 PM UTC+1, Cecil Westerhof wrote:
>
> 2017-02-27 13:57 GMT+01:00 Cecil Westerhof  >:
>
>> Maybe you have some other conflicting configuration somewhere that sets 
>>> it explicitly to 4G? Usually no maximum is set and the JVM will 
>>> automatically adjust it based on your system.
>>>
>>
>> ​Not that I know of, but I will try to find it out.
>>
>
> ​In the Clojure directory I gave:
> grep -r -- '-Xmx' *
>
> And this only gave:
> data.int-map/project.clj:  :jvm-opts ^:replace ["-server" "-Xmx1g"]
> Quotes/project.clj:  :jvm-opts ^:replace ["-Xmx512m"]
> ​
>  
> ​So I would say it is not set. (But in a way it is.)
>
> -- 
> Cecil Westerhof
>

-- 
You 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: Prgram uses a lot of swap

2017-02-26 Thread Thomas Heller
Maybe you are running an old version of leiningen?

This might work although JVM_OPTS works fine for me as well

:jvm-opts ^:replace ["-Xmx512m"]

Maybe you have some other conflicting configuration somewhere that sets it 
explicitly to 4G? Usually no maximum is set and the JVM will automatically 
adjust it based on your system.


On Sunday, February 26, 2017 at 10:14:22 PM UTC+1, Cecil Westerhof wrote:
>
> 2017-02-26 21:59 GMT+01:00 Cecil Westerhof  >:
>
>> To control the memory you can add :jvm-opts ["-Xmx512m"] to your 
>>> project.clj. It will set the max memory of the JVM to 512mb which should be 
>>> enough for your program.
>>>
>>
>> ​Did not work either, but at the moment I use:
>> export JVM_OPTS=-Xmx512m
>>
>> For the moment that does the trick.
>>
>
> ​No it does not. :'-( When looking to the commandline parameters I see:
> -Xmx512m-Xmx4096M
>
> I need to invest some time.
>
> -- 
> Cecil Westerhof
>

-- 
You 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: Prgram uses a lot of swap

2017-02-26 Thread Thomas Heller
Ideally you would run your program without lein, probably as an uberjar.

But if you insist on lein you can do "lein trampoline run -m your.main/fn" 
which will allow the lein process to exit after setting up your program 
leaving you with only one JVM.

To control the memory you can add :jvm-opts ["-Xmx512m"] to your 
project.clj. It will set the max memory of the JVM to 512mb which should be 
enough for your program.

HTH,
Thomas

On Saturday, February 25, 2017 at 11:41:03 AM UTC+1, Cecil Westerhof wrote:
>
> 2017-02-24 15:07 GMT+01:00 Timothy Baldridge <tbald...@gmail.com 
> >:
>
>> What are the JVM memory settings set at? And how much physical memory 
>> does the box have?
>>
>
> ​My system has 16 GB of memory.
>
> I use ‘lein  run’ and this results in the following process:
> 
> java-Xbootclasspath/a:/home/cecil/.lein/self-installs/leiningen-2.6.1-standalone.jar-Dfile.encoding=UTF-8-Dmaven.wagon.http.ssl.easy=false-Dmaven.wagon.rto=1-XX:+TieredCompilation-XX:TieredStopAtLevel=1-Dleiningen.original.pwd=/home/cecil/Clojure/Quotes-Dleiningen.script=/home/cecil/bin/lein-classpath.:/home/cecil/scala:/var/lib/h2/jars/h2-current.jar:/home/cecil/Java/jars/sqlite-jdbc.jar:/home/cecil/Java/jars/javax.mail.jar:/home/cecil/Java/qtjambi-linux64-4.7.4-beta-4/qtjambi-4.7.4-beta-4.jar:/home/cecil/Java/qtjambi-linux64-4.7.4-beta-4/qtjambi-examples-4.7.4-beta-4.jar:/home/cecil/Java/qtjambi-linux64-4.7.4-beta-4/qtjambi-native-linux64-gcc-4.7.4-beta-4:/home/cecil/Java/ghost4j/ghost4j-0.5.0.jar:/home/cecil/.lein/self-installs/leiningen-2.6.1-standalone.jarclojure.main-mleiningen.core.mainrun
>
> The program itself is:
> 
> java-classpath/home/cecil/Clojure/Quotes/test:/home/cecil/Clojure/Quotes/src:/home/cecil/Clojure/Quotes/dev-resources:/home/cecil/Clojure/Quotes/resources:/home/cecil/Clojure/Quotes/target/classes:/home/cecil/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar:/home/cecil/.m2/repository/com/miglayout/miglayout/3.7.4/miglayout-3.7.4.jar:/home/cecil/.m2/repository/org/clojure/tools.nrepl/0.2.12/tools.nrepl-0.2.12.jar:/home/cecil/.m2/repository/clojure-complete/clojure-complete/0.2.4/clojure-complete-0.2.4.jar:/home/cecil/.m2/repository/org/clojure/java.jdbc/0.5.8/java.jdbc-0.5.8.jar:/home/cecil/.m2/repository/org/clojure/math.numeric-tower/0.0.4/math.numeric-tower-0.0.4.jar:/home/cecil/.m2/repository/com/fifesoft/rsyntaxtextarea/2.5.6/rsyntaxtextarea-2.5.6.jar:/home/cecil/.m2/repository/org/swinglabs/swingx/swingx-autocomplete/1.6.3/swingx-autocomplete-1.6.3.jar:/home/cecil/.m2/repository/j18n/j18n/1.0.2/j18n-1.0.2.jar:/home/cecil/.m2/repository/clj-time/clj-time/0.12.0/clj-time-0.12.0.jar:/home/cecil/.m2/repository/org/swinglabs/swingx/swingx-plaf/1.6.3/swingx-plaf-1.6.3.jar:/home/cecil/.m2/repository/org/swinglabs/swingx/swingx-painters/1.6.3/swingx-painters-1.6.3.jar:/home/cecil/.m2/repository/com/jgoodies/forms/1.2.1/forms-1.2.1.jar:/home/cecil/.m2/repository/joda-time/joda-time/2.9.3/joda-time-2.9.3.jar:/home/cecil/.m2/repository/com/h2database/h2/1.3.176/h2-1.3.176.jar:/home/cecil/.m2/repository/seesaw/seesaw/1.4.5/seesaw-1.4.5.jar:/home/cecil/.m2/repository/org/swinglabs/swingx/swingx-common/1.6.3/swingx-common-1.6.3.jar:/home/cecil/.m2/repository/org/swinglabs/swingx/swingx-core/1.6.3/swingx-core-1.6.3.jar:/home/cecil/.m2/repository/instaparse/instaparse/1.4.2/instaparse-1.4.2.jar:/home/cecil/.m2/repository/org/swinglabs/swingx/swingx-action/1.6.3/swingx-action-1.6.3.jar:/home/cecil/.m2/repository/yesql/yesql/0.5.3/yesql-0.5.3.jar-Dfile.encoding=UTF-8-Xmx4096M-Dclojure.compile.path=/home/cecil/Clojure/Quotes/target/classes-Dquotes.version=0.0.1-Dclojure.debug=falseclojure.main-i/tmp/form-init417092364626579473.clj
>
> ​So maximum memory is set to 4 GB. That could probably be a lot less.​ 
> Where can I change that?
> And can I set the maximum memory for lein?
>
>
> -- 
> Cecil Westerhof
>

-- 
You 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.


Socket server and PuTTY

2016-11-22 Thread 'Thomas Meyer' via Clojure
Hi,

I think the problem is that clojure server reply sends LF only but RFC 854 
wants a CR LF for a newline. PuTTY has an option to convert LF into CR LF.
Bug or feature?

Kind regards
Thomas

-- 
You 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.


Socket server and PuTTY

2016-11-21 Thread 'Thomas Meyer' via Clojure
Hi,

When I connect to the socket server with PuTTY, what are the correct connection 
parameters? Telnet mode gives strange error messages, raw mode seems to work 
but when doing (find-doc "string") the output has strange blanks and carriage 
returns.

Help is appreciated.

With kind regards
Thomas

-- 
You 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: defrecord in cljc

2016-11-12 Thread Thomas Heller
You may overwrite the default IPrintWriter by doing calling extend-type 
after the defrecord.

But CLJS should probably allow the protocol in defrecord itself instead of 
forcing the default. Not sure if there is an open issue for it.

On Friday, November 11, 2016 at 9:29:25 PM UTC+1, William la Forge wrote:
>
> To answer my own question, it is because IPrintWithWriter is already 
> defined for records. Only define this with deftype.
>
> On Friday, November 11, 2016 at 3:16:46 PM UTC-5, William la Forge wrote:
>>
>> WARNING: Protocol IPrintWithWriter implemented multiple times at line 9 
>> src\simpleArk\rolonRecord.cljc
>>
>> Any ideas?
>>
>> (ns simpleArk.rolonRecord)
>>
>>
>> #?(:clj
>>(defrecord Rolon-record [rolon-uuid])
>>:cljs
>>(defrecord Rolon-record [rolon-uuid] ;;this is line 9
>>   IPrintWithWriter
>>   (-pr-writer [this writer opts]
>>   (let [pr-pair (fn [keyval]
>> (pr-sequential-writer writer 
>> pr-writer "" " " "" opts keyval))]
>>(pr-sequential-writer writer pr-pair
>>  "#ark/Rolon-record {"
>>  ", "
>>  "}"
>>  opts 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
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: need help on `pprint/write` code with better readability

2016-10-24 Thread Thomas Heller
Try https://github.com/weavejester/cljfmt 

It is specifically written for clj code and not general pprinter.

/thomas

On Sunday, October 23, 2016 at 1:28:23 PM UTC+2, Jiyin Yiyong wrote:
>
> I'm using `write` function to generate code very heavily. But small part 
> of the code are hard to read.
> So I digged into the options and increased `right-margin` to make it a 
> little better. Here's the changes:
>
>
> https://github.com/Cirru/sepal.clj/commit/e65e2d3cac8a5c5537716acd12cc475712ab6f66
>
>
> https://github.com/Quamolit/quamolit/commit/1d2e2a579a3b6741109223faa88c84157035577f
>
> But it turned out the algorithm is doing layout like always appending code 
> in a line, until it reaches right margin.
> So if `right-margin` is too big, all the code are in a single line, which 
> is hard to read.
> if `right-margin` is too small, then all the code in a column, which is 
> also hard to read.
> I think it's not smart enough to make all of my code readable enough, but 
> majority of that is fine.
>
> Is there any solution to improvement the readability at this moment?
> Especially for such scenarios:
>
>
> https://github.com/Quamolit/quamolit/blob/master/src/quamolit/render/expand.cljs#L102
>
>
> Thanks.
>

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


Re: Possible ClojureScript compiler issue...

2016-10-18 Thread Thomas Heller
Don't think there is a best practice for your case in particular.

The issue is that js->cli is built on top of protocols to allow converting 
custom JS types to CLJS types. Which makes it extensible for the price of 
checking protocols. In your case you are converting JSON which cannot have 
custom types, so a custom converter only checking for the very few possible 
JSON types would "fix" your problem (and would probably be a lot faster).

The case can be made that cljs-ajax should not be using js->clj when 
converting JSON, maybe even add a json->clj to cljs.core.

The sentinel is the "safest" solution but impacts the performance of 
*everyone*, so we should be doing more benchmarks on more platforms before 
deciding anything. Benchmarks and Votes on the Jira Issue would help to 
push this along.

Cheers,
/thomas

On Tuesday, October 18, 2016 at 10:21:21 AM UTC+2, John Szakmeister wrote:
>
> On Tue, Oct 18, 2016 at 2:59 AM, Thomas Heller <th.h...@gmail.com 
> > wrote: 
> [snip] 
> > While this issue can be very confusing you will hardly ever run into it 
> when 
> > following best practices. As David suggested using a custom js->clj here 
> > would prevent the issue and is probably the best course of action 
> > regardless. 
>
> Which best practices?  Is there a good place to read about them?  I've 
> not seen anything that would have steered me away from this problem. 
> In fact, I've seen quite the opposite: js->clj appears to be *the* way 
> to convert from JavaScript data structures to ClojureScript ones. :-( 
>
> FWIW, I did end up putting something together that was able to do what 
> I needed, but it could have easily gone a different direction. 
> js->clj was being called in a library that I'm using (cljs-ajax), and 
> it, fortunately, had a knob that I could turn to just get the raw json 
> back out without running anything through js->clj.  Had the knob been 
> missing, I think the solution would have been much more painful as I'd 
> either have to fork and maintain a copy of the library, migrate to a 
> different library, or write my own to replace it with. :-( 
>
> I also like the sentinel idea.  I hope some version of your patch is 
> incorporated. 
>
> -John 
>

-- 
You 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: Possible ClojureScript compiler issue...

2016-10-18 Thread Thomas Heller
Yeah the issue can be quite confusing since the error produced may complain 
about protocols you are not even calling anywhere. I've run into it several 
times when the code ended up checking protocols on js/window. Since that 
has all the munged global variables closure produces just about anything 
can result in a false positive there.

As for the sentinel, there is no notable difference to which sentinel is 
used. Strings, Numbers, boolean, object ... doesn't really matter. object 
with ===/identical? check seemed the simplest without a chance for a false 
positive (any number, string, boolean can in theory still clash).

4) would not be acceptable to me as there are quite a lot of "$cljs..." 
properties and increasing the code size for such a tiny benefit isn't 
really justified IMHO.

While this issue can be very confusing you will hardly ever run into it 
when following best practices. As David suggested using a custom js->clj 
here would prevent the issue and is probably the best course of action 
regardless.

/thomas

On Tuesday, October 18, 2016 at 3:12:40 AM UTC+2, Antonin Hildebrand wrote:
>
> I think one reason why these issues are reported infrequently is because 
> it is really hard to track them down. I can imagine people disable 
> :advanced optimizations or restructure their code instead of hunting down 
> the real cause. John went really far to isolate/demonstrate the issue.
>
> Thanks for posting that sentinel idea, Thomas. It looks really simple. I 
> think instead of sentinel object we could use some large random integer 
> which could have similar performance profile as checking for boolean.
>
> I would add another possible idea:
>
> 4. we could alter google closure compiler with ClojureScript-aware 
> renaming logic, it would preserve prefix $cljs prefix when renaming 
> properties[1]. Also in ClojureScript compiler we would rename all 
> cljs-related properties to use this convention.
>
> Pros:
> 1. This would decrease a chance of clashes. When someone runs into it - it 
> would be quite self-describing that "$cljs" named property is involved.
>
> Cons:
> 1. This would lead to slightly bigger generated code (all the $cljs 
> prefixes which would previously disappear).
> 2. The bigger downside IMO is that we would have to maintain our own fork 
> of Closure Compiler. Which is not that scary with git. It is pretty easy to 
> automate rebasing of a few patch-commits on top of arbitrary complex 
> foreign repo.
>
> [1] 
> https://github.com/google/closure-compiler/blob/5616a66e40c5dc6ec9be9beacfc0ea20d47bbcfc/src/com/google/javascript/jscomp/RenameProperties.java#L284
>
>
>
> On Sunday, October 16, 2016 at 4:36:38 PM UTC+2, Thomas Heller wrote:
>>
>> FWIW I investigated the check with "true" and a sentinel value and found 
>> them to both have a small performance impact over just checking for a 
>> true-ish property.
>>
>> http://dev.clojure.org/jira/browse/CLJS-1658
>>
>> The impact is really small so it might be worth the trade-off.
>>
>> /thomas
>>
>> On Sunday, October 16, 2016 at 3:59:20 PM UTC+2, David Nolen wrote:
>>>
>>> It's true that there other scenarios where you can encounter this but it 
>>> gets reported infrequently enough that I don't think these kinds of 
>>> property name collisions are common.
>>>
>>> Still it has come up before and I think the simplest solution least 
>>> likely to adversely affect performance is to test for a def'onced unique 
>>> object instead of `true`.
>>>
>>> David
>>>
>>> On Sat, Oct 15, 2016 at 8:46 PM, Antonin Hildebrand <
>>> antonin.h...@gmail.com> wrote:
>>>
>>>> Unfortunately, this problem is not specific to `js->clj` only.
>>>>
>>>> I believe in general under :advanced optimizations, any object which 
>>>> was created or modified by a code which 
>>>> was not subject of the same closure compiler optimization pass could 
>>>> exhibit similar problems when used with ClojureScript core functions like 
>>>> `satisfies?`.
>>>>
>>>> That also includes working with external data (your case), and working 
>>>> with objects created/modified by adding properties by string names.
>>>>
>>>> To illustrate, I created a screenshot of cljs type instance with two 
>>>> protocols, to see the internals in dev mode:
>>>>
>>>> https://dl.dropboxusercontent.com/u/559047/cljs-protocol-internals-01.png
>>>> In the selected text I highlighted part of generated code for 
>>>> `satisfies?` call.
>>&g

Re: Possible ClojureScript compiler issue...

2016-10-16 Thread Thomas Heller
FWIW I investigated the check with "true" and a sentinel value and found 
them to both have a small performance impact over just checking for a 
true-ish property.

http://dev.clojure.org/jira/browse/CLJS-1658

The impact is really small so it might be worth the trade-off.

/thomas

On Sunday, October 16, 2016 at 3:59:20 PM UTC+2, David Nolen wrote:
>
> It's true that there other scenarios where you can encounter this but it 
> gets reported infrequently enough that I don't think these kinds of 
> property name collisions are common.
>
> Still it has come up before and I think the simplest solution least likely 
> to adversely affect performance is to test for a def'onced unique object 
> instead of `true`.
>
> David
>
> On Sat, Oct 15, 2016 at 8:46 PM, Antonin Hildebrand <
> antonin.h...@gmail.com > wrote:
>
>> Unfortunately, this problem is not specific to `js->clj` only.
>>
>> I believe in general under :advanced optimizations, any object which was 
>> created or modified by a code which 
>> was not subject of the same closure compiler optimization pass could 
>> exhibit similar problems when used with ClojureScript core functions like 
>> `satisfies?`.
>>
>> That also includes working with external data (your case), and working 
>> with objects created/modified by adding properties by string names.
>>
>> To illustrate, I created a screenshot of cljs type instance with two 
>> protocols, to see the internals in dev mode:
>> https://dl.dropboxusercontent.com/u/559047/cljs-protocol-internals-01.png
>> In the selected text I highlighted part of generated code for 
>> `satisfies?` call.
>>
>> ClojureScript adds/checks $cljs prefixed properties to objects. These 
>> internal properties get renamed by closure compiler.
>> So any object which happens to have one of those renamed names 
>> independently added as their property will potentially confuse functions 
>> like `satisfies?`.
>>
>> Possible solutions I see:
>>
>> 1. use string names for clojurescript internal properties, and avoid 
>> clashes by using "unique-enough" prefix even in advanced mode - still not 
>> safe solution, but would minimize clash chances
>>
>> or 
>>
>> 2. start tracking which objects belong to cljs land, have one 
>> "unique-enough" string name as a marker, clojurescript functions like 
>> satisfies? would check this marker before proceeding further. Still dirty, 
>> one could clobber cljs properties by modifying a cljs-land-object from 
>> unaware Javascript code. And this would probably change behaviour of some 
>> existing code.
>>
>> or
>>
>> 3. use prototypal inheritance and "hide" all ClojureScript internal 
>> properties in a new link in the prototype chain, plain javascript objects 
>> would miss this link so it could be easily detected, properties would not 
>> clash even if they got same names. ClojureScript functions like satisfies? 
>> would properly
>> walk the chain and read properties from proper link which belongs only to 
>> ClojureScript. Ale we would not need any special "magic" marker - the 
>> Javascript type of the link in prototype would safely identify it.
>> I believe this would be correct solution. But I guess, this would be too 
>> dramatic change in ClojureScript internals and might break a lot of other 
>> things I currently don't understand. Also performance could get a hit.
>>
>> Better ideas, anyone? :-)
>>
>> ps. don't use :advanced mode when programming atomic reactors in 
>> ClojureScript ;-p
>>
>> On Saturday, October 15, 2016 at 10:59:14 PM UTC+2, John Szakmeister 
>> wrote:
>>
>>> On Sat, Oct 15, 2016 at 2:49 PM, David Nolen <dnolen...@gmail.com> 
>>> wrote: 
>>> > This issue is somewhat to be expected if you're going to use 
>>> `js->clj`. This 
>>> > issue has nothing to do with ClojureScript compiler versions - you 
>>> just got 
>>> > lucky before. Google Closure will collapse properties, but some of 
>>> these 
>>> > collapsed properties are going to be used to determine protocol 
>>> membership. 
>>> > That's it. 
>>>
>>> Wow.  I did not that expect that at all.  It makes sense, but it's 
>>> unfortunate. 
>>>
>>> > I suggest just avoiding `js->clj` and using your own simple helper for 
>>> > recursively converting JSON into Clojure values. Changing the 
>>> (admittedly 
>>> > questionable) behavior of `js->clj` will only lead to

Re: should edn/read call close() on the PushbackReader?

2016-09-02 Thread Thomas Heller
In general Java it is up to the creator of a "stream" to close it, the same 
applies to Clojure pretty much.

Java has "try with resources" and in Clojure you can use "with-open":

(with-open [rdr (open-the-reader)]
  (edn/read rdr {}))

This will ensure .close is called in a finally block.

HTH,
Thomas

On Friday, September 2, 2016 at 2:24:31 PM UTC+2, John Valente wrote:
>
> Running on Windows, I found that I could not delete an edn file that I had 
> read from.  I've looked at a few examples of reading edn, and none of them 
> seem to suggest that the user code should explicitly call close() on the 
> Java object, or that it needs to use with-open.  Should I be doing 
> something like that?
>
> I wonder why Clojure doesn't call close when it hits EOF:
>
>
> https://github.com/clojure/clojure/blob/c6756a8bab137128c8119add29a25b0a88509900/src/jvm/clojure/lang/EdnReader.java#L134
>
> Maybe it shouldn't be necessary, but it seems safe to me:
>
>
> https://docs.oracle.com/javase/7/docs/api/java/io/PushbackReader.html#close()
>
> I've mostly worked on a Mac, where I haven't had trouble.  This only 
> happened to me on Windows, and only once (so far).  I haven't tried to 
> reproduce it.  It is certainly possible I did something else wrong to cause 
> the file to get into an undeletable state.  Still, it does seem to me it 
> would be safe to have the Clojure Java source code call close(), unless I'm 
> missing something.
>
> Thanks,
> John
>
>

-- 
You 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: Running a certain function of your project

2016-07-14 Thread Thomas Mulvaney
For one-off scripts I typically have a `scripts/` directory in my projects.
I also have a scripts profile in my project.clj which includes "src/clj"
and "scripts", that way my scripts can call functions from my project. I
then have a bash script called `bin/script` which just contains "lein run
with-profile +scripts -m $@"

Now, say I have a script with namespace 'db.migrate' under
"scripts/db/migrate.clj", calling it is just a matter of doing `bin/scripts
db.migrate arg1 arg2 `.

HTH

On Thu, Jul 14, 2016 at 10:34 PM, Cecil Westerhof 
wrote:

> 2016-07-14 23:18 GMT+02:00 Gary Trakhman :
>
>> Boot  and inlein
>>  are both more suitable for one-off scripts.
>>
>
> ​OK, I will look into them.​
>
>
>
>> On Thu, Jul 14, 2016 at 5:16 PM Cecil Westerhof 
>> wrote:
>>
>>> In my project I have some functions I use when calling ‘lein repl’ in
>>> the project directory. Would it be possible to use just that function? So
>>> use lein to call this function and return?
>>>
>>> Maybe not very useful because of the time it takes to start the JVM, but
>>> I like to experiment. ;-)
>>>
>>
> --
> Cecil Westerhof
>
> --
> You 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.
>

-- 
You 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: How to compile with optimizations none when using web workers

2016-05-30 Thread Thomas Heller
Not sure I understand what you mean. What do you mean by "main module"? 
cljs has a notion of a base module, while shadow-build does not.

Typically your ns structure and the requires are enough to establish 
relationships between them so shadow-build can figure out what needs to be 
where. If that is not possible for some reason you need to list them all 
yes.

/thomas

On Monday, May 30, 2016 at 1:04:08 PM UTC+2, Asher Coren wrote:
>
> Thomas,
> I as well think modules is the right approach when using web workers.
>
> What can I do if my app code is build from many namespaces? How do I tell 
> the main module to use all of them? Do I have to list them ALL?
>
>
> On Friday, February 19, 2016 at 5:54:59 PM UTC+2, William la Forge wrote:
>>
>> Compiling with optimizations none is no doubt quite handy, especially in 
>> conjunction with source maps, as a traceback will take you to the line of 
>> code causing the problems, and with the same variable names used in your 
>> original clojurescript code. But this is not currently possible for .jc 
>> files used by web workers as the unoptimized .js file contains a reference 
>> to js/window--and window does not exist in a web worker.
>>
>>
>> You should still be able to use optimizations none with your main 
>> javascript code, but you will need to compile your main code and your web 
>> worker code separately so that you can use different optimizations as 
>> appropriate. And you can do this so long as your not using shared workers. 
>> The question then is, how to compile the .js files separately.
>>
>> The duracell <https://github.com/aatree/aademos/tree/master/duracell> demo 
>> uses a web worker AND is itself compiled with optimizations none. There are 
>> two things done to accomplish this:
>>
>>1. Duracell itself has no web worker code. Though it uses a library, 
>>durable-cells <https://github.com/aatree/durable-cells>, which 
>>includes a web worker.
>>2. In the duracell build.boot 
>><https://github.com/aatree/aademos/blob/master/duracell/build.boot> file, 
>>the dev task uses pandeiro/boot-http 
>><https://github.com/pandeiro/boot-http> rather than the simpler 
>>tailrecursion/boot-jetty <https://github.com/tailrecursion/boot-jetty>. 
>>The advantage to using boot-http is that it supports the loading of 
>> static 
>>files from library jar files. In this case, that means the main code in 
>>aaworker can create a web worker using durable-cell's dcells.js file.
>>
>> So how does the durable-cells library create the dcells.js file? Again, 
>> there are two things done to accomplish this:
>>
>>1. In the durable-cells build.boot 
>><https://github.com/aatree/durable-cells/blob/master/build.boot> file, 
>>the dev task includes (cljs :optimizations :simple). This invokes the 
>>compiler with an appropriate level of optimizations.
>>2. But we still need to define the .js file. This is done in the 
>>dcells.cljs.edn 
>>
>> <https://github.com/aatree/durable-cells/blob/master/src/worker/dcells.cljs.edn>
>>  file. 
>>See Multiple Builds 
>><https://github.com/adzerk-oss/boot-cljs/wiki/Usage#multiple-builds> for 
>>more information on cljs.edn files.
>>
>> From 
>> https://github.com/aatree/aaworker/wiki/Compiling-with-Optimizations-None
>>
>

-- 
You 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: Removing duplicates from a series

2016-05-17 Thread Thomas Mulvaney
Rather than writing a new function you could always use something like (map
first (partition-by :value events)). partition-by will create lists of
events where consecutive values have not changed. You could also assemble a
transducer pipeline using the transducer arities of the functions: `(into
[] (comp (partition-by :value) (map first)) events)`.

Hope that helps,

Tom

On Tue, May 17, 2016 at 10:47 AM, 'Simon Brooke' via Clojure <
clojure@googlegroups.com> wrote:

> I'm having trouble with writing a function
>
>1. in idiomatic clojure
>2. which doesn't blow the stack
>
> The problem is I have a time series of events e.g.
>
> ({:idhistory 78758272, :timestamp #inst
> "2016-03-31T19:34:27.31300-00:00", :nameid 5637, :stringvalue nil,
> :value 8000.0}
>  {:idhistory 78756591, :timestamp #inst
> "2016-03-31T19:33:31.69700-00:00", :nameid 5637, :stringvalue nil,
> :value 7368.0}
>  {:idhistory 78754249, :timestamp #inst
> "2016-03-31T19:32:17.1-00:00", :nameid 5637, :stringvalue nil,
> :value 6316.0}
>  {:idhistory 78753165, :timestamp #inst
> "2016-03-31T19:31:41.84300-00:00", :nameid 5637, :stringvalue nil,
> :value 5263.0}
>  {:idhistory 78751187, :timestamp #inst
> "2016-03-31T19:30:36.21300-00:00", :nameid 5637, :stringvalue nil,
> :value 4211.0}
>  {:idhistory 78749476, :timestamp #inst
> "2016-03-31T19:29:41.36300-00:00", :nameid 5637, :stringvalue nil,
> :value 3158.0} ...)
>
> which is to say, each event is a map, and each event has two critical
> keys, :timestamp and :value. The series is sorted in descending order by
> timestamp, i.e. most recent event first. These series are of up to millions
> of events; the average length of the series is about half a million events.
> However, many contain successive events at which the value does not change,
> and where the value doesn't change I want to retain only the first event.
>
> So far what I've got is:
>
> (defn consolidate-events
>   "Return a time series like this `series`, but without those events whose
> value is
>identical to the value of the preceding event."
>   [series]
>   (let [[car cadr & cddr] series]
> (cond
>   (empty? series) series
>   (=
> (get-value-for-event car)
> (get-value-for-event cadr)) (consolidate-events (rest series))
>   true (cons car (consolidate-events (rest series))
>
>
> Obviously, with millions of events or even merely hundreds of thousands, a
> recursive function blows the stack. Furthermore, this one isn't even tail
> call optimisable. I tried creating an inner function which I naively
> thought should be tail call optimisable, but it fails 'Can only recur from
> tail position':
>
> (defn consolidate-events
>   "Return a time series like this `series`, but without those events whose
> value is
>   identical to the value of the preceding event."
>   [series]
>   (remove
> nil?
> (let [inner (fn [series]
>   (let [[car cadr & cddr] series]
> (if
>   (not (empty? series))
>   ;; then
>   (cons
> (if
>   (= (get-value-for-event car)
>  (get-value-for-event cadr))
>   ;; then
>   nil
>   ;; else
>   car)
> (if
>   (not (empty? series))
>   (recur (rest series)))]
> (inner series
>
>
> Test for the function is as follows:
>
> (deftest consolidate-events-test
>   (testing "consolidate-events"
> (let [s1 [{:timestamp #inst "2016-03-31T19:34:27.31300-00:00",
> :value 8000.0}
>   {:timestamp #inst "2016-03-31T19:33:31.69700-00:00",
> :value 7368.0}
>   {:timestamp #inst "2016-03-31T19:32:17.1-00:00",
> :value 6316.0}
>   {:timestamp #inst "2016-03-31T19:31:41.84300-00:00",
> :value 5263.0}
>   {:timestamp #inst "2016-03-31T19:30:36.21300-00:00",
> :value 4211.0}
>   {:timestamp #inst "2016-03-31T19:29:41.36300-00:00",
> :value 3158.0}]
>   s2 [{:timestamp #inst "2016-03-31T19:34:27.31300-00:00",
> :value 8000.0}
>   {:timestamp #inst "2016-03-31T19:33:31.69700-00:00",
> :value 7368.0}
>   {:timestamp #inst "2016-03-31T19:33:17.1-00:00",
> :value 6316.0}
>   {:timestamp #inst "2016-03-31T19:32:27.1-00:00",
> :value 6316.0}
>   {:timestamp #inst "2016-03-31T19:32:17.1-00:00",
> :value 6316.0}
>   {:timestamp #inst "2016-03-31T19:31:41.84300-00:00",
> :value 5263.0}
>   {:timestamp #inst "2016-03-31T19:30:36.21300-00:00",
> :value 4211.0}
>   {:timestamp #inst "2016-03-31T19:29:41.36300-00:00",
> :value 3158.0}]]
>   (is (= s1 (consolidate-events s1)) "There are no 

Re: Clojure IoT?

2016-04-11 Thread Thomas
I have made the Eclipse Paho JS client available for 
CLJS: https://github.com/cljsjs/packages/tree/master/paho  And there is 
also machine head  http://clojuremqtt.info/

Thomas

On Saturday, 9 April 2016 23:39:05 UTC+1, Gregg Reynolds wrote:
>
> A very general question : is anybody other than me working with Clojure 
> for IoT stuff?
>

-- 
You 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: cljs build goog/base.js is not getting generated properly..

2016-03-06 Thread Thomas Heller
Did you lein clean?

Although I'm not sure cljsbuild actually cleans anything. 
Delete resources/public/js/out manually if clean doesn't help.

If that also doesn't help try this

lein repl
(clojure.java.io/resource "goog/base.js")

That should give you the URL of a base.js inside the closure-library jar. 
If it is the third-party jar something weird is happening on your classpath.



On Sunday, March 6, 2016 at 3:41:14 PM UTC+1, Sunil Nandihalli wrote:
>
> I added all the recommended exclusions and I still see the above issue I 
> mentioned.
>
>
> On Sun, Mar 6, 2016 at 7:03 PM, Sunil S Nandihalli <sunil.na...@gmail.com 
> > wrote:
>
>> Thanks Thomas for the response
>>
>> when I did 
>>
>> lein deps :tree | egrep google 
>>
>> I got 
>>
>>[com.google.javascript/closure-compiler "v20151216"]
>>[org.clojure/google-closure-library "0.0-20151016-61277aea"]
>>  [org.clojure/google-closure-library-third-party 
>> "0.0-20151016-61277aea"]
>>
>> the full output is here.
>>
>> https://gist.github.com/8801e6554f501acdc4c1
>>
>> looks like the google-closure library is recent enough..
>>
>> Regards,
>> Sunil.
>>
>>
>>
>> On Sun, Mar 6, 2016 at 6:50 PM, Thomas Heller <th.h...@gmail.com 
>> > wrote:
>>
>>> That was an issue with old closure library releases but was fixed a 
>>> while ago.
>>>
>>> Try lein clean and make sure there are no conflicting versions being 
>>> used (via lein deps :tree).
>>>
>>> --
>>> 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/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: cljs build goog/base.js is not getting generated properly..

2016-03-06 Thread Thomas Heller
That was an issue with old closure library releases but was fixed a while ago.

Try lein clean and make sure there are no conflicting versions being used (via 
lein deps :tree).

-- 
You 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: [GSoC idea] Pluggable back-ends architecture for ClojureScript compiler

2016-02-22 Thread Thomas Heller
Projects for this already exist but are somewhat dormant.

See:
https://github.com/clojure/tools.analyzer
https://github.com/clojure/tools.analyzer.jvm
https://github.com/clojure/tools.analyzer.js
https://github.com/clojure/tools.analyzer.clr
https://github.com/clojure/tools.emitter.jvm

Neither Clojure or ClojureScript currently use them since they are either 
incomplete or have performance issues compared to the default 
implementation. The idea was however to have a pluggable solution that can 
share as much code as possible. IIRC it all started as GSoC work, so it 
might be useful to continue in this way. I'm not sure who was involved but 
authors are still around I think.

Cheers,
/thomas



On Sunday, February 21, 2016 at 9:20:18 AM UTC+1, Edward Knyshov wrote:
>
>
>
> *Pluggable back-ends architecture for ClojureScript compilerBrief 
> explanation:* There are a lot of ClojureScript script compiler forks 
> exist to provide different compilation targets other than js. Most of them 
> are currently stuck because of rapid ClojureScript development and 
> difficulties with keeping fork in sync with upstream. We could consider 
> refactoring ClojureScript to provide plugable backends architecture, 
> specifically to allow users replace code generation stage of compiler and 
> implement js generator as one of such backends.
>  
> *Expected results: *ClojureScript compiler is refactored to allow further 
> active development of plenty other backends to bootstrap Clojure in such 
> environments as c/c++, llvm, python, emacs lisp, lua, etc. Ability to use 
> clojure mostly everywhere.
>  
> *Knowledge:* ClojureScript, Clojure, JavaScript
>
> Need to know, what do you think guys.
>

-- 
You 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: How to compile with optimizations none when using web workers

2016-02-20 Thread Thomas Heller
Hey,

I have seen Servant but I do not like it. In general I do not like 
solutions that use macros to solve problems a build tool should solve. YMMV.

cljs-runtime is the directory used by shadow-build for all compiled files. 
The structure it creates is that you have one directory, with a .js file 
for each module [1]. These .js files then load the .js and .map files in 
the cljs-runtime diretory. For :none builds the module files only contain a 
bunch of goog.require statements that mirror namespaces only used by these 
modules [2]. The base module includes goog/base.js and all setup stuff. For 
optimized builds (:whitespace and up) the directory with the module files 
contain the actual code and the cljs-runtime directory is no longer 
relevant. This is a very different structure from what CLJS or boot produce.

I use this project for tests and accidentally included some more output 
that should not have been there. Just pushed a cleaner version that 
actually only contains stuff used by this version of the project.

Anyways ... Modules for the win! ;)

Cheers,
/thomas


[1] https://github.com/thheller/worker-example/tree/master/demo/js
[2] https://github.com/thheller/worker-example/blob/master/demo/js/demo.js


On Saturday, February 20, 2016 at 2:29:56 AM UTC+1, William la Forge wrote:
>
> Thomas,
>
> Your worker demo includes the entire cljs runtime as part of the project? 
> https://github.com/thheller/worker-example/tree/master/demo/js/cljs-runtime
>

-- 
You 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: How to compile with optimizations none when using web workers

2016-02-19 Thread Thomas Heller
Hello,

I'm not quite sure what you are saying here since I do not know boot or 
hoplon or durable-cells.

I can however suggest a "better" solution for Workers: Using Closure 
Modules.

CLJS or boot do not implement them for :none at the moment but shadow-build 
does. I also have a few extra hints for web-worker support but first let me 
try to explain why you want to use modules.

If you do a separate build for your worker and your main app you'll have to 
download 2 full builds. Meaning that your main.js file will contain an 
implementation of cljs.core and the worker.js will contain a different one. 
If you are on :none they will share some parts, but :advanced will share 
nothing. This is bad as you want to keep the scripts to download to a 
minimum.

So how would the ideal solution look like:

1) base.js for all common code (eg. cljs.core)
2) app.js for all the app code
3) worker.js for all the worker related code

2+3 both share the base.js, you can add more workers trivially. IMHO the 
best way to organize this from a code perspective is to have a separate 
namespace for each worker as well as the app, where the app should not 
depend on the worker or vice versa.

Since this is only one build now, you only need to worry about one compile 
as well.

I have a demo repo here:
https://github.com/thheller/worker-example

First we have the code:
https://github.com/thheller/worker-example/tree/master/src/cljs/demo/app.cljs
https://github.com/thheller/worker-example/tree/master/src/cljs/demo/worker1.cljs

Each is a self contained namespace that just does some trivial stuff.

The :none output is a bit confusing but lets look at the :advanced output:

https://github.com/thheller/worker-example/blob/advanced/demo/js/demo.js
https://github.com/thheller/worker-example/blob/advanced/demo/js/worker1.js

Each is only the very minimum of code, the worker1.js will automatically 
load the base.js which means it shares all of the code in base.js with the 
page itself. There will be not additional download as the browser has 
already downloaded it when loading the page (since it included base.js and 
demo.js). The :none build basically does the same thing just in a closure 
compliant way. No duplicate file downloads will happen.

Everything is compiled using shadow-build, I can go into further detail on 
how if anyone is interested. I just wanted to make the point that web 
workers should *ALWAYS* be used via closure modules, it is just the most 
efficient way to organise the code and output.

Just my 2 cents,
/thomas







On Friday, February 19, 2016 at 4:54:59 PM UTC+1, William la Forge wrote:
>
> Compiling with optimizations none is no doubt quite handy, especially in 
> conjunction with source maps, as a traceback will take you to the line of 
> code causing the problems, and with the same variable names used in your 
> original clojurescript code. But this is not currently possible for .jc 
> files used by web workers as the unoptimized .js file contains a reference 
> to js/window--and window does not exist in a web worker.
>
>
> You should still be able to use optimizations none with your main 
> javascript code, but you will need to compile your main code and your web 
> worker code separately so that you can use different optimizations as 
> appropriate. And you can do this so long as your not using shared workers. 
> The question then is, how to compile the .js files separately.
>
> The duracell <https://github.com/aatree/aademos/tree/master/duracell> demo 
> uses a web worker AND is itself compiled with optimizations none. There are 
> two things done to accomplish this:
>
>1. Duracell itself has no web worker code. Though it uses a library, 
>durable-cells <https://github.com/aatree/durable-cells>, which 
>includes a web worker.
>2. In the duracell build.boot 
><https://github.com/aatree/aademos/blob/master/duracell/build.boot> file, 
>the dev task uses pandeiro/boot-http 
><https://github.com/pandeiro/boot-http> rather than the simpler 
>tailrecursion/boot-jetty <https://github.com/tailrecursion/boot-jetty>. 
>The advantage to using boot-http is that it supports the loading of static 
>files from library jar files. In this case, that means the main code in 
>aaworker can create a web worker using durable-cell's dcells.js file.
>
> So how does the durable-cells library create the dcells.js file? Again, 
> there are two things done to accomplish this:
>
>1. In the durable-cells build.boot 
><https://github.com/aatree/durable-cells/blob/master/build.boot> file, 
>the dev task includes (cljs :optimizations :simple). This invokes the 
>compiler with an appropriate level of optimizations.
>2. But we still need to define the .js file. This is done in the 
>dcells.cljs.edn 
>

Re: [ClojureScript] Re: ANN replikativ 0.1.0 - strong eventual consistent P2P replication for clj and cljs

2016-01-22 Thread Thomas

>
> I am curious about what the Clojure community can come up with in this 
> area, as Clojure developers mostly open-source libraries, but not so 
> many build open-source applications as for instance free-software 
> communities in Python do. 
>
>
Just reading this and Braid came to mind:

https://github.com/braidchat/braid

Maybe that is something we can show off some Clojure and ClojureScript. 
Haven't had time yet to look at this myself yet.

Thomas 

-- 
You 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 replikativ 0.1.0 - strong eventual consistent P2P replication for clj and cljs

2016-01-20 Thread Thomas
Looks very interesting and I suspect there were some pretty hard problems to 
solve!!!

Thank you for open sourcing this.

Thomas

-- 
You 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.8.0 is now available

2016-01-20 Thread Thomas
An extra big thank you for all involved!!!

Thomas

On Wednesday, 20 January 2016 13:22:28 UTC, Alex Miller wrote:
>
> The docs just haven't been regenerated yet - that's coming.
>
>

-- 
You 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: Compare between clojure and Java

2016-01-05 Thread Thomas
While these examples are good (there is also a good one in Suart Halloways 
book for instance) I think it would be better to look at the difference for 
a whole project. There is for instance a talk from Nokia Bristol a few 
years ago (Now MixRadio)  where they went from 44K LOC to 4K LOC with more 
functionality. There are a few more examples around on the web I think.

Thomas

On Tuesday, 5 January 2016 13:27:10 UTC, Thomas Saillard wrote:
>
> Dear,
>  
> In order to good understand the powerful of Clojure,
> I have heard that compare to a code in java you need only few lines in 
> clojure.
> Is that true ?
> If it is the case, have you a sample of the 2 codes ?
> I appreciate your help.
> My Kind regards,
> Thomas
>

-- 
You 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.


Compare between clojure and Java

2016-01-05 Thread Thomas Saillard
Dear,
 
In order to good understand the powerful of Clojure,
I have heard that compare to a code in java you need only few lines in 
clojure.
Is that true ?
If it is the case, have you a sample of the 2 codes ?
I appreciate your help.
My Kind regards,
Thomas

-- 
You 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: If a Java function seems to never return, how do I test?

2015-10-31 Thread Thomas Heller

>
>
> What could we do to make the Exception visible, assuming there is one? 
>
>
Exceptions are ALWAYS visible, the only way they get lost is the try/catch 
blocks you added in your code which effectively swallow and ignore them. 
The JVM will not randomly lose an Exception, it is always code you write 
that decided to handle them in some way. If you do not know how to handle 
an exception do not catch it, printing its stacktrace and ignoring it is 
never a good idea.

In your case since you say that the function never returns I'd put my guess 
on an infinite loop. There is no exception that gets lost, your code is 
just still running. If your JVM is running locally you can attach to it via 
jvisualvm [1] and get a quick overview of what the JVM is doing. If you 
look at the thread information you'll see if something is still running or 
dead-locked somehow.

You can also use a debugger and step through the java code step by step.

Also, consider coding against interfaces in java (eg. java.util.List and 
java.util.Map instead of java.util.Collection), it will save you tons of 
conversion calls.

HTH
/thomas

[1] https://visualvm.java.net/

-- 
You 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: How do I return the data I need from this Exception?

2015-10-08 Thread Thomas Heller
I see no code to ever call

 (timbre/log :trace (str  "in catch-exceptions our reply was: " reply))   

Probably just a copy error, other than that things look correct.

The JVM is complex, but strange things happening are pretty much always 
related to programmer errors.

If you add that line things should work as expected?

Cheers,
/thomas

On Thursday, October 8, 2015 at 8:35:18 AM UTC+2, Lawrence Krubner wrote:
>
> I'm thinking that I've misunderstood something about how to catch an 
> Exception. I have these 2 functions: 
>
> (defn catch-exceptions [e this-users-conversation]
>   (try 
> (timbre/log :trace (str  "in catch-exceptions our exception was: " e))
> (let [error (:object (ex-data e))
>   status (if (:status error)
>(:status error)
>500)
>   body (if (:body error)
>  (:body error)
>  (str e))
>   intent (if (:intent this-users-conversation)
>(:intent this-users-conversation)
>"api")
>   reply {:message body :status status :intent intent}]
>   reply)
> (catch Exception e (println "in catch-exceptions we triggered this 
> exception: " e
>
> (defn pull-response-from-query [this-users-conversation function-to-call]
>   "Formatting exceptions as Peter requested so the iPhone app only needs 
> to check the top-level status."
>   (try
> (function-to-call this-users-conversation)
> (catch Exception e (catch-exceptions e this-users-conversation
>
>
> Testing in the terminal, and feeding in garbage in a deliberate attempt to 
> trigger the exception, I see this line over and over again: 
>
> (timbre/log :trace (str  "in catch-exceptions our exception was: " e))
>
> but I never get this line: 
>
>   (timbre/log :trace (str  "in catch-exceptions our reply was: " 
> reply))
>
> nor do I ever see: 
>
> "in catch-exceptions we triggered this exception: "
>
> What am I doing wrong? 
>
>
>
>
>

-- 
You 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: Trying to understand Clojure/Java concurrency performance?

2015-10-07 Thread Thomas Heller
FWIW getting 1mil+ connections will requires some OS level tuning even in 
Erlang. So you are not going to get that in a benchmark that is not set up 
for this.

In the JVM you are going to run into GC problems eventually, depending on 
how much state/memory you keep per connection. It might work with something 
Azul [1] offers but the standard JVM still has no comparable GC. You can do 
some heavy tuning of the different standard GCs but that is a science in 
itself and can not be answered without a deep understanding of your app 
architecture.

Erlang was specifically designed for this purpose and makes some things 
significantly simpler, so it is going to be much more straightforward 
writing such a system. Erlang is also pretty fun.

As you can see in the http-kit benchmark, the application itself barely 
uses any CPU. Most of it is GC, so this is going to be your worst enemy as 
you are going to run into some hefty GC pauses on large heaps, which will 
affect ALL connections. Erlang does not suffer from this problem.

I'm a big fan of using the right tool for the job, in this case I would 
recommend Erlang and only Erlang. Unless you want to write C, which is 
going to be much much harder and more prone to error. You can also use 
Erlang to handle all the connection stuff and interface it to a Clojure app 
that does the DB work, you do not have to write everything in Erlang.

Just my 2 cents,
/thomas

PS: I have not written such a system in either language, so everything is 
just an educated guess.

[1] https://www.azul.com/

On Wednesday, October 7, 2015 at 8:17:57 PM UTC+2, Nick Pavlica wrote:
>
> All,
> I posed this question with a little more detail in the Quasar/Pulsar group 
> in hopes that they may have some insight into my question (
> https://groups.google.com/forum/#!topic/quasar-pulsar-user/l8ZX7pk9bkI) 
> because they are more focused on that domain.  Hopefully, my question is 
> clear, if not please help me clarify it.
>
> Thanks Again
> -- Nick
>

-- 
You 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: Trying to understand Clojure/Java concurrency performance?

2015-10-07 Thread Thomas Heller
Just realized that I misread the http-kit benchmark, but still stand by my 
arguments. GC problems are pretty much directly tied to the size of the 
heap. So if you'd re-run the http-kit benchmark with a 8gb heap instead of 
3gb things would probably look different. How much heap you are going to 
need depends on your app. Also there is this whole aspects of latency vs. 
throughput.
 
I would recommend looking at everything Martin Thompson, Gil Tene or Cliff 
Click have written or spoken about, they are the real Java experts. 
Although they are not necessarily talking about networked server, pretty 
much all of it is till going to apply to an app of that scale. Are you sure 
you are going to need that scale? 1mil connections is a pretty ambitious 
goal.

/thomas

On Wednesday, October 7, 2015 at 8:50:47 PM UTC+2, Thomas Heller wrote:
>
> FWIW getting 1mil+ connections will requires some OS level tuning even in 
> Erlang. So you are not going to get that in a benchmark that is not set up 
> for this.
>
> In the JVM you are going to run into GC problems eventually, depending on 
> how much state/memory you keep per connection. It might work with something 
> Azul [1] offers but the standard JVM still has no comparable GC. You can do 
> some heavy tuning of the different standard GCs but that is a science in 
> itself and can not be answered without a deep understanding of your app 
> architecture.
>
> Erlang was specifically designed for this purpose and makes some things 
> significantly simpler, so it is going to be much more straightforward 
> writing such a system. Erlang is also pretty fun.
>
> As you can see in the http-kit benchmark, the application itself barely 
> uses any CPU. Most of it is GC, so this is going to be your worst enemy as 
> you are going to run into some hefty GC pauses on large heaps, which will 
> affect ALL connections. Erlang does not suffer from this problem.
>
> I'm a big fan of using the right tool for the job, in this case I would 
> recommend Erlang and only Erlang. Unless you want to write C, which is 
> going to be much much harder and more prone to error. You can also use 
> Erlang to handle all the connection stuff and interface it to a Clojure app 
> that does the DB work, you do not have to write everything in Erlang.
>
> Just my 2 cents,
> /thomas
>
> PS: I have not written such a system in either language, so everything is 
> just an educated guess.
>
> [1] https://www.azul.com/
>
> On Wednesday, October 7, 2015 at 8:17:57 PM UTC+2, Nick Pavlica wrote:
>>
>> All,
>> I posed this question with a little more detail in the Quasar/Pulsar 
>> group in hopes that they may have some insight into my question (
>> https://groups.google.com/forum/#!topic/quasar-pulsar-user/l8ZX7pk9bkI) 
>> because they are more focused on that domain.  Hopefully, my question is 
>> clear, if not please help me clarify it.
>>
>> Thanks Again
>> -- Nick
>>
>

-- 
You 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: macro help

2015-10-02 Thread Thomas Heller
Well, if you don't like that 'form' you could use a binding.

(binding [form/*state*
  {:editing? true
:values form-values
:validation validation-report
:on-change handle-form-change}]
  (form/tag 
(form/text :name)
(form/number :age)))

Anyways, I would not recommend using the binding but doesn't mean you can't.

I can't quite imagine what your future plans look like but you probably 
won't need a macro. ;)

cheers,
/thomas

On Friday, October 2, 2015 at 3:34:48 PM UTC+2, Colin Yates wrote:
>
> Hi Thomas - yes, you are right. The example I provided is all pain/no-gain 
> in terms of macros. However, future plans will require manipulating the 
> invocation of (for example form/text and form/number) before they are 
> evaluated.
>
> Having said all of that, that repeated ‘form’ does bug me a bit :-). I do 
> absolutely agree that the cognitive overhead of the macro isn’t justified 
> here.
>
> On 2 Oct 2015, at 14:29, Thomas Heller <th.h...@gmail.com > 
> wrote:
>
> Have you tried NOT using a macro at all? This code does not need to be a 
> macro at all if you ask me.
>
> Just a little sketch but things could look just about the same without any 
> macros at all:
>
> (let [form {:editing? true
> :values form-values
> :validation validation-report
> :on-change handle-form-change}]
>   (form/tag form
> (form/text form :name)
> (form/number form :age)))
>
>
> ;; in-ns 'form
>
> (defn text [form field]
>   [text-component {:id field
>:value (get-in form [:values field])
>...}])
>
> (defn tag
>   [{:keys [editing?] :as form} & children]
>   (into [:div.form.horizontal
>  {:class (if editing? "editing" "editable")}]
> children))
>
>
> Use macros very sparingly, most of the time data and functions are just 
> better.
>
> Just my 2 cents,
> /thomas
>
> On Wednesday, September 30, 2015 at 10:29:30 PM UTC+2, Colin Yates wrote:
>>
>> Hi all,
>>
>> I am banging my head against the wall - I think it is obvious but I have 
>> started too long:
>>
>> The use-case is that I want a form which takes a set of children. The 
>> form also takes in some form-wide state, like the form-wide validation, the 
>> values for each item etc. I want the macro, for each child, to decorate 
>> that child by extracting the validation errors and value from the form-wide 
>> state.
>>
>> So, assuming:
>>  - validation looks like {:name "Duplicate name" :age "You must be at 
>> least 0"}
>>  - form-values looks like {:name "a-duplicate-user" :age -1}
>>
>> then my form might look like:
>>
>> (form {:editing? true :values form-values :validation validation-report 
>> :on-change handle-form-change}
>>   [form/text {:id :name}]
>>   [form/number {:id :age}])
>>
>> After the macro I want the following code:
>>
>> [:div.form.horizontal
>>   {:class "editing"}
>>   [form/text {:id :name :value "a-duplicate-user" :errors "Duplicate 
>> name" :on-click (fn [e] (handle-form-change :name (-> e .target .value])]
>>   [form/number {:id :age :value "-1" :errors "You must be at least 0" 
>> :on-click (fn [e] (handle-form-change :age (-> e .target .value))]]
>>
>> However, ideally the macro would _not_ emit the contents of the input as 
>> literals but would emit code that inspects the provided parameters at 
>> run-time (i.e. rather than :value "a-duplicate-user" I would much prefer 
>> :value (-> state values :name) as that will allow me to pass in an atom for 
>> example.
>>
>> I have tried so many variations and evaluating the state (e.g. (:editing? 
>> state)) works fine as the emitted code has the destructured values, but 
>> that doesn't work for an atom.
>>
>> Here is my attempt at trying to emit code that interrogates the provided 
>> parameter.
>>
>> (defmacro form [state & elements]
>>   (let [state# state]
>> `[:div.form.horizontal
>>   {:class (if (:editing? state#) "editing" "editable")}
>>   ~@(map (fn [[_ {:keys [id]} :as child]]
>>(update child 1 assoc
>>:editing? (:editing? state#)
>>:value `(-> (:values state#) 'deref (get ~id))
>>:on-change `(fn [e#]
>>  (js/console.log "E: " 
>> (cljs.core/clj->js e#)

Re: macro help

2015-10-02 Thread Thomas Heller
Have you tried NOT using a macro at all? This code does not need to be a 
macro at all if you ask me.

Just a little sketch but things could look just about the same without any 
macros at all:

(let [form {:editing? true
:values form-values
:validation validation-report
:on-change handle-form-change}]
  (form/tag form
(form/text form :name)
(form/number form :age)))


;; in-ns 'form

(defn text [form field]
  [text-component {:id field
   :value (get-in form [:values field])
   ...}])

(defn tag
  [{:keys [editing?] :as form} & children]
  (into [:div.form.horizontal
 {:class (if editing? "editing" "editable")}]
children))


Use macros very sparingly, most of the time data and functions are just 
better.

Just my 2 cents,
/thomas

On Wednesday, September 30, 2015 at 10:29:30 PM UTC+2, Colin Yates wrote:
>
> Hi all,
>
> I am banging my head against the wall - I think it is obvious but I have 
> started too long:
>
> The use-case is that I want a form which takes a set of children. The form 
> also takes in some form-wide state, like the form-wide validation, the 
> values for each item etc. I want the macro, for each child, to decorate 
> that child by extracting the validation errors and value from the form-wide 
> state.
>
> So, assuming:
>  - validation looks like {:name "Duplicate name" :age "You must be at 
> least 0"}
>  - form-values looks like {:name "a-duplicate-user" :age -1}
>
> then my form might look like:
>
> (form {:editing? true :values form-values :validation validation-report 
> :on-change handle-form-change}
>   [form/text {:id :name}]
>   [form/number {:id :age}])
>
> After the macro I want the following code:
>
> [:div.form.horizontal
>   {:class "editing"}
>   [form/text {:id :name :value "a-duplicate-user" :errors "Duplicate name" 
> :on-click (fn [e] (handle-form-change :name (-> e .target .value])]
>   [form/number {:id :age :value "-1" :errors "You must be at least 0" 
> :on-click (fn [e] (handle-form-change :age (-> e .target .value))]]
>
> However, ideally the macro would _not_ emit the contents of the input as 
> literals but would emit code that inspects the provided parameters at 
> run-time (i.e. rather than :value "a-duplicate-user" I would much prefer 
> :value (-> state values :name) as that will allow me to pass in an atom for 
> example.
>
> I have tried so many variations and evaluating the state (e.g. (:editing? 
> state)) works fine as the emitted code has the destructured values, but 
> that doesn't work for an atom.
>
> Here is my attempt at trying to emit code that interrogates the provided 
> parameter.
>
> (defmacro form [state & elements]
>   (let [state# state]
> `[:div.form.horizontal
>   {:class (if (:editing? state#) "editing" "editable")}
>   ~@(map (fn [[_ {:keys [id]} :as child]]
>(update child 1 assoc
>:editing? (:editing? state#)
>:value `(-> (:values state#) 'deref (get ~id))
>:on-change `(fn [e#]
>  (js/console.log "E: " 
> (cljs.core/clj->js e#))
>  ((:on-change state#) ~id (-> e# 
> .-target .-value)
>  elements)]))
>
> The error I am getting is that there is such var as the gen-sym's state# 
> in the namespace.
>
> The generic thing I am trying to do is remove the boilerplate from each of 
> the items in the form.
>
> Any and all suggestions are welcome. 
>
> Thanks!
>

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


Re: macro help

2015-10-02 Thread Thomas Heller
Well, yeah .. don't use binding. Sometimes they are a good solution though, 
so don't forget about it.

Again I do not know your future plans. I would always recommend writing 
everything with data+functions first. If you find that you have written the 
same thing over and over again it might be time to introduce a new function 
OR actually a macro if that doesn't work.

Macros sure are extremely powerful, so figuring out exactly when to use 
them is quite hard. I know that it took me quite some time to get rid of 
the "hey, just use a macro" urge.

Anyways, glad we agree that your initial macro does not need to exist. ;)

cheer,
/thomas

On Friday, October 2, 2015 at 4:15:47 PM UTC+2, Colin Yates wrote:
>
> Hi Thomas, binding - really? :-). Apart from the general negative reaction 
> they seem to have, I don’t want the individual elements (e.g. text and 
> number) to assume rely on the binding as they can be called individually as 
> well and the binding would just get in the way.
>
> My understanding is that if I want to change a call to a function _before_ 
> that call happens then my only option is to use a macro?
>
> (I also realise this use-case will never need a macro as hiccup very 
> sensibly uses data so the thing passed to (form) is simply a vector.)
>
> I am saying, the discussion of whether _this example_ justifies a macro is 
> mute - I agree it doesn’t.
>
> On 2 Oct 2015, at 15:01, Thomas Heller <th.h...@gmail.com > 
> wrote:
>
> Well, if you don't like that 'form' you could use a binding.
>
> (binding [form/*state*
>   {:editing? true
> :values form-values
> :validation validation-report
> :on-change handle-form-change}]
>   (form/tag 
> (form/text :name)
> (form/number :age)))
>
> Anyways, I would not recommend using the binding but doesn't mean you 
> can't.
>
> I can't quite imagine what your future plans look like but you probably 
> won't need a macro. ;)
>
> cheers,
> /thomas
>
> On Friday, October 2, 2015 at 3:34:48 PM UTC+2, Colin Yates wrote:
>>
>> Hi Thomas - yes, you are right. The example I provided is all 
>> pain/no-gain in terms of macros. However, future plans will require 
>> manipulating the invocation of (for example form/text and form/number) 
>> before they are evaluated.
>>
>> Having said all of that, that repeated ‘form’ does bug me a bit :-). I do 
>> absolutely agree that the cognitive overhead of the macro isn’t justified 
>> here.
>>
>> On 2 Oct 2015, at 14:29, Thomas Heller <th.h...@gmail.com> wrote:
>>
>> Have you tried NOT using a macro at all? This code does not need to be a 
>> macro at all if you ask me.
>>
>> Just a little sketch but things could look just about the same without 
>> any macros at all:
>>
>> (let [form {:editing? true
>> :values form-values
>> :validation validation-report
>> :on-change handle-form-change}]
>>   (form/tag form
>> (form/text form :name)
>> (form/number form :age)))
>>
>>
>> ;; in-ns 'form
>>
>> (defn text [form field]
>>   [text-component {:id field
>>:value (get-in form [:values field])
>>...}])
>>
>> (defn tag
>>   [{:keys [editing?] :as form} & children]
>>   (into [:div.form.horizontal
>>  {:class (if editing? "editing" "editable")}]
>> children))
>>
>>
>> Use macros very sparingly, most of the time data and functions are just 
>> better.
>>
>> Just my 2 cents,
>> /thomas
>>
>> On Wednesday, September 30, 2015 at 10:29:30 PM UTC+2, Colin Yates wrote:
>>>
>>> Hi all,
>>>
>>> I am banging my head against the wall - I think it is obvious but I have 
>>> started too long:
>>>
>>> The use-case is that I want a form which takes a set of children. The 
>>> form also takes in some form-wide state, like the form-wide validation, the 
>>> values for each item etc. I want the macro, for each child, to decorate 
>>> that child by extracting the validation errors and value from the form-wide 
>>> state.
>>>
>>> So, assuming:
>>>  - validation looks like {:name "Duplicate name" :age "You must be at 
>>> least 0"}
>>>  - form-values looks like {:name "a-duplicate-user" :age -1}
>>>
>>> then my form might look like:
>>>
>>> (form {:editing? true :values form-values :validation validation-report 
>>> :on-change handle-form

Re: scheduling with core.async?

2015-09-23 Thread Thomas Heller
To be honest I see no point in using core.async or any other library for 
that matter. Java already solves this problem very well.

(ns ...
  (:import [java.util.concurrent TimeUnit Executors]))

(def scheduler
  (doto (Executors/newSingleThreadScheduledExecutor)
(.scheduleAtFixedRate
 the-function-that-gets-called-every-hour
 0 ;; initial delay till execution starts
 1 ;; delay between each runs
 TimeUnit/HOURS ;; the unit of the above two values
 )))

When and where you set this up is dependent on your app and you must 
remember to (.shutdown scheduler) at some point, but beyond that it is 
pretty simple.

HTH,
/thomas

On Wednesday, September 23, 2015 at 1:00:32 PM UTC+2, bahadir cambel wrote:
>
>
> Hi Leon, 
>
> you may check http://www.clojure-toolbox.com/ and see the schedule 
> section. Here are the suggestions; 
>
> https://github.com/jarohen/chime (has core.async examples)
> https://github.com/overtone/at-at
> https://github.com/zcaudate/cronj
>
> Also, if you're using HTTP-Kit http://www.http-kit.org/timer.html
>
> Cheers,
> Bahadir
> twitter.com/bahadircambel
>
>
>
>
>
>
> On Tuesday, September 22, 2015 at 4:35:37 PM UTC+2, Leon Grapenthin wrote:
>>
>> Is it recommended to use core.asyncs timeout channel to wait on hour or 
>> even longer for light scheduling tasks?
>>
>> High precision is a nongoal.
>>
>> Kind regards,
>>  Leon.
>>
>

-- 
You 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/Pedestal vs Go

2015-09-14 Thread Thomas Heller
Hey,

this might not be too relevant to your project but since you said "web 
project" it might be.

I cannot speak for Go but Clojure is "fast enough". I went from Ruby to 
Clojure in one app and the difference was huge (150ms-ish -> 10ms-ish). I'm 
actually somewhat of a performance junkie and even got most Clojure numbers 
down to 2ms but NONE OF IT MATTERED! At the time of transition most of the 
frontend was still a large ball of jQuery-sphagetti and absolutely no 
proper HTTP caching config in the backend. While the initial request got 
faster we were still looking at average page load times of 3+ seconds. When 
I started rewriting all of the speed related stuff in the frontend the 
performance gains were huge, it more than halved the average page load time 
which had a far greater impact overall than the choice of programming 
language in the backend.

None of these techniques are specific to any programming language. What had 
the biggest impact for me was that in Clojure you are just writing 
Clojure(Script). You don't have to switch between 2 languages for the 
backend/frontend and get some of the most amazing tools (Closure Compiler) 
for "free". When it comes to raw speed Clojure and Go will probably produce 
rather similar numbers, but for me Clojure definitely has the better 
development story. (Disclaimer: I actually don't know anything about Go 
frontend story.) 

I don't care much for micro benchmarks in any language and you should not 
make decisions based on them. Look at the whole stack. The initial response 
time for a "hello world" request will never properly reflect your 
production app. In the end all that matters is your code, it won't be fast 
just because it is Go and not a JVM.

Just my 2 cents,
/thomas





On Sunday, September 13, 2015 at 9:44:48 PM UTC+2, Alan Thompson wrote:
>
> Hi,
>
> I'm about to start a new web project and they are thinking about using Go 
> (golang) instead of a JVM (preferably Clojure) based approach.  The idea is 
> "BARE METAL SPEED!!!", but I really think the network and DB will be the 
> bottlenecks, not Clojure vs Go.
>
> Is anybody out there aware of any speed comparisons using Clojure/Pedestal 
> and/or Go?  I'm thinking basic measurements like connections/sec, latency, 
> simultaneous users, etc.
>
> Thanks,
> Alan
>

-- 
You 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: Just found out about Elixirs function argument pattern matching...

2015-09-08 Thread Thomas Heller
I don't use schema/core.typed much in my actual projects, while I have done
many attempts it just never worked out. I like the idea and should
definitely use them more but it is just too much of a moving system and not
stable enough yet (eg. didn't even know s/either is deprecated).

If you look at these implementations

(def OneOff [(s/one s/Str 'name) (s/one s/Str 'email)])

(s/defrecord OneOff
[name :- s/Str
 email :- s/Str])

(defrecord OneOff [name email])

All of them do more or less the same thing, just different. Clojure has
really good support for records and they feel natural to me. I don't need
to remember that :email is the second field. So I can do (:email one-off)
instead of (get one-off 1). Remembering the positions can get tedious and
very error prone over time. Always remember that software evolves over time.

(:email one-off) still works if my data changes to (defrecord OneOff [name
note email]), the vector version doesn't. Referring to things by name is a
good thing.

I do not know Elixir but in Erlang you very rarely use tuples for actual
data, usually just messages and return values. Data is all Records, maybe
maps these days but I left before R15B so can't say.

I usually only do data validation on the system boundary and trust in it
after. Otherwise you might end up validating the same data over and over
again. So if I get something from a user (eg. HTTP) I validate that it is
what I expect and transform if needed. I have an explicit (if
(is-this-what-i-expect? data) ...) and not something hidden in a {:pre ...}
or some macro magic. I expect the data to be wrong (never trust the user)
and want to test that assumption ASAP. I don't like to use exception for
validation errors. Writing validation functions is not fun but it is very
simple.

YMMV, do what feels right.

Keep it simple.

/thomas




On Tue, Sep 8, 2015 at 4:42 AM, Amith George <strider...@gmail.com> wrote:

> >> I probably wouldn't use protocols since I doubt there is a function
> signature that is exactly identical for all branches. Each branch probably
> needs access to different parts of your system (eg. database) and always
> passing everything to everything is not ideal.
>
> >> Multi-Method is great if you want something openly extensible but that
> again seems unlikely here and also assumes that everything requires the
> same arguments.
>
> I had the same concerns and wanted to use a simple function with
> pattern/condition matching to dispatch to the appropriate function. I had
> considered using Records as synonymous with using polymorphic calls (multi
> methods, protocols). Its good to know the alarm bells ringing in my head
> had merit :). Thanks for that.
>
> Thinking out loud, if we are not using Records for polymorphism, are we
> using it to guarantee structure? If you could indulge me a little more,
> consider the following two implementations.
>
>
> (def OneOff [(s/one s/Str 'name) (s/one s/Str 'email)])
>
> (defn send-one-off
>   [something thing [name email :as data]]
>   {:pre [(s/validate OneOff data)]}
>   ,,,)
>
> (defn send
>   [app thing recipient]
>   (match [recipient]
> [[:one-off & data]] (send-one-off (:something app) thing data)))
>
>
>
>
> Individual schema are created for each variant case and are checked
> against by the respective functions. The dispatch function only needs to
> know how to check for individual cases of the variant.
>
>
> (def OneOffMap {:type (s/eq :one-off) :name s/Str :email s/Str})
> (def ExistingContactMap {:type (s/eq :existing) :contact-id s/Int})
>
> (def Recipient (s/either ExistingContactMap OneOffMap))
> ;; s/either is deprecated and s/cond-pre is recommended
> ;; however, validating valid OneOffMap data using the following
> ;; still throws an error.
> ;; (def Recipient (s/cond-pre ExistingContactMap OneOffMap))
>
> (defn send-one-off
>   [something thing {:keys [name email] :as data}]
>   ,,,)
>
> (defn send
>   [app thing recipient]
>   {:pre [(s/validate Recipient recipient)]}
>   (match [(:type recipient)]
> [:one-off] (send-one-off (:something app) thing recipient)))
>
> This reverts to using a map with a :type key. Individuals schema for each
> :type value. A combined schema to represent a recipient. The dispatch
> function only needs to know about the existence of the :type key and the
> values it can handle.
>
>
> Whether we use records or maps or variants, the dispatch function needs to
> know what contract is implemented by recipient. Whether it will be an
> instance of something, or a variant or a map with type keys. Neither
> versions care for any other data present in recipient or its structure.
>
> At this point I am confused, what makes one version better than the other.
> Creating schema definiti

Re: Just found out about Elixirs function argument pattern matching...

2015-09-08 Thread Thomas Heller

>
>
> For instance, which one of these to you consider to be the best 
> representation of a event to set the expiry time:
>
>[:cache/expire #inst "2015-09-08T12:00:00Z"]
>
>{:type :cache/expire, :value #inst "2015-09-08T12:00:00Z"}
>
>#cache.Expire [#inst "2015-09-08T12:00:00Z"]
>
>#cache.Expire {:value #inst "2015-09-08T12:00:00Z"}
>

None of those, well the {:type ... :value ...} one is closest.

I tried to stay away from the Type/Variant discussion since I'm not 
familiar enough with all the theory behind it and generally like to be more 
practical. Also there isn't enough context in your question to give an 
acceptable answer. Generally I'd have something like (set-expiration-time 
thing time) but since you said "event" I assume you have some kind of 
messaging system. So I'd abstract the usual message patterns and use a 
message "envelope".

(defrecord Message [type payload])

type would probably be a Keyword and payload probably Any.

So to write it as edn:

#my.app/message [:cache/expire #inst "2015-09-08T12:00:00Z"]
#my.app/message {:type :cache/expire, :payload ...}

Note that this is ONLY the representation on-the-wire which you generally 
want to be compact as possible, so I'd choose the vector variant since it 
is more compact and doesn't encode the keys.

What I get when I "read" this data is not tied to the data format used on 
the wire though, don't mix those up. The wire-format has totally different 
requirements than your code.

/thomas






-- 
You 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: Just found out about Elixirs function argument pattern matching...

2015-09-07 Thread Thomas Heller
FWIW before I came to Clojure I did a lot of Erlang and in the beginning I 
was at the exact same spot wanting to use pattern matching everywhere 
because it is so damn cool. Same goes for tagged literals.

After a little while I realized that it is just not the way to do it in 
Clojure and forcing the Erlang(or Elixir)-Way onto Clojure is not ideal and 
probably overthinking it. Protocols provide a good/better solution to some 
problems and using Clojure's excellent handling of "data" solves 
the rest. While it might feel weird in the beginning, wait a while for 
Clojure to click and you probably won't even miss pattern matching.

Looking at the "(defn register [...])" example. Where is the problem with 
the first solution? It doesn't have the bugs the other implementations have 
and is extremely simple to reason about? The other two solutions do the 
exact same thing just slower with absolutely no gain. If you need the 
"status" abstraction use a real state machine. Don't write a recursive 
function when you don't have to. The code should never be at a point where 
it can be called with forged data and directly skip over the :create and 
:check-unqiue states which is possible in 2 of the 3 solutions.

Embrace the data and data all the things is all I have to say.

Also if you like types (using prismatic/schema [1], core.typed looks pretty 
similar):

(def ContactId s/Int)

(s/defrecord Placeholder
[text :- s/Str])

(s/defrecord Existing
[contact-id :- ContactId])

(s/defrecord OneOff
[name :- s/Str
 email :- s/Str])

(def Recipient
  (s/either PlaceHolder
Existing
    OneOff))

Just my 2 cents,
/thomas

[1] https://github.com/Prismatic/schema


>  
> Possible F# (might not compipe!!)
>
> Recipient = | Placeholder of string
>| Existing of ContactId
>| OneoffRecipient of string * string
>
>
> Possible options in Clojure
>
> {:type :placeholder ; or :existing :one-off
>  :placeholder-text :all-my-team-mates
>  :name nil
>  :email nil
>  :contact-id nil
> }
>
> ;; or
>
> (defrecord PlaceholdRecipient [placeholder-text])
> (defrecord ExistingReceipient [contact-id])
> (defrecord OneoffReceipient [name email])
>
> ;; or 
>
> [:one-off name email]
> [:existing contact-id]
> [:placeholder text]
> ;; [:self]
>
> The variant needed not be a two element vector. It is a 1 or more element 
> vector. We could just as easily have a fourth variant [:self] with no data 
> to indicate send message to self. 
>
> To actually use the above data structures and get the actual email 
> addresses from them, we need atleast three methods - 1) fetch the emails of 
> all the users team mates, 2) fetch the email for a contact in the 
> datastore, 3) return the email as is. We could implement these using a 
> multi method or implement some protocol or use a pattern matched method. 
> Each choice has a different extensibility story and are all equally valid. 
> We don't always replace every hashmap with a record. Variants are a viable 
> alternative over using a map like the one shown in the first Clojure 
> choice. 
>
> >> As much as possible I try to build my apps in such a way that the 
> program can self-explore the data you give it to self-optimize, 
> self-extend, or otherwise provide flexibility to the programmer. You can't 
> do that with a variant as a vector. Hand a vector to a function and the 
> logic has to be something like "If this is a two element vector and the 
> first thing is a keyword, then this might be a variant, but I'm not sure 
> because it could also just be a vector". While if you pass in a record, 
> type, or even a variant type, it's trivial to have a program recognize that 
> value and act upon it. 
>
> I have no experience writing apps that had to operate on any arbitrary 
> data with any arbitrary structure. Pretty much all the functions in my apps 
> could rely on data arriving in a particular format in a particular order 
> (positional destructuring). 
>
> More importantly we are pretty much agreeing that [:tagged vectors with 
> some data] are only a representation of a variant. One chosen out of 
> convenience and existing feature set. We could have a defrecord Variant 
> with two fields, a type keyword and value hashmap. If core.match was able 
> to easily pattern match over a record as well as easily destructure the 
> values in the value hashmap, we would use it. From what I have seen of 
> core.match, it is nowhere near as easy/clean as pattern matching a vector.
>
> >> As far as performance goes, this is normally the sort of thing that 
> gets baked into an app at a pretty low level, that's why I suggest it 
> should be as fast as possible. If you're going t

Re: Just found out about Elixirs function argument pattern matching...

2015-09-07 Thread Thomas Heller

>
>
> (def Recipient
>>   (s/either PlaceHolder
>> Existing
>> OneOff))
>>
>
> This looks interesting. Where would I actually use this? I mean, if I have 
> created three records, I may as well implement multi methods or protocols, 
> right? Even if I don't do those, I will still need to use `(condp instance? 
> obj ...)` or equivalent to select the appropriate branch for processing. Is 
> there a way I can use Recipient to select a branch? 
>

I probably wouldn't use protocols since I doubt there is a function 
signature that is exactly identical for all branches. Each branch probably 
needs access to different parts of your system (eg. database) and always 
passing everything to everything is not ideal.

Multi-Method is great if you want something openly extensible but that 
again seems unlikely here and also assumes that everything requires the 
same arguments.

cond(p) sounds perfect for this case. I tend to write each branch as a 
single function and keep the dispatch as compact as possible.

(defn send-placeholder [thing {:keys [text]}]
  ...)

(defn send-existing [db thing {:keys [contact-id]}]
  ...)

(defn send-one-off [something thing {:keys [name email]}]
  ...)

(defn send [app thing recipient]
  (condp instance? recipient
PlaceHolder
(send-placeholder thing recipient)
Existing
(send-existing (:db app) thing recipient)
OneOff
(send-one-off (:something app) thing recipient)))


That greatly reduces the cognitive load when looking at each separate 
implementation and also keeps the actual internal structure of the 
Recipient out of the dispatch. The conpd does not need to know how many 
fields are in OneOff, the tuple/vector/variant match versions must know 
that. 

/thomas






-- 
You 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: when the body of the request is HttpInputOverHTTP, how do I get the string representation?

2015-08-19 Thread Thomas Heller
No idea what HttpInputOverHTTP is but I'd guess that it is an InputStream 
implementation.

Try (slurp (:body request))

HTH,
/thomas

On Wednesday, August 19, 2015 at 9:57:57 PM UTC+2, Lawrence Krubner wrote:

 I know this has been asked before, but Google is interpreting 
 HttpInputOverHTTP as Http Input Over HTTP which renders it useless for 
 finding conversations that are specific to the HttpInputOverHTTP class. 
 (off topic: I wish there was a good search engine for software terms).

 I've a simple web app using Jetty and Ring and Compojure. The body of each 
 request that comes in is: 

 :body #HttpInputOverHTTP HttpInputOverHTTP@3aa0a4ac

 If I do: 

 (str (:body request))

 I simply get:

 HttpInputOverHTTP@3aa0a4ac

 Can someone remind how I get a string representation of what should be in 
 the body? 











-- 
You 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.


Is this resource only loaded once?

2015-08-14 Thread Thomas Goossens

When a java class uses the compiled Test (gen-class) from test namespace. 
Everytime the static function -run is called, will parser be slurped again 
or only once ?

(ns test  (:gen-class   :name Test   :methods [ ^:static [run [] 
String]))  (def parser (slurp ..))

(defn -run [] ;... do something with parser )



-- 
You 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: Is this resource only loaded once?

2015-08-14 Thread Thomas Goossens
Thank you gary!

(Hope to see soon again :) )

On Friday, August 14, 2015 at 1:30:08 PM UTC+2, Gary Verhaegen wrote:

 Once you've AOT compiled that (which is necessary for the class to be 
 actually generated), slurp won't be called again. Beware, however, that 
 `def` (and hence `slurp`) will be executed by the compiler, at compile 
 time, in the context (classpath, cwd, etc.) of the compiler, which may not 
 be what you want.

 Note that you can easily test that by replacing your def with:

 (def parser
   (do (println def parser executed)
   (slurp .)))

 If you want the parser to be slurped once per execution, you can use an 
 atom and a function, something like:

 (let [p (atom nil)]
   (defn parser
 []
 (swap! p (fn [p] (if (nil? p) (slurp ) p)

 You can then access your parser with (parser), which will only slurp the 
 file once. (If it matters, there are alternatives that will not keep on 
 paying the atom update cost.)



 On 14 August 2015 at 10:59, Thomas Goossens con...@thomasgoossens.be 
 javascript: wrote:

 When a java class uses the compiled Test (gen-class) from test namespace. 
 Everytime the static function -run is called, will parser be slurped again 
 or only once ?

 (ns test  (:gen-class   :name Test   :methods [ ^:static [run 
 [] String]))  (def parser (slurp ..))

 (defn -run [] ;... do something with parser )
 


 -- 
 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 
 javascript:
 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 javascript:
 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 javascript:.
 For more options, visit https://groups.google.com/d/optout.




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


Re: Using go/! like C#'s async/await

2015-07-30 Thread Thomas Heller
Hey,

I made a similar suggestion (minus the ThreadLocal) a few weeks ago, 
although for slightly different reasons. [1]

It should be noted that your async macro does in fact use the dispatcher 
just like a normal go would, the only difference is that it will start 
executing immediately in the current thread until the first pause instead 
of dispatching. After the pause the dispatcher will run it though which 
is not guaranteed to be the same thread. Therefore I'm not actually sure a 
ThreadLocal will work. Did you test that you get the actual correct result?

Your benchmark is also not very useful, you are basically just measuring 
the frameworks overhead which is tiny to what it provides. In actual 
programs most of the time will not be spent in core.async internals, at 
least not from what I have observed so far. go blocks are actually pretty 
cheap.

YMMV,
/thomas


[1] http://dev.clojure.org/jira/browse/ASYNC-131

On Thursday, July 30, 2015 at 8:52:45 AM UTC+2, Martin Raison wrote:

 go blocks tend to spread in Clojure programs just like async/await in 
 C#/Hack/Python, etc. The problem is that they aren't cheap.

 I was curious to know what you guys think of the following workaround: 
 http://blog.martinraison.com/clojure/2015/07/27/clojure-core-async-go-blocks-everywhere.html
 (TL;DR: use go only in the few functions that do some actual work, in 
 all other places use an alternate version - called async in the article - 
 that doesn't use the dispatcher and doesn't create a chan. The only thing 
 async does is handling the state machine stuff, so that !, alt!, etc 
 work as expected.)

 Does that seem reasonable or do you see a better way 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
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] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component

2015-07-03 Thread Thomas Heller
That article makes it sound like an OOP beast, it is really much simpler 
than that. 

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component

2015-07-03 Thread Thomas Heller
Hey James,

the webserver being a client is really very simple. Basically instead of 
starting one app you start two. Your actual app and the web-app that 
depends on app. One contains your business logic and the other everything 
related to translating HTTP to app API calls. app doesn't know about the 
web part.

The component stuff also assumes that the web server itself is not a 
component. A typical Servlet Container is built this way, it assumes that 
it will host your app and not the other way around. I use http-kit but I 
still want that hierarchy. Trying to turn the web server itself into 
component just produces nightmares of cyclic dependencies and such.

Can't really explain this very well, it is way too hot to think straight.

I wanted to create a proper library out of my component stuff for a while 
but never get around to it. I might do that some day to create an actual 
example I can refer to.

Cheers,
/thomas


On Friday, July 3, 2015 at 9:39:24 AM UTC+2, James Henderson wrote:

 Hey Thomas, thanks for your e-mail :)

 On Monday, 29 June 2015 11:25:44 UTC+1, Thomas Heller wrote:

 Hey,

 interesting approach but I don't like the nesting and manual wiring of 
 dependencies. 


 I've found people at both ends of that particular spectrum - some that 
 won't live with DI, some that won't live without it :) I guess a library 
 like Yo-yo has two options - either be opinionated about it, or let people 
 choose one or the other. In this case, I've chosen to let people choose - 
 there's nothing about Yo-yo that mandates the nesting (except the top-level 
 function) - what you do within that is up to you.
  

 I don't quite like that every with-* function remains on the stack as 
 well, but it shouldn't hurt that much. 


 Hmm - I was wondering about that too. Maybe an approach similar to 
 trampoline would help here?
  

 An uncaught exception will also take down your entire system, but I guess 
 you'd have a try/catch in your latch anyways.


 I'm not sure it will? If there's an exception thrown during system 
 startup, the components will then have an opportunity to stop themselves 
 (in the reverse order) because of their try/finally's - I'd say this is the 
 behaviour we'd want, in order to avoid half-started systems. Once the 
 system's started, and (latch) called, an uncaught exception in the 
 components won't stop the system - because it'll be thrown on a different 
 thread, if I understand correctly? Certainly need to write some test cases 
 around it!
  


 But what I miss the most is an instance of your app (ie. all components 
 together). You create it yourself in the example but I really want that 
 always. Sometimes you just want to access your system from the outside just 
 to see whats up (eg. REPL into a live system). I also consider the 
 webserver to be a client of my app and not part of it (or another layer 
 of it if you will), but that is a topic for another day.


 Yep, I agree with this - I've been using some workarounds to get values 
 out of the system, none of them particularly pretty. Interesting idea about 
 the webserver being a client of the app - would be good to see where you 
 take that?


 Way way back in the day I used to work with (and on) PicoContainer which 
 was/is a dependency injection and lifecycle management container. I tried 
 writing a DSL for it (in Groovy, this was 2003 or so) but concluded that 
 Java already was good enough to set everything up, a DSL (or XML) is 
 overkill. All you need to describe a Component is:

 a) what are its dependencies
 b) how do I start it
 c) how do I stop it

 In that light I wrote my own dependency injection helper functions 
 since nothing like Stuart's Component existed at the time I got into 
 Clojure. I don't like Component due to its invasive protocol but in essence 
 I do the same.

 In my system I just set up a map of components and use that as a 
 descriptor for wiring:

 {:a {:depends-on []
  :start my.components.a/start
  :stop my.components.a/stop}
  :b {:depends-on [:a]
  :start my.components.b/start
  :stop my.components.b/stop}}
  
 The key in the outer map becomes whatever the :start function returns and 
 is refered to it by its name :a (the key of the map). The :start function 
 of :b is called as (my.components.b/start instance-of-a). An instance of a 
 component is treated as an opaque value and other components interact with 
 it only via its public interface (ie. my.components.a). Whether this is 
 done via a protocol or not doesn't matter. When a shutdown is requested the 
 :stop function is called with the instance of the component as the argument.

 That is about it. Mocking is just assoc over default descriptor map and I 
 have helper functions to only do partial start/stop calls if only a 
 specific component is needed (eg. I only need :a).

 Like I said it basically does the same stuff as Component, just a little 
 less invasive since I think a component should not know

Re: [ANN] Introducing Yo-yo, a protocol-less, function composition-based alternative to Component

2015-06-29 Thread Thomas Heller
Hey,

interesting approach but I don't like the nesting and manual wiring of 
dependencies. I don't quite like that every with-* function remains on the 
stack as well, but it shouldn't hurt that much. An uncaught exception will 
also take down your entire system, but I guess you'd have a try/catch in 
your latch anyways.

But what I miss the most is an instance of your app (ie. all components 
together). You create it yourself in the example but I really want that 
always. Sometimes you just want to access your system from the outside just 
to see whats up (eg. REPL into a live system). I also consider the 
webserver to be a client of my app and not part of it (or another layer 
of it if you will), but that is a topic for another day.


Way way back in the day I used to work with (and on) PicoContainer which 
was/is a dependency injection and lifecycle management container. I tried 
writing a DSL for it (in Groovy, this was 2003 or so) but concluded that 
Java already was good enough to set everything up, a DSL (or XML) is 
overkill. All you need to describe a Component is:

a) what are its dependencies
b) how do I start it
c) how do I stop it

In that light I wrote my own dependency injection helper functions since 
nothing like Stuart's Component existed at the time I got into Clojure. I 
don't like Component due to its invasive protocol but in essence I do the 
same.

In my system I just set up a map of components and use that as a descriptor 
for wiring:

{:a {:depends-on []
 :start my.components.a/start
 :stop my.components.a/stop}
 :b {:depends-on [:a]
 :start my.components.b/start
 :stop my.components.b/stop}}
 
The key in the outer map becomes whatever the :start function returns and 
is refered to it by its name :a (the key of the map). The :start function 
of :b is called as (my.components.b/start instance-of-a). An instance of a 
component is treated as an opaque value and other components interact with 
it only via its public interface (ie. my.components.a). Whether this is 
done via a protocol or not doesn't matter. When a shutdown is requested the 
:stop function is called with the instance of the component as the argument.

That is about it. Mocking is just assoc over default descriptor map and I 
have helper functions to only do partial start/stop calls if only a 
specific component is needed (eg. I only need :a).

Like I said it basically does the same stuff as Component, just a little 
less invasive since I think a component should not know about the container 
it runs in.

  
Hope that was somewhat useful as feedback to Yo-Yo.

Cheers,
/thomas


On Sunday, June 28, 2015 at 4:03:34 PM UTC+2, James Henderson wrote:

 As promised, have blogged: 'Yo-yo  Component - Side by Side 
 https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org
 '

 Contents:


- Making components 

 https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#making-components
- Using a component as a dependency 

 https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#using-a-component-as-a-dependency
- Serving a REST API 

 https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#serving-a-rest-api
- Wiring it all up 

 https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#wiring-it-all-up
- Yo-yo / Component Interoperability 

 https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#yo-yocomponent-interoperability
- Mockable Services 

 https://github.com/james-henderson/yoyo/blob/master/articles/side-by-side.org#mockable-services
- ‘Mocking out’ dependencies 

 https://github.com/james-henderson/yoyo/blob/master/articles/mocking-out-dependencies

 Let me know what you think!

 Cheers,

 James

 On Thursday, 25 June 2015 09:25:56 UTC+1, James Henderson wrote:

 Seems like the next step for this would be for me to put together a blog 
 with an example Component system, and its equivalent Yoyo system?! :) 
 Should have time for that over the weekend.

 James

 On Thursday, 25 June 2015 09:05:39 UTC+1, James Henderson wrote:



 On Wednesday, 24 June 2015 11:17:41 UTC+1, Atamert Ölçgen wrote:



 On Tue, Jun 23, 2015 at 11:47 PM, James Henderson ja...@jarohen.me.uk 
 wrote:

 Hi Atamert - thanks :)

 I thought it might be preferable to keep the call to (latch)explicit 
 - it means that ylet can be used in nested calls, too - for example, 
 to set up and compose groups of components/sub-systems: (contrived 
 example, 
 though!)

 ;; (docs for ylet at 
 https://github.com/james-henderson/yoyo#introducing-ylet )

 (require '[yoyo :refer [ylet]])
  
 (defn with-connections [config f]
   (ylet [db-pool (with-db-pool (:db config))
  es-conn (with-es-connection (:elasticsearch config))]
  
 (f {:db-pool db-pool
 :es-conn es-conn})))
  
 (defn make-system [latch]
   (let [config ...]
 (ylet

Re: ring - setting no-cache for everything?

2015-06-19 Thread Thomas Heller



 Cache-control is evil. Users concerned with seeing the most up-to-date 
 information know to hit reload (and probably do anyway, just to be sure), 
 and there's also the option of AJAX polling for that (or whatever precisely 
 sites like Facebook do).

  
I don't even  a wrong Cache-Control will cause problems but 
Cache-Control is probably one of the most important headers to set for your 
webapp. It is also one of the harder ones to get right but the benefits are 
significant.

As for preventing users from seeing stale CSS/Javascript I'd recommend 
serving files with a unique name which changes with each new release. This 
way old HTML refers to old CSS and new HTML to new CSS, plus you can add 
Cache-Control: public, max-age=31536000 to the static files which allows 
the browser to actually SKIP checking if a resource was modified (ie. huge 
speed gains, no if-modified-since-not modified round trip).

Disabling cache is usually the least desirable option and if you care about 
performance at all you should think twice before doing so (yes, even for 
intranet sites). 

/thomas

-- 
You 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: Making Java serializables transparently printable and readable

2015-06-17 Thread Thomas Heller
On Wed, Jun 17, 2015 at 9:50 PM, James Reeves ja...@booleanknot.com wrote:

 On 17 June 2015 at 09:51, Thomas Heller th.hel...@gmail.com wrote:

 On another note: Sessions in cookies should be VERY VERY small.
 java.io.Serializable usually isn't small and especially if you go java
 object - binary - base64 - base64 (yes twice) - encrypt. The size of
 the cookie matters as it is transmitted with EVERY request.


 The cookie is only transmitted when the session changes. However, several
 browsers place limits on the size of stored cookies, and so it's generally
 not a good idea to serialize anything large into a cookie.



They are transmitted for every request client - server. If you host
images/css/js on the same host each request will contain the cookie. 2kb
cookie for 100 requests (quite common for webapps) and all the
optimizations done to keep javascript small go out the window.

-- 
You 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] piton - SQL-targeting migrations and seeding

2015-06-17 Thread Thomas Meier
Just put up a little library for sql migrations and seeding. I wanted 
something really simple; naturally at the cost of generality. Thus this is 
a weaker take on migrations and seeding that focuses specifically on SQL 
databases. Comes with a plugin to help with managing things--specifically 
for writing an edn file for handling migrations and seeding from an uberjar 
(keeping my database credentials out of version control).

*https://github.com/thomasmeier/piton 
https://github.com/thomasmeier/piton*




-- 
You 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: Making Java serializables transparently printable and readable

2015-06-17 Thread Thomas Heller
Hey,

the issue is not in clojure.core. It is with ring in this case, it uses 
clojure.tools.reader.edn/read-string which supports an optional {:readers 
{...}} argument but there is no way to specify those in ring. Should be a 
fairly simple fix though, doing anything to clojure.edn won't help as it is 
not used.

On another note: Sessions in cookies should be VERY VERY small. 
java.io.Serializable usually isn't small and especially if you go java 
object - binary - base64 - base64 (yes twice) - encrypt. The size of 
the cookie matters as it is transmitted with EVERY request.

I would recommend writing print-method implementation for the Java objects 
you need to serialize and keeping those to a minimum. Session cookies are 
not arbitrary storage and writing a transparent serialization format that 
doesn't check the size will lead to uncontrolled growth. I have seen way 
too many web apps with cookies above 4kb. One even had Apache configured to 
reject requests (well, default config) that had too large cookies and no 
one even noticed except for the users that left confused and never came 
back.

Just as a warning. :)

Cheers,
/thomas



On Wednesday, June 17, 2015 at 3:47:39 AM UTC+2, Surgo wrote:

 I've been working on a Ring app that involves storing sessions as cookies, 
 and within the session there are a couple Java objects that implement 
 java.io.Serializable. I was somewhat surprised to find that the print-dup 
 multimethod didn't have native support for Java Serializables, though I can 
 understand why (they aren't really meant for long-term storage because 
 version changes are troublesome). It wasn't too much trouble to come up 
 with a basic implementation that could cover all of java.io.Serializable: 
 https://bitbucket.org/snippets/morgon/jkjyA

 The trouble I'm having comes with reading it back in, though. In the above 
 snippet, we output as a function call and depend on the behavior of 
 clojure.core/read{,-string} to evaluate the function where the magic 
 happens. This obviously doesn't work with the safer and recommended 
 clojure.edn/read{,-string}. According to the EDN specification I should be 
 able to set a dispatch tag like, say, #java base64 and attach a 
 deserialization function to :readers for the tag. This isn't transparent 
 though: I can't just include the library and have it work with Ring's 
 already-existing (de)serialization, nor anywhere else that doesn't 
 explicitly pass my special function to clojure.edn/read{,-string}.

 Is there anything I can do without filing a ticket and hoping something 
 comes to be a part of the core library? To the best of my knowledge there's 
 no binding I can alter for the :readers or :default options for 
 clojure.edn/read{,-string}; that needs to be passed directly into the 
 function at the call site. I could maybe alter the clojure.edn/read and 
 clojure.edn/read-string vars themselves to wrap them so I can pass in a 
 :readers option with my tag, though that seems kind of nasty and I'm not 
 sure it will work in 100% of cases. What is there that can be done for this 
 problem?

 Thanks,
 -- Morgon


-- 
You 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: Making Java serializables transparently printable and readable

2015-06-17 Thread Thomas Heller
Well, the exact same serialization problems do not exist with a database 
because size doesn't matter so much. Security does matter more also because 
of replay attacks, it is not just about keeping your key secret. Anyways, 
that was meant as a warning.

I don't agree with the alterable var approach and changing the ring 
handler to properly handle the API of read is less work than typing out 
this email but if you want to alter a var you can probably alter 
#'clojure.tools.reader/*data-readers* to get what you want. I prefer 
explicit configuration over transparent vars spread all over but YMMV.

/thomas

On Wednesday, June 17, 2015 at 3:27:44 PM UTC+2, Surgo wrote:

 Let's not get into the motivation behind this too much -- the exact same 
 serialization problems exist if you write out the session to a database. 
 Ring also encrypts the cookies so the above issue is not a problem, it's 
 only on you to actually choose and protect your encryption key.

 I came across *data-readers* as well.I did not find it possible to make it 
 completely transparent if one was to use the REPL though because it is 
 bound on entering the REPL. Furthermore I don't think it works with 
 clojure.edn as well. However, it seems that 
 clojure.core/default-data-readers does work with both clojure.core and 
 clojure.edn functions. Thus I've solved the issue by altering 
 clojure.core/default-data-readers to include my library's tag. This seems a 
 bit hackish because I'm not sure you're supposed to be modifying this var, 
 but it's the only thing I can find that both clojure.core/read{,-string} 
 and clojure.edn/read{,-string} respect.

  the issue is not in clojure.core. It is with ring in this case, it uses 
 clojure.tools.reader.edn/read-string which supports an optional {:readers 
 {...}} argument but there is no way to specify those in ring.

 I don't think the fault lies here with ring. It doesn't seem right to 
 expect that library callers of these functions expose their full API to 
 their own users...that would put a serious burden on them to more closely 
 track the API as well. Better to have some alterable var so this can all 
 run transparently.

  it uses clojure.tools.reader.edn/read-string

 Ugh, thanks. I forgot about that one as well.

 On Wednesday, June 17, 2015 at 5:10:24 AM UTC-4, Fluid Dynamics wrote:

 On Wednesday, June 17, 2015 at 4:52:00 AM UTC-4, Thomas Heller wrote:

 Hey,

 the issue is not in clojure.core. It is with ring in this case, it uses 
 clojure.tools.reader.edn/read-string which supports an optional {:readers 
 {...}} argument but there is no way to specify those in ring. Should be a 
 fairly simple fix though, doing anything to clojure.edn won't help as it is 
 not used.

 On another note: Sessions in cookies should be VERY VERY small. 
 java.io.Serializable usually isn't small and especially if you go java 
 object - binary - base64 - base64 (yes twice) - encrypt. The size of 
 the cookie matters as it is transmitted with EVERY request.

 I would recommend writing print-method implementation for the Java 
 objects you need to serialize and keeping those to a minimum. Session 
 cookies are not arbitrary storage and writing a transparent serialization 
 format that doesn't check the size will lead to uncontrolled growth. I have 
 seen way too many web apps with cookies above 4kb. One even had Apache 
 configured to reject requests (well, default config) that had too large 
 cookies and no one even noticed except for the users that left confused and 
 never came back.

 Just as a warning. :)


 If you really do need to store session state that can potentially grow 
 that large, your best bet is to stick it in a server-side database and put 
 that table's primary key in the client-side cookie, looking up the state 
 object on receiving it back. This also prevents the end-user or a MITM from 
 monkeying with the state, which might prevent some types of attacks 
 (typically, session hijacking methods that aren't simple replay attacks, or 
 cheating to give yourself the super-duper armor for free in an online game, 
 or whatever). Remember when ATT was embarrassed by some guy finding he 
 could peek at every customer's data just by changing an custID=nnn sort of 
 URL parameter? Same thing can happen with a cookie that just says logged 
 in as user#6178 or equivalent. Change it to 6179 and boom you're someone 
 else. But if the cookie is something like a random UUID that points to a 
 server-side DB entry that says logged in as user#6178 fiddling with the 
 UUID will just produce error messages. Just don't use an autoincrement 
 integer PK or you are right back where you started. :)



-- 
You 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

Re: [ANN] Instaparse 1.4.0

2015-05-07 Thread thomas van der veen
Thank you for this release of this fantastic library. I haven't had time 
yet to update my project that uses it but one day I will  ;)

Thank you again,

Thomas

On Wednesday, 6 May 2015 09:56:47 UTC+1, Mark Engelberg wrote:

 Instaparse 1.4.0 is now deployed to clojars and available to use in 
 leiningen projects by adding [instaparse 1.4.0] to your project file. 

 Instaparse is a convenient way to generate parsers from context-free 
 grammars.

 The new release features an improved algorithm for handling complex nested 
 negative lookaheads, and the ability to print out a trace of what your 
 parser is doing.

 Instaparse: https://github.com/engelberg/instaparse
 Description of new tracing feature: 
 https://github.com/Engelberg/instaparse/blob/master/docs/Tracing.md


-- 
You 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 web server capacity

2015-04-22 Thread Thomas Heller
Hey,

I'm curious what you are trying to measure in regards to Clojure. As far as 
I know there is not a single Web Server actually written in Clojure, they 
are all written in Java and we just use them. The Compojure benchmark you 
linked uses the default Jetty Adapter for Ring (like Rack in Ruby land). 
http-kit is written in Java as well with only tiny bits of Clojure.

So to answer your question: If I wanted to write something that satisfies 
your requirements (and only those) I would probably take something like 
undertow and just use that. See

https://github.com/thheller/undertow-test
https://github.com/thheller/undertow-test/blob/master/src/undertow_test/core.clj

There are some tweaked settings in there which I used from the Java version 
of the techempower benchmark, I'm doubt they are ideal for your benchmark 
but I cannot run a test like you describe on my machine to find better 
parameters. OSX just runs out of sockets after a couple seconds.

You'll need leiningen [1] to produce the uberjar.

lein uberjar
java -cp target/undertow-test-0.1.0-SNAPSHOT-standalone.jar clojure.main -m 
undertow-test.core localhost 5500 


That launches a JVM with the example server bound to localhost:5500. I have 
not used undertow before myself and don't know about recommended GC 
parameters. The Clojure bits do very little and you are basically just 
testing undertow at this point so I'd imagine the performance to be 
identical to a similar pure Java version.

I doubt that this is what you have in mind when trying to produce a 
Clojure benchmark but since all we Clojure-Folk do is built upon Java 
servers anyways and I wouldn't want to make it look bad by using things we 
don't really need (ring, compojure, etc ...). I don't use ring or compojure 
myself so I can't say how much overhead they would introduce.

I'm happy to help if you have any Clojure related questions for your 
benchmark. If all you really want to test is the web server performance it 
probably doesn't make much sense to include Clojure since there are no 
Clojure web servers (AFAIK).

HTH,
/thomas

[1] http://leiningen.org/ 


On Wednesday, April 22, 2015 at 3:05:29 PM UTC+2, Jesper Louis Andersen 
wrote:

 Hi,

 I'm trying to build up a different kind of web server framework benchmark, 
 where measurement is not on peak performance, but on capacity and latency. 
 That is, the numbers we keep stable are:

 * 10k connections
 * 30k req/s
 * 2053 bytes of static content served by a GET request on a simple route
 * Near perfect 1 gigabit connection between two machines
 * The test runs for 20 minutes.

 This is in contrast to many such measurements. The recent round 10 
 TechEmpower benchmark will for instance let connections vary, try to push 
 as many req/s through and report the maximal number for a Hello World! 
 message. So for one system, they will report the number for 1024 
 connections, whereas another system will have 4096 connections, whichever 
 has the highest peak performance. This is a big no-no in my book. 
 Furthermore, I'm questioning the correctness of their latency measurements 
 because they report average latency and std. deviation without establishing 
 that their distributions are normal. And they don't report the median 
 latency so we can see they aren't.

 The thing I'm interested in is latency of the 30k req/s, run over a 20 
 minute period. That is, employing Gil Tene's HDRHistogram, we can 
 accurately measure latencies for each request and make a distribution 
 function plot of those latencies. I'm sitting with approximately 15 
 frameworks, spread out over multitiple languages. The numbers are vastly 
 different from typical benchmarks and they are interesting to report. 

 For Clojure, I started out with a simple adaptation of the Compojure 
 benchmark from the TechEmpower-land. But it exhibits lots of queueing when 
 trying to process requests simply due to maximizing the CPU cores of the 
 System-under-test. My JVM-fu is quite weak, which is a big problem in these 
 tests. I more or less need a setup, which has some kind of well-tunedness 
 in advance, because I have little hope in achieving it myself on my own. 
 It's somewhat like 10 years ago I last tuned GC on a JVM and I bet things 
 change. Currently Clojure is in the ballpark of Python and Ruby in speed, 
 which is so slow I'm going to argue that there is something wrong with my 
 test implementation:

 http://imgur.com/wCFnFnd

 (X-axis are percentiles, note it's compression toward the 0th percentile. 
 I'm interested in the upper percentiles)

 The graphs of Python, Ruby and Clojure/Compojure here are clear indicators 
 that queueing/stalling is going on even at the very low percentiles. The 
 solutions Go and Java/Undertow are in the graph for comparison with a 
 couple of frameworks which does not exhibit queueing[0].

 The highest scoring benchmark in the techempower rounds is a combination 
 of Clojure and Resin (whatever resin is, I've not really

Re: Clojure web server capacity

2015-04-22 Thread Thomas Heller
You should check your sources. http-kit is not written in Clojure and does 
not use netty.


On Wednesday, April 22, 2015 at 11:40:21 PM UTC+2, François Rey wrote:

  On 22/04/15 20:22, Thomas Heller wrote:
  
 As far as I know there is not a single Web Server actually written in 
 Clojure, they are all written in Java and we just use them.
  

 http-kit http://www.http-kit.org/ would be one, although it's using 
 netty http://netty.io/ which is a java io library.
  

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

2015-03-19 Thread Thomas
FYI: At IBM we are suppose to only the IBM JVM and not other version due to 
legal reason.

Thomas

-- 
You 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: Any Lispers in South Devon, UK?

2015-03-05 Thread Thomas
There are also a few of us in the Southampton/Winchester area

Get in touch if you are interested.

Thomas

On Tuesday, 3 March 2015 21:53:57 UTC, Stephen Wakely wrote:

 Hi,

 Are there any other Lispers in South Devon who would be interested in 
 meeting up and talking code? Clojure, Common Lisp, Scheme, anything as long 
 as there are loads of parentheses!

 Please get in touch.


 Cheers

 Stephen



-- 
You 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: Looking for an equivalent of reductions for reduce for -

2015-03-03 Thread Thomas Meier
Just wanted to double check. This? ((f 1)(g (f 1) (h (g (f 1

Or this? ((f 1)(g (f 1))(h (g (f 1 

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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: Looking for an equivalent of reductions for reduce for -

2015-03-01 Thread Thomas Hicks
I'm not quite sure what you want to do here in the general case but.a 
few thoughts:

- is implemented as a macro, whereas reduce and reductions are functions. 
Depending on what you really want you may need a macro over a function.

Note that reduce is picky about the reducing function it takes: it must be 
function of two arguments. This is very different from the operation of the 
threading macro (-).

If you want to implement this as a function, you might look at the 
implementation of juxt or comp for ideas since they are HOFs (functions 
taking other functions as arguments).

If functions f, g, and h all take one argument you can implement the 
specific example you show as: ((juxt f (comp g f) (comp h g f)) 1)
For functions of one argument this could be generalized to take multiple 
arguments and return vectors of composed applications:

(defn intermediates [fns]
  (let [f (fn [x] ((apply juxt (map #(apply comp (reverse (take %1 fns))) 
(range 1 (inc (count fns) x)) ]
(fn [ xs] (map f xs)) ))

(def f inc)
(defn g [x] (* x 2))
(defn h [n] (+ n 5))

((intermediates [f g]) 5)
;= ([6] [12])

((intermediates [f g h]) 5)
;= ([6 12 17])

((intermediates [f g h]) 5 7 9)  ; each vector is [(f x) (g (f x)) (h 
(g (f x)))]
;= ([6 12 17] [8 16 21] [10 20 25])

cheers,
-tom


On Sunday, March 1, 2015 at 2:16:06 PM UTC-7, Bill Allen wrote:

 Hopefully that makes sense. Let me illustrate.

 (reduce + [1 2 3 4])
 ;= 10
 (reductions + [1 2 3 4)
 ;= (1 3 6 10)

 (- 1 f g h)
 ;= (h (g (f 1)))

 I'm hoping to get a function that behaves like:
 (-- 1 f g h)
 ;= ((f 1) (g (f 1) (h (g (f 1

 Any ideas?

 Regards,
 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
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: Reducers question

2015-02-09 Thread Thomas Heller
Cat is just missing a print-method entry.

Try (into [] (r/fold 1 r/cat r/append! [1 2 3])), the result is what you'd 
expect. The n parameter isn't actually about parallelism but partition 
size. Fork/Join will decide the parallelism. In the case of n=1 the input 
will be split into 3 partition of 1 (eg, [[1] [2] [3]]) and then handed off 
to reducers, the default of n=512 is larger than your input so you'll just 
use regular reduce.

/thomas

On Monday, February 9, 2015 at 10:38:59 AM UTC+1, Aaron Cohen wrote:

 I'm not sure if the 4-arity fold function is working as expected. My 
 understanding is that it should be equivalent to the 3-arity version, but 
 with specified parallelism.

 However:

 (r/fold r/cat r/append! [1 2 3]) = [1 2 3]

 (r/fold 1 r/cat r/append! [1 2 3]) = #Cat 
 clojure.core.reducers.Cat@4b2ae664

 I don't actually understand how this is possible from reading the source 
 code.

 --Aaron


-- 
You 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: Clojurescript :advanced compilation extern only partly working.

2015-01-30 Thread Thomas Heller
For the missing data.json, you probably need to run ./script/bootstrap.

I tend to just run lein install but the version which gets installed is 
[org.clojure/clojurescript 0.0-SNAPSHOT] so you have to adjust the 
version in your project as well. Or edit the clojurescript/project.clj to 
set a specific version.

Alternatively you can run ./script/build which generates a proper version 
off the number of git commits but that script touches some files so extra 
take must be taken those changes don't end up in any git commit later.


On Friday, January 30, 2015 at 2:16:42 AM UTC+1, Crispin Wellington wrote:

 I got to the bottom of it. It's almost embarrassing to say. But the path 
 to the w3c_audio.js extern file was wrong. Unfortunately, lein doesn't give 
 any sort of warning or error if any of the externs files don't exist. I'm 
 not sure if it's a cljsbuild issue, or a clojurescript issue, or a google 
 closure compiler issue.

 So I am thinking I'll give adding this warning (or error?) to 
 clojurescript a go. I notice in clojurescript source that closure.clj deals 
 with running the closure compiler. I can see exactly where I want to add 
 the warning (or tweak the calling of google closure compiler). I could do 
 this, but I'm having trouble now running a locally built clojurescript. 

 I've checked it out. Added some debug. Then I build a jar with 'lein jar'. 
 I upload it to a local maven repository. I add that repository to my 
 project-with-the-missing-extern's project.clj. I lein deps. It grabs the 
 new jar. I lein cljsbuild, and the build begins, but then the build 
 explodes with:

 Exception in thread main java.io.FileNotFoundException: Could not locate 
 clojure/data/json__init.class or clojure/data/json.clj on classpath: , 
 compiling:(cljs/source_map.clj:1:1)
 ...
 Caused by: java.io.FileNotFoundException: Could not locate 
 clojure/data/json__init.class or clojure/data/json.clj on classpath: 

 So this is now off the original topic, but how do you work on 
 clojurescript itself? What step am I missing thats leading to the missing 
 clojre/data/json.clj class on the classpath? What's the best workflow for 
 hacking clojurescript itself?

 Regards

 Crispin

 On Wednesday, January 28, 2015 at 11:29:25 PM UTC+8, David Nolen wrote:

 Run a `lein deps :tree` to compare the version of the Google Closure 
 Compiler you are getting.

 David

 On Wed, Jan 28, 2015 at 9:58 AM, Crispin Wellington retrogr...@gmail.com
  wrote:

 OK something very strange is going on. I tried the let block, and it was 
 the same in my project. 

 So I created a new minimal project, lein new mies test-sound, and made a 
 minimal test: https://github.com/retrogradeorbit/test-sound

 And here it works!

 Go back to my old project, and it doesn't.

 So now I have to go and gradually work through the project differences 
 to see what's causing this. If I find anything, I'll post it.

 Thanks for your help

 Crispin

 On Wednesday, January 28, 2015 at 10:06:52 PM UTC+8, David Nolen wrote:

 I mentioned trying this in a `let` binding instead. What happens when 
 you try that?

 David

 On Wed, Jan 28, 2015 at 9:04 AM, Crispin Wellington 
 retrogr...@gmail.com wrote:

 No, that's not it. So I tried:

 (def audio-context (js/AudioContext.))
 (.decodeAudioData audio-context (js/ArrayBuffer. 256) #(println ok 
 %) #(println error %))

 and it compiled to:

 ;var zv = new AudioContext;
 zv.Rd(new ArrayBuffer(256), function(a) {
   return fo.c(mh([ok, a], 0));
 }, function(a) {
   return fo.c(mh([error, a], 0));
 });

 This has really got me stumped.

 Crispin


 On Wednesday, January 28, 2015 at 6:23:29 PM UTC+8, Thomas Heller 
 wrote:

 I just have a guess for you.

 AudioContext.decodeAudioData parameters are declared as ArrayBuffer, 
 Function, Function but you are passing data which is a String not an 
 ArrayBuffer. Maybe the type inference thinks you are calling a method 
 that 
 is not defined in the externs?

 Maybe it will work if you pass an ArrayBuffer? Other than that I see 
 no reason why it would munge the name.

 /thomas

 On Wednesday, January 28, 2015 at 2:14:31 AM UTC+1, Crispin 
 Wellington wrote:

 Hi there,

 I have been trying to compile some audio code in clojurescript in 
 advanced mode. I have setup the w3c_audio.js extern (from: 
 http://closureplease.com/externs/) into my extern list. When I 
 compile, it prevents the munging of AudioContext (without the extern, 
 this is being munged, so the extern is 'working'). But it doesn't 
 prevent 
 the munging of methods on AudioContext object. 

 A super minimal example (but not working code):

 (def audio-context (js/AudioContext.))
 (.decodeAudioData audio-context data #(println ok %) #(println 
 error %))

 compiles with advanced to:

 ;var zv = new AudioContext;
 zv.Rd(data, function(a) {
   return fo.c(mh([a], 0));
 }, function() {
   return(0).call(null);
 });

 zv.Rd is wrong. It should be zv.decodeAudioData.

 The externs file does indeed have

Re: Clojurescript :advanced compilation extern only partly working.

2015-01-28 Thread Thomas Heller
I just have a guess for you.

AudioContext.decodeAudioData parameters are declared as ArrayBuffer, 
Function, Function but you are passing data which is a String not an 
ArrayBuffer. Maybe the type inference thinks you are calling a method that 
is not defined in the externs?

Maybe it will work if you pass an ArrayBuffer? Other than that I see no 
reason why it would munge the name.

/thomas

On Wednesday, January 28, 2015 at 2:14:31 AM UTC+1, Crispin Wellington 
wrote:

 Hi there,

 I have been trying to compile some audio code in clojurescript in advanced 
 mode. I have setup the w3c_audio.js extern (from: 
 http://closureplease.com/externs/) into my extern list. When I compile, 
 it prevents the munging of AudioContext (without the extern, this is 
 being munged, so the extern is 'working'). But it doesn't prevent the 
 munging of methods on AudioContext object. 

 A super minimal example (but not working code):

 (def audio-context (js/AudioContext.))
 (.decodeAudioData audio-context data #(println ok %) #(println error 
 %))

 compiles with advanced to:

 ;var zv = new AudioContext;
 zv.Rd(data, function(a) {
   return fo.c(mh([a], 0));
 }, function() {
   return(0).call(null);
 });

 zv.Rd is wrong. It should be zv.decodeAudioData.

 The externs file does indeed have this function prototype. here are the 
 excerpts:

 /**
  * @constructor
  */
 var AudioContext = function() {};

 

 /**
  * @param {ArrayBuffer} audioData
  * @param {Function} successCallback
  * @param {Function=} errorCallback
  */
 AudioContext.prototype.decodeAudioData = function(audioData, 
 successCallback,
 errorCallback) {};

 Why would closure compiler protect the AudioContext name, but munge the 
 decodeAudioData name? What am I doing wrong?

 Regards

 Crispin Wellington




-- 
You 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: Properly parse clojure source code?

2015-01-15 Thread Thomas Heller
https://github.com/clojure/tools.reader is probably your best bet.

On Friday, January 16, 2015 at 12:13:22 AM UTC+1, zirkonit wrote:

 I'm thoroughly confused. If I want to parse clojure code from string 
 without evaluating or caring a lot about its context, I'm out of luck.

 EDN tools choke on reader macros ( #(blah % blah) is not valid EDN ), yet 
 more context-aware tools like read-string with *read-eval* set to false 
 choke on namespace-specific tokens like ::om/pass.

 What would be a best choice to parse Clojure code into analyzable data 
 structure while both parsing all of it (so, not just clojure.edn/read), 
 _and_ not going the entire namespaces/shadowing/etc dance?


-- 
You 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: camelize-dasherize - reinventing the wheel?

2015-01-06 Thread Thomas Heller
If you want to boost performance a bit just memoize the conversion 
functions. Memoize makes you vurnable to exploits though, better use 
something with WeakRefs if you convert anything from untrusted sources (eg. 
guava CacheBuilder). But given your usecase this will probably be the 
biggest gain, no matter what else you use to convert maps.

https://gist.github.com/thheller/7ddc0371561deaf13e11
Elapsed time: 35.488 msecs

clojure.walk has keywordize-keys and stringify-keys, maybe a suitable 
starting point for your implementation.

HTH,
/thomas


On Tuesday, January 6, 2015 8:25:57 PM UTC+1, Noam Ben-Ari wrote:

 Hi,

 I've written a small library (1 ns, 100 lines) to transform nested maps 
 from dash-case keys to camelCase keys and back.

 The original use case was taking MySQL records that use camelCase field 
 names and convert them to dash-case so they don't stick out like a sore 
 thumb in my code. Similarly, when writing new records into the DB, I wanted 
 to camelize them back before passing to JDBC.

 It should work on an arbitrarily deep nested map without blowing the stack 
 (using zipper).

 It is symmetric:

 (dasherize clientOSVersion)
 = client-OS-version
 (camelize client-OS-version)
 = clientOSVersion


 The library starts with defining functions that work on strings, then ones 
 that work on keywords (internally calling the string ones) and later ones 
 working on maps (that assume all keys are keywords and use the keyword 
 functions). Lastly, the library defines protocols that will ease working 
 with different types.

 I would love any feedback, but especially:
 - is there any off-the-shelf library for this already?
 - I found zipper and regex to be really hurting performance here, anything 
 you would do differently to improve this?
 - anything about style... I'm writing Clojure for a year and didn't get 
 much code reviews.

 the gist is here:

 https://gist.github.com/NoamB/6e940775dfa63c73ee9c

 Thanks.

 PS - I took the string versions of the functions from cuerdas (
 https://github.com/funcool/cuerdas) and modified a bit, mainly to get the 
 symmetry working.


-- 
You 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: Please critique my code (barber problem with core.async)

2015-01-05 Thread Thomas
Thank you all for you valuable feedback. I really appreciate it and the 
suggestions are really good.

Thomas

-- 
You 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: A (foolish) plan to re-invent IO on top of core.async

2015-01-05 Thread Thomas Heller
I built a PostgreSQL Java client from scratch recently. Since it was not a 
goal to support JDBC ever I thought about writing it with non-blocking 
async IO. I played with some ideas but ultimately I decided not to. The 
reason is quite simple. Async IO works well if you do enough IO to keep one 
a more cores busy by just doing IO, which you get with something like a 
server with many (100k+) connections for example. Threaded IO works equally 
well or better if you only have a very few connections.

You can't have many thousands connections to a postgresql server since a 
connection is quite expensive and if you really stress the server you can 
overload it with a handful of connections already. More connections won't 
make anything any faster since they will basically slow each other down 
more. So if you limit the connections anyway its alot simpler to do 
blocking IO and API.

That does not mean you can't interact with the database through core.async 
channels, it's just not required to do in at the socket level.

Async IO is not a magical solution to scalable servers, in fact many 
servers probably won't benefit at all. Of course there are going to be some 
that would benefit.

Re-inventing the wheel is probably a huge waste of time. Stuff like Netty 
already works pretty well and can be used from Clojure quite easily.

Just my 2 cents,
/thomas

On Monday, January 5, 2015 11:18:42 PM UTC+1, Robin Heggelund Hansen wrote:

 I guess this post is mostly going to be a question, but one that could 
 shape up to be a long open source project and contribution on my part, if 
 it is warranted.

 The Clojure community has been blessed with good language interoperability 
 with Java, which has made it easy to use and wrap Java-libraries, which 
 again I suspect is why Clojure is where it is today, a tool for 
 professional development.

 This has also, to some extent, been a curse, as we've relied on libraries 
 made for a different language, instead of creating the world in our 
 image, so to speak. I assume this is why core.async isn't as integrated in 
 the Clojure ecosystem as I would like, because we already have libraries 
 that works, and taking the time to make sure they scale well simply isn't 
 worth it.

 So I thought I would re-invent the wheel a little, but it depends on my 
 premise being correct.

 From what I understand, core.async basically creates state machines, that 
 are run on a threadpool. Once you do something that blocks (like IO), you 
 are kinda ruining the idea behind core.async, which is efficient 
 concurrency at a large scale. I also assume, that having more than one 
 threadpool, isn't really what you want. You want core.async to have the 
 only threadpool running, and you want to run most things as go-blocks.

 Today, way to many things block, like reading a file or reading from a 
 database. Things that are async, mostly uses it's own threadpool. If I got 
 this correctly, a standard web-app today will usually perform a blocking 
 action for most DB-ops, requests will run in a http-server-specific 
 threadpool, while agents or go-blocks has their own threadpool again.

 Would I be correct that a clojure web-server, would be more efficient (at 
 scale) if DB-ops and general request handling, ran entirely as go-blocks on 
 the core.async threadpool alone?

 I was thinking of creating a async.io library (core.async + NIO for file 
 and socket ops), and after that perhaps create a socket-pool library before 
 creating a core.async friendly SQL interface. Is there a point to this, or 
 would I just be doing a lot of work for very little gain?

 Thanks!


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


Re: Creating Hiccup From Code Keeping Formatting and Comments

2015-01-04 Thread Thomas Heller
Here is a crazy idea I had.

https://gist.github.com/thheller/ad7dc6234f205cf4a53f

Basically it slurps the .clj file of the current namespace, then looks at 
the form metadata to skip to the line where the (example ...) starts.

It then takes the next row as the title, then reads all rows until it find 
one that ends in ;; END. All lines are then joined and tada you got your 
function body with all indentation. If you want to do more advanced parsing 
you leave the ;; END bit out but I just wanted to test the concept. ;)

Maybe this works for you.

Cheers,
/thomas

On Sunday, January 4, 2015 4:57:14 PM UTC+1, Stefan Kamphausen wrote:

 Hi,


 Currently, I am trying to write a presentation using ring and reveal.js.  
 For the code samples, I'd like to write real clojure code, i.e. no 
 strings or the like.  

 Then, I want to turn that into a suitable hiccup vector which will create 
 the correct reveal.js/highlight.js syntax.  

 I wrote a trvial macro:

 (defmacro example [ body]
   `[:pre
 [:code ~(apply str body)]])

 The problem is, that it looses all formatting, because the Clojure reader 
 already had its fun with the code. So,

 (example
  A string literal
  (defn a-function [x y]
;; concat x and y as strings
(str x y)))

 macro-expands to

 [:pre [:code A string literal(defn a-function [x y] (str x y))]]

 which is pretty useless.

 I already thought about using form but this too has been read already.


 Any ideas?


 Kind regards,
 stefan


-- 
You 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: Creating Hiccup From Code Keeping Formatting and Comments

2015-01-04 Thread Thomas Heller
Oops, simplified a little. We already have access to the title. ;)

On Monday, January 5, 2015 1:09:24 AM UTC+1, Thomas Heller wrote:

 Here is a crazy idea I had.

 https://gist.github.com/thheller/ad7dc6234f205cf4a53f

 Basically it slurps the .clj file of the current namespace, then looks at 
 the form metadata to skip to the line where the (example ...) starts.

 It then takes the next row as the title, then reads all rows until it find 
 one that ends in ;; END. All lines are then joined and tada you got your 
 function body with all indentation. If you want to do more advanced parsing 
 you leave the ;; END bit out but I just wanted to test the concept. ;)

 Maybe this works for you.

 Cheers,
 /thomas

 On Sunday, January 4, 2015 4:57:14 PM UTC+1, Stefan Kamphausen wrote:

 Hi,


 Currently, I am trying to write a presentation using ring and reveal.js.  
 For the code samples, I'd like to write real clojure code, i.e. no 
 strings or the like.  

 Then, I want to turn that into a suitable hiccup vector which will create 
 the correct reveal.js/highlight.js syntax.  

 I wrote a trvial macro:

 (defmacro example [ body]
   `[:pre
 [:code ~(apply str body)]])

 The problem is, that it looses all formatting, because the Clojure reader 
 already had its fun with the code. So,

 (example
  A string literal
  (defn a-function [x y]
;; concat x and y as strings
(str x y)))

 macro-expands to

 [:pre [:code A string literal(defn a-function [x y] (str x y))]]

 which is pretty useless.

 I already thought about using form but this too has been read already.


 Any ideas?


 Kind regards,
 stefan



-- 
You 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.


Please critique my code (barber problem with core.async)

2015-01-02 Thread Thomas
Happy New to all of you!!!

Recently I came across the barber problem (again) and while reading it I 
thought that code.async would be ideal for this kind of problem. Below is 
the code I have come up with. I think it does the trick but I am not 
entirely happy with it, for instance the fact that I use the two atoms as 
counters. I also wonder if there is a better way to time the ten seconds, 
something instead of the atom.

So please critique the code below, any comments, improvements, obfuscations 
etc. are welcome!!

Thomas


(ns barber.core
  (:require [clojure.core.async :as async]))

;; A barber shop takes customers
;; Customer arrive at random intervals, from ten to thirty milliseconds
;; The barber shop has three chairs in the waiting room
;; The barber shop has one barber and one barber chair
;; When the barber's chair is empty, a customer sits in the the chair
;;   wakes up the barber, and gets a haircut.
;; If the chairs are occupied , all new customer will turn away
;; Haircuts takes twenty milliseconds
;; After a customer receives a haircut, he gets up and leaves.
;;
;; Write a program that determines how many haircuts a barber can
;;   give in ten seconds.

(def running (atom false))
(def counter1 (atom 0))
(def counter2 (atom 0))

(defn customers []
  (let [c (async/chan (async/dropping-buffer 3))]
 (async/go
  (while @running
(async/! (async/timeout (+ 10 (rand-int 21
(async/! c (swap! counter1 inc
c))

(defn barber [c]
  (async/go
   (while true
 (let [r (async/! c)]
   (async/! (async/timeout 20))
   ;(println r)
   (swap! counter2 inc)

(comment
  (reset! counter1 0)
  (reset! counter2 0)
  (reset! running true)
  (barber (customers))
  (Thread/sleep (* 10 1000))
  ;(async/timeout (* 10 1000)) ;; not sure why this doesn't work here, 
would make it portable to clojureScript I think
  (reset! running false)
  (println (str Served  @counter2  customers out of  @counter1  
possible customers))
)

-- 
You 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 dev/user.clj breaks java compilation

2015-01-02 Thread Thomas Heller
I had a similar problem some time ago.

The analysis is correct that Clojure will always load user.clj. As a 
workarround I just moved the require out of the ns form.

(ns user
  (:require [mdg.meat2]))

becomes

(ns user)

(defn start []
  (require 'mdg.meat2 :reload-all)
  (do-something-useful))

This will basically load everything on-demand (eg. when you call the 
start function) instead of always.

HTH,
/thomas

On Friday, January 2, 2015 9:03:22 PM UTC+1, David James wrote:

 I noticed this issue which I'm currently facing:
 https://github.com/technomancy/leiningen/issues/1477

 Technomancy commented in the issue: This appears to be a bug in Clojure 
 causing an incorrect error message that's masking the actual issue. What's 
 happening here is that the javac task is invoking some Clojure code which 
 performs the Java compilation, but before this code runs, Clojure runs 
 user.clj first. (Leiningen doesn't have any control over this.) Since this 
 contains a call to a file that imports TestClass, you've created a circular 
 dependency. I don't know why you get this error message; it seems to be an 
 issue with Clojure itself.

 Do others agree that this is an issue with Clojure itself?

 I haven't seen any tickets in JIRA pertaining to this. Did I overlook one?


-- 
You 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: Please critique my code (barber problem with core.async)

2015-01-02 Thread Thomas


On Friday, 2 January 2015 16:45:14 UTC, Erik Price wrote:

  ;(async/timeout (* 10 1000)) ;; not sure why this doesn’t work here, 
 would make it portable to clojureScript I think

 Did you forget to use ! on that line?

 e


.. :) thank you!!!

Thomas 

-- 
You 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: Handling increasingly-intensive processes

2014-12-15 Thread Thomas Heller
Hey,

without knowing much about your application/business needs its hard to 
speculate what might be good for you. The root of your problem might be 
CouchDB since it was never meant for Big Data and since we are talking 
tweets I generally think a lot. I'm not sure how your map value looks but 
I think you do something like

obj = (couch/get hash-tag)
obj = (my-app/update obj new-tweet)
(couch/put hash-tag obj)

Which will always perform badly since you cannot do this concurrently, 
except with CRDTs which CouchDB doesn't support since it does its own 
MVCC.  Don't remember exaclty how their conflict resolution works but I 
think it was last write wins. Caching will not save you for long, since 
writes will eventually become the bottleneck.

Why do you not use a CouchDB view to create the hash-tag map on the server 
and then just append-only the tweets? The views map function can then just 
emit each tweet under the hash-tag key (once for each tag) and the reduce 
function can build your map. That should perform alot better up to a 
certain point and you can control how up-to-date your view index has to be.

Anyways, might be best to choose another Database. Regardless of what 
database you are using, updating a single place concurrently is going to be 
a problem. An Atom in Clojure makes this look like a no-brainer but under 
high load it can still blow up since it has no back-pressure in any way.

Bit Data and Distributed Systems are hard and cannot be described in 
short. Without exact knowledge of what your app/business needs look like it 
is impossible to make the correct recommendation.

HTH,
/thomas

On Monday, December 15, 2014 4:54:04 AM UTC+1, Sam Raker wrote:

 I'm (still) pulling tweets from twitter, processing them, and storing them 
 in CouchDB with hashtags as doc ids, such that if a tweet contains 3 
 hashtags, that tweet will be indexed under each of those 3 hashtags. My 
 application hits CouchDB for the relevant document and uses Cheshire to 
 convert the resulting string to a map. The map's values consist of a few 
 string values and an array that consists of all the tweets that contain 
 that hashtag. The problem is thus with common hashtags: the more tweets 
 contain a given hashtag, the long that hashtag's tweets array will be, 
 and, additionally, the more often that document will be retrieved from 
 CouchDB. The likelihood and magnitude of performance hits on my app are 
 therefore correlated, which is Bad.

 I'm reaching out to you all for suggestions about how best to deal with 
 this situation. Some way of caching something, somehow? I'm at a loss, but 
 I want to believe there's a solution.


 Thanks,
 -sam


-- 
You 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: Ring and Compojure with Node.js via Clojurescript

2014-12-09 Thread Thomas Heller
Due to significant platform differences from the JVM to Node.js (no real 
threads, everything needs callbacks) you'd probably be better off writing 
something more javascript-y. Porting Ring is probably not likely since 
everything is async and Ring is not. Same goes for Compojure but that is 
mostly macro stuff so it could probably fit in somehow.

Running something on Node.js requires a completely different (async) way of 
thinking, which you don't nescessarily do on the JVM. You'd probably be 
better of using something from the node.js ecosystem. Iits not like you 
could ever take any Clojure Ring Handler and plug it into 
ClojureScript/Node, at least not likely as soon as you do something with IO.

Just my 2 cents,
/thomas

On Monday, December 8, 2014 3:50:48 PM UTC+1, Matthew Molloy wrote:

 Dear Community,

 I love making Clojure web apps, however their startup time is a serious 
 drawback when used with a transient hosting service such as Heroku.  My 
 thought is to port Ring and Compojure over to Clojurescript so that can get 
 their nice abstractions hosted on the Node.js runtime.

 Any thoughts or suggestions?

 Matthew


-- 
You 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 + voltdb

2014-12-07 Thread Thomas Steffes
Hey Todd, any chance you still have this kicking around somewhere?


On Friday, July 9, 2010 2:03:05 AM UTC-4, Todd wrote:

 I've created a basic project to show how to create a voltdb database, 
 and then to create java and clojure clients for this database:

 http://github.com/ToddG/clojure-voltdb

 Any feedback would be most welcome. There's a tutorial and ant tasks for 
 each step.

 -Todd



-- 
You 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: ring-transit issue

2014-12-02 Thread Thomas
Hi,

After quite a bit of trying various things I got this working now:

(ns trans.core.handler
  (:require [compojure.core :refer :all]
[compojure.route :as route]
[compojure.handler :as handler]
[ring.util.response :as ring-response]
[ring.middleware.transit :as trans :only [wrap-transit-response 
wrap-transit-params]]))

(defn get-data []
  (ring-response/response {:a 1 :b 2}))

(defroutes app-routes
  (GET / [] Hello World)
  (GET /test [] (get-data))
  (route/not-found Not Found))

(def app
  (- app-routes
  (handler/site)
  (trans/wrap-transit-params)
  (trans/wrap-transit-response)))

The change that made the difference seems to the the ring-response/response 
call in the get-data function.

I hope that this helps other people and a big thank you to Ahmad for a hint 
in the right direction.

Thomas

-- 
You 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.


ring-transit issue

2014-11-28 Thread Thomas
Hi,

I am using the ring-transit middleware but something doesn't seem to be 
quite right. Below is the code on the server side:

(defn get-test-data []
  {:a 1 :b 2})

(defroutes app-routes
  (GET / [] (main-page))
  (wrap-transit-response
(GET /test [] (get-test-data)))
  (route/resources /)
  (route/not-found Not Found))

(def app
  (- app-routes
  (handler/site)
  (wrap-transit-params)))

On the client I am getting this error when using cljs-ajax:

something bad happened: 200 Unexpected end of input  Format should have 
been Transit

and the content-length is reported as 0 by postman. I am sure the error is 
between my ears ;)  but I have no idea what!! Any ideas?

TIA,
Thomas

-- 
You 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: If code is data why do we use text editors?

2014-11-17 Thread Thomas Huber
Hi Phil, thanks for your reply.

The source data structure doesn't have to contain only bare source code. 
It could contain everything that is in a text file, but just saved in a 
structured way. 
The data needs to be compiled to bytecode anyway.

I'm not sure if diffing is a huge problem. You can still pretty print you 
source data and save it into a text file. 
Diffing these files should be enough to get an idea what was changed. 
And if not a special diffing tool would have other advantages to I think. 

Finally, source code is often wrong, or a work in progress. Okay, with 
 paredit, Clojure can be mostly kept correct (syntactically) most of the 
 time, but lisp is the oddity, and you need all the brackets to enable 
 this. Even with paredit, for me, editing in this way fails often enough 
 for me, that I wrote something to switch paredit off rapidly, and then 
 back on again when I've fixed it. 


You can still save your programm as a data structure even if its wrong. Or 
am I missing your point?


Thomas

Am Freitag, 14. November 2014 18:05:47 UTC+1 schrieb Phillip Lord:



 I can think of several reasons. 

 First and most important, code is data, but source files are not code. 
 They are source and include many things a lot of which do not obey the 
 syntactic rules of the language. Comments and indentation are the most 
 obvious ones. 

 Second, reason is that not only do you need a special tool for editing, 
 you need a special tool for diffing as well. And version control. Maybe 
 you will have to rewrite these for every language now, rather than using 
 the lowest common denominator line-orientated syntax. 

 Also, you will have to update your editing environment for every new 
 version of the language. 

 Finally, source code is often wrong, or a work in progress. Okay, with 
 paredit, Clojure can be mostly kept correct (syntactically) most of the 
 time, but lisp is the oddity, and you need all the brackets to enable 
 this. Even with paredit, for me, editing in this way fails often enough 
 for me, that I wrote something to switch paredit off rapidly, and then 
 back on again when I've fixed it. 

 It sounds like a nice idea, but I think it's not. In fact, one of the 
 motivations behind my clojure library (Tawny-OWL) was to move away from 
 manipulating a program (well, not a program, but a complex, formal data 
 structure, but it's the same thing) by changing an live data structure, 
 and move toward a flat file that has to be parsed. Sounds like a 
 backwards step, but isn't. 

 Phil 


 Thomas Huber th0mas...@googlemail.com javascript: writes: 

  Hi, here is an idea that has been in my mind for a while. I wonder what 
 you 
  think about it. 
  
  In Clojure code is data, right? But when we program we manipulate flat 
 text 
  files, not the data directly. 
  
  Imagine your source code where a data structure (in memory). And 
  programming is done by manipulating this data structure. No text editor 
 and 
  text files involved. 
  
  Your editor directly manipulates the source data and later saves it on 
 disk 
  (maybe as a text file). 
  
  
  These are the benefits I can think of: 
  
   - It enables you to use any Clojure function to manipulate your source 
  „code“. Giving you hole new opportunities for refactoring.This functions 
  can be provides as library. 
  
  
  - Really nice auto complete. 
  
  
  - Visual programming. Source code can be represented in many different 
 ways 
  (not just text) . The easiest example I can think of is color. It can be 
  represented as text of course (#23FF02) 
  
  but that’s a quite bad interface for humans. Why not display the actual 
  color and provide a color picker? Or what about music notes? Or Math 
  formulars? Or what about a tree view to move and rename functions like 
  files? 
  
  This could all be implemented in a way that every library can ship there 
  own „views“. I think this „views“ are basically macros that are not 
 limited 
  to text. 
  
  
  - You don’t have to worry that you text files are in the same state as 
 your 
  JVM (when developing interactive). You only work on your sourcedata and 
 it 
  gets loaded into the JVM automatically. 
  
  
  - Answer questions about your source code. What is the most called 
  function? Who depends on this namespace? Where is this function used? 
 What 
  is the biggest function? Thinks like that become easy. Again you can 
 ship 
  this queries as a library. 
  
  
  
  
  The drawback is you can’t simply program using any text editor. You need 
 a 
  special tool. But we have that anyway (syntax highlighting, paredit 
 etc.). 
  Nobody programs using a bare text editor. 
  
  
  Maybe this idea is not new? What do you think? 

 -- 
 Phillip Lord,   Phone: +44 (0) 191 208 7827 
 Lecturer in Bioinformatics, Email: philli...@newcastle.ac.uk 
 javascript: 
 School of Computing Science,
 http://homepages.cs.ncl.ac.uk/phillip.lord

Re: If code is data why do we use text editors?

2014-11-17 Thread Thomas Huber
Yes that s ounds quite reasonable to me

Am Freitag, 14. November 2014 18:01:04 UTC+1 schrieb Jan-Paul Bultmann:

 Yeah this would be awesome, but sadly representing Clojure code as data is 
 as hard as representing Java.
 All the reader macros make it a nightmare, and the closest thing you'll 
 get is tools.analyzer AST nodes.

 Session is certainly a step in the right direction, and I wish more people 
 would embrace it,
 but it works on text as well. Same pretty much goes for codeq, if that is 
 not dead.

 One could define a Clojure subset that is valid EDN though,
 which would make everything from serialisable functions to a nano-pass 
 compiler a lot easier.
 This has to be the first step imho.

 Cheers Jan

 On 14 Nov 2014, at 17:09, atucker agjf@gmail.com javascript: 
 wrote:
 re
 As I understand it, Session https://github.com/kovasb/session and codeq 
 https://github.com/Datomic/codeq are tools that somehow keep your code 
 in a database instead of plain text.

 On Friday, 14 November 2014 12:42:57 UTC, Thomas Huber wrote:

 Hi, here is an idea that has been in my mind for a while. I wonder what 
 you think about it.


 In Clojure code is data, right? But when we program we manipulate flat 
 text files, not the data directly.

 Imagine your source code where a data structure (in memory). And 
 programming is done by manipulating this data structure. No text editor and 
 text files involved. 

 Your editor directly manipulates the source data and later saves it on 
 disk (maybe as a text file). 


 These are the benefits I can think of:

  - It enables you to use any Clojure function to manipulate your source 
 „code“. Giving you hole new opportunities for refactoring.This functions 
 can be provides as library. 


 - Really nice auto complete. 


 - Visual programming. Source code can be represented in many different 
 ways (not just text) . The easiest example I can think of is color. It can 
 be represented as text of course (#23FF02)

 but that’s a quite bad interface for humans. Why not display the actual 
 color and provide a color picker? Or what about music notes? Or Math 
 formulars? Or what about a tree view to move and rename functions like 
 files? 

 This could all be implemented in a way that every library can ship there 
 own „views“. I think this „views“ are basically macros that are not limited 
 to text. 


 - You don’t have to worry that you text files are in the same state as 
 your JVM (when developing interactive). You only work on your sourcedata 
 and it gets loaded into the JVM automatically.


 - Answer questions about your source code. What is the most called 
 function? Who depends on this namespace? Where is this function used? What 
 is the biggest function? Thinks like that become easy. Again you can ship 
 this queries as a library.




 The drawback is you can’t simply program using any text editor. You need 
 a special tool. But we have that anyway (syntax highlighting, paredit 
 etc.). Nobody programs using a bare text editor. 


 Maybe this idea is not new? What do you think?


 -- 
 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 javascript:
 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 javascript:
 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 javascript:.
 For more options, visit https://groups.google.com/d/optout.




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


If code is data why do we use text editors?

2014-11-14 Thread Thomas Huber


Hi, here is an idea that has been in my mind for a while. I wonder what you 
think about it.


In Clojure code is data, right? But when we program we manipulate flat text 
files, not the data directly.

Imagine your source code where a data structure (in memory). And 
programming is done by manipulating this data structure. No text editor and 
text files involved. 

Your editor directly manipulates the source data and later saves it on disk 
(maybe as a text file). 


These are the benefits I can think of:

 - It enables you to use any Clojure function to manipulate your source 
„code“. Giving you hole new opportunities for refactoring.This functions 
can be provides as library. 


- Really nice auto complete. 


- Visual programming. Source code can be represented in many different ways 
(not just text) . The easiest example I can think of is color. It can be 
represented as text of course (#23FF02)

but that’s a quite bad interface for humans. Why not display the actual 
color and provide a color picker? Or what about music notes? Or Math 
formulars? Or what about a tree view to move and rename functions like 
files? 

This could all be implemented in a way that every library can ship there 
own „views“. I think this „views“ are basically macros that are not limited 
to text. 


- You don’t have to worry that you text files are in the same state as your 
JVM (when developing interactive). You only work on your sourcedata and it 
gets loaded into the JVM automatically.


- Answer questions about your source code. What is the most called 
function? Who depends on this namespace? Where is this function used? What 
is the biggest function? Thinks like that become easy. Again you can ship 
this queries as a library.




The drawback is you can’t simply program using any text editor. You need a 
special tool. But we have that anyway (syntax highlighting, paredit etc.). 
Nobody programs using a bare text editor. 


Maybe this idea is not new? What do you think?

-- 
You 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: Idiomatic way to return a single value from an async function

2014-11-11 Thread Thomas Heller
Hey,

what is your definition of an async function in Clojure? I imagine 
something something that starts a (go ...), if appropriate you can use the 
result of (go ...) as the result of the function since that is a channel 
that will receive the return value of the go block when it dies.

(defn start-async []
  (go (! (async/timeout 1000))
  :done))

(let [c (start-async)]
  (prn (!! c)))

Other than it is highly dependent on the function you are writing. 
Sometimes it will be required to take an external channel, sometimes it 
will be useless. Usually depends on the types of coordination required 
between the different parts. There is no universally correct way.

Just my 2 cents,
/thomas

On Monday, November 10, 2014 5:30:41 PM UTC+1, Alexander Kiel wrote:

 Hi,

 what is the most idiomatic way to return a single value from an async 
 function in Clojure?

 A: return a channel which conveys the result later; also closes the channel

 (defn f [x]
   (let [c (chan)]
 ; put result onto c and close c later
 c))

 B: take a channel onto which the result is put later; do not close that 
 channel; return nil immediately

 (defn f [x c]
   ; put result onto and close c later
   nil)

 Variant A has the advantage that it needs one function argument less than 
 variant B. It's also better usable in higher order functions like map. 
 Variant A is also more easy to use if you need to create a channel anyway.

 Variant A has the disadvantage of creating a new channel each time the 
 async function is called. According my measurements using criterium 
 0.4.3, clojure 1.6.0 and core.async 0.1.346.0-17112a-alpha, the runtime 
 cost of creating a channel is about 8 times more expensive as creating a 
 single object.

 Variant B has the advantage to not create a channel on every call. You can 
 supply the same channel many times to the function. On the other hand, the 
 results of multiple calls to f are not likely to arrive on that single 
 channel in call order. If you have such an ordering requirement, you have 
 to create a single channel for each function call anyway.

 Variant B has the disadvantage that it requires one function argument more 
 than variant A. As a consequence, you can't simply map such a function over 
 a list of inputs.

 Variant A seems to be the winner. But I ask specially because 
 pipeline-async 
 https://clojure.github.io/core.async/#clojure.core.async/pipeline-async 
 uses 
 variant B.

 What do you think?

 Alex




-- 
You 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: Mutable local variables

2014-11-10 Thread Thomas Heller
@Jacob: If you get too many arguments in a loop I found it best to use a 
map.

(loop [{:keys [a b c] :as state} a-map]
  (cond
   (and (= a 1) (= b 2))
   (recur (update state :a inc)) ;; 1.7+ only, otherwise use update-in
   ...))

Working with named arguments (vs. positional) is a lot more user-friendly 
since you don't have to repeat everything all the time.

HTH,
/thomas 

On Monday, November 10, 2014 8:21:57 AM UTC+1, Jacob Goodson wrote:

 Sometimes, when writing code that loops with a good bit of branching, it 
 can be quite annoying to stay immutable.

 (loop [way 1
   too   2
   many   3
   args 4
   makes 5
   things  6
   annoying 7]
   (cond (and (= way 3) (= too 4)) (recur (inc way) you get the point.  

 Imagine about 14 different conditions under cond and this thing starts 
 looking like crap.  I got around this with macros and pattern matching, 
 however, I do not think that this happens too often for many clojurians. 

 On Saturday, November 8, 2014 11:49:42 PM UTC-5, Fluid Dynamics wrote:

 I wonder if the OP is aware that you can rebind the same name multiple 
 times in a let. For instance

 (let [x something
   y otherthing
   x (if (pred? x y) x (some-func x y))
   x (further (complex (calculations x)))
   ...]
   (do-something-with x))

 No actual mutability, but most of the times that suffices for whatever 
 you might use a mutable local for in another language.

 Then there's loop/recur. I'd consider let rebinding and loop/recur long 
 before resorting to any sort of mutable. The most significant pain point in 
 my experience has been wanting to smuggle a side calculation out of some 
 closure that has to return something else. The most recent case I ran into 
 like that involved (swap! some-atom conj thingy) where the atom held a 
 vector, I also wanted to know the new length of the vector, I didn't want 
 any race conditions (following up with a (count @some-atom) allowed the 
 possibility of the vector changing again in between the swap and the deref, 
 but I wanted to know the position of the item just conjed on), and 
 dosync/ref seemed like overkill (only the one isolated mutable). I *could* 
 have done something like

 (let [c (int-array 1)]
   (swap! some-atom (fn [x] (let [x (conj x thingy)] (aset c 0 (count x)) 
 x)))
   (let [c (aget c 0)]
 ; work with c
 ...))

 but it was unnecessary to use this kluge, for swap! returns not the atom 
 itself but the new value that was returned by the passed-in function. So 
 all I actually needed was

 (let [c (count (swap! some-atom conj thingy))]
   ...)

 with no mutability besides the atom itself (and in particular no local 
 mutability). I've since needed swap!'s return value on another occasion, 
 when it was a map, resulting in (get-in (swap! m update-in [k1 k2] f arg1 
 arg2) [k1 k2]) to both update the map and have the exact value for the 
 sub-key that was updated, as of that update. With maps, it may also be 
 possible to store some extra information in the map with a 
 ::module-local-keyword without this interfering with anything else, which 
 can be pulled out of swap!'s return value, and with several kinds of 
 objects you can smuggle extra information out of a closure by adding a 
 ::module-local-keyword to the object's *metadata* (in particular, this 
 won't perturb the equality semantics of the object, as well as working with 
 vectors and several other non-map-like things as well as with records and 
 maps. And if you're wanting to return extra information out of an ordinary 
 function or a loop where you control how the return value is interpreted, 
 you can bind and destructure the return value after making that a short 
 vector or a map with several thingys in it.

 Lately I hardly ever find myself feeling the need for any kind of local 
 mutables, and only small amounts of global state (often nothing, or just 
 one atom wrapping a map handled with nesting, update-in, assoc-in, and 
 get-in, though refs and dosync will put in an appearance if a high degree 
 of concurrency is required).



-- 
You 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: io/writer + map/recur

2014-11-01 Thread Thomas Heller
The way you wrote your loop it will only ever run once which means you 
could take it out.

1 res = take from queue
2 if res nil? terminate
3 if res recur with result from with-open (always nil)
4 back to 2 and terminate

Not sure if this is intended but the way it is written it does not make 
sense to loop. Also remember that .take will block if nothing is available 
meaning you are writing essentially an infinite loop unless you create some 
other kind of exit condition.

Also if you just want to append a string to a file you can use spit [1]

(spit f some-string :append true)

Other than that, never use something lazy with IO unless you remember to 
doall.

HTH,
/thomas

http://grimoire.arrdem.com/1.6.0/clojure.core/spit/

On Friday, October 31, 2014 9:08:01 PM UTC+1, Sam Raker wrote:

 I'm writing some stuff to interact with the Twitter API. I want to be able 
 to write tweets (as JSON) to a file, so I can, e.g., test things without 
 connecting to the API. I've proxied the LinkedBlockingQueue that Twitter's 
 HBC library uses to use an agent, so ideally I want to be able to write the 
 contents of the agent AND the LBQ. Here's what I have right now:

 (defmulti write-tweets (fn [q f] (class q)))
 (defmethod write-tweets clojure.lang.Agent [a f]
   (with-open [w (clojure.java.io/writer f :append true)]
 (.write w (apply str (interpose \n @a)
 (defmethod write-tweets java.util.concurrent.LinkedBlockingQueue [lbq f]
 (loop [res (.take lbq)]
   (if res
 (recur 
   (with-open [w (clojure.java.io/writer f :append true)]
 (.write w (str (generate-string res) \n)))

 My first implementation of this used `(map #(.write w %) @a)` and had the 
 `recur` within the `with-open` block. Unfortunately, at least with the 
 agent part, I ran into an error about the file being closed when I tried to 
 write to it. I assumed `with-open` kept the file open within the block, but 
 maybe I'm missing something? I'm worried about the performance of either 
 creating a potentially super-huge string in memory for the agent method 
 (twitter returns pretty sizable JSON blobs) or repeatedly opening/closing a 
 file for the LBQ method (I realize I could collapse this into one problem 
 by taking everything out of the LBQ and putting it into an agent, but 
 that's not really a solution...)

 Does `writer` auto-close the file after it's done? Is there some better 
 way of handling this kind of situation? 


-- 
You 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] shadow-pgsql: PostgreSQL without JDBC

2014-10-17 Thread Thomas Heller
I meant to do a proper release announcement for quite some time now but 
simply don't have the time to do it properly.

That being said I have now been using shadow-pgsql [1] in production for 
well over a month and it has been working as expected and stable. A 
couple million Queries were executed successfully and no major issues have 
come up. There are still some features missing but if you only need basic 
SQL features it should all work out.

Happy to talk about it if anyone is interested.

Hope to find some time next month to write some docs and cut a proper 
release.

Cheers,
/thomas


[1] https://github.com/thheller/shadow-pgsql

-- 
You 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.


  1   2   3   4   >