Re: Vars as global thread-locals?

2017-03-28 Thread Didier

>
> which brings up the limitation of implementing dynamically scoped vars 
> with ThreadLocal: It would be reasonable to expect that the bindings of 
> dynamic vars propagate to all code inside the same function, even if 
> executed by a different thread
>

This is not a limitation, this was done on purpose. Traditional dynamic 
vars are not thread safe and don't play well inside threaded environments. 
Clojure purposely restricted the scope to single threads. You can propagate 
it explicitly by using (bound-fn). Dynamic vars in Clojure were designed as 
a concurrency primitive, not as an implicit parameter, though it is fine to 
use them for that if you know what you are doing. You can see that from 
Rich Hickey's Clojure slides: https://i.imgur.com/jx2vtPb.png

A Clojure var is not only an object, it is a language construct. And when 
> you make it dynamic, you can bind and re-bind it with different values as 
> your functions are invoked within each other. This is something a 
> ThreadLocal can't do, and it makes the dynamic var a different kind of 
> beast, used for different purposes. A dynamic var emulates a local var that 
> you don't need to pass as a parameter to functions down the stack.
>

You don't need to make them dynamic to re-bind them. The symbol is 
immutably bound to the Var, so to allow re-binding of def in Clojure, all 
symbols are mapped to Vars instead of the value being defed, which are 
mutable data structures with thread safety features. The first thread 
safety feature is volatile access across threads of a root pointer with 
automatic deref. Volatile is needed to guarantee that as soon as you 
re-def, all access will see the new def and not the old. The second thread 
safety feature is thread isolated value overrides. This is useful when you 
don't need threads to cooperate on the same data, but you need all of them 
to have their own copy to work with. Each feature is optional. So if you 
only want thread isolation, you create a dynamic with no root. If you only 
want volatile root, you create a non dynamic var. If you want both, you can 
do that too.

So yes, it is not exactly like ThreadLocal, but I guess this is the biggest 
thing I disagree about, it's that for every use case Var can be used for, 
there is nothing wrong with using it, even if a ThreadLocal could also be 
used. In fact, I'd frown upon someone using ThreadLocal when Var would work.

Dynamic vars are required to be global in Clojure, because Clojure will 
> check that your symbols have been defined, but they wouldn't need to.


Dynamic vars are not required to be global in Clojure, you can use 
(with-local-vars) if you only need them to be local. I know it is a bit 
complicated to refer to their instance directly, and there's no constructor 
for them, only indirect ones like def and (with-local-vars), but they can 
be used as a simple instance if you want. You can refer to the instance by 
using (var). You can pass this instance around. You can create local 
versions of them. You can even call into their java constructor if you want 
more control on them, at which point, you can fine tune when to push and 
pop on them. Now, I don't advise you use them through their Java interface, 
but you can if you want.

This is not unimportant, and indicates that vars and ThreadLocals are meant 
> for different purposes. A ThreadLocal will guarantee a new, different value 
> for each thread. For Vars, you need to manually do that at thread creation, 
> and it may be tricky for threads that you don't create, if possible.
>

This I agree with, and that's the only use case I can think of where 
ThreadLocal would be better. Slight correction though, ThreadLocals won't 
guarantee that, but can be made too, by overriding their init method. By 
default they return null otherwise. Vars and ThreadLocal are meant to be 
tools in my opinion, and they overlap quite a bit in functionality, and 
where it overlaps, I see no reason to use ThreadLocal over Vars, especially 
when considering that in most cases, you'll put your ThreadLocal inside a 
Var when using it from Clojure.

Regression: The reason that I brought up this discussion is that I didn't 
> understand why clojure.tools.logging uses a dynamic var for enforcing the 
> use of a specific *logger-factory*. Does anybody have an explanation for 
> that?
>

This lets you override the factory used to create the logger if you need 
too, within a particular thread and binding block. I'm not sure when that 
would come in handy for tools.logging, but I assume it sometimes is.

By the way, as I revisit your initial question:

Clojure encourages avoiding the use of vars as global thread-local storage, 
> by restricting their use to dynamic binding only.
>

I can see now what you were asking. The "dynamic" part is the idea that the 
value is pushed and poped within entry and exit of a binding block. I doubt 
Clojure has anything against global thread-local storage, but it wanted to 

Re: Compiling gen-class runs static initializers: workarounds, solutions?

2017-03-28 Thread Colin Fleming
Ah yes, I remember this now. It seems like this is a fix that would
definitely help, too, since many (most?) people using serious interop will
be type hinting.

On 28 March 2017 at 23:15, Adam Clements  wrote:

> Potentially relevant? I posted a patch two years ago for some static
> initialisers still running in 1.8, not yet merged. It was actually the type
> hints causing the initialisers to be run at compile time
>
> http://dev.clojure.org/jira/browse/CLJ-1714
>
> On Tue, Mar 28, 2017 at 10:21 AM 'Gunnar Völkel' via Clojure <
> clojure@googlegroups.com> wrote:
>
>> The JavaFX workaround consist of creating a javafx.embed.swing.JFXPanel
>> statically in a namespace that is loaded before any other namespace that
>> import problematic JavaFX classes as in [1,2].
>> This initializes the JavaFX platform.
>>
>> [1] https://github.com/halgari/fn-fx/blob/master/src/fn_fx/
>> render_core.clj#L20
>> [2] https://github.com/zilti/clojurefx/blob/master/src/
>> clojurefx/core.clj#L7
>>
>> --
>> You received this 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.
>

-- 
You received this 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: Vars as global thread-locals?

2017-03-28 Thread Ernesto Garcia

>
> Right, except each thread gets its own binding. So it's not necessarily 
> that you'll get the value of the last binding up the call stack. This will 
> only be true if you are in the same thread also.


The last binding up in the call stack implies that you are in the same 
thread, but I think I know what you mean, which brings up the limitation of 
implementing dynamically scoped vars with ThreadLocal: It would be 
reasonable to expect that the bindings of dynamic vars propagate to all 
code inside the same function, even if executed by a different thread.
 

> ThreadLocal is an object, and so is a Clojure Var.
>

A Clojure var is not only an object, it is a language construct. And when 
you make it dynamic, you can bind and re-bind it with different values as 
your functions are invoked within each other. This is something a 
ThreadLocal can't do, and it makes the dynamic var a different kind of 
beast, used for different purposes. A dynamic var emulates a local var that 
you don't need to pass as a parameter to functions down the stack.
 

> In both, you'll probably want to store the instance through a globally 
> accessible name, like with def in Clojure or a static in Java. You don't 
> have too, but I don't see the use case for a local reference to the 
> ThreadLocal or the Var.
>

Dynamic vars are required to be global in Clojure, because Clojure will 
check that your symbols have been defined, but they wouldn't need to.

ThreadLocals don't need to be global either, you can define them in the 
smaller scope where they are used.
 

> Then there's the details, like Vars have a default global scope value, 
> while ThreadLocal has a default init method if you get before a set.
>

This is not unimportant, and indicates that vars and ThreadLocals are meant 
for different purposes. A ThreadLocal will guarantee a new, different value 
for each thread. For Vars, you need to manually do that at thread creation, 
and it may be tricky for threads that you don't create, if possible.


Regression: The reason that I brought up this discussion is that I didn't 
understand why clojure.tools.logging uses a dynamic var for enforcing the 
use of a specific *logger-factory*. Does anybody have an explanation for 
that?

Thanks,
Ernesto

>

-- 
You received this 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 gen-class runs static initializers: workarounds, solutions?

2017-03-28 Thread Gregg Reynolds
give clojurians a try on slack.  monitoring that and this list i get the
impression that helpful people do not necessarily work both fora.

On Mar 27, 2017 11:00 AM, "lonign via Clojure" 
wrote:

> Hi Gregg,
>
> I've have tried them, but have not been able to get anything that will
> compile, let alone run.
>
> On Sunday, March 26, 2017 at 5:15:52 PM UTC-4, Gregg Reynolds wrote:
>>
>>
>>
>> On Jan 2, 2015 12:36 PM, "David James"  wrote:
>>
>> I have a problem when compiling while using gen-class with static
>> initializers. I use gen-class to extend a JavaFX 8 class,
>> javafx.scene.control.Control. During compilation, a static initializer
>> is run, raising an exception saying that the JavaFX toolkit has not been
>> initialized. I'm going to share what I've read, since this issue seems to
>> pop up from time to time, and see if there are better solutions than
>> currently posted online. Here are my questions and comments:
>>
>>- Is there a way to run code during compilation that fires before the
>>static initializers? I could use this as a workaround to initialize the
>>toolkit.
>>- Is there a way to stop the static initializers from being run? This
>>would solve the problem.
>>- More broadly, is is necessary for gen-class to run the static
>>initializers during compilation? I recently read over CLJ-1315:
>>"Problem: When classes are imported in Clojure, the class is loaded using
>>Class.forName(), which causes its static initialisers to be executed. This
>>differs from Java where compilation does not cause classes to be loaded." 
>> I
>>wonder if a similar approach should be used with Clojure's gen-class.
>>
>> Related discussions:
>>
>>- JIRA: CLJ-1315 
>>- Compilation question - why initialize classes when loading for
>>compilation?
>>
>> 
>>- Stack Overflow: How can a static initializer be defined using
>>gen-class
>>
>> 
>>- Stack Overflow: Clojure can't import JavaFX classes with static
>>initializers
>>
>> 
>>
>> Thanks,
>> David
>>
>>
>> just curious, have you tried using :init/:constructors in gen-class?
>>
>> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: Compiling gen-class runs static initializers: workarounds, solutions?

2017-03-28 Thread Didier
In my experience, there's definitly still issues with static initializers, even 
in 1.8.

I'd recommend you go mixed Java for those use case.

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


Protocol support with spec?

2017-03-28 Thread Didier
I was wondering if protocols do or will be extended to support specs?

I'm thinking in the two following ways:

1) I can spec a protocol's functions so that whoever implements it has a better 
and more complete specification of how it should do so.

2) Protocols can dispatch based on the tagged entity of the first argument. So 
if I have a multi-spec for a map, it can be used as a record, in that I can 
have protocol implementations for each type of the specced map.

-- 
You received this 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 gen-class runs static initializers: workarounds, solutions?

2017-03-28 Thread lonign via Clojure
Hi Gunnar,

Yes, I use this trick to get tests to run without starting up an 
application. That is a run-time issue.

The problem I'm having is a compile-time issue. That is, errors are thrown 
when the compiler hits a gen-class or proxy used to try to extend (some) 
JavaFX classes.

-- 
You received this 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 and RFC] Bifurcan: impure functional data strucures

2017-03-28 Thread Mark Engelberg
I do a lot of work with data structures, so this, I think, would be useful
to me.

For the immutable data structures, it seems like they could be done as a
drop-in replacement for the Clojure built-ins.  There are a couple new
functions for splitting and concatenating.  I'd recommend following
precedents set by core.rrb-vector when relevant.  Map linear/forked to
transient API.

For the mutable Linear data structures, my instinct would be to hook into
the transient functions when possible, even though it doesn't behave
exactly like transients.  Name new functions on the mutable collections
with a `!` character, but return the mutated collection as output (as
opposed to returning void), so you don't have to write functions over the
data as a "bang in place".

--Mark

-- 
You received this 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 gen-class runs static initializers: workarounds, solutions?

2017-03-28 Thread Adam Clements
Potentially relevant? I posted a patch two years ago for some static
initialisers still running in 1.8, not yet merged. It was actually the type
hints causing the initialisers to be run at compile time

http://dev.clojure.org/jira/browse/CLJ-1714

On Tue, Mar 28, 2017 at 10:21 AM 'Gunnar Völkel' via Clojure <
clojure@googlegroups.com> wrote:

> The JavaFX workaround consist of creating a javafx.embed.swing.JFXPanel
> statically in a namespace that is loaded before any other namespace that
> import problematic JavaFX classes as in [1,2].
> This initializes the JavaFX platform.
>
> [1]
> https://github.com/halgari/fn-fx/blob/master/src/fn_fx/render_core.clj#L20
> [2]
> https://github.com/zilti/clojurefx/blob/master/src/clojurefx/core.clj#L7
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: Compiling gen-class runs static initializers: workarounds, solutions?

2017-03-28 Thread 'Gunnar Völkel' via Clojure
The JavaFX workaround consist of creating a javafx.embed.swing.JFXPanel 
statically in a namespace that is loaded before any other namespace that 
import problematic JavaFX classes as in [1,2].
This initializes the JavaFX platform.

[1] 
https://github.com/halgari/fn-fx/blob/master/src/fn_fx/render_core.clj#L20
[2] https://github.com/zilti/clojurefx/blob/master/src/clojurefx/core.clj#L7

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