[ANN] com.stuartsierra/component 1.1.0

2022-02-26 Thread Stuart Sierra
Hello everyone, 

The first change in almost 2 years — it's a new release of Component!

Component  is a tiny framework 
for starting and stopping many stateful resources in the right order.

This release adds the `subsystem` function 

.

Change Log 


Leiningen project.clj:
[com.stuartsierra/component "1.1.0"]

deps.edn:
com.stuartsierra/component {:mvn/version "1.1.0"}

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


[ANN] [com.stuartsierra/component "0.4.0"]

2018-12-30 Thread Stuart Sierra
Component: managed lifecycles and dependencies for stateful objects

https://github.com/stuartsierra/component


### Version 0.4.0 released to Clojars 
 on December 
30, 2018

  * Add :extend-via-metadata to Lifecycle protocol
for Clojure 1.10 extend-via-metadata 

.
Backwards-compatible with earlier Clojure versions.
(suggested by Joe Lane in GitHub #62 
).

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

2018-05-06 Thread Stuart Sierra
https://github.com/clojure/java.classpath - utility functions to
search the Java classpath.

Build #339  is complete, 
should be sync'd with the
Maven Central repository soon.

Release 0.3.0:

* Fix [CLASSPATH-8 ]: 
empty classpath returned on Java 9.

Starting with Java 9, the default class loader is no longer an
instance of URLClassLoader, so `classpath` returned an empty sequence.
The strategy of using URLClassLoader started with release [0.2.0] to
accommodate Java application containers (see [CLASSPATH-1] 
 and
[CLASSPATH-2 ]). After 
this change, application containers based on
URLClassLoader should still work as expected.

On Java 9 without an application container, it appears that the
`java.class.path` system property is the only way to get the
classpath. While this is essentially a bugfix for Java 9
compatibility, it is a change in behavior, hence the version change
from 0.2 to 0.3.

Leiningen dependency information:

[org.clojure/java.classpath "0.3.0"]

Maven dependency information:


  org.clojure
  java.classpath
  0.3.0


Gradle dependency information:

compile "org.clojure:java.classpath:0.3.0"


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

2018-03-10 Thread Stuart Sierra
I sometimes use inf-clojure mode 
 in Emacs, which can connect 
directly to a socket REPL. I have a helper Elisp function 
inf-clojure-to-socket 

.

You might also try readline with Netcat (nc) as an alternative to Telnet.

–S

On Friday, March 2, 2018 at 8:49:45 PM UTC-5, Didier wrote:
>
> I want to connect to a Clojure socket repl server, but telnet is a really 
> terrible repl experience. Anyway I can have a better client to connect to 
> it that would have some better support for history, backspace, maybe even 
> some auto-complete, highlight, etc. Whatever I can get over telnet?
>
> 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: Is there some central information available on Java 9 compatibility for Clojure and tools

2018-02-25 Thread Stuart Sierra
There's no single source, but you can find issues with Clojure and contrib 
libraries by searching the Clojure JIRA  for 
"Java 9".

Toby Crawley started a small collection of known issues at 
github.com/tobias/clojure-java-9

–S

On Sunday, February 25, 2018 at 11:01:43 AM UTC-5, Arie van Wingerden wrote:
>
> Some time ago I tried Java 9 and reverted back to 8 when I ran into 
> problems.
> Is there conclusive info on the versions which will definitely (not) work 
> correctly with Java 9?
>

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

2017-12-22 Thread Stuart Sierra

>
> => CompilerException java.lang.Exception: namespace 'foo.bar' not found 
> after loading '/foo/bar', compiling:(*cider-repl foo*:65:7)
>

An error like this usually means that the ns declaration does not match the 
expected namespace name, based on the file path.

Also be aware that AOT-compilation 
 causes all sorts of havoc with 
namespace reloading, because AOT-compiled .class files get read by a 
different ClassLoader. In effect, you cannot "unload" an AOT-compiled 
namespace. Make sure you do not have any AOT-compiled .class files in your 
project, and note that some tools and templates enable AOT by default.

–S

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

2017-11-24 Thread Stuart Sierra
The way I like to think of it, if it helps: Transients are still *immutable*, 
but they are not *persistent*. Each new value *invalidates* the previous 
value.

–S


On Friday, November 24, 2017 at 11:01:48 AM UTC-5, Alex Miller wrote:
>
> Transients must still be used in the same calling pattern as persistent 
> data structures. That is, you must use the value returned from the ! call 
> to make the next call. 
>

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

2017-07-09 Thread Stuart Sierra
Hi,

Clojure is syntactically similar to other Lisps, but it is its own language 
with a unique design. In particular, Clojure emphasizes immutable data 
structures and a pure functional programming style more than “classic” Lisp 
does. 

Familiarity with other Lisp-like languages will make it easier to learn 
Clojure, but there is still a lot to learn.

Unlike most other Lisps, Clojure is designed to be “hosted” in another 
language runtime such as Java or JavaScript. Most Clojure programs rely on 
the host language for environment-specific capabilities such as I/O. You 
don’t need to worry much about this to get started, but once you start 
working on real applications you will need to get familiar with the 
standard library of the host language.

Good luck, and have fun!

–S


On Sunday, July 9, 2017 at 7:30:39 AM UTC-4, HappyMacXL wrote:
>
> Hi all,
>
> I'm new to Clojure.  How close is it to LISP (MacLISP for example)?
>
> I ask because i'm also learning ZIL (Zork Implementation Language) which 
> is a descendant of the original LISP.  Well, actually it's a 'lite' version 
> of MDL ("Muddle").
>
> 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: Simultaneous development of a clojure project and an internal util library

2017-07-04 Thread Stuart Sierra
Hi Istvan,

I often work with multiple source directories by temporarily adding them to 
the :source-paths 

 in 
a Leiningen profile 
.

If you have a mono-repo or a consistent pattern for checking out multiple 
repos, you can use relative paths in :source-paths.

–S

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

2017-07-04 Thread Stuart Sierra
Hi Oded,

I think you would have to implement your own message-routing to achieve 
this. Create one "output" mult for each topic, subscribe to them with 
`tap`, and route the messages to the channels as they arrive.

Pseudo-code:
(go-loop []
  (when-some [message (! topic-ch message)))

This is quite similar to the go-loop in the implementation of `pub`: async.clj 
line 886 

.

–S

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

2017-07-04 Thread Stuart Sierra
Hi Ed,

I could not reproduce the behavior you described with Leiningen. Here is my 
test script:
https://gist.github.com/stuartsierra/ca2b9bd7072224e099beb8b95b49b69c

This issue might be caused by some pre-compiled files on the classpath when 
you run `lein test`. Since macros are evaluated during compilation, if the 
namespace using the macro was AOT-compiled then the macro would not be 
evaluated again. Try running `lein clean` or the Gradle equivalent, and 
make sure there are no stale AOT-compiled .class files in the /target 
directory.

–S

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

2017-03-13 Thread Stuart Sierra
This is a well-known problem in the JVM world, not just Clojure.

The most common approach is: Always use the latest versions, and don't 
break backwards-compatibility.

Most open-source Java and Clojure libraries are careful about not breaking 
backwards-compatibility. So in general, you're safe choosing the latest 
version of any library.

Leiningen has the `:pedantic` option which can be set to warn or fail when 
there are possible dependency conflicts.

Neither Clojure nor the JVM has explicit support for linking to specific 
versions of a library. Work-arounds exist, but they often increase overall 
complexity and lead to conflicts which are harder to debug.

–S


On Monday, March 13, 2017 at 4:13:19 PM UTC-4, arthur wrote:
>
> Hello All,
>
>
>  I have a general inquiry regarding conflicting dependencies in 
> Clojure projects and how they affect applications at runtime. I believe 
> this is a common problem faced by many languages in this day and age where 
> we try not to reinvent the wheel by depending on the work of others. 
> Basically: my application depends on libraries *A*, *B*, *C*, and *D*. 
> Libraries *B*, *C*, *D* *also* depend on library *A*, but all of us 
> depend on *different versions* of library *A.* Leiningen thankfully warns 
> us in many of these situations by suggesting exclusions. However, how can I 
> possibly know that something hasn't broken? Stringent testing can give a 
> certain degree of confidence that things are still working, but it would 
> seem to me that to ensure correctness, we should include *all* versions 
> of the dependencies and have the functions link to their respective 
> *versioned* identites. Does anyone have advice on how they solve these 
> kinds of problems on their codebases in the wild? Thankfully nothing has 
> broken yet (to my knowledge), but it seems we have very few assurances here 
> and the best we can do is *hope* nothing is broken. Any advice is much 
> appreciated.
>
> Thanks,
>
> Arthur
>

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


[moderated] I don't understand what (:t :t) means

2016-12-26 Thread Stuart Sierra
As a moderator, I am posting this message on behalf of a new forum user, 
below. I have edited the message for appropriate language. –Stuart S.


From: silver1 silver1 
Date: Mon, 26 Dec 2016 22:11:17 +0800
Subject: I don't understand (:t :t)mean ,please help me !!

hello,everyOne,i'm a new clojure learner.
I don't know what the structure of (:t :t)!
when i use coll? list? vector? set? map? seq? they all return false!!
what is the structure of (:t :t)? thank you very much!

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

2016-09-28 Thread Stuart Sierra
I will answer the clojure.test question, since I wrote it.

You can call clojure.test/is with *any* Clojure expression: if the 
expression returns logical true, the assertion passes. Having just the one 
expression keeps the scope of the testing library small.

The `clojure.test/is` macro was designed to be extensible, based on the 
syntax of the expression you pass it, but in a really convoluted way 
involving multimethods and macroexpansion. It was an experiment that did 
not turn out well, and I don't recommend it.

–Stuart S.


On Wednesday, September 28, 2016 at 10:31:37 AM UTC-4, paul wrote:
>
> The second is smaller, but is more a question. clojure.test seems to only 
> have 'is' so for things like equality I end up writing (is (= (...) (...))) 
> a lot. Or to test if an exception is thrown (is (thrown? ...)). That's OK, 
> but I'm wondering what led to that decision rather than having is-eq and 
> is-thrown and so on (considering the core language has shortcuts like when 
> and unless and if-not so the compound macros seem idiomatic).
>

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

2016-09-13 Thread Stuart Sierra
The `get` function will accept `nil` as the map argument and return `nil`, 
but invoking `nil` will throw a NullPointerException.

By convention, people use `get` when they don't know what the map argument 
is, since it might be nil. And we use keywords as functions when they are 
literals, like (:foo m).

(let [m (...something that might return a map or nil...)]
  (get m "some key"))  ; returns nil or value

(let [m (...something that might return a map or nil...)]
  (m "some key"))  ; might throw exception

All forms of map lookup support a default argument if the key is not found:

user=> (let [m {:a 1 :b 2}] (m :c "not found"))
"not found"
user=> (let [m {:a 1 :b 2}] (:c m "not found"))
"not found"
user=> (let [m {:a 1 :b 2}] (get m :c "not found"))
"not found"

–S


On Tuesday, September 13, 2016 at 7:58:14 AM UTC-4, Rickesh Bedia wrote:
>
> Hi everyone,
>
> I am new to Clojure and have been playing around with it for a little 
> while. I have seen that (get [3 2 1] 0) and ([[3 2 1] 0) both return the 
> value 3. Similarly (get {:a 0 :b 1} :b) and ({:a 0 :b 1} :b) return 1.
>
> I was wondering if anyone could explain why the get function is useful or 
> maybe an example?
>
> Apologies in advance if this question is due to ignorance and I haven't 
> reached the level where this function is used.
>
> Thanks in advance
>

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

2016-09-09 Thread Stuart Sierra
This approach would only work in ClojureScript, where IDeref is defined as 
a Protocol. In Clojure(JVM), the core functions are defined in terms of 
Java interfaces, which are not extensible to `nil`.

I don't find atom-or-nil to be a common value pattern. But if it's 
something you encounter frequently, you could work with it by either:
- defining functions to return (atom nil) instead of nil
- defining your own nil-safe version of deref

–S



On Friday, September 9, 2016 at 4:10:11 AM UTC-4, Deon Moolman wrote:
>
> Hey all,
>
> I'm having some pain with atoms and dereferencing nil - mostly around my 
> functions sometimes returning an atom and other times nil - I don't really 
> want to create a special 'nil' atom and do the bits for returning that and 
> I don't want to be checking nils absolutely everywhere when nil-punning 
> works perfectly otherwise, so I was wondering what the pitfalls of this 
> approach would be?
>
> (extend-type nil IDeref
>   (-deref [_] nil))
>
> Effectively, make @nil nil-pun to nil. makes sense to me?
>
> Cheers,
>  - Deon
>
>

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

2016-09-09 Thread Stuart Sierra
Functions like map/filter/remove are not "collection functions" but rather 
"sequence functions." The collection functions like conj preserve the type 
of their argument. Sequence functions, by contrast, coerce any argument to 
a sequence, and always return a sequence.

Since Clojure 1.7, transducers provide a convenient way to compose 
sequence-like operations but produce a non-sequence as a result:

user=> (into [] (comp (map inc) (filter even?)) [1 2 3 4 5])
[2 4 6]

mapv and filterv were convenience functions added before the introduction 
of transducers, as I recall.
–S




On Friday, September 9, 2016 at 6:23:37 AM UTC-4, Colin Yates wrote:
>
> Hi all,
>
> So in the spirit of exposing my ignorance to the internet :-), I have just 
> been bitten by a bug due to the behaviour of the core libraries which I 
> find really surprising:
>
> (def v [1 2 3])
> (conj v 4) => [1 2 3 4]
> (conj (map identity v) 4) => (4 1 2 3)
> (conj (remove (constantly false) v) 4) => (4 1 2 3)
> (conj (filter identity v) 4) => (4 1 2 3)
>
> In other words, I was relying on map, remove and filter preserving the 
> semantics (other than laziness) of the structure of the input, give it a 
> vector and you get a vector-like lazy sequence. This turns out not to be 
> the case.
>
> Now, I know there is mapv which returns a vector but why isn't there a 
> removev and a filterv etc.?
>
> What makes it more onerous for me is the fact conj states that its 
> behaviour differs depending on the concrete type, which is great, but how 
> am I supposed to know which concrete type is returned from 
> map|filter|remove? My assumption was it would be semantically equivalent to 
> the input (i.e. a vector in this case).
>
> The reason I have dodged this is because I don't frequently rely on vector 
> semantics but I am surprised this isn't better documented?
>
> Is it me?
>
> Thanks,
>
> Colin
>

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

2016-09-09 Thread Stuart Sierra
loop/recur is more typical for this kind of counting loop, as it avoids the 
risk of a stack-overflow when the number of iterations is high.

Also, I recommend against the [a b & [n]] argument pattern here:
https://stuartsierra.com/2015/06/01/clojure-donts-optional-arguments-with-varargs

–S


On Friday, September 9, 2016 at 8:02:14 AM UTC-4, Joeyjoejoe wrote:
>
> Hi,
>
> I'm just stating to learn clojure, i made a first read of "clojure 
> programming" to get the big picture, and i'm starting to play with the 
> repl, trying to solve some katas. A lot of theses katas involves returning 
> the count of loop iterations. Most of the time, i end up with this kind of 
> functions:
>
> (defn my-function [a b & [n]]
>  (if cond
>(my-function new-a new-b (inc (or n 0))
>(or n defaut-value)
>   )
> )
>
> What are the pros/cons of doing this? Are there any idiomatic ways of 
> doing this.
>
> Thank you
>

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

2016-04-20 Thread Stuart Sierra
The first answer: test & measure. Benchmark your code, use a JVM profiler 
to find hotspots, etc. Test every change you make to see if it has a 
measurable improvement. Any assumptions about what “should” be 
faster/slower are likely to be wrong.

The long answer:

The JVM does not give you much control over how objects are arranged in 
memory. In Java and Clojure, almost everything is a pointer to an object on 
the heap. Java collection classes and Clojure collections store pointers to 
objects; they do not store values “in-line” like an array of structs in C. 
The JVM *may* have optimizations that try to arrange objects “near” other 
objects, but you have no control over this.

So my (untested) expectation is that all Clojure collection types are 
more-or-less equal in terms of memory locality.

The only built-in data structure that offers the possibility of contiguous 
allocation in Java — without dropping down to native code — is an array of 
primitives, such as integers or doubles. Clojure has built-in functions to 
create and manipulate Java primitive arrays, if that works for your use 
case.

–S


On Wednesday, April 20, 2016 at 2:03:10 PM UTC-4, JvJ wrote:
>
> I'm writing some code that I would like to perform as quickly as possible. 
>  Currently, I am iterating over large hash maps and performing assocs and 
> dissocs.
>
> I don't know much about performance optimization, but I am told that 
> memory locality is a big factor.  I would like to know how Persistent Maps, 
> Persistent Vectors, Transient Maps, and Transient Vectors compare to one 
> another in this respect.
>
> Also, the objects in the collection that I'm iterating over will 
> themselves be maps.  So, if I had a vector with good memory locality, but 
> it stored what are effectively pointers to maps allocated elsewhere, will 
> that nullify the benefits of memory locality?
>
> 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: Downloading Clojure + Contrib Source

2016-04-04 Thread Stuart Sierra
Hi Chris,

No, there is no single command I know of to automatically download all of 
the contrib libraries. It's something you could do with a shell script, I 
expect.

But you probably don't need to do that if you're just interested in 
learning Clojure.

'contrib' just means things contributed to “Clojure” as an organization, 
governed by the same Contributor Agreement and patch process. The 'contrib' 
libraries have many different authors, release cycles, and degrees of 
maturity. They are not necessarily meant to be a “standard library,” 
although some of them are more-or-less standard.
What is Clojure Contrib? 


If you're interested in learning about Clojure by reading source code, you 
might look for popular Clojure libraries (not necessarily 'contrib') on 
GitHub or sites like Clojure Toolbox . 
Most Clojure books and online tutorials will also point you in the 
direction of popular libraries.

–S


On Monday, April 4, 2016 at 8:16:45 AM UTC-4, Chris White wrote:
>
> I'm currently in the process of learning Clojure and would like to look 
> around the source code to see how it's laid out. Unfortunately I'm having 
> trouble finding an easy way to download not only the Clojure source code, 
> but also the contrib packages. Currently it looks like I have to download 
> everything in the clojure GitHub organization. Is there some kind of script 
> used by developers to pull everything down into a single folder? Is there a 
> way that all the contrib packages can be released as a single source 
> tarball? Thanks ahead of time for any responses.
>
> - Chris White
>

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

2016-03-15 Thread Stuart Sierra
Not sure, but possible related to 
http://dev.clojure.org/jira/browse/CLJ-1208 "Namespace is not loaded on 
defrecord class init"
–S

On Friday, March 11, 2016 at 12:20:44 AM UTC-5, Andy L wrote:
>
> Hi,
>
> I noticed that after upgrade to Clojure  1.8.0 (from 1.7.0) a weird 
> occurrence of logging, even during uberjar generation which looks like 
> this, using lein 2.5.3:
>
> $ lein uberjar 
> Compiling core
> 2016-03-10 22:11:23.030:INFO::main: Logging initialized @964ms
>
> I believe that actual log is pegged from here 
> https://github.com/eclipse/jetty.project/blob/master/jetty-util/src/main/java/org/eclipse/jetty/util/log/Log.java#L186
>  
> , which gniazdo depend on. 
>
> I spend some time trying to better understand the underlying cause but 
> failed to do so. My questions are:
>  1) why client code would be executed during uberjar generation (provided 
> my assumption is valid)?
>  2) what changed in 1.8 to cause that?
>
> Thanks in advance,
> Andy
>
>
> = sources 
> $ cat project.clj src/core.clj 
> (defproject tmp "0.1.0-SNAPSHOT"
>   :dependencies [[org.clojure/clojure "1.8.0"] [stylefruits/gniazdo 
> "0.4.1"]]
>   :profiles {:uberjar {:aot :all}})
> (ns core
>   (:require [gniazdo.core :as ws]))
>

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

2016-02-15 Thread Stuart Sierra
A macro can't do this, it must return a single form. But the `apply` 
function can do something similar in the context of a function call.

(apply foo '(1 2 3))
is the same as
(foo 1 2 3)

–S



On Monday, February 15, 2016 at 2:05:52 PM UTC-5, Sonny To wrote:
>
> I am trying to write a macro to unwrap a list:
>
> here's my naive attempt
>
> (defmacro unwrap [s]
>   (-> s pr-str  (clojure.string/replace #"[\(\)]" "") read-string))
>
> (unwrap (1 2 3) ) should give 1 2 3
>
> any ideas how this can be done?
>
> thanks,
> Sonny
>

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

2016-02-12 Thread Stuart Sierra
(.printStackTrace *e) 
will print the full stacktrace of the most recent exception to the standard 
error stream (STDERR) of the Java process.

Depending on your REPL / tooling environment, stuff printed to standard 
error may not show up in your REPL. If that happens, try this:
(.printStackTrace *e *out*)

*out* is Clojure's thread-local binding for standard output (STDOUT), which 
tools like nREPL rebind to capture output and display in the REPL.

–S

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

2016-02-08 Thread Stuart Sierra
Clojure's destructuring is not the same thing as the "pattern matching" 
found in some other functional languages. Pattern matching can do various 
conditional checks, destructuring cannot. Clojure's "defn" supports 
destructuring in the argument list.

Full pattern matching is available in Clojure via libraries such as 
core.match:
https://github.com/clojure/core.match

–S



On Monday, February 8, 2016 at 2:41:44 PM UTC-5, Laws wrote:
>
> Sean Johnson has a great video about pattern matching, where he suggests 
> that any function that starts with a conditional should have the 
> conditional removed and the conditional logic implemented as 
> pattern-matching and restructuring in the signature of the function. But 
> after some experimentation, I have failed to figure out a way to do this 
> here: 
>
> (defn add-parties-to-customer-queue [parties]
>   (if (seq parties)
> (swap! customer-queue
>(fn [previous-customer-queue]
>  (apply conj previous-customer-queue parties)
>
> "parties" sometimes has a vector of vectors, but sometimes it is simply: ()
>
> Is there any way I can match against that pattern in the function 
> signature? 
>
>
>
>
>
>

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

2016-01-05 Thread Stuart Sierra
tools.namespace
https://github.com/clojure/tools.namespace

Development tools for managing namespaces in Clojure. Parse ns declarations 
from source files, extract their dependencies, build a graph of namespace 
dependencies within a project, update that graph as files change, and 
reload files in the correct order.

Release 0.3.0-alpha3

Leiningen dependency [org.clojure/tools.namespace "0.3.0-alpha3"]

This is a development release. Changes:

* Ignore `:require-macros` and `:use-macros` when parsing namespace 
dependencies. This is a change in behavior from previous 0.3 alphas and is 
a more robust fix for [TNS-38]. tools.namespace currently only models one 
dependency graph at a time, so it treats Clojure and ClojureScript as 
separate worlds and will not attempt to analyze dependency relationships 
which cross that boundary.

* Fix [TNS-40]: do not catch exceptions in `c.t.n.file`. Instead, catch and 
ignore only syntax exceptions (identified by `ex-data` from 
[tools.reader]). This is a change in behavior from 0.3.0-alpha2 and 0.2. It 
should have minimal impact on users but make some errors (such as an 
incompatible version of tools.reader) more obvious.

* Known bugs not yet fixed: [TNS-42] When the same namespace is defined in 
both `.clj` and `.cljc` files, dependencies may be read from either, when 
it should prefer the `.clj` file.

[TNS-38]: http://dev.clojure.org/jira/browse/TNS-38
[TNS-40]: http://dev.clojure.org/jira/browse/TNS-40
[TNS-42]: http://dev.clojure.org/jira/browse/TNS-42

Full change log:
https://github.com/clojure/tools.namespace/blob/master/CHANGES.md

This is a Clojure-contrib project:
http://dev.clojure.org/display/doc/Clojure+Contrib



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

2016-01-03 Thread Stuart Sierra
I recently adapted my Emacs config 

 
to work with Org 8.3.2 and CIDER 0.10.0. Here it is. 

 
This is just my personal setup, not something I can support. Posting here 
in case someone else might find it useful.
–S

On Monday, December 21, 2015, martin_clausen wrote:
>
> I found that
>
> Org-mode version 8.3.2 and CIDER 0.11.0 snapshot (package: 20151212.1044)
>
> works great and can be easily be installed from repos.
>

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

2015-12-29 Thread Stuart Sierra
AOT-compilation breaks almost any code that tries to redefine Vars. I 
wouldn't expect this to work.
—S


On Monday, December 28, 2015, wparker30 wrote:
>
> I have found what appears to be a bug in AOT-compiled Clojure when 
> ns-unmap is used.  I have the following reduced case:
>
> (ns unmap-test.core)
>
> (def a :test-1)
>
> (ns-unmap 'unmap-test.core 'a)
>
> (def a :test-2)
>
> It turns out that a is not resolvable when this namespace is loaded.  When 
> I looked at the compiled bytecode,
> it appears that the following operations occur:
>
> 1. A call to RT.var withe 'unmap-test.core and 'a returns a Var, which is 
> bound to a constant.
>   This var is added to the namespaces's mapping during this call.
> 2. Same as 1.
> 3. The var from 1 is bound to :test-1.
> 4. ns-unmap is called.
> 5. The var from 2 is bound to :test-2.
>
> Disclaimer: This is the first time I have had occasion to look directly at 
> bytecode and I could be missing something.
>
> The basic problem here is that the var is accessible from the load method, 
> but when step 5 executes the var is no longer
> accessible from the namespace mappings.  Thus, the root of the Var is set 
> to :test-2, but that Var is not mapped from the namespace.
> This works when there is no AOT compilation, as well as when I use 
>
> (ns unmap-test.core)
>
> (def a :test-1)
>
> (ns-unmap 'unmap-test.core 'a)
>
> (intern 'unmap-test.core 'a :test-2)
>
> I realize that creating defs, unmapping them, and then recreating them is 
> generally poor practice in Clojure.
> We have an odd case in that we need to have an interface and a Var of the 
> same name in the same namespace.  Simply
> doing definterface and then def causes a compilation failure:
>
> user=> (definterface abc)
> user.abc
> user=> (def abc 1)
> CompilerException java.lang.RuntimeException: Expecting var, but abc is 
> mapped to interface user.abc, 
> compiling:(/private/var/folders/3m/tvc28b5d7p50v5_8q5ntj0pmflbdh9/T/form-init4734176956271823921.clj:1:1)
>  
>
> Without going into too much detail, this is basically a hack to allow us 
> to refactor our internal framework code
> without immediately changing a very large amount of downstream consumer 
> code.  We get rid of the usage of the interface during macroexpansion,
> but it still needs to exist on the classpath so it can be imported by 
> downstream namespaces.  
> There are a number of other ways to accomplish this, so it isn't a 
> particularly big problem for us, but I thought the issue was worth raising.
> This was just the first thing I tried and I was surprised when it didn't 
> work.
>
> Note that I used the 1.8.0 RC4 version of Clojure in my sample project, 
> but I had the same behavior on 1.7.0.
>
> Relevant links:
>
> 1. Bytecode for the load method of the init class: 
> https://gist.github.com/WilliamParker/d8ef4c0555a30135f35a
> 2. Bytecode for the init0 method: 
> https://gist.github.com/WilliamParker/dc606ad086670915efd9
> 3. Decompiled Java code for the init class.  Note that this does not 
> completely line up with the bytecode as far as I can tell,
> but it is a quicker way to get a general idea of what is happening than 
> the bytecode.
> https://gist.github.com/WilliamParker/4cc47939f613d4595d94
> 4. A simple project containing the code above: 
> https://github.com/WilliamParker/unmap-test
> Note that if you try it without AOT compilation the target folder with any 
> previously compiled classes should be removed.
>
> I may or may not be able to respond to any replies before next week; I 
> apologize for any delayed responses.
>

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

2015-12-23 Thread Stuart Sierra
This is an application design decision that will depend on how you want to 
handle failure in general.

If the application cannot run without being able to start the component, 
then it is appropriate to throw an exception from the component's `start` 
method. This will abort the system start. The component library wraps the 
exception with ex-info containing the component that failed AND the 
complete system so far, including components which were successfully 
started How you want to handle that exception is up to you.

In production, I would handle this by calling System/exit with a non-zero 
status code from my `main` method.

During development, if a component fails to start, it may leave the rest of 
the system in an inconsistent state. This may make it difficult to restart 
the system because of old state from the half-started system. For example, 
a web server may have bound to a socket. Technically you could use the 
system object attached to the exception to clean up the state manually, but 
I usually just restart the REPL.

If the application could continue to operate successfully without that 
component, it's much more complicated. You're on your own here;
the 'component' library doesn't have any functions to help with 
partially-failed systems. 

–S


On Wednesday, December 23, 2015 at 1:42:21 PM UTC-5, fahptv wrote:
>
> If a component discovers it cannot start successfully (e.g. some necessary 
> bit of data is badly formatted), how can it tell the system that it's hosed 
> and therefore all dependents are hosed?
>
> Should it throw an exception to stop 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.
For more options, visit https://groups.google.com/d/optout.


Re: [Q] What would be the best approach or design for converting this common lisp code?

2015-12-20 Thread Stuart Sierra
Hi Sungjin,

Although Clojure draws from the long history of Lisps, it is very much its 
own language. In particular, the emphasis on immutable data by default 
makes Clojure very different from both Common Lisp and Scheme. Porting code 
from another Lisp to Clojure will usually require a complete redesign.

Based on looking very briefly at the code you linked to, it looks like it 
might be some kind of agent-based simulation. Clojure's Agents may be 
something worth exploring: http://clojure.org/agents

–S



On Friday, December 18, 2015 at 5:07:38 PM UTC-5, Sungjin Chun wrote:
>
> Hi,
>
> The code repo is https://github.com/wzrdsappr/trading-core .
>
> If you look at the code, the main trading agent is designed using 
> inheritance and the main
> operation (consume) function mainly depends upon mutable update of agent's 
> states.
>
> As far as I know Clojure does not permit attribute inheritance and this 
> kind of state update is
> not recommended approach. 
>
> What would be the best approach in Clojure?
>
> Thank you in advance and sorry for my poor english.
>

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

2015-11-28 Thread Stuart Sierra
https://github.com/stuartsierra/component

Bugfix release 0.3.1 contains the following changes:

   - Fix #40 ,
   incorrect values for ex-data keys in missing-dependency error

Leiningen dependency:

[com.stuartsierra/component "0.3.1"]


Full change log


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

2015-11-25 Thread Stuart Sierra
Hi,

Channels are many-to-many in the sense that many processes can "put" values 
on the same channel, and many processes can be waiting to "take" a value. 
They are one-to-one in the sense that each "put" value will be delivered to 
exactly one "taker".

What you're describing sounds like a typical Observer pattern, which 
implies some state to keep track of "subscribers." You could implement 
something like this with channels using mult/tap or pub/sub, but it's not 
expressed directly in the core.async APIs.

Depending on the use case, doing it with channels may or may not be easier 
than implementing an Observer-style pattern directly. But having tried to 
implement an Observer once or twice, I've learned it's hard to get all the 
edge cases right, so now I find channels easier to understand.

–S

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

2015-11-13 Thread Stuart Sierra
tools.namespace — Parse ns declarations from source files, extract their 
dependencies, build a graph of namespace dependencies within a project, 
update that graph as files change, and reload files in the correct order.

https://github.com/clojure/tools.namespace

Leiningen-style dependency:
[org.clojure/tools.namespace "0.3.0-alpha2"]


Release 0.3.0-alpha2 contains the following changes since 0.3.0-alpha1:

   - Fix TNS-38 : ignore 
   circular dependency from .cljs file to .clj file in :require-macros
   - dependency on tools.reader version 0.10.0
   - dependency on java.classpath version 0.2.3
   - Add clojure.tools.namespace.parse/name-from-ns-decl


Change log:

https://github.com/clojure/tools.namespace/blob/master/CHANGES.md


This is a Clojure Contributed library:

http://dev.clojure.org/display/doc/Clojure+Contrib

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

2015-11-06 Thread Stuart Sierra
java.classpath — utilities to examine the Java classpath from Clojure 
programs.

https://github.com/clojure/java.classpath

Release 0.2.3.

Leiningen dependency: [org.clojure/java.classpath "0.2.3"]

This is a bugfix release. Changes:


   - Fix CLASSPATH-7 : 
   ignore classloaders which do not implement URLClasspath


See Change Log 


This is a Clojure Contrib 
 project.

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

2015-11-04 Thread Stuart Sierra
Hi, Johannes,

Sorry, I don't know. That error looks like an incompatibility of Elisp 
functions from different libraries.

There are just too many different moving pieces here: Emacs, org-mode, 
CIDER, and nREPL. These projects are not coordinated with regard to version 
numbers and API incompatibilities.

The code snippet I linked to only works on the specific versions I have: 
Emacs (GNU 24.5.1), org-mode (commit d3196f0 
),
 
CIDER (0.9.1), and nREPL (0.9.1).

You will probably have to debug and tweak the Elisp code to work with your 
local Emacs installation. I don't know of any easier way to get org-babel & 
Clojure working together.

Good luck,
–S



On Wednesday, November 4, 2015 at 4:36:01 AM UTC-5, Johannes wrote:
>
> Hi Stuart, 
>
> thanks a lot for your help. I’ve included your settings in my Emacs 
> (Aquamacs) setup. After having activated CIDER I tried to compile (C-c C-c) 
> a little code snippet:
>
> #+begin_src clojure  :results silent
>(+ 1 2)
> #+end_src
>
> What happens, is:
>
> Evaluate this clojure code block on your system? (y or n) y
> executing Clojure code block...
> let: Wrong number of arguments: (3 . 4), 1
>
> What I am doing wrongly?
>

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

2015-11-03 Thread Stuart Sierra
Hi Johannes

I have a working Org babel & Clojure in my Emacs setup. It's idiosyncratic 
to my preferences, but maybe it will be useful:
github.com/stuartsierra/dotfiles 


–S


On Tuesday, November 3, 2015 at 3:25:51 AM UTC-5, Johannes wrote:
>
> Hi,
>
> I am looking for a working environment for using org-mode with Clojure 
> babel. Googleing for the issue I can only find some apparently outdated 
> hints. I am using org-mode version 8.2.10, Clojure 1.6.0, Leiningen 2.5.1, 
> and CIDER 0.10.0.
>
> Any hints, where I can find the right configuration?
>
> 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: Processing futures and promises asynchronously

2015-10-28 Thread Stuart Sierra
core.async and Transducers target some of this, although in a slightly 
different way. Instead of clojure.core/future, you can use 
core.async/thread or core.async/go. Instead of flatMap, you can use a `map` 
Transducer on a channel or in a core.async/pipeline.

–S

On Monday, October 26, 2015 at 6:46:27 PM UTC-4, Daniel Hinojosa wrote:
>
> I am looking for a functional, non-blocking way to process the return of a 
> future. In the Scala world, you can use map, flatMap, and foreach to 
> process the return values of a future asynchronously.  In Clojure, 
> dereferencing blocks, so that makes it kind of rough since we have to set 
> up our constructs.  If anyone can steer me on the "Functional Clojure way" 
> to process futures and promises that would be greatly appreciated. ;)
>

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

2015-10-03 Thread Stuart Sierra
Interfaces like ISeq are internal details of Clojure's implementation. 
They're not part of the public API, so there is no guarantee that they 
won't change in future releases.

–S


On Thursday, October 1, 2015 at 4:59:12 AM UTC-4, crocket wrote:
>
> http://clojure.github.io/clojure/javadoc/ doesn't expost interfaces like 
> clojure.lang.ISeq, so when I refer to such interfaces, I have to download 
> clojure javadoc from maven.
> I'd like to refer to those interface on web browsers. Why are they not 
> exposed on the web?
>

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


Re: Question on clojure.test thrown? and clojure.lang.ArityException

2015-09-21 Thread Stuart Sierra

I think this might be a special case related to inlining in the Clojure 
compiler. It has nothing to do with clojure.test.

The hint is the name of the function in the error message: 
core/quot--inliner--4345

The "inlined" version of `quot` is defined for two arguments:
https://github.com/clojure/clojure/blob/b8607d5870202034679cda50ec390426827ff692/src/clj/clojure/core.clj#L1232

The inlined version of `/` is also defined for two arguments, but has an 
additional check before inlining that there is more than 1 argument:
https://github.com/clojure/clojure/blob/b8607d5870202034679cda50ec390426827ff692/src/clj/clojure/core.clj#L991

-S

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

2015-09-18 Thread Stuart Sierra
'Component' - lifecycle and dependency management for objects with runtime 
state.

https://github.com/stuartsierra/component

Leiningen dependency: 
[com.stuartsierra/component "0.3.0"]


Changes in this release:

* Added ClojureScript support via Conditional Read (.cljc)

* Minimum Clojure version is now 1.7.0

* Exceptions have been modified slightly for cross-platform compatibility.

* No public API changes from 0.2.3


License: MIT  http://opensource.org/licenses/MIT

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

2015-08-14 Thread Stuart Sierra
tools.namespace: Parse ns declarations from source files and
reload files in the correct order.

https://github.com/clojure/tools.namespace


This is an ALPHA release with some significant changes,
including ClojureScript support (see below). It should be
fully backwards-compatible with the 0.2.x series, except for
the new dependency on Clojure 1.7, but I would like to
encourage anyone working on development tools or libraries
that use tools.namespace to try out this release and report
any bugs you find. Thanks!


Leiningen dependency information:

   [org.clojure/tools.namespace 0.3.0-alpha1]

   
Changes in this release:

  * Minimum Clojure version is 1.7.0

  * Enhancement [TNS-36]: Use java.classpath for better JVM
classpath resolution

  * Partial ClojureScript Support [TNS-35]

  * Platform-neutral namespaces were converted to
conditional-read (`.cljc`) files: c.t.n.dependency,
c.t.n.track, and c.t.n.parse. These namespaces can
be used in ClojureScript programs.

  * Added support for finding, parsing, and analyzing
ClojureScript source files (`.cljs` and `.cljc`) in
c.t.n.file, c.t.n.parse, c.t.n.dir, and c.t.n.find
with optional platform arguments. These namespaces
still only **run** on the Clojure(JVM) platform.

  * Reloading and interactive features remain
Clojure(JVM) only for now: c.t.n.move, c.t.n.reload,
and c.t.n.repl

  * Uses [tools.reader] for platform-independent parsing
and conditional-reader support.

  * Breaking change: `c.t.n.parse/read-ns-decl` no longer
returns `nil` on syntax errors. Instead, exceptions are
allowed to propagate up from tools.reader. This change
only affects code which calls `read-ns-decl` directly.
c.t.n.file and c.t.n.find will catch and ignore reader
exeptions when trying to read namespace declarations.

  * Some definitions deprecated; see source code or Var
metadata for details.


This is a Clojure Contrib project.
http://dev.clojure.org/display/doc/Clojure+Contrib

[TNS-35]: http://dev.clojure.org/jira/browse/TNS-35
[TNS-36]: http://dev.clojure.org/jira/browse/TNS-36
[tools.reader]: https://github.com/clojure/tools.reader

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

2015-08-07 Thread Stuart Sierra
Hi Simone,

The stack overflow here is caused by the REPL trying to print a circular 
reference. `swap!` always returns the new value of the Atom, and the REPL 
tries to print it.

If you don't print the Atom, this self-reference can still work:

user= (def a (atom {}))
#'user/a
user= (do (swap! a assoc :self a) nil)
nil
user= (= a (:self @a))
true

–S


On Friday, August 7, 2015 at 9:42:05 AM UTC-4, Simone Mosciatti wrote:

 Hi all,

 I noticed this behaviour that I was not expecting:

 simo@simo:~$ lein repl
 nREPL server started on port 42010 on host 127.0.0.1 - nrepl://
 127.0.0.1:42010
 REPL-y 0.3.5, nREPL 0.2.6
 Clojure 1.6.0
 OpenJDK 64-Bit Server VM 1.7.0_79-b14
 Docs: (doc function-name-here)
   (find-doc part-of-name-here)
   Source: (source function-name-here)
  Javadoc: (javadoc java-object-or-class-here)
 Exit: Control+D or (exit) or (quit)
  Results: Stored in vars *1, *2, *3, an exception in *e

 user= (def a (atom {}))
 #'user/a
 user= (swap! a assoc :self a)

 StackOverflowError   java.util.regex.Pattern$GroupHead.match 
 (Pattern.java:4556)
 user= (swap! a assoc :test :ok)

 StackOverflowError   java.lang.Character.codePointAt (Character.java:4668)
 user= a

 StackOverflowError   java.util.regex.Pattern$Curly.match0 
 (Pattern.java:4148)
 user= (def b (atom {}))
 #'user/b
 user= (swap! b assoc :test :ok)
 {:test :ok}

 It is something expected or I should open a bug report ?

 Greets

 Simone


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

2015-07-28 Thread Stuart Sierra
Thanks for the responses everyone.

So far, my general plan is starting to look like this:

c.t.n.*dependency* and c.t.n.*track* are platform agnostic.

c.t.n.*file* and c.t.n.*parse* can be extended to support Clojure  
ClojureScript by adding an optional argument read-opts passed through to 
tools.reader/read.

c.t.n.*find* can be extended with optional arguments to select a 
platform, either Clojure or ClojureScript, which will encapsulate both 
valid file extensions and reader options.

Reload/refresh functionality will remain Clojure(JVM) only for now: c.t.n.
*dir*, c.t.n.*reload*, and c.t.n.*repl*.

More notes and work-in-progress are visible on TNS-35 
http://dev.clojure.org/jira/browse/TNS-35

I'm not saying there will *never* be any ClojureScript support for 
refresh/reload, just that I have no idea how to do it right now and I want 
to deal with the easier problems first.

–S

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

2015-07-25 Thread Stuart Sierra
On Sat, Jul 25, 2015 at 10:37 AM, Dylan Butman dbut...@gmail.com wrote:

 Clojurescript support would be a fantastic improvement for reloading cljs
 component systems.


As I said, I am not planning a complete port of the reloading functionality
of clojure.tools.namespace.repl to work in ClojureScript. The mechanics of
reloading code are completely different in ClojureScript.

The ClojureScript compiler itself now has some auto-compiling
functionality, and tools like lein-figwheel are filling in the rest.

–S

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

2015-07-25 Thread Stuart Sierra
On Sat, Jul 25, 2015 at 11:15 AM, Bozhidar Batsov wrote:

 it'd be great if we could provide the same functionality for cljs.


I'd like to say I know how to do that, but I just don't think it's possible
right now. The way tools.namespace does reloading in Clojure(JVM) depends
on implementation details of the Clojure runtime, including the function
remove-ns which doesn't exist in ClojureScript.

–S

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


Tool authors: ClojureScript support in tools.namespace?

2015-07-24 Thread Stuart Sierra
Hello to anyone and everyone writing tools for working with Clojure and 
ClojureScript source files …

I've been looking into adding better support for ClojureScript in 
tools.namespace.

It's not a trivial problem. Lots of places in tools.namespace assume there 
is only one kind of source file. For Clojure 1.7 it got updated to include 
.cljc files as well, but it's still hard-coded. I've collected some of my 
notes in TNS-35: http://dev.clojure.org/jira/browse/TNS-35

My question to you: if you maintain a tool or library which uses 
tools.namespace:

   1. Do you need/want ClojureScript support?

   2. What namespaces (repl, find, dir, file, parse) do you call in 
tools.namespace?

   3. How would you like to distinguish between get me Clojure sources 
and get me ClojureScript sources?

Note: I am **not** proposing a full port of tools.namespace to 
ClojureScript. Something like c.t.n.repl/refresh is too tightly coupled to 
JVM Clojure, and equivalent tools already exist for ClojureScript.

This is just about using tools.namespace to parse and analyze the 
dependencies of ClojureScript source files, statically, the same way it now 
does for Clojure source files.

Thanks,
–S

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

2015-07-24 Thread Stuart Sierra
Hi Lawrence,

I think Clojure's concurrency primitives are more narrowly scoped than that.

Clojure's most significant concurrency features (Atoms, Refs, Vars, Agents) 
are mostly about managing changes to *shared, mutable state* via pure 
functions. Hystrix is about managing code with unpredictable behavior and 
timing, e.g. client libraries which do blocking I/O and other side effects.

When I do presentations or workshops about Clojure, I always make a point 
to say that Clojure does not try to solve **all** problems related to 
concurrency and parallelism. You still need things like Java thread pools. 
Clojure was designed as a hosted language precisely so that it can take 
advantage of the rich set of concurrency tools available on the JVM 
platform, including frameworks like Hystrix.

Clojure makes it easier to write programs which manage their state 
correctly. Hystrix makes it easier to write programs which manage 
side-effect-heavy libraries correctly. Together, they make a pretty good 
combination.

–S


On Friday, July 24, 2015 at 1:10:10 PM UTC-4, Lawrence Krubner wrote:

 I find this very interesting: 

 http://blog.josephwilk.net/clojure/building-clojure-services-at-scale.html

 [Using Hystrix comes at a cost:] We cannot use Clojure’s concurrency 
 primitives (futures/promises/agents).

 That is fascinating to think that at some point Clojure's concurrency 
 primitives are not enough, and so we need to give up on them and move to a 
 Java library. I am aware that Netflix is dealing with unusual scale, but 
 what is the point of Clojure if it doesn't automate exactly these issues? I 
 don't mean this as an attack on Clojure, but rather, I'm curious why issues 
 of thread pool management and circuit breakers don't get baked in to a 
 deeper level of Clojure? After all, that is the reason why people use 
 Clojure, yes? The argument for Clojure is exactly that it automates so much 
 of the work of dealing with concurrency, right? 

 Am I being stupid? 






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

2015-07-20 Thread Stuart Sierra
Thanks for the correction, Alex.

On Sunday, July 19, 2015 at 12:34:37 PM UTC-4, Alex Miller wrote:

 seqs on eductions *are* chunked - they will fall into this case during 
 seq: 
 https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/RT.java#L524-L525
  
 which produces a chunked sequence over an Iterable.


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

2015-07-19 Thread Stuart Sierra
Hi Leon,

I think this is an edge case related to how varargs functions are 
implemented in Clojure.

The varargs arity of `max` is implemented with `reduce1`: core.clj line 1088 
https://github.com/clojure/clojure/blob/36d665793b43f62cfd22354aced4c6892088abd6/src/clj/clojure/core.clj#L1088

`reduce1` is a simplified implementation of reduce defined early in 
clojure.core before the optimized reduction protocols have been loaded: 
core.clj 
line 894 
https://github.com/clojure/clojure/blob/36d665793b43f62cfd22354aced4c6892088abd6/src/clj/clojure/core.clj#L894.
 
`reduce1` is implemented in terms of lazy sequences, with support for 
chunking.

So `apply max` defaults to using chunked lazy sequence operations. `map` 
and `range` both return chunked sequences.

`eduction` returns an Iterable, so when you `apply max` on it, it turns the 
Iterable into a Seq, but it's not a chunked seq. Therefore, it's slightly 
slower than `apply max` on a chunked seq.

In this case, to ensure you're using the fast-path internal reduce over `
eduction`, you can use `reduce` directly:
(reduce max 0 (eduction (map inc) (range 10)))
You must provide an init value because `eduction` does not assume the init 
with first element behavior of sequences.

This version, in my informal benchmarking, is the fastest.

Lots of functions in clojure.core use `reduce1` in their varargs 
implementation. Perhaps they could be changed to use the optimized `reduce`, 
but this might add a lot of repeated definitions as clojure.core is 
bootstrapping itself. I'm not sure.

In general, I would not assume that `eduction` is automatically faster than 
lazy sequences. It will be faster only in the cases where it can use the 
optimized reduction protocols such as InternalReduce. If the optimized path 
isn't available, many operations will fall back to lazy sequences for 
backwards-compatibility. 

I would suggest using `eduction` only when you *know* you're going to 
consume the result with `reduce` or `transduce`. As always, test first, and 
profilers are your friend. :)

–S



On Saturday, July 18, 2015 at 9:11:45 AM UTC-4, Leon Grapenthin wrote:

 My understanding was that if I pass an eduction to a process using reduce, 
 I can save the computer time and space because the per step overhead of 
 lazy sequences is gone and also the entire sequence does not have to reside 
 in memory at once.

 When I time the difference between (apply max (map inc (range 10))) 
 and (apply max (eduction (map inc) (range 10))), the lazy-seq variant 
 wins.

 I'd like to understand why, and when eductions should be used instead.


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

2015-07-19 Thread Stuart Sierra
This is an old thread, but it showed up in my Google Groups so I figured I 
would give an answer.

I have worked on fairly large (10-50 machines) distributed systems written 
entirely in Clojure.

The language itself doesn't provide an explicit mechanism for communication 
between machines, so you just have to pick an existing tool or technique 
that suits your application architecture. There are many possibilities to 
choose from, all with different strengths and weaknesses:

1. Direct connections between nodes, e.g. HTTP, raw sockets, HornetQ
2. Message broker, e.g. ActiveMQ, RabbitMQ
3. Distributed shared memory, e.g. ZooKeeper, Hazelcast, memcached
4. Distributed job control, e.g. Hadoop, Storm

You can end up implementing something that looks very much like the Actor 
Model using these components. But you have other options as well.

Where Clojure helps you in designing these systems is its focus on generic, 
immutable data structures and pure functions.

Clojure's data structures are trivially serializable (EDN, Transit, 
Fressian). When all the data in your application can be represented by 
Clojure's generic data structures, it is easy to distribute work or data 
across multiple machines.

When functions are stateless, it is less important where they are 
executed. When functions (or declarative expressions, e.g. database 
queries) can be expressed as data structures, they are easier to compose 
and distribute.

–S


On Wednesday, July 3, 2013, Hussein B. wrote:

 I read recently on the internet that Clojure concurrency tools make it 
 easy to implement a highly concurrent system but on a single machine.

 But how to implement a highly concurrent system that runs on a multiple 
 machines?

 Erlang, Elixir and Scala have the Actors model.


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

2015-07-19 Thread Stuart Sierra
Absolutely would use again. But I'm biased towards Clojure already. :)
–S

On Sunday, July 19, 2015 09goral wrote:

 Thanks Stuart for your answer, it is very helpfull. Would you choose 
 Clojure again ?

 2015-07-19 17:13 GMT+02:00 Stuart Sierra:


 This is an old thread, but it showed up in my Google Groups so I figured 
 I would give an answer.

 I have worked on fairly large (10-50 machines) distributed systems 
 written entirely 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: component: dynamic configuration

2015-07-07 Thread Stuart Sierra
Not sure if this helps, but remember that components and systems are just 
records, and records behave like maps. You can construct an empty 
`system-map` and then `assoc` components or even `merge` other maps into it.

–S


On Tuesday, July 7, 2015 at 1:00:51 PM UTC-4, Pierre-Yves Ritschard wrote:

 Hi, 

 I've been using an approximation of what component provides in my 
 applications for quite a while, and I'm trying to see if it's feasible 
 to move to component, in the sake of homogeneity with the rest of the 
 clojure world and to see if there are things that make my life easier. 

 I have a couple of apps which expose a somewhat generic way of 
 manipulating data in a certain way. Most follow the pattern of having 
 several possible inputs (which must all adhere to a protocol), an engine 
 that does its work and several possible outputs (again, adhering to a 
 protocol). 

 While configuring each of these inputs or outputs as components is 
 straightforward, I failed to find a good strategy for storing them and 
 constructing the system-map correctly. 

 Did anyone tackle this yet and if so are they willing to share their 
 approach ? 

 Cheers, 
   - pyr 


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

2015-07-07 Thread Stuart Sierra
Hi pyr,

There are many downsides to hierarchical structure of components and 
systems. The effects are complicated and hard to understand. See, for 
example, the discussion at
https://groups.google.com/forum/#!topic/clojure/2-baBp61XTs/discussion

I recommend that system maps be kept flat, without any nested systems.

To prevent name clashes, you can always generate unique keys for the 
components.

–S


On Tuesday, July 7, 2015 at 2:47:03 PM UTC-4, Pierre-Yves Ritschard wrote:

 Would you directly assoc :inputA :inputB :outputA :outputB components 
 in the first layer of the system map or would you retain a hierarchical 
 structure and if so, are there any downsides to 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: side-effecting re-/transducers

2015-06-25 Thread Stuart Sierra
Hi Sam,

Transducers are a new feature, and best practices are still emerging.

Transducing/reducing is always non-lazy, so it's *less* risky to have side 
effects in a reduce compared with side effects in a lazy sequence.

Still, I would offer the same advice I give for lazy sequences. Keep your 
side-effects as separated as possible from the purely-functional 
computation that feeds them.

Don't put a side-effect in the middle of a chain of map/filter-like 
operations. Do all your map/filter/whatever with pure functions, then 
process the entire result non-lazily to do the side effects.

The driver for that process could be `doseq`, `run!`, `transduce`, or 
even `reduce`. `doseq` has overhead to allocate the sequence, which the 
others avoid.

–S

On Thursday, June 25, 2015 at 2:30:21 PM UTC-4, Sam Raker wrote:

 This seems bad, is this bad:

 (defn to-db
   [conn]
   (fn
  ([val] (upload-to-my-db conn val))
  ([_ val] (upload-to-my-db conn val)))

 (defn -main []
   (transduce my-preprocessing-xf (to-db (get-db-conn)) seq-of-things-to-
 preprocess-and-upload))

 I ask only because
 1) Plugging the side-effecting part into the transducer pipeline seems 
 cleaner and potentially more efficient than e.g. 
 (doseq [v (sequence my-preprocessing-xf sea-of-things)] (upload-to-my-db 
 conn v))
 which is what I was doing
 2) The addition of `run!`[1] in 1.7 seems to perhaps implicitly condone 
 this kind of thing. There's very little out there about it, though, so I 
 could very well be wrong.




 [1] 
 http://conj.io/store/v1/org.clojure/clojure/1.7.0-alpha4/clj/clojure.core/run%21


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

2015-06-25 Thread Stuart Sierra
Scala has to compile down to JVM bytecode just like Clojure, but it may 
change method signatures along the way.

You could try running `javap` to disassemble the compiled Scala bytecode 
and figure out what the method signatures actually are. Or use Java 
reflection to examine the objects you have and see what methods they 
declare.

–S


On Tuesday, June 23, 2015 at 10:51:55 AM UTC-4, Stephen Wakely wrote:

 I am trying to call into some Scala that has the following overloaded 
 methods :

   def apply[T](clauses: (Double, Element[T])*)(implicit name: Name[T], 
 collection: ElementCollection) =
 new AtomicDist(name, clauses.toList, collection)

   def apply[T](clauses: (Element[Double], Element[T])*)(implicit name: 
 Name[T], collection: ElementCollection) =
 new CompoundDist(name, clauses.toList, collection)

 So one method takes a list of tuples of Double to Element and the other 
 method takes a list of tuples of Element to Element.

 I am using t6.from-scala (https://github.com/t6/from-scala) to build up 
 my list of Tuples. But when building these up there is no way to specify 
 explicit type information about the collections. Consequently when calling 
 this apply method Clojure will always choose to call the first method - 
 even when my list is a collection of Element to Element tuples. 

 I can definitely appreciate how it is going to be tricky for Clojure to 
 determine the correct overload to use here. Is there any way I can somehow 
 force it to call the correct overload myself?


 Thanks

 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: Writing REST api the right way

2015-06-24 Thread Stuart Sierra
On Tuesday, June 23, 2015, Mike Grabowski wrote:
 ... I just can't stop thinking about non-blocking evented
 IO interactions. It just does not feel right to me to
 block the thread when e.g. logging in an user.
 Unfortunately, there are no NIO drivers for the database
 engines I am interested in (Neo4J, Mongo) so async
 channels are not the way to go.

This is pretty much unavoidable on the JVM. Java started
with a multi-threaded blocking I/O model, and that's still
how most Java code is written despite the availability of
non-blocking I/O.

The typical way to mitigate this in Java is with thread
pools. The JVM is capable of handling hundreds of threads,
and modern operating systems are pretty good at
context-switching.

For an extreme example, look at Netflix's [Hystrix], which
isolates *every* library in its own thread pool, so they can
guarantee timeouts and other bounded behaviors. Netflix
reports that the overhead of extra threads is worth the
more-predictable behavior.

[Hystrix]: https://github.com/Netflix/Hystrix

-S

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

2015-06-19 Thread Stuart Sierra
tools.namespace: parse namespace declarations and reload
files in dependency order.

https://github.com/clojure/tools.namespace

Release 0.2.11 contains the following changes:

  * [TNS-34] Support for reader conditionals

tools.namespace still works only in Clojure(JVM), not
ClojureScript. But it is now able to parse both .clj files
and .cljc source files containing reader conditionals.

This release of tools.namespace remains backwards-compatible
with older versions of Clojure back to 1.3.0.


Leiningen dependency information:
[org.clojure/tools.namespace 0.2.11]

This is a Clojure-contrib project,
http://dev.clojure.org/display/doc/Clojure+Contrib

[TNS-34]: http://dev.clojure.org/jira/browse/TNS-34

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

2015-06-09 Thread Stuart Sierra
Reloading a protocol definition invalidates any instances of objects which 
implement the protocol. This may be the problem you are seeing.

After reloading a protocol definition, you must also reload any code with 
`deftype`, `defrecord`, or `reify` which implements the protocol, THEN 
re-evaluate any code which creates instances of those types.

For more discussion of this issue, see the tools.namespace docs under 
Warnings for Protocols:
https://github.com/clojure/tools.namespace#warnings-for-protocols

–S


On Tuesday, June 9, 2015 at 6:42:31 AM UTC-4, Timur wrote:

 Hi everyone,

 I have a mutli-project set-up using Leiningen checkouts. I have a 
 protocols project where I store all my needed protocols and another project 
 depends on this project. I linked the project folder to the checkout folder 
 of the project that depends on the protocols. However, when I change a 
 protocol in the protocols project, I have to call a lein install, 
 re-start REPL to see the effects of this in the dependent project. As far 
 as I understood, Protocols are dynamically built and, therefore, I don't 
 need to restart and reload it. Do you have any idea what I might be doing 
 wrong? Or is this an expected behavior and I'm missing something?

 Thanks in advance. 

 Regards,

 Timur 


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

2015-05-27 Thread Stuart Sierra
Hi Édipo,

I'm not sure I understand the question. Why do you want to remove a 
component from the system after it has been started?

Systems are just records, which behave like maps, so `assoc` and `dissoc` 
should work normally. But the process of starting a system creates copies 
of components to satisfy dependency relationships, so if you `dissoc` a 
component from the top-level system map it may still be present under other 
components which depend on it.

In general, the 'component' framework does not provide a way to modify 
individual components in the system after it has been started. It's good 
for starting everything at once and stopping everything at once.

–S


On Tuesday, May 26, 2015 at 4:25:50 PM UTC+1, Édipo Luis Féderle wrote:

 Hi everyone,


 I am using componente framework 
 https://github.com/stuartsierra/component, I have the follow system:


 (def system

   (let [config (get envs :dev)]

 (component/system-map

  :db (db-connection (get (get config :db) :host) 

 (get (get config :db) :db-name)

 (get (get config :db) :port))

  :http-server (s/new-http-server 8080)

  :confs config

  :receivers receivers)))


 There is some way to remove some component after it start? I tried use 
 disassoc, but without success. Any idea how to I can do this?


 Thanks in advance for any help.


 Édipo


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: Advice when running java -jar rather than a managed server like tomcat?

2015-05-27 Thread Stuart Sierra
JSVC (Apache Commons daemon for Unix) is excellent for this sort of thing. 
There's a Windows Services version too.
–S


On Tuesday, May 26, 2015 at 12:38:30 PM UTC+1, Colin Yates wrote:

 Hi,

 I am venturing into new territory using http-kit, as I usually use a 
 'managed' web server container like tomcat and have a few questions about 
 packing and running a JAR file:

  - are there are convenient service wrappers for windows and/or Linux
  - any best practice around managing class path for things like logback.xml

 I have a jar created from lein uberjar and java -jar the.jar works, but 
 this seems a long way away from automated deployment :).

 Any advice 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: what demonstrates Stuart Sierra's State/Event Pattern

2015-05-26 Thread Stuart Sierra
Yes, you can use this pattern to define a mini-interpreter for a stream of 
events or commands, where each event is represented as a data structure.

For example, I've used this pattern to write little scripts, a a collection 
of maps, for driving an integration test.
–S


On Monday, May 25, 2015 at 10:57:22 PM UTC+1, piastkrakow wrote:

 Stuart Sierra,

 Thank you for the response. I won't take that talk as encyclopedic. 
 The 'chain-consequences' function is very interesting, though it is 
 unfamiliar to me. I am still learning about Clojure. 

 You mention that the State/Event pattern is a common one. If you were 
 talking about architectures, I would say your description reminds me of 
 Kafka (events are data structures, replaying events can replay the whole 
 history of state in the app, etc) but I am curious where you feel this 
 pattern shows up as a design pattern? I assume you mean to broadly define 
 this to include those situations where we might use pure functions in loop 
 or reduce to iterate over a message where the message is some data 
 structure, perhaps a JSON document, or some other kind of seq generated by 
 an event? 


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: what demonstrates Stuart Sierra's State/Event Pattern

2015-05-25 Thread Stuart Sierra
This is a pattern I have used **occasionally**.

That whole talk is just patterns that were in my head at the time. Take 
whatever you find useful from it, but don't treat it as a universal or 
complete list.

If you squint, that 'chain-consequences' function behaves sort of like a 
monad, but I won't claim it's properly monadic according to anyone's 
definition.

–S

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

2015-05-17 Thread Stuart Sierra
Just like the rest of the article, it's about readability. With `:refer` 
you don't know where a symbol came from when you encounter it in the middle 
of the code.

–S



On Sunday, May 17, 2015 at 4:05:14 PM UTC+1, Akiva Schoen wrote:

 In Stuart Sierra's article here 
 (http://stuartsierra.com/2015/05/10/clojure-namespace-aliases), he 
 recommends to use :refer sparingly but doesn't explain why this is a 
 good idea. Only thing I could think of without putting too much effort 
 into it is that it makes it slightly more tedious when you want to use a 
 function from a namespace that hasn't been already explicitly referred. 

 Are there no benefits other than possibly excluding function names that 
 might otherwise suffer a namespace clash (assuming their namespace isn't 
 being aliased already)? 

 Thanks, 
 Akiva 


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

2015-05-14 Thread Stuart Sierra
You can put a .sql file in /resources and read it with 
clojure.java.io/resource.
–S


On Thursday, May 14, 2015 at 9:45:31 AM UTC+1, Colin Yates wrote:

 Is there a lib that will allow me to have my sql defined in a file which I 
 can reference from Clojure? I cannot use one of the existing migration 
 libraries as I need to do more than just manipulate SQL on a version 
 upgrade.

 I am aware of yesql which would be great but it didn't work out for DDL. 
 Specifically yesql seems to associate one block of sql for each name. I 
 want to have multiple blocks (e.g. a 'create table ...' as well as a number 
 of 'alter table create index idx_').

 I have tried embedding the sql as a string in the .clj file. This isn't as 
 painful as it might sound but is still painful enough.

 Any suggestions?



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

2015-05-10 Thread Stuart Sierra
I find it's really the same as in any other language. Certainly if you 
don't have any clearly-defined boundaries at all, you'll get a big ball of 
mud.

Encapsulation is about code organization and self-discipline. Define module 
responsibilities and boundaries in your developer documentation. Make it 
clear that X is not supposed to depend on Y. Enforce those boundaries 
through code review and refactoring. Regularly review module definitions to 
make sure they match the real requirements of the system.

I developed Component[1] to help with one aspect of this problem. One 
shared map defines the structure of the entire system, but each “module” is 
only exposed to the subset of the system it needs.

Other approaches: With a shared map, namespaced keywords can be a hint that 
something is “private” to a particular module. Alternately, you could 
establish the convention that elements of a shared data structure should 
*only* be accessed via helper functions, and use public/private Vars to 
enforce which aspects of a data structure are meant to be “public” to other 
modules.

–S

[1]: https://github.com/stuartsierra/component

On Friday, May 8, 2015 at 5:29:50 PM UTC+1, Brian Craft wrote:

 Talk on the list about encapsulation usually comes back to some variation 
 of you don't need it when you have immutable data structures. But in the 
 long term I'm finding the problem of working w/o encapsulation is not the 
 danger of data being mutated under you. Rather, it's the danger of all the 
 module boundaries blurring over time, leading to the big ball of mud: a 
 very fragile code base where everything depends on everything else.

 E.g. if you model your application with a plain data structure which you 
 pass around to different modules, each concerned with a small part of that 
 data structure, the tendency over time is for every module to become 
 concerned with every part of that data structure.  Then you have no 
 separation, nothing is reusable, and the code is very fragile.

 How do you avoid this, practically? In OO it would be enforced with 
 encapsulation, so the next developer (which might be me, six months later) 
 trying to fix a bug, or add a feature, knows Oh, I shouldn't peek in here: 
 this module isn't supposed to depend on that piece of data.


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

2015-05-03 Thread Stuart Sierra
Hi Chap,

There isn't, unfortunately, a good way to modify systems after they have 
are started. I have put a fair amount of thought into this but never come 
up with a  solution I was satisfied with.

In your case, I think I would suggest creating one system just to load the 
configuration data and then using it to bootstrap another system.

–S


On Saturday, May 2, 2015 at 11:02:00 PM UTC+1, Chap Lovejoy wrote:

 Hi,

 I'm building a system which handles data synchronization with remote 
 services. The credentials and configuration parameters for the remote 
 services are stored in the database. I'd like to be able to build a 
 component which is constructed from the information from the database and 
 uses component to resolve the dependencies for other components in the 
 system (s3, etc). Is there a mechanism for either adding components to a 
 system at runtime or resolving the dependencies for a component which can 
 then be stored as part of the state of another?

 Thanks,
 Chap


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

2015-04-30 Thread Stuart Sierra
Hi Andy,

That was just an example I made up for the slides, and not a very good one.

Usually, the functions/protocols you implement for your components are 
specific to your application.

–S


On Thursday, April 30, 2015 at 4:54:38 AM UTC+1, Andy Chambers wrote:

 Hi All,

 I'm trying to follow the component architecture for an app I'm working 
 on and wondered if I was missing something. In the Just enough structure 
 talk, one of the examples Stuart presents is a DB component that contains 
 just a small selection of DB related functions (i.e. insert, and query 
 IIRC) so that when you need to mock it out for your tests, you don't have 
 to implement the entire JDBC interface.

 This makes sense but I'm wondering if anyone has released such a subset 
 (possibly expanded to include things like transactions, and maybe a few 
 utility query builders) as open source ideally with a corresponding mock 
 implementation. With the popularity of the component library, I'm surprised 
 not to find ready made components I can just plug into my app.

 If there's nothing like this already, then I guess I have an idea for a 
 new project. Anyone think this is a good idea or would everyone's ideal DB 
 component look a little different? Look forward to hearing your thoughts.

 Cheers,
 Andy


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: wondering the reasons to choose defrecord vs reify in stuartsierra/component

2015-04-29 Thread Stuart Sierra
Hi Juan,

Components are records in order to support the dependency-injection 
features of `component/start-system`, which work via `assoc`.

There are potentially many other ways to do dependency injection, but I 
found `assoc` to be practical.

If you want to create a component that has a Lifecycle but no dependencies, 
then `reify` will work just fine.

If you want to create a component that has dependencies but no Lifecycle, 
then an ordinary Clojure map will work.

–S


On Wednesday, April 29, 2015 at 2:41:54 PM UTC+1, Juan A. Ruz @tangrammer 
wrote:

 Hi guys, 
 I'm just wondering the pros/contras that justify to choose defrecord vs 
 reify as component fn constructor.

 in the component README we can read 
 To create a component, define a Clojure record that implements the 
 Lifecycle protocol.

 Yes I know that defrecord creates an immutable persistent map which 
 implements a protocol. but I think that the same thing can be achieved 
 with reify (BTW: om way to define component) over a persistent map... 

 Do you think there are more reasons to set defrecord as default base fn 
 for components?

 Thanks in advance
 Juan



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

2015-04-22 Thread Stuart Sierra
core.async is still technically alpha, so everything is potentially subject 
to change. Rich H. wrote[1] most of those core.async functions, and he 
tends to treat the docstring as the only contract for future releases.

If you want to be safe, make a unit test in your app that specifically 
tests any undocumented properties of public functions, so you can see if 
and when they change.

[1]: 
https://github.com/clojure/core.async/blame/d8047c0b0ec13788c1092f579f03733ee635c493/src/main/clojure/clojure/core/async.clj#L455

–S



On Wednesday, April 22, 2015 at 11:26:11 AM UTC+1, Stanislav Yurin wrote:

 Hello,

 There are functions like 'pipe' and 'tap' that are returning back 
 receiving channel parameter,
 but this behavior is not explicitly documented.

 Should we rely on this feature or this may be changed in future?

 Thanks.

 Stanislav.


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

2015-04-16 Thread Stuart Sierra
   
:baz (new-baz) 
:qux (c/using  
  (new-qux)
  [:baz] ) ) ) 
   
 (defn new-super-system [] 
   (c/system-map   
:system (new-system)   
:system2 (c/using  
  (new-system2)
  [:system] ) ) )  
   
 (defn -main [ args]  
   (c/start (new-super-system)) )  
 ```

 Output:

 ```
 Starting foo
 Starting bar
 Starting baz
 Starting qux
 Starting foo
 Starting bar
 ```

 Thank you!

 --Dan

 On Wednesday, March 18, 2015 at 8:51:17 AM UTC-5, platon...@gmail.com 
 wrote:

 A possible implementation for the idea expressed in the previous post - 
 https://github.com/stuartsierra/component/pull/25


 On Wednesday, March 18, 2015 at 2:41:46 PM UTC+1, platon...@gmail.com 
 wrote:

 I've also been investigating the nested system approach/problem.

 The primary use case that I have is composing subsystems which are 
 mostly independent modules using a higher order system to run in one 
 process. The modules themselves can be easily extracted into separate 
 applications thus becoming their own top level systems which makes it 
 desirable to keep their system maps intact. 

 Components inside modules might depend on the *whole* modules, not 
 their constituent parts. This allows to have modules call each other 
 through the API's in-process as well as being easily replaced by remote 
 endpoints when separated into multiple processes.

 This mostly works except for the components depending on other 
 modules/systems, e.g.:

 (require '[com.stuartsierra.component :as cmp])

 (defrecord X [x started] 
cmp/Lifecycle 
(start [this] (if started (println Already started  x) (println 
 Starting  x   this)) (assoc this :started true)) 
(stop [this] (println Stopping  x   this) this))

 (def sys1 (cmp/system-map :x (cmp/using (X. depends on dep nil) 
 [:dep])))
 (def sys2 (cmp/system-map :y (cmp/using (X. depends on sys1 nil) 
 [:sys1])))
 (def hsys (cmp/system-map :sys1 (cmp/using sys1 [:dep]), :sys2 
 (cmp/using sys2 [:sys1]) :dep (X. dependency nil)))

 (cmp/start hsys)

 Starting  dependency   #user.X{:x dependency, :started nil}
 Already started  dependency
 Starting  depends on dep   #user.X{:x depends on dep, :started nil, :dep 
 #user.X{:x dependency, :started true}}

 clojure.lang.ExceptionInfo: Error in component :sys2 in system 
 com.stuartsierra.component.SystemMap calling 
 #'com.stuartsierra.component/start
 clojure.lang.ExceptionInfo: Missing dependency :dep of 
 clojure.lang.Keyword expected in system at :dep

 This happens because of the following:
 1. Dependency :*dep* of *sys1* is started in *hsys*
 2. *sys1* is started (:*dep* is started again, so the start/stop should 
 be idempotent)
 3. Dependency :*sys1* of *sys2* is started in *hsys*
 4. :*sys1* cannot be started as it depends on :*dep* which isn't 
 present in *sys2*

 This scenario could be supported by the Component library in several 
 ways:

 1. introduce an IdempotentLifecycle protocol which will be respected by 
 the Component library. Implement the protocol for the SystemMap. 
 IdempotentLifecycles will not be started or stopped for the second time, 
 also their dependencies will not be updated if they are already started.
 2. do not fail if a component already has a dependency under the 
 specified key. This is a hack compared to the first solution, but I might 
 go with it in the short term.

 Stuart, what do you think about that? Would you consider a PR 
 implementing the first proposal?

 On Wednesday, March 18, 2015 at 10:18:36 AM UTC+1, Stuart Sierra wrote:


 On Tue, Mar 17, 2015 at 5:47 PM, James Gatannah james.g...@gmail.com 
 wrote:

 FWIW, we've been using something that smells an awful lot like nested
 systems for months now. I never realized we weren't supposed to.



 It's not that nested systems *never* work, but from what I've seen 
 they cause more complications than they're worth. The 'component' model 
 doesn't forbid it, but it does not support dependencies between components 
 in different subsystems.

 I've found it easier to keep system maps flat and use namespaced 
 keywords to distinguish subsystem groups, even in large systems with 30+ 
 components.

 –S



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

Re: Datomic namespaced idents question

2015-04-06 Thread Stuart Sierra
On Sunday, April 5, 2015, Stig Brautaset wrote:
 I understand that you must use namespaces in idents for
 logically distinct types of entities.
...
 My question is: do you expose this namespacing outside the
 model layer when working in Clojure?

I find it easier when there are as **few** transformations as
possible between layers. That means keeping the attribute
names, including namespaces, consistent across the entire
application.

Obviously, if some layer cannot handle the namespaces (e.g.
JavaScript client) you will have to transform them. But even
then I try to push those transformations to the outer-most
layer of code, the last thing that happens before sending
the data off to a client.

-S

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

2015-03-18 Thread Stuart Sierra
On Tue, Mar 17, 2015 at 5:47 PM, James Gatannah james.gatan...@gmail.com
wrote:

 FWIW, we've been using something that smells an awful lot like nested
 systems for months now. I never realized we weren't supposed to.



It's not that nested systems *never* work, but from what I've seen they
cause more complications than they're worth. The 'component' model doesn't
forbid it, but it does not support dependencies between components in
different subsystems.

I've found it easier to keep system maps flat and use namespaced keywords
to distinguish subsystem groups, even in large systems with 30+
components.

–S

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

2015-03-12 Thread Stuart Sierra
On Wednesday, March 11, 2015, Colin Yates wrote:
 I can't merge the two systems because the reusable
 component is chocka full of very fine grained command
 handlers and both the internal and external systems will
 have their own 'bus' for example. I could namespace the
 keys but that again feels painful...

That's exactly how I would do it.

Nested systems don't really work.

But one system can contain implicit groups of components.

Create each group as a map, then `merge` them into the
system.

Use namespaced keys to prevent clashes.

The constructor functions for each component (or component
group) can take an argument which tells them the names of their
dependencies in the system.

Pseudo example:

(defn reusable-component [collaborator-key]
  (component/using (map-ReusableComponent {})
[:my/logger :my/bus collaborator-key]))

(defn reusable-group [collaborator-key]
  {:my/logger ...
   :my/bus ...
   :my/reusable-component
 (reusable-component collaborator-key)})

(defn new-system []
  (merge (system-map :main/logger ...
 :main/bus ...
 :main/collaborator ...)
 (reusable-group :main/collaborator)))


-S

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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: Could use a better error message here (using a list in update-in)

2015-03-10 Thread Stuart Sierra
Please file a ticket in JIRA and tag it with errormsg
http://dev.clojure.org/display/community/Creating+Tickets

–S


On Tuesday, March 10, 2015 at 3:13:36 PM UTC, John Gabriele wrote:

 In Clojure v1.6.0. This one confused me when I'd accidentally passed a 
 list in to `update-in` instead of a vector:


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

2015-03-03 Thread Stuart Sierra
A tiny update to my Component library.

https://github.com/stuartsierra/component

Leiningen:  [com.stuartsierra/component 0.2.3]

Changes in this release:

* More-specific error message when a component returns nil from start or 
stop

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

2015-02-01 Thread Stuart Sierra
tools.namespace: parse namespace declarations and reload
files in dependency order.

https://github.com/clojure/tools.namespace

Release 0.2.9 contains the following changes:

  * Fix [TNS-20]: Undefined 'unload' order after namespaces
are first added to an new, empty tracker.

  * Improvement [TNS-21]: Support `ns` clauses which use
vectors instead of lists for clauses, contrary to docs.

  * Improvement [TNS-32]: Support `ns` clauses which use
symbols as clause heads instead of keywords, contrary to
docs.

[TNS-20]: http://dev.clojure.org/jira/browse/TNS-20
[TNS-21]: http://dev.clojure.org/jira/browse/TNS-21
[TNS-32]: http://dev.clojure.org/jira/browse/TNS-32


Leiningen dependency information:
[org.clojure/tools.namespace 0.2.9]

Downloads and dependency information for other tools:
http://search.maven.org/#artifactdetails%7Corg.clojure%7Ctools.namespace%7C0.2.9%7Cjar

This is a Clojure-contrib project,
http://dev.clojure.org/display/doc/Clojure+Contrib


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

2015-01-30 Thread Stuart Sierra
Almost never.

Seriously, anything important enough to be included in your program's input 
or output is almost certainly important enough to be *data*, not metadata. 
And the non-equality-checking semantics of metadata are confusing.

About the only place I've found metadata to be worthwhile is 
meta-programming namespaces and Vars, e.g. what clojure.test does.

My personal rule of thumb is: if you strip all the metadata from your 
program it should still work, thought maybe less efficiently.

–S


On Thursday, January 29, 2015 at 10:10:34 AM UTC-5, Jonathon McKitrick 
wrote:

 Is there a rule of thumb or set of use cases when metadata is a more 
 elegant solution than simply adding more entries to a map or record?


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

2014-12-19 Thread Stuart Sierra
tools.namespace: parse namespace declarations and reload
files in dependency order.

https://github.com/clojure/tools.namespace

Release 0.2.8 contains the following changes:

  * Improvement [TNS-31]: Specific error message when
`:after` symbol passed to `refresh` cannot be resolved.

  * Fix [TNS-26]: namespace alias recovery after failed
reload did not work due to local binding shadowing
global Var

[TNS-26]: http://dev.clojure.org/jira/browse/TNS-26
[TNS-31]: http://dev.clojure.org/jira/browse/TNS-31



Leiningen dependency information:
[org.clojure/tools.namespace 0.2.8]

Downloads and dependency information for other tools:
http://search.maven.org/#artifactdetails%7Corg.clojure%7Ctools.namespace%7C0.2.8%7Cjar


This is a Clojure-contrib project,
http://dev.clojure.org/display/doc/Clojure+Contrib

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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.edn won't accept clojure.java.io/reader? How to work around this and why isn't this documented anywhere?

2014-12-08 Thread Stuart Sierra
As the original author of the function that eventually became 
clojure.java.io/reader, it was one of those unfortunate decisions that 
seemed like a good idea at the time and cannot be changed without breaking 
backwards compatibility.

Long before EDN existed, I wrote clojure.contrib.io 
https://github.com/clojure/clojure-contrib/blob/1.2.x/src/main/clojure/clojure/contrib/io.clj

This included a function `reader` that returned a java.io.BufferedReader: 
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html

BufferedReader was a convenient type to return because it supports 
.readLine, which is used by clojure.core/line-seq: 
https://github.com/clojure/clojure/blob/1.1.x/src/clj/clojure/core.clj#L1954-L1960

However, clojure.core/read and later clojure.edn/read were written in terms 
of java.io.PushbackReader, because they need the ability to look ahead one 
character in the stream while parsing it:
http://docs.oracle.com/javase/7/docs/api/java/io/PushbackReader.html

java.io.PushbackReader and java.io.BufferedReader are both subclasses of 
java.io.Reader, but there is no class in the JDK which combines the 
features of both PushbackReader and BufferedReader. Java does not permit 
multiple inheritance of concrete classes.

In Java it is common to have several layers of Reader sub-classes wrapped 
around each other, so that's what we do.

We cannot change clojure.java.io/reader to return a different type without 
breaking a lot of existing code that expects it to return a BufferedReader.

This was reported as an issue in 2009 and discussed on the mailing list:
https://groups.google.com/forum/#!topic/clojure/_tuypjr2M_A
http://dev.clojure.org/jira/browse/CLJ-82

It turns out there are some subtle issues which can cause incorrect 
behavior were clojure.core/read to blindly wrap a PushbackReader around its 
argument:
https://groups.google.com/d/msg/clojure/_tuypjr2M_A/W1EcEbMUg_cJ

In conclusion, this is a minor nuisance, well-known to Clojure developers, 
for which no good solution has been identified.

–S


On Sunday, December 7, 2014 11:27:05 PM UTC-5, Fluid Dynamics wrote:

 = (with-open [in (io/reader (io/resource foo))] (edn/read in))
 ClassCastException java.io.BufferedReader cannot be cast to 
 java.io.PushbackReader  clojure.edn/read (edn.clj:35)

 Er, what? Aren't these things supposed to just plug into each other and 
 work OOTB? Do I need to muck about with interop to use edn with any input 
 source other than strings, then?


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

2014-12-07 Thread Stuart Sierra
Yes, it's about the size of a compilation unit and how to handle undefined 
references. Rich Hickey posted this
https://news.ycombinator.com/item?id=2467359
detailing the trade-offs involved in choosing Clojure's strategy.

-S


On Sunday, December 7, 2014 9:37:40 AM UTC-5, Ashton Kemerling wrote:

 Clojure, like most lisps, is designed around a REPL. So the highest 
 compilation unit isn't a file, but a top level definition like defn or 
 defmacro. 



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

2014-11-29 Thread Stuart Sierra
Here's a version I did that only uses as many threads as necessary to keep 
up with the input, subject to an upper bound:
http://stuartsierra.com/2013/12/08/parallel-processing-with-core-async

–S

-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
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 Stuart Sierra
Similarly, but I would be explicit about the different arities, to avoid 
the intermediate sequence created by [arg  [option]] and to get errors if 
there are too many arguments.

(defn foo
  ([input] (foo input (chan 1))
  ([input ch]
 ... do something and put to ch ...))

If your function can produce multiple outputs, you can `close!` the channel 
to signal it is finished, which is what `pipeline-async` expects.

–S

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

2014-10-04 Thread Stuart Sierra
On Sat, Oct 4, 2014 at 12:31 AM, Brian Guthrie btguth...@gmail.com wrote:

 But I'm troubled by the idea of accepting channels as arguments, even
 though there's a lot to be said for consumer control of buffer sizes (to
 say nothing of providing potential fakes for test purposes). In that
 scenario you'd essentially be *mutating* the input when you set up the
 go-loop that feeds (or takes input from) the channel, yes? So in effect
 they become out-params.



Once you start messing around with channels, you're no longer in the
pure-functional business. Channels aren't values. Things which use channels
are processes, not functions.

-S

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

2014-10-03 Thread Stuart Sierra
You generally provide more power and flexibility to consumers by handing 
them channels. That way the consumer can use things like transducers and 
pipelines.

For maximum flexibility, allow the consumer to *pass in* the channels to be 
used for input / output. That way the consumer gets to decide about 
buffering.

-S



 Friday, October 3, 2014 12:06:05 PM UTC-4, Brian Guthrie wrote:

 Hi all,

 I'm assembling a library for working with sockets asynchronously (both as 
 a server and a client) and was wondering if there was a widely-accepted way 
 of handling channels. The rough idea is that each socket gets two channels, 
 in and out, receiving data in the former and using the latter to write it 
 out.

 What I'm asking is whether it's preferable to set up a construction 
 function and return a record (or map) with :in and :out keys, with the 
 expectation that consumers can manipulate those channels directly, or 
 expose functions like read-line and write-line that returns a channel which 
 yields and closes once on completion.

 Essentially, it's the difference between writing:

   (let [sock (socket-client localhost 1024)
  line (async/! (:in sock))]
   ...)

 or writing:

   (let [sock (socket-client localhost 1024)
  line (async/! (read-line sock))]
   ...)

 The disadvantage to the latter approach is that it breaks the channel 
 contract: channels should return nil on closure. With single-yield 
 channels, detecting nil closure is tiresome: you intentionally return an 
 empty channel. And though the function name is nice and clear, it seems 
 like a lot of effort to put up a nice facade, especially if folks are 
 already comfortable managing channels directly.

 Any thoughts?

 Thanks,

 Brian


-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: `remove-ns' prevents namespace from being reloaded by `require' in clj 1.5.1 and 1.6

2014-09-22 Thread Stuart Sierra
I'm not sure I understand what you mean.

`remove-ns` does not remove the namespace from the set of loaded 
namespaces kept by `require`.  tools.namespace 
https://github.com/clojure/tools.namespace has a hack 
https://github.com/clojure/tools.namespace/blob/a166936bd757b71348c7c1608569fc0fcb1318bd/src/main/clojure/clojure/tools/namespace/reload.clj#L19
 
to work around this.

But `require ... :reload` should still work.

-S


On Monday, September 22, 2014 10:04:49 AM UTC-4, Daniel König wrote:

 Hi,

 after removing a namespace with the remove-ns form, I am not able to 
 require it a second time.
 From what I can tell, I should be able to reload a namespace after 
 removing it.
 This behaviour was found in Clojure 1.5.1 and Clojure 1.6.

 Example:

 = (require 'config :reload)
 nil
 = (remove-ns 'config)
 #Namespace config
 = (require 'config :reload)
 nil
 = (remove-ns 'config)
 nil



 Is this intentional or can it be considered broken?

 Best regards,
 Daniel


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

2014-09-20 Thread Stuart Sierra
tools.namespace: parse namespace declarations and reload files in
dependency order.

https://github.com/clojure/tools.namespace

Release 0.2.7 reverts a bad commit, mistakenly included in
0.2.6, which could cause the 'unload' order of namespaces
to be incorrect.

The impact of this bug is minimal, since unload order rarely
matters in practice. Still, you should consider 0.2.6
broken and switch immediately to 0.2.7.

Leiningen dependency information:

[org.clojure/tools.namespace 0.2.7]

tools.namespace is a Clojure-contrib project:
http://dev.clojure.org/display/doc/Clojure+Contrib

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

2014-09-08 Thread Stuart Sierra
tools.namespace: parse namespace declarations and reload files in
dependency order.

https://github.com/clojure/tools.namespace

Release 0.2.6 contains the following bugfixes:

  * `clojure.tools.namespace.parse/read-ns-decl` asserts that its
argument is a PushbackReader, instead of silently returning nil

  * Fix [TNS-22]: broken `clojure.string/replace` with Windows path
separator

Leiningen dependency information:

[org.clojure/tools.namespace 0.2.6]

This is a Clojure-contrib project,
http://dev.clojure.org/display/doc/Clojure+Contrib


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

2014-09-07 Thread Stuart Sierra
Component: managed lifecycle and dependency injection for
stateful objects

https://github.com/stuartsierra/component

Release 0.2.2 contains the following minor enhancements:

  * System maps print as `#SystemMap` to avoid trying to
print huge objects in the REPL.

  * Added error helpers `ex-component?` and
`ex-without-components`: refer to docstrings for details

  * Exceptions:

 * Change `:component-key` to `:system-key` in `ex-data`
   maps: this is a breaking change for code which
   depended on the value of `:component-key`

 * Added `:system-key` to `ex-data` map from `try-action`

 * Minor changes to exception message strings

Leiningen dependency information:

[com.stuartsierra/component 0.2.2]


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

2014-08-01 Thread Stuart Sierra
I think clojure.github.io is just the gh-pages of all the individual 
projects under github.com/clojure, so you should be able to grab the 
gh-pages of each one.

For example, https://github.com/clojure/tools.namespace/tree/gh-pages

The root index at clojure.github.io is just another repo at 
https://github.com/clojure/clojure.github.com

-S


On Friday, August 1, 2014 12:26:51 PM UTC-4, Andrea Richiardi wrote:

 I have noticed that gh-pages are no more in-sync with the latest 
 developments of the code, especially after clojure-contrib has been split 
 in separate repositories. I would like to ask if there is something similar 
 to:

 curl-L https://github.com/clojure/clojure/archive/gh-pages.tar.gz | tar 
 xvzf -

 but for clojure.github.io, which contains everything.

 Thank you very much!


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

2014-07-24 Thread Stuart Sierra
They're just different versions of the same thing, written at different 
times by different people, that both got merged into Clojure at different 
times.

Speaking as the original author of clojure.stacktrace, I now think neither 
one of them should exist. The .printStackTrace method on an exception gives 
you all the same information and is more reliable.

-S


On Monday, July 21, 2014 7:30:17 AM UTC-4, Pierre Masci wrote:

 Hi, I'm learning about tools to help me debug from the REPL, and I found 
 these two with the same name:

 clojure.stacktrace/root-cause

 clojure.repl/root-cause


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

2014-07-16 Thread Stuart Sierra
*tools.namespace:* finding, parsing, and reloading Clojure
namespaces in correct dependency order

https://github.com/clojure/tools.namespace

*Release 0.2.5*

Leiningen dependency:

[org.clojure/tools.namespace 0.2.5]

This release contains bugfixes, performance enhancements,
and minor feature enhancements:

  * New `clojure.tools.namespace.repl/clear` empties the
state of the REPL dependency tracker. This can help
repair the dependency tracker after a failed load or a
circular dependency error.

  * Enhancement [TNS-19]: `deps-from-ns-decl` should return
an empty set instead of nil. This may be a breaking
change for some but is consistent with the original
docstring.

  * Enhancement [TNS-18]: Compute transitive dependencies in
linear time. Thanks to Andy Fingerhut.

  * Enhancement [TNS-17]: The `ns` form doesn't need to be
the first top-level form in a file.

  * Fix [TNS-16]: Don't depend on specific hash ordering in
tests. Exposed by new hash functions in Clojure 1.6.0.

  * Fix [TNS-15]: Handle spaces in classpath directories
(old `clojure.tools.namespace`)

  * Fix [TNS-12]: Duplicate definition of `jar-file?`

tools.namespace is a Clojure contrib project.
http://dev.clojure.org/display/doc/Clojure+Contrib

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

2014-06-17 Thread Stuart Sierra
On Tuesday, June 17, 2014 6:14:27 PM UTC-4, Gary Trakhman wrote:

 I'm not sure if the STM guarantees any ordering, but you'd probably want 
 to be explicit.



Two or more `send`s or `send-off`s from the *same* thread will be delivered 
in the order they were sent. There are no guarantees about the interleaving 
of those messages with send's from other threads.

-S 

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

2014-06-13 Thread Stuart Sierra
data.json: parsing and generating JSON in pure Clojure

https://github.com/clojure/data.json

Leiningen dependency information:

[org.clojure/data.json 0.2.5]

This is a bugfix release. Changes:


   - DJSON-17: do not print Infinity or NaN floating-point values


This is a clojure-contrib project:
http://dev.clojure.org/display/doc/Clojure+Contrib

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

2014-05-31 Thread Stuart Sierra
You can use the namespace itself as the mapping. For example:

(ns app.commands)

(defn dothis [ args] ...)

(defn dothat [ args] ...)


(ns app)

(defn execute-command [name  args]
  (let [var (ns-resolve 'app.commands
(symbol name))]
(apply var args)))

-S


On Wednesday, May 28, 2014 9:05:56 PM UTC-4, Will Duquette wrote:

 If there's a better place to ask this kind of question, please point me in 
 the right direction!

 I'm learning Clojure, and part of the project I'm making is a command 
 language: the user can type commands at the application in something like a 
 REPL, and have a dialog with the application.  I want to dispatch to a 
 function that carries out the command based on the first word of the 
 command; the function then receives the remaining words in the command, and 
 can do with them what it likes.  So I'm going to need a map, something like 

 { dothis #'commands/dothis, dothat #'commands/dothat ...}

 The question is, how best to build up that map?  I'd like to define a 
 command like this:

 (command dothis 
Documentation string
[argv]
)

 and have (command) define the function and add the entry to the map.

 I can think of all kinds of ways to do this.  I could define

 (def command-map {})

 and then have (command) rebind it:

 ...
 (def command-map (assoc command-map name function))

 but I know that's frowned upon.  I could make command-map contain an atom, 
 and use (swap!) to update the atom, but really, the mapping isn't going to 
 change at run-time.  I could make (command) a macro, so that it's really 
 updating command-map at the top-level, but that seems cheesy.

 Or, I could make (command) define the function as a public function in the 
 'commands namespace, which would be reserved for that purpose, and attach 
 the command name, e.g., dothis to the function as metadata.  Then I could 
 build the map by querying the namespace using (ns-publics).

 Is there is a normal way to do this kind of thing?


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

2014-05-23 Thread Stuart Sierra
I would say do one of:

- define your own constructor functions like (defn user [id] ...)
- use the map-User constructors created by defrecord
- do not specify the non-required keys as fields in the defrecord
- use plain maps



On Friday, May 23, 2014 4:47:43 PM UTC-4, Elliot wrote:

 There seem to be two kinds of definitions of what a record could be:

 1. A full representation of a resource,e.g. (defrecord User [id name age 
 gender address])
 2. A *handle* to a resource, e.g. (defrecord User [id]), e.g. [wikipedia] 
 below

 Some protocols only ever need a handle, not the full resource, e.g.:

 (retrieve-from-datomic (-User 42)

 But other protocols need a complete representation, e.g.:

 (produce-edn-for-api (-User 42 John Doe 64 ...)

 Is there an idiomatic approach to solving this problem?  It seems like the 
 options are:

 A. Define complete representations (#1 above) everywhere, and only 
 partially fill them in when used as handles (e.g. (-User 42 nil nil nil 
 nil).  This seems somewhat annoying and worse, makes it unclear what 
 exactly is the data expected as I/O for a given function, which was 
 original point of making a named, well-defined data structure.

 B. Define two separate but related records (e.g. UserHandle vs. User).  
 This is also somewhat annoyingly duplicative, especially since every 
 protocol implemented by UserHandle will need to be re-implemented by User 
 (though it could be a simple delegation thereto).

 Is there a standard and/or satisfying way to solve this?  Thanks.

 - Elliot


 [wikipedia] http://en.wikipedia.org/wiki/Handle_%28computing%29




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

2014-05-09 Thread Stuart Sierra
This sounds more like a problem with remote access to X-Windows (the Unix 
graphical back-end) than a Clojure-specific problem. You might find some 
helpful answers in Ubuntu docs, forums, or chat rooms.
-S


On Friday, May 9, 2014 6:57:26 AM UTC-4, stiffyrabbit jr wrote:

 Hi,

 What should my approach be, if I want my headless server to run a client 
 program that uses the client GUI?

 How can my server provide the same resources as a local client, to use GUI 
 objects?

 I have a Clojure program that opens a file dialog on the client.  It works 
 fine, until I try to run it from the server.

 My setup:

 A Macbook Pro with VirtualBox and LightTable on it;
 VirtualBox running Ubuntu 14.4, Leiningen, Clojure.  Ubuntu has extension 
 pack, in response to this problem;

 I start VB - VBoxManage startvm 'Core' --type headless;

 I login to Core - ssh Core normally, ssh -v -X Core in desparation;

 I launch a repl in a Clojure proj.  I use the host:port details as a LT 
 nrepl connection.  I get the following error:



 *java.awt.HeadlessException: No X11 DISPLAY variable was set, but this 
 program performed an operation which requires it.*I have tried so many 
 things to resolve this, that I get lost in it all.

 What approach will ensure that my server can run a program that requires 
 DISPLAY, and use client GUI objects?


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

2014-05-07 Thread Stuart Sierra
Actually, now that I think about it, that's not right. It shouldn't matter 
where or when you create the Atom. 

Instead, what I suspect you have is two or more instances of the component 
containing the Atom, thus two different Atoms.

You can tell if the Atoms are the same object by printing them, which shows 
a unique hash of each Atom's identity.

-S


On Monday, May 5, 2014 6:25:55 PM UTC-4, frye wrote:

 Ahh, so that was it then. Yeah, I definitely created that atom in the 
 start method. 
  

 On Mon, May 5, 2014 at 3:27 PM, Stuart Sierra the.stuart.sie...@gmail.com
  wrote:

 At what point did you **create** the Atom in :a? Any mutable references 
 which need to be shared among all usages of a component must be created in 
 the **constructor**, not the `start` or `stop` methods.



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

2014-05-05 Thread Stuart Sierra
At what point did you **create** the Atom in :a? Any mutable references 
which need to be shared among all usages of a component must be created in 
the **constructor**, not the `start` or `stop` methods.

-S


On Wednesday, April 30, 2014 5:13:15 PM UTC-4, frye wrote:

 Hi all, 

 I'm having a weird state problem with 
 Componenthttps://github.com/stuartsierra/component. 
 Let's say I have a system component, like in fig.1. Starting / stopping and 
 loading state is fine. 
 However, let's say I have 2 other components (:updater , :reader) that use 
 component :a. This is the problem that occurs.

1. When *:updater*, modifies an atom in *:a*, that change appears in 
path [*:core :a*], not path [*:updater :a*] or [*:a*]. 
2. Because of the abouve, when *:reader* goes to it's local path [
*:reader :a*] to read that change, it doesn't see those modifications. 
3. Using this scheme, *:a* is duplicated 4 times, in the system map. 
However, the modifications only appear in path [*:core :a*]. Thus 
:reader is unable to access it (it's local [*:a*] is unchanged). 


 (def system-components [:a :updater :reader])

 (defrecord Core [env] component/Lifecycle
   (start [this] ...)
   (stop [this] ...))

 (defn component-core [env]

   (component/system-map
:a (component/using
   (ca/component-a env)
   {})
:updater (component/using
  (cs/component-updater env)
  {:a :a})
:reader(component/using
  (cs/component-reader env)
  {:a :a})
:core (component/using
 (map-Foobar {:env env})
 {:a :a 

  :updater :updater 

  :reader :reader })))

 *fig.1 *


 I was hoping to use Component to manage all internal application state. 
 But maybe it's not designed for this use case (state changes between 
 components). I imagine that immutability is preventing all those duplicates 
 from seeing the modifications. However, in this case I do need an update to 
 :a in one component, to be accessed by another component. 

 Any suggestions on patterns here? I'm also looking at 
 component/update-systemhttps://github.com/stuartsierra/component/blob/master/src/com/stuartsierra/component.clj#L116.
  
 But again, I don't have access to the core *system* var, from within my 
 components. 


 Any insights appreciated 

 Tim Washington 
 Interruptsoftware.com http://interruptsoftware.com 


  

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

2014-04-03 Thread Stuart Sierra


On Wednesday, April 2, 2014 7:49:07 AM UTC-4, Jakub Holy wrote:

 When starting lein (namely lein ring server) I got a little helpful 
 exception and stack trace with the key line being:

 FileNotFoundException: Could not locate 
 clojure/tools/namespace/parse__init.class or 
 clojure/tools/namespace/parse.clj on classpath



This could be caused by different libraries or plugins depending on 
different versions of tools.namespace.

clojure.tools.namespace.parse is present starting with tools.namespace 
version 0.2.0.

Note: In tools.namespace version 0.2.0 I removed the namespace 
`clojure.tools.namespace` which was present in 0.1.x. After learning that 
this caused problems, I added the deprecated namespace back in version 
0.2.1.

You can use `lein deps :tree` to figure out which version is getting 
included in your project.

You can add an explicit dependency in your project.clj on a version that 
you know is compatible with all the libraries/plugins you want to use.

In this case, the latest version of tools.namespace is backwards compatible 
with 0.1.X versions. If that were not the case, you'd be out of luck.

 

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

2014-03-31 Thread Stuart Sierra
Oof, it's been ages since I looked at that stuff. I'll take a look.

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

2014-03-31 Thread Stuart Sierra
Yes, during the upgrade to the new Nexus release plugin
(required by Sonatype OSS) we forgot to include the
distribution profile, which builds the ZIP, in the Hudson
configuration for Clojure.

I've updated the Hudson configuration, so future releases
should get a ZIP.

I will manually build a ZIP for 1.6.0 and upload it to
Sonatype OSS, unless there's a reason not to.

-S

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