Re: [inheritable-var] A wrapper of InheritableThreadLocal to define thread-inheritable variable

2017-07-29 Thread Didier
For the core.async example, it was my mistake. Forgot to definheritable 
foo. The example does not return an exception, but "Main Thread", showing 
that the inheritable did not work. If using async/thread it does work 
though.



On Saturday, 29 July 2017 08:07:08 UTC-7, Jiacai Liu wrote:
>
> After digging into dynamic + binding doesn't work in multithread, I create 
> a simple wrap to define thread-inheritable var.
> Any suggestions(bugs) are welcome.
>
> https://github.com/jiacai2050/inheritable-var
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: [inheritable-var] A wrapper of InheritableThreadLocal to define thread-inheritable variable

2017-07-29 Thread Didier
Your doc says this doesn't work with dynamic binding:

(def ^:dynamic *foo* 5)
(defn adder
  [param]
  (+ *foo* param))
(binding [*foo* 10]
 (doseq [v (pmap adder (repeat 3 5))]
   (println v)))

But it does since Clojure 1.3. They added binding conveyance: 
https://github.com/clojure/clojure/blob/master/changes.md#234-binding-conveyance

This means that in Clojure 1.3+, when using dynamic binding and future, 
agent, pmap or core.async, child threads will inherit the bounded vars 
properly.

You might want to make that clear in your doc.

I also believe there's an issue with your library, this does not work:

(definheritable foo "Main thread.")
(inheritable-binding [foo "In thread inside future, running on Clojure 
ThreadPools."]
 @(future @foo))

It also doesn't seem to play nice with core.async, whereas dynamic vars do:

(let [chan (async/chan)]
  (inheritable-binding [foo "In chan Thread."]
   (async/go
(async/>! chan @foo))
   (async/ CompilerException java.lang.RuntimeException: Unable to resolve symbol: 
foo in this context

(def ^:dynamic bar "In main thread.")
(let [chan (async/chan)]
  (binding [bar "In chan Thread."]
   (async/go
(async/>! chan bar))
   (async/ "In chan Thread."



On Saturday, 29 July 2017 19:37:13 UTC-7, Jiacai Liu wrote:
>
> Thanks for your tips.
>
> I have updated my code to wrap TransmittableThreadLocal 
> ,
>  an 
> enhanced version of InheritableThreadLocal, to solve threadpool problem.
>
> On Sunday, July 30, 2017 at 3:11:59 AM UTC+8, Didier wrote:
>>
>> InheritableThreadLocal is not safe to use with ThreadPools. And a lot of 
>> the Clojure parallel constructs rely on ThreadPools.
>>
>> I'd recommend you rely on dynamic Vars instead and use bound-fn when you 
>> want child threads to inherit parent's bindings. 
>>
>> If you knew this already, then I see no harm in using 
>> InheritableThreadLocal, but just be sure you understand its risk. In most 
>> cases, it is unsafe. 
>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from 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: [inheritable-var] A wrapper of InheritableThreadLocal to define thread-inheritable variable

2017-07-29 Thread Jiacai Liu
Thanks for your tips.

I have updated my code to wrap TransmittableThreadLocal 
,
 an 
enhanced version of InheritableThreadLocal, to solve threadpool problem.

On Sunday, July 30, 2017 at 3:11:59 AM UTC+8, Didier wrote:
>
> InheritableThreadLocal is not safe to use with ThreadPools. And a lot of 
> the Clojure parallel constructs rely on ThreadPools.
>
> I'd recommend you rely on dynamic Vars instead and use bound-fn when you 
> want child threads to inherit parent's bindings. 
>
> If you knew this already, then I see no harm in using 
> InheritableThreadLocal, but just be sure you understand its risk. In most 
> cases, it is unsafe. 
>
>

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


[inheritable-var] A wrapper of InheritableThreadLocal to define thread-inheritable variable

2017-07-29 Thread Didier
InheritableThreadLocal is not safe to use with ThreadPools. And a lot of the 
Clojure parallel constructs rely on ThreadPools.

I'd recommend you rely on dynamic Vars instead and use bound-fn when you want 
child threads to inherit parent's bindings. 

If you knew this already, then I see no harm in using InheritableThreadLocal, 
but just be sure you understand its risk. In most cases, it is unsafe. 

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

2017-07-29 Thread Didier
> I thought there would be be many benefits to using records, particularly 
> around protocols but I haven't felt the loss.

I like having the constructor ready made, and the extra documentation they 
provide on which key it has. Though spec remediates the latter a bit.

Other then that, they're faster, but that's not why I use them.

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


[inheritable-var] A wrapper of InheritableThreadLocal to define thread-inheritable variable

2017-07-29 Thread Jiacai Liu
After digging into dynamic + binding doesn't work in multithread, I create 
a simple wrap to define thread-inheritable var.
Any suggestions(bugs) are welcome.

https://github.com/jiacai2050/inheritable-var

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

2017-07-29 Thread Didier
I feel your pain, but you kinda shot yourself in the foot from the get go. 
What you did is the same as if you had decided to use a Java List 
to store your Account info.

I'd suggest you read over this: 
https://clojure.org/reference/datatypes#_why_have_both_deftype_and_defrecord

It explains the idiomatic way to deal with application domain information, 
such as Account, Employees, etc. Spoiler, use records, or at least a map.

Now having said that, given a project across many namespaces, you will 
still have some of the problems of not having type declarations. Like if a 
function takes the record, but the argument is not called account, but say 
x instead, you would need to dig back to understand what this operates on. 
Spec could change that though.

On Tuesday, 25 July 2017 18:52:41 UTC-7, Kevin Kleinfelter wrote:
>
> I ran into the 'refactoring an unnamed type' problem.  I'd like to know 
> how experienced Clojurists avoid it.
>
> I've got an account record/structure.  It has things like an account name, 
> account number, etc.  I started off storing it in a vector, because it had 
> just two elements.  Account name was (first v).  Account number was (second 
> v).  And that worked up to a point.  Over time, it has acquired enough 
> pieces and rules that I really need to change its implementation.  I need 
> to refactor it.
>
> When it was only a few hundred lines long, in a couple of files, I could 
> examine each line.  Now that it's a dozen files and several thousand lines, 
> I just don't have the attention span.
>
> In a language with named types, I could search for AccountRecord.  I 
> could thoroughly find all the places I used it and refactor it.  Or I could 
> change the name of the type to tAccountRecord, and the compiler would 
> identify all the places where I used it (with error messages).
>
> In an OO language, I'd be accessing all of its pieces via getters and 
> setters, and I wouldn't have to find all of the places where I used it, 
> because the implementation would be a black box.
>
> But in a language with unnamed types, it's just a vector and I've just got 
> first and second and nth to search for.  That's going to find lots of 
> irrelevant stuff.  It's enough to make me pine for Java and a refactoring 
> IDE.  =:-o
>
> So how do developers who work with un-typed (or un-named type) languages 
> avoid this sort of problem?  Or, failing to avoid it, how do they clean up 
> afterward?
> tnx
>
>

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

2017-07-29 Thread Didier

>
> Why does `alter-var-root` here seem to succeed, but have no effect?


What you want is:

(set! *print-level* 2)

But, this will not work 100% of the time, and sometimes you might want 
alter-var-root.

Here's the trick. *print-level* is a dynamic Var. Alter-var-root only 
changes the root value of a Var, it can not change a dynamically binded 
value:

(def ^:dynamic x "I am root!")
x ; => "I am root!"
(binding [x "I am dynamically binded!"] x) ; => "I am dynamically binded!"
(alter-var-root #'x (constantly "I've had my root altered!"))
x ; => "I've had my root altered!"
(binding [x "I am dynamically binded!"] x) ; => "I am dynamically binded!"

So where is *print-level* binded you ask? Well, that depends on how you 
bootstrapped Clojure. Most of the time, such as when using lein, or 
clojure.main, those things will wrap your entire code in a binding, and 
they will bind a certain number of default dynamic var such as 
*print-level*. You can see the code for clojure.main here: 
https://github.com/clojure/clojure/blob/master/src/clj/clojure/main.clj#L76

So in your case, you're probably bootstrapping Clojure using a mechanism 
that binds *print-level*, thus changing its root has no effect in your 
code, you have to change its binding, and the function to do that is set!.

On Monday, 24 July 2017 07:12:05 UTC-7, Rob Nikander wrote:
>
> I think in my case here the easiest thing will be to remove the cycles, 
> but still I'd like to understand a couple things...
>
> On Sunday, July 23, 2017 at 10:12:46 PM UTC-4, Didier wrote:
>>
>> I'm not sure I can fully help without you explaining more what you're 
>> doing. It sounds like you've got a collection or container type which has 
>> an implementation of print that loops over its elements, and calls print on 
>> them. So if you have a cycle, the print will go on forever until memory 
>> runs out.
>>
>
> My container type (the tree node) is simply the standard clojure map. 
>
> If you're using a standard type, you might be able to limit *print-level* 
>> . Most Clojure 
>> collections will limit how deep they print based on the value of this 
>> global dynamic Var.
>>
>
> Okay, *print-level* works but it looks like I have to call print myself. I 
> can't rely on the REPL to print it. 
>
> (binding [*print-level* 2] (println (find-route "/reports")))   ; okay
>
> Why does `alter-var-root` here seem to succeed, but have no effect?
>
> (alter-var-root #'*print-level* (constantly 2))
> => 2
> *print-level*
> => nil
> (find-route "/reports")
> stack overflow
>
>  
>

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

2017-07-29 Thread Jeaye
This looks superb, Ben, thanks for the awesome work.

On Tue, Jul 25, 2017 at 04:16:44PM -0700, Ben Brinckerhoff wrote:
> Expound formats clojure.spec errors in a way that is optimized for humans 
> to read. Expound works in Clojure and Clojurescript.
> 
> This release provides human-optimized error messages when using a number of 
> spec features, including instrumentation and `assert`.
> 
> More information is available in the README 
> .
> 
> -- 
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with your 
> first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> --- 
> You received this message because you are subscribed to the Google Groups 
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

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


signature.asc
Description: PGP signature