Re: About transients no longer being safe in 1.7-alpha2

2014-11-04 Thread Daniel Marjenburgh
I'll be more careful before posted code that doesn't compile :)
Anyway,  here's my output using clojure 1.7-alpha3

https://lh4.googleusercontent.com/-MqiKnTcxneE/VFigwvQtzBI/A08/vGvY2waCJdc/s1600/Screen%2BShot%2B2014-11-04%2Bat%2B10.43.17.png
It could be that depending on OS/env the second future starts after the 
first one finishes (if you add more futures or Thread sleeps it might be 
easier to reproduce).
But this example already shows that 2 threads are mutating the same 
transient, otherwise, as Atamert pointed out, the result should have been 
45.

Op dinsdag 4 november 2014 08:45:37 UTC+1 schreef Sean Corfield:

 On Nov 3, 2014, at 11:13 PM, Daniel Marjenburgh dmarje...@gmail.com 
 javascript: wrote: 
  I was a bit too quick there and posted some errors int he code: 

 That’s still not quite right. I think you mean: 

 (let [v (transient {:a 0}) 
   f1 (future (reduce #(assoc! % :a (+ (:a %) %2)) v (range 10))) 
   f2 (future (reduce #(assoc! % :a (+ (:a %) %2)) v (range 10)))] 
   @f1 @f2 ; wait for futures 
   (persistent! @f1)) 

 Which seems to consistently produce {:a 90} on both Clojure 1.7.0 Alpha 2 
 and Clojure 1.7.0 Alpha 3. 

 Sean Corfield -- (904) 302-SEAN 
 An Architect's View -- http://corfield.org/ 

 Perfection is the enemy of the good. 
 -- Gustave Flaubert, French realist novelist (1821-1880) 





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

2014-11-04 Thread Jean Niklas L'orange
Hi there,

On Tuesday, November 4, 2014 8:05:03 AM UTC+1, Daniel Marjenburgh wrote:

 I know transients aren't bash-in-place, as they may return new references, 
 but that is not the problem I'm having here.
 If you bash in place, you would get unexpected results, but still the same 
 result every time. The problem here is that the 'value' of the transient is 
 changing underneath you because of another thread.


To ensure consistency, you must ensure that you update a transient value at 
most once – all calls (including reads) on the same transient value after 
an update is illegal/undefined behaviour. Transient updates – minus 
persistent! – will always return a new transient value, even though the 
transient returned may be the same reference. So the code

(let [v (transient {:a 0})
  f1 (future (reduce #(assoc! % (+ (:a %) %2)) v (range 10)))
  f2 (future (reduce #(assoc! % (+ (:a %) %2)) v (range 10)))]
  @f1 @f2 ; wait for futures
  (persistent! @f1))

will result in undefined behaviour, because the original v is updated twice 
(and is potentially read after an update). The correct way would be to do 
the following:

(let [v {:a 0}
  f1 (future (reduce #(assoc! % (+ (:a %) %2)) (transient v) (range 
10)))
  f2 (future (reduce #(assoc! % (+ (:a %) %2)) (transient v) (range 
10)))]
  @f1 @f2 ; wait for futures
  (persistent! @f1))

I don't see an explicit rule at http://clojure.org/transients stating this, 
although I feel it is implicit from the bash in-place rule. Perhaps that's 
something worth adding to the page to avoid confusion.

--
Regards,
Jean Niklas L'orange

 

 Op dinsdag 4 november 2014 06:13:00 UTC+1 schreef Alex Miller:



 On Monday, November 3, 2014 10:44:19 PM UTC-6, Atamert Ölçgen wrote:

 Thanks Alex!

 Now that I took a second look at Daniel's code, it seems assoc! is used 
 like swap!, as if it would modify m in place. So I would expect, if it runs 
 without errors, result to be {:a 0}.


 Right, that is an incorrect usage - it will actually modify with changes 
 though, but not in expected ways (this is independent of the change we're 
 discussing - you can get the same behavior in a single thread modifying a 
 transient without reusing the return).

 Given that transients are values (not reference types like ref or atom) I 
 can't think of a case where they can be modified concurrently.


 You can, but not without going pretty far out of normal Clojure code. 
  



 On Tue, Nov 4, 2014 at 11:19 AM, Alex Miller al...@puredanger.com 
 wrote:



 On Monday, November 3, 2014 9:00:10 PM UTC-6, Atamert Ölçgen wrote:



 On Mon, Nov 3, 2014 at 5:57 PM, Daniel Marjenburgh 
 dmarje...@gmail.com wrote:

 Hi,

 I just want to address this issue (CLJ-1498 
 http://dev.clojure.org/jira/browse/CLJ-1498). It was accepted in 
 1.7-alpha2 and I haven't seen a lot of discussion around it, even though 
 it's quite a big change.

 With this change the following code is possible:


 With persistents the result would be the same, every time. If this is 
 now valid Clojure, I didn't run it myself, we are sacrificing 
 consistency. 
 I don't understand what we're getting in return.

 Even the simple example in the ticket (with one future) doesn't make a 
 lot of sense to me.

 Am I missing something obvious?


 Transients always expect thread isolation. In the past this was locked 
 to a single thread (the one that made the transient). That restriction now 
 extends to being used by multiple threads, but isolation should still be 
 maintained for proper use. 

 What we are gaining is the ability to use transient collections in go 
 blocks with core.async, where the thread being used is just one pool out 
 of 
 a thread. For example (just typing this not running it, so excuse any 
 typos):

 (defn drain [ch coll] 
   (let [t (transient []]
 (go-loop
   (if-some [v (! ch)]
 (do (conj! t v) (recur))
 (persistent! t)

 This doesn't necessarily work in core.async because each time the ! 
 parks, it may be woken up with a different thread from the pool. The 
 transient change allows this kind of code to succeed.



 (let [m (transient {:a 0})
   futs (for [n (range 100)]
  (future (assoc! m :a (inc (:a m)]
   (mapv deref futs) ; wait until futures are done
   (persistent! m))


 The results will vary per run, where it used to throw 
 an IllegalAccessError: Transient used by non-owner thread.

 I understand the problems of not being able to have 1 go routine 
 access a transient, even though it would be safe, but this solution 
 feels 
 like it's throwing out the baby with the bathwater. Basically, it's 
 doing 
 away with what the following block on clojure.org 
 http://clojure.org/transients says:

 *Transients enforce thread isolation**.* Because each result of a 
 transient operation shares (mutable) structure with the previous, it 
 would 
 be very dangerous if more than one thread were to manipulate a 
 transient at 
 once. In order to 

Re: About transients no longer being safe in 1.7-alpha2

2014-11-04 Thread Daniel Marjenburgh
Hi Jean,

In this case, we are dealing with 1 key-value pair, so there is only one 
transient reference all the time. It is not my experience that each update 
returns a new transient value (here, each update is identical to the 
original, as per the identical? predicate).

I know you shouldn't use transients in the way I illustrated, but use it as 
if it always returns a new value. In that scenario, you would not get 
inconsistent results, as multiple threads would have to coordinate to pass 
the reference around (as happens in core.async) and the birth-thread check 
is unnecessary.

Still, the onus is now put on the user to ensure correct use of transients 
in a multi-threaded environment, as no warning or error is given anymore. 
It has always been the case that Clojure makes it hard to write unsafe 
mutable code, you had to go out of your way. With this change, I feel we 
are giving up this safeguard a bit too easily.

Maybe another solution could be to have the birth-thread explicitly 
relinquish ownership of the transient, for example, by calling 
(relinquish-transient m). Then the thread that makes the next transient 
update would become the new owner. If another thread updates a transient 
while another threads owns it, the usual error is thrown. This way we 
maintain the safety as before and it becomes a issue for core.async to deal 
with transients in logical threads, not clojure.core. I guess a go macro 
could recognize transients in go-blocks and auto-relinguish them before 
parking operations so that the user can keep thinking in logical threads. 
I'd like to know how feasible a solution like that would be.

Op dinsdag 4 november 2014 11:12:08 UTC+1 schreef Jean Niklas L'orange:

 Hi there,

 On Tuesday, November 4, 2014 8:05:03 AM UTC+1, Daniel Marjenburgh wrote:

 I know transients aren't bash-in-place, as they may return new 
 references, but that is not the problem I'm having here.
 If you bash in place, you would get unexpected results, but still the 
 same result every time. The problem here is that the 'value' of the 
 transient is changing underneath you because of another thread.


 To ensure consistency, you must ensure that you update a transient value 
 at most once – all calls (including reads) on the same transient value 
 after an update is illegal/undefined behaviour. Transient updates – minus 
 persistent! – will always return a new transient value, even though the 
 transient returned may be the same reference. So the code

 (let [v (transient {:a 0})
   f1 (future (reduce #(assoc! % (+ (:a %) %2)) v (range 10)))
   f2 (future (reduce #(assoc! % (+ (:a %) %2)) v (range 10)))]
   @f1 @f2 ; wait for futures
   (persistent! @f1))

 will result in undefined behaviour, because the original v is updated 
 twice (and is potentially read after an update). The correct way would be 
 to do the following:

 (let [v {:a 0}
   f1 (future (reduce #(assoc! % (+ (:a %) %2)) (transient v) (range 
 10)))
   f2 (future (reduce #(assoc! % (+ (:a %) %2)) (transient v) (range 
 10)))]
   @f1 @f2 ; wait for futures
   (persistent! @f1))

 I don't see an explicit rule at http://clojure.org/transients stating 
 this, although I feel it is implicit from the bash in-place rule. Perhaps 
 that's something worth adding to the page to avoid confusion.

 --
 Regards,
 Jean Niklas L'orange

  

 Op dinsdag 4 november 2014 06:13:00 UTC+1 schreef Alex Miller:



 On Monday, November 3, 2014 10:44:19 PM UTC-6, Atamert Ölçgen wrote:

 Thanks Alex!

 Now that I took a second look at Daniel's code, it seems assoc! is used 
 like swap!, as if it would modify m in place. So I would expect, if it 
 runs 
 without errors, result to be {:a 0}.


 Right, that is an incorrect usage - it will actually modify with changes 
 though, but not in expected ways (this is independent of the change we're 
 discussing - you can get the same behavior in a single thread modifying a 
 transient without reusing the return).

 Given that transients are values (not reference types like ref or atom) 
 I can't think of a case where they can be modified concurrently.


 You can, but not without going pretty far out of normal Clojure code. 
  



 On Tue, Nov 4, 2014 at 11:19 AM, Alex Miller al...@puredanger.com 
 wrote:



 On Monday, November 3, 2014 9:00:10 PM UTC-6, Atamert Ölçgen wrote:



 On Mon, Nov 3, 2014 at 5:57 PM, Daniel Marjenburgh 
 dmarje...@gmail.com wrote:

 Hi,

 I just want to address this issue (CLJ-1498 
 http://dev.clojure.org/jira/browse/CLJ-1498). It was accepted in 
 1.7-alpha2 and I haven't seen a lot of discussion around it, even 
 though 
 it's quite a big change.

 With this change the following code is possible:


 With persistents the result would be the same, every time. If this is 
 now valid Clojure, I didn't run it myself, we are sacrificing 
 consistency. 
 I don't understand what we're getting in return.

 Even the simple example in the ticket (with one future) doesn't make 
 a lot of 

Re: About transients no longer being safe in 1.7-alpha2

2014-11-04 Thread Jean Niklas L'orange
Hi Daniel,

On Tuesday, November 4, 2014 11:54:30 AM UTC+1, Daniel Marjenburgh wrote:

 Hi Jean,

 In this case, we are dealing with 1 key-value pair, so there is only one 
 transient reference all the time. It is not my experience that each update 
 returns a new transient value (here, each update is identical to the 
 original, as per the identical? predicate).


I probably worded myself poorly: When I wrote transient value, I meant the 
contents of a transient, not the reference to it.

I like to think of transients like this: They work exactly like persistent 
data structures, but when any kind of update is performed on the transient, 
the runtime should be allowed to deallocate the old transient head if it 
wants to. If I use transients correctly, I should never see any segfaults 
(or whatever you want to call it) due to transient usage.

Now, the runtime doesn't actually deallocate the transient head, it 
(usually) reuses it for performance. Which means that the old transient 
references are equal to the new transient references, even though the old 
transient contents are overwritten (and therefore invalidated). So even 
though you can use the old transient reference to refer to the new 
transient value, it's not referring to the old transient value.

If it helps you, you can also think of transients as linear types, like the 
ones in Rust. Their constraints are very similar, but correct transient 
usage have to be verified by us, not the compiler. Now, whether that's a 
good idea or not is another matter.
 

 I know you shouldn't use transients in the way I illustrated, but use it 
 as if it always returns a new value. In that scenario, you would not get 
 inconsistent results, as multiple threads would have to coordinate to pass 
 the reference around (as happens in core.async) and the birth-thread check 
 is unnecessary.

 Still, the onus is now put on the user to ensure correct use of transients 
 in a multi-threaded environment, as no warning or error is given anymore. 
 It has always been the case that Clojure makes it hard to write unsafe 
 mutable code, you had to go out of your way. With this change, I feel we 
 are giving up this safeguard a bit too easily.

 Maybe another solution could be to have the birth-thread explicitly 
 relinquish ownership of the transient, for example, by calling 
 (relinquish-transient m). Then the thread that makes the next transient 
 update would become the new owner. If another thread updates a transient 
 while another threads owns it, the usual error is thrown. This way we 
 maintain the safety as before and it becomes a issue for core.async to deal 
 with transients in logical threads, not clojure.core. I guess a go macro 
 could recognize transients in go-blocks and auto-relinguish them before 
 parking operations so that the user can keep thinking in logical threads. 
 I'd like to know how feasible a solution like that would be.


 Op dinsdag 4 november 2014 11:12:08 UTC+1 schreef Jean Niklas L'orange:

 Hi there,

 On Tuesday, November 4, 2014 8:05:03 AM UTC+1, Daniel Marjenburgh wrote:

 I know transients aren't bash-in-place, as they may return new 
 references, but that is not the problem I'm having here.
 If you bash in place, you would get unexpected results, but still the 
 same result every time. The problem here is that the 'value' of the 
 transient is changing underneath you because of another thread.


 To ensure consistency, you must ensure that you update a transient value 
 at most once – all calls (including reads) on the same transient value 
 after an update is illegal/undefined behaviour. Transient updates – minus 
 persistent! – will always return a new transient value, even though the 
 transient returned may be the same reference. So the code

 (let [v (transient {:a 0})
   f1 (future (reduce #(assoc! % (+ (:a %) %2)) v (range 10)))
   f2 (future (reduce #(assoc! % (+ (:a %) %2)) v (range 10)))]
   @f1 @f2 ; wait for futures
   (persistent! @f1))

 will result in undefined behaviour, because the original v is updated 
 twice (and is potentially read after an update). The correct way would be 
 to do the following:

 (let [v {:a 0}
   f1 (future (reduce #(assoc! % (+ (:a %) %2)) (transient v) (range 
 10)))
   f2 (future (reduce #(assoc! % (+ (:a %) %2)) (transient v) (range 
 10)))]
   @f1 @f2 ; wait for futures
   (persistent! @f1))

 I don't see an explicit rule at http://clojure.org/transients stating 
 this, although I feel it is implicit from the bash in-place rule. Perhaps 
 that's something worth adding to the page to avoid confusion.

 --
 Regards,
 Jean Niklas L'orange

  

 Op dinsdag 4 november 2014 06:13:00 UTC+1 schreef Alex Miller:



 On Monday, November 3, 2014 10:44:19 PM UTC-6, Atamert Ölçgen wrote:

 Thanks Alex!

 Now that I took a second look at Daniel's code, it seems assoc! is 
 used like swap!, as if it would modify m in place. So I would expect, if 
 it 
 runs without errors, result to be 

Re: About transients no longer being safe in 1.7-alpha2

2014-11-04 Thread Alex Miller
I think all of these examples violate the usage expectations of transients 
(regardless of release) and you should expect to get confusing results from 
them.

I do not think it's worth modifying core.async go blocks to do anything special 
in this regard (eince go is a macro I don't think you can detect at compile 
time which locals are transients anyways). 

One possibility I've kicked around with some people is deciding at the time you 
create the transient whether it is allowed to cross threads (through a flag or 
something). When you don't need it you could then retain the existing safety 
check.

-- 
You 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: Proof of concept: ClojureScript - Apple's Javascript for Automation.

2014-11-04 Thread Yehonathan Sharvit
Could you please elaborate a bit about what you are trying to achieve?

On Thursday, 30 October 2014 02:16:55 UTC+2, Daniel Szmulewicz wrote:

 This is a proof of concept to show how ClojureScript can be used in the 
 context of Apple's JavaScript for Automation that ships with Yosemite. 

 https://gist.github.com/danielsz/9c4ed2fbf4c0ac6b2d95


-- 
You 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: OJ - A friendly way to talk to your database using Clojure.

2014-11-04 Thread Niels van Klaveren
Looks cool, any design decisions that made you create this instead of using 
honeysql https://github.com/jkk/honeysql ?

On Tuesday, November 4, 2014 3:45:35 AM UTC+1, Taylor Lapeyre wrote:



 GitHub project link:
 https://github.com/taylorlapeyre/oj

 The idea is to lay a solid foundation for talking to databases in Clojure 
 using regular Clojure data structures to represent queries. My goal is to 
 let this library become established enough that is becomes the foundation 
 for larger frameworks that abstract away the ideas found in SQL.

 Looking for feedback and for others to help me on this project! I hope you 
 find this useful, it has been very useful for me so far.


-- 
You 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] Eastwood the Clojure lint tool version 0.1.5

2014-11-04 Thread Andy Fingerhut
Eastwood is a Clojure lint tool.  It analyzes Clojure source code in
projects, reporting things that may be errors.

Installation instructions are in the documentation here:

https://github.com/jonase/eastwood/#installation--quick-usage

Updates since the last release are described in the change log here:


https://github.com/jonase/eastwood/blob/master/changes.md#changes-from-version-014-to-015

The changes most visible to Eastwood users are:

   -

   New linter :local-shadows-var that warns if a local name (e.g. a
   function argument or let binding) has the same name as a global Var, and is
   called as a function. This is sometimes a mistake.  More details with
   examples here:
   
https://github.com/jonase/eastwood#local-shadows-var---a-local-name-that-is-same-as-a-global-name-called-as-a-function
   -

   New linter :wrong-tag that warns for some kinds of erroneous type tags.
   For example, a primitive type tag like ^int or ^bytes on a Var name
   being def'd or defn'd should be given as ^{:tag 'int} instead. Also it
   is best if Java class names outside of the java.lang package are fully
   qualified when used to hint the return type of a function on its argument
   vector. More details with examples here:
   https://github.com/jonase/eastwood#wrong-tag---an-incorrect-type-tag
   -

   New API for running Eastwood from a REPL session, nearly identical to
   what is available from the command line. Note that this means you need not
   use Leiningen at all to use Eastwood, even if the instructions are
   currently Leiningen-specific.  Instructions here:
   https://github.com/jonase/eastwood#running-eastwood-in-a-repl
   -

   :unlimited-use warnings are no longer issued for the namespace
   clojure.test. It is very common for Clojure developers to have (:use
   clojure.test) in test namespaces. Issue #95
   https://github.com/jonase/eastwood/issues/95.
   - :suspicious-expression warnings are no longer issued for forms inside
   quote forms. Issue #74 https://github.com/jonase/eastwood/issues/74.


For those who have asked, sorry, there is still no way to annotate
expressions in your source code to disable linters for expressions that you
know are ok, while leaving the linter enabled in the rest of the code.
That is coming.

Go squash some bugs!

Jonas Enlund, Nicola Mometto, and Andy Fingerhut

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


how clojure infers types.

2014-11-04 Thread Phillip Lord



I have a piece of code that looks like this

(.getOWLEquivalentClassesAxiom
  (owl-data-factory)
  (set classlist)
  (union-annotations classlist))

The method signature is

getOWLEquivalentClassesAxiom(Set,Set)

On runing lein check I get 


Reflection warning, tawny/owl.clj:2219:6 - call to method
getOWLEquivalentClassesAxiom on
org.semanticweb.owlapi.model.OWLDataFactory can't be resolved (argument
types: unknown, java.util.Set).

which makes no sense. Surely, the return type of clojure.core/set is
known to be java.util.Set? I have quite a few calls like this in my
code, which is why I don't want to type hint the return of set
individually.

If I add a function like so:

(defn ^java.util.Set hset [coll]
  (set coll))

and call like this:

(.getOWLEquivalentClassesAxiom
  (owl-data-factory)
  (hset classlist)
  (union-annotations classlist))

The reflection warning goes away.


I've tried to reproduce this with simpler cases, like so:


(defn one []
  (java.util.Collections/unmodifiableSet
   (java.util.HashSet.)))


(defn two []
  (java.util.Collections/unmodifiableSet
   (set [])))

But both of these pass lein check just fine. Which suggests that clojure
knows set returns a java.util.Set object.

Now, given that I can't give a simple test case, I realise that it's
hard for anyone to work out what is happening. But, worse, I don't know
how to debug this at all. So, how I find out what clojure things the
return type of a function is? Or probe any further why this is failing?

Phil

-- 
You 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 clojure infers types.

2014-11-04 Thread Nicola Mometto

Actually `set` and a lot of other clojure.core functions are neither
inlineable nor have type hints.

Phillip Lord writes:

 I have a piece of code that looks like this

 (.getOWLEquivalentClassesAxiom
   (owl-data-factory)
   (set classlist)
   (union-annotations classlist))

 The method signature is

 getOWLEquivalentClassesAxiom(Set,Set)

 On runing lein check I get


 Reflection warning, tawny/owl.clj:2219:6 - call to method
 getOWLEquivalentClassesAxiom on
 org.semanticweb.owlapi.model.OWLDataFactory can't be resolved (argument
 types: unknown, java.util.Set).

 which makes no sense. Surely, the return type of clojure.core/set is
 known to be java.util.Set? I have quite a few calls like this in my
 code, which is why I don't want to type hint the return of set
 individually.

 If I add a function like so:

 (defn ^java.util.Set hset [coll]
   (set coll))

 and call like this:

 (.getOWLEquivalentClassesAxiom
   (owl-data-factory)
   (hset classlist)
   (union-annotations classlist))

 The reflection warning goes away.


 I've tried to reproduce this with simpler cases, like so:


 (defn one []
   (java.util.Collections/unmodifiableSet
(java.util.HashSet.)))


 (defn two []
   (java.util.Collections/unmodifiableSet
(set [])))

 But both of these pass lein check just fine. Which suggests that clojure
 knows set returns a java.util.Set object.

 Now, given that I can't give a simple test case, I realise that it's
 hard for anyone to work out what is happening. But, worse, I don't know
 how to debug this at all. So, how I find out what clojure things the
 return type of a function is? Or probe any further why this is failing?

 Phil

--

-- 
You 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] Arcadia, the integration of Clojure and Unity3D

2014-11-04 Thread David Koontz
The video linked here is different from the one in your Readme.md on 
github. This one works, the one in the Readme is broken 
(http://youtu.be/X4xCVsLhaZ0).

On Friday, October 17, 2014 12:10:29 PM UTC-7, tims wrote:

 Arcadia lives at https://github.com/arcadia-unity/Arcadia. For now, the 
 best way to get started is by cloning the repo. A brief screencast on 
 getting set up is here https://www.youtube.com/watch?v=KLq9b9lDmkc.



-- 
You 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 clojure infers types.

2014-11-04 Thread Phillip Lord


Yes, I checked the code.

(defn set
  Returns a set of the distinct elements of coll.
  {:added 1.0
   :static true}
  [coll] (clojure.lang.PersistentHashSet/create (seq coll)))

And that was my first assumption. But if clojure doesn't know the return
type, then why does this:

(defn two []
  (java.util.Collections/unmodifiableSet
   (set [])))

Not require reflection? Clojure should not know which method to call.
Unless it is just because unmodifiableSet has an arity of one and it's
the only arity of one, so it doesn't try to disambiguate.

I guess even if set was type hinted (to IPersistentSet) it would still
not work since, IPersistentSet is not assignable from java.util.Set.

Phil



Nicola Mometto brobro...@gmail.com writes:

 Actually `set` and a lot of other clojure.core functions are neither
 inlineable nor have type hints.

 Phillip Lord writes:

 I have a piece of code that looks like this

 (.getOWLEquivalentClassesAxiom
   (owl-data-factory)
   (set classlist)
   (union-annotations classlist))

 The method signature is

 getOWLEquivalentClassesAxiom(Set,Set)

 On runing lein check I get


 Reflection warning, tawny/owl.clj:2219:6 - call to method
 getOWLEquivalentClassesAxiom on
 org.semanticweb.owlapi.model.OWLDataFactory can't be resolved (argument
 types: unknown, java.util.Set).

 which makes no sense. Surely, the return type of clojure.core/set is
 known to be java.util.Set? I have quite a few calls like this in my
 code, which is why I don't want to type hint the return of set
 individually.

 If I add a function like so:

 (defn ^java.util.Set hset [coll]
   (set coll))

 and call like this:

 (.getOWLEquivalentClassesAxiom
   (owl-data-factory)
   (hset classlist)
   (union-annotations classlist))

 The reflection warning goes away.


 I've tried to reproduce this with simpler cases, like so:


 (defn one []
   (java.util.Collections/unmodifiableSet
(java.util.HashSet.)))


 (defn two []
   (java.util.Collections/unmodifiableSet
(set [])))

 But both of these pass lein check just fine. Which suggests that clojure
 knows set returns a java.util.Set object.

 Now, given that I can't give a simple test case, I realise that it's
 hard for anyone to work out what is happening. But, worse, I don't know
 how to debug this at all. So, how I find out what clojure things the
 return type of a function is? Or probe any further why this is failing?

 Phil

 --

-- 
Phillip Lord,   Phone: +44 (0) 191 222 7827
Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk
School of Computing Science,
http://homepages.cs.ncl.ac.uk/phillip.lord
Room 914 Claremont Tower,   skype: russet_apples
Newcastle University,   twitter: phillord
NE1 7RU 

-- 
You 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 clojure infers types.

2014-11-04 Thread Nicola Mometto

The reason why that call doesn't require reflection is that
Collection.unmodifiableSet has no overloaded methods, it only takes a
Set so the compiler doesn't have to disambiguate between different
signatures.

Phillip Lord writes:

 Yes, I checked the code.

 (defn set
   Returns a set of the distinct elements of coll.
   {:added 1.0
:static true}
   [coll] (clojure.lang.PersistentHashSet/create (seq coll)))

 And that was my first assumption. But if clojure doesn't know the return
 type, then why does this:

 (defn two []
   (java.util.Collections/unmodifiableSet
(set [])))

 Not require reflection? Clojure should not know which method to call.
 Unless it is just because unmodifiableSet has an arity of one and it's
 the only arity of one, so it doesn't try to disambiguate.

 I guess even if set was type hinted (to IPersistentSet) it would still
 not work since, IPersistentSet is not assignable from java.util.Set.

 Phil



 Nicola Mometto brobro...@gmail.com writes:

 Actually `set` and a lot of other clojure.core functions are neither
 inlineable nor have type hints.

 Phillip Lord writes:

 I have a piece of code that looks like this

 (.getOWLEquivalentClassesAxiom
   (owl-data-factory)
   (set classlist)
   (union-annotations classlist))

 The method signature is

 getOWLEquivalentClassesAxiom(Set,Set)

 On runing lein check I get


 Reflection warning, tawny/owl.clj:2219:6 - call to method
 getOWLEquivalentClassesAxiom on
 org.semanticweb.owlapi.model.OWLDataFactory can't be resolved (argument
 types: unknown, java.util.Set).

 which makes no sense. Surely, the return type of clojure.core/set is
 known to be java.util.Set? I have quite a few calls like this in my
 code, which is why I don't want to type hint the return of set
 individually.

 If I add a function like so:

 (defn ^java.util.Set hset [coll]
   (set coll))

 and call like this:

 (.getOWLEquivalentClassesAxiom
   (owl-data-factory)
   (hset classlist)
   (union-annotations classlist))

 The reflection warning goes away.


 I've tried to reproduce this with simpler cases, like so:


 (defn one []
   (java.util.Collections/unmodifiableSet
(java.util.HashSet.)))


 (defn two []
   (java.util.Collections/unmodifiableSet
(set [])))

 But both of these pass lein check just fine. Which suggests that clojure
 knows set returns a java.util.Set object.

 Now, given that I can't give a simple test case, I realise that it's
 hard for anyone to work out what is happening. But, worse, I don't know
 how to debug this at all. So, how I find out what clojure things the
 return type of a function is? Or probe any further why this is failing?

 Phil

 --

 --
 Phillip Lord,   Phone: +44 (0) 191 222 7827
 Lecturer in Bioinformatics, Email: phillip.l...@newcastle.ac.uk
 School of Computing Science,
 http://homepages.cs.ncl.ac.uk/phillip.lord
 Room 914 Claremont Tower,   skype: russet_apples
 Newcastle University,   twitter: phillord
 NE1 7RU

--

-- 
You 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: OJ - A friendly way to talk to your database using Clojure.

2014-11-04 Thread Taylor Lapeyre
It's funny, I actually didn't know about honeysql until today. When I found 
out that it existed, I got a little excited that someone else also came to 
the same conclusion independently. I think it says something good about 
this approach.

As far as design decisions, I think OJ has a more minimalistic approach and 
a stronger specification than honeysql. Also, OJ has support for nested 
joins -

{:table :users, :join {:items {:user_id :id}}}
= ({:username blah :items ({:id 1 :name Thing})} ...



On Tuesday, November 4, 2014 9:54:04 AM UTC-6, Niels van Klaveren wrote:

 Looks cool, any design decisions that made you create this instead of 
 using honeysql https://github.com/jkk/honeysql ?

 On Tuesday, November 4, 2014 3:45:35 AM UTC+1, Taylor Lapeyre wrote:



 GitHub project link:
 https://github.com/taylorlapeyre/oj

 The idea is to lay a solid foundation for talking to databases in Clojure 
 using regular Clojure data structures to represent queries. My goal is to 
 let this library become established enough that is becomes the foundation 
 for larger frameworks that abstract away the ideas found in SQL.

 Looking for feedback and for others to help me on this project! I hope 
 you find this useful, it has been very useful for me so far.



-- 
You 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: Deterministic Randomness in Functional Clojure

2014-11-04 Thread blake
Pardon my interruption: What are you using for screen output for your
roguelike?

On Tue, Oct 28, 2014 at 12:08 PM, Isaac Karth isaacka...@gmail.com wrote:

 I've been working on some projects (roguelikes, story-generators) that
 often have a reason to have a random outcome for things like procedurally
 generating a map. Ideally, they would be deterministically psuduorandom, so
 that I can generate the same results from the same seed. The part I'm
 having trouble with is figuring out what method to use to implement this in
 a functional way.

 The naive approach that first occurred to me was to pass a PRNG and seed
 value into each function. That would certainly keep the functions
 referentially transparent. But it would also require either rewriting a
 bunch of functions that don't directly use the randomness themselves or
 adding the RNG as part of the map that's already being passed.

 Plus, the seed should probably vary (deterministically) between calls to
 the subfunctions. It's not too useful if all the rooms on a map have the
 same type because they all pulled their die roll from the same-nth result
 of the exact same seed. Maybe the seed could be created from the contents
 of the vector or a UUID of a map object or something?

 The other suggestion I've run across is to rebind something like
 clojure.data.generators/*rnd* for each high-level procedural generation
 call. I think this requires the generation to be single threaded and
 otherwise deterministic. At the moment I don't feel like I know enough
 about how things work under the hood to say if this a good idea or not.

 I've poked around at the bigml.sampling and clojure.data.generators
 libraries, which look useful for dealing with some of this, but I haven't
 come across anything that directly addresses what kind of architecture to
 use for deterministic randomness. This may be my inexperience. I feel like
 I may be a bit too close to the problem, and I can't quite see what the
 idiomatic answer is. Re-read SICP? Implement some kind of monad? Just bite
 the bullet and pass the RNG+seed? Find the secret pure functional library
 everyone is using for repeatable stochastic simulations?

 Does anyone have any advice on this? Or prior experience with approaches
 that work? What are some best practices for approaching deterministic
 simulations in an idiomatic, functional way?

 --
 You 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: Clojure usage in production - survey on Hacker News (Nov 2014)

2014-11-04 Thread Alex Miller
I've added the list of companies using Clojure to clojure.org 
at http://clojure.org/Companies - feel free to ping me at 
alex.mil...@cognitect.com or here if you want something 
added/removed/changed.

Alex

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


Re: Testing and infrastructure management for large Clojure app - how are you doing it?

2014-11-04 Thread David Mitchell
Thanks Colin

I probably should've added that this is a large enterprise doing what's 
essentially an in-house startup - building an app using Clojure.  The app 
initially sat somewhat off to the side of the corporation's main line of 
business, but there was always the intent to incorporate the new app into 
the existing core infrastructure at some future date.  It was left open as 
to how that would actually happen, and now we're having to confront that 
problem directly.  While we have something of a startup mentality within 
the project with respect to what gets done day to day and how it gets done, 
there's an overarching set of tools/processes/requirements/constraints that 
come hand in hand with working for a large enterprise.

One of those is that we've got an existing pool of testers already within 
the enterprise, and need to find some alignment between their existing 
tools/capabilities/processes/... and the requirements of our new shiny 
Clojure app.  We've got testers who've been on the project virtually since 
it began (who've NOT used Clojure but instead have focused on testing 
interfaces using SoapUI and the web client) but now the project has grown 
to the point where we need both (a) more testers just to keep pace with 
development, (b) testers with different backgrounds (mobile being the big 
one) and (c) the testers need to come from the existing enterprise pool. 
 I'm sure we COULD cross train at least some of these testers to do their 
work within Clojure, but there's currently zero long-term tangible benefit 
for either their career path or the enterprise in doing so.  If the 
enterprise had a pool of upcoming Clojure projects, then it would probably 
be a different story.

Absolutely agree that there's a lot of time and expense in testing that's 
not always focused appropriately, and that's ultimately what I'm trying to 
fix/avoid in this project.  Personally, I wish we'd all stop using the 
phrase testing and instead use risk mitigation to try to keep the 
desired outcome of the activity clear in everyone's mind at key decision 
points, but this isn't the forum for THAT discussion ;-

Thanks again for your response

Dave M.



On Wednesday, 29 October 2014 20:07:34 UTC+11, Colin Yates wrote:

 I also meant to say that it is worth doing a cost-benefit analysis on 
 testing. When I did my consultant thing I frequently saw massive investment 
 in tools, process, emotion(!) etc. in things that on paper were a good 
 thing but in reality weren't mitigating any real risk.

 All testing isn't equal - what risks do you currently face right now (e.g. 
 are you playing whack-a-moley due to developer's poor impact analysis, or 
 for example, are the developers consistently producing great code which 
 doesn't piece together well and so on)? Put your energies into resolving 
 those risks.

 Most testing processes and resources I see are by definition re-active - 
 they find effects (bugs) of the cause (which is typically developer 
 insufficiency in terms of requirements). In my view resources should all be 
 about mitigating the cause. Why not get your testers (although I really 
 don't like segmenting resources by calling them testers) to sit with a 
 developer just before they do a new piece of work and think through the 
 impact analysis? Have your testers take the use cases and start building 
 the test scenarios immediately. Have your testers review the developers 
 unit tests - if it doesn't make sense to a (technically orientated) tester 
 than the developer is probably doing it wrong and so on. 

 Simply spotting effects is helpful but all resources should be focused on 
 mitigating the cause of those effects and more often than not I see a whole 
 bunch of testing activity which isn't really solving any real problems 
 but is certainly slowing down the flow. Please let me clear - I am not 
 challenging the _requirements_ of the traditional testing process (e.g. 
 ensuring quality), I am claiming the way most people do it is incredibly 
 expensive and inefficient.

 I can hear the internet taking a breath saying No!, he didn't just go 
 there :).

 On Wednesday, 29 October 2014 00:12:52 UTC, David Mitchell wrote:

 Hi Colin

 Thanks for your reply.

 My post is almost exclusively technology oriented because I think the 
 technology is what's killing us!

 We've got what you'd probably call BDD lite working, in that we've got 
 a mutant form of agile process running whereby we work in 2 week sprints, 
 but there's rarely an installable product that emerges at the end of the 2 
 weeks.  I won't go into detail as to what I feel are the root causes in a 
 public forum - however I'm convinced that our adoption of Clojure is at 
 least partly to blame.

 Just to make it clear, I absolutely believe Clojure is a good tool to use 
 for this project, and personally I'll be actively seeking out other Clojure 
 projects in the future.  I'm saying that from the viewpoint of someone 
 who's 

Re: Testing and infrastructure management for large Clojure app - how are you doing it?

2014-11-04 Thread David Mitchell
Thanks Linus,

You make a really good point - why can't testers use the REPL?  I'd like to 
think that was possible too - after all, *I* can do it so why can't anyone 
else?

That said, I'm slightly blessed in that I've done a lot of work in Erlang 
and R over many years, so I was already comfortable with functional 
programming.  Even then, I found it quite a learning curve to get a level 
of competency with Clojure - the language itself is pretty easy, but 
working out what libraries exist for a specific domain and how best to 
leverage them is hard work.

If we had a bunch of pre-canned test scripts that the testers had to run 
and check the results, then the REPL wouldn't be at all important - testers 
would simply e.g. type commands into the REPL and make sure the responses 
were appropriate.  Unfortunately, we want our testers to do a lot more 
exploratory-style testing; for example, send some data through a published 
API and confirm it gets written to the database correctly, then send some 
incorrect data through the same API and confirm it DOESN'T get written to 
the database.  Doing these sorts of tasks require either (a) a fair grasp 
of Clojure *and* several libraries if the tester is working alone, or (b) a 
fairly tight partnership with a developer who would essentially tell the 
tester what to type, or (c) a set of domain-specific tools built to 
simplify this testing to the point where the tester can do these tasks with 
minimal assistance.  

Now, if you or I was given this testing task to perform *and* we knew it 
was going to be an ongoing demand on our time, we'd probably take option 
(c) and build some tools to make our lives as simple as possible.  That 
presupposes that we have the Clojure and domain knowledge to do so, which 
our testers don't have.  Option (b) is what we're essentially doing today - 
being tied so closely to QA with a developer, it's inherently non-scalable 
and we're now hitting the limitations of how far this approach will take 
us.  Option (a) - ... well, I'd love it if we had testers who already knew 
Clojure, or a stream of Clojure projects whereby acquiring these skills 
made sense for the testers' long term career prospects.

What's really frustrating is that the app we're building is actually pretty 
simple, and a competent tester doesn't require deep domain knowledge in 
order to work out what needs to be tested.  The problem is in their working 
out how to attack it, within a set of constraints that are probably pretty 
common to most work environments.

Thanks again

Dave M.

On Thursday, 30 October 2014 17:55:48 UTC+11, Linus Ericsson wrote:


 I really cant see how the testers could NOT be able to use a repl to do 
 some exploratory testing.

 Clojure's strength is really that you can align the code very closely to 
 the domain, although this modelling is (as always) challenging.

 And the application logic does not have to be tested through and 
 http-based interface, sometimes it's a good start to test it through the 
 Repl.

 If this is hard to use, then everything will be hard with the application.

 /Linus
 Den 29 okt 2014 10:07 skrev Colin Yates colin...@gmail.com 
 javascript::

 I also meant to say that it is worth doing a cost-benefit analysis on 
 testing. When I did my consultant thing I frequently saw massive investment 
 in tools, process, emotion(!) etc. in things that on paper were a good 
 thing but in reality weren't mitigating any real risk.

 All testing isn't equal - what risks do you currently face right now 
 (e.g. are you playing whack-a-moley due to developer's poor impact 
 analysis, or for example, are the developers consistently producing great 
 code which doesn't piece together well and so on)? Put your energies into 
 resolving those risks.

 Most testing processes and resources I see are by definition re-active - 
 they find effects (bugs) of the cause (which is typically developer 
 insufficiency in terms of requirements). In my view resources should all be 
 about mitigating the cause. Why not get your testers (although I really 
 don't like segmenting resources by calling them testers) to sit with a 
 developer just before they do a new piece of work and think through the 
 impact analysis? Have your testers take the use cases and start building 
 the test scenarios immediately. Have your testers review the developers 
 unit tests - if it doesn't make sense to a (technically orientated) tester 
 than the developer is probably doing it wrong and so on. 

 Simply spotting effects is helpful but all resources should be focused on 
 mitigating the cause of those effects and more often than not I see a whole 
 bunch of testing activity which isn't really solving any real problems 
 but is certainly slowing down the flow. Please let me clear - I am not 
 challenging the _requirements_ of the traditional testing process (e.g. 
 ensuring quality), I am claiming the way most people do it is incredibly 
 expensive and 

Re: Introducing Boot v2 with a streamlined CLJS workflow

2014-11-04 Thread Micha Niskin
Hi, sorry for the late reply! Boot pretty much takes care of that part for
you, as long as you follow a few basic rules (I will be adding a “how to be
a good citizen of the boot-o-sphere” section to the wiki on github soon):

   1.

   Tasks don’t fish around in the filesystem directly to find things to
   compile or otherwise operate on. Instead, tasks use functions in
   boot.core that return immutable sets of java.io.File objects from
   boot-managed temp directories. These functions present a sort of overlay
   filesystem with files in anonymous temporary directories. This allows tasks
   to be completely decoupled from the filesystem layout. Additionally, this
   makes it possible for boot to shuffle files around and use hardlinks and
   such to craft the classpath and the build fileset in different ways during
   the build cycle. In this way boot can emulate immutability and lexical and
   dynamic scope for things on the filesystem.
2.

   Tasks don’t create files in the filesystem directly. Instead, tasks use
   functions in boot.core that create various flavors of anonymous,
   boot-managed temp directories (the ones mentioned in item 1, in fact). An
   important concept in boot is that the output of any task is part of the
   input for the next task in the pipeline. This is the property that supports
   the amazing composition of tasks that is possible with boot, without
   needing to generate miles of boilerplate configuration.
3.

   The boot-managed temp directory lifespan is one build session only. This
   means one JVM, basically. The temp directories are stored in the .boot
   directory in the project root. The next time you run boot it cleans out any
   old temp dirs in there (they are not cleaned up on exit because you may
   want to look in them if something goes wrong with the build; stack traces
   could be referencing source files in these temp dirs).
4.

   The only directories that boot knows about that are not temp dirs it
   created are the ones you specify in the build.boot file via set-env!
   (i.e. the :src-paths, :rsc-paths, and :tgt-path keys). The source and
   resource paths are not molested by boot in any way (no files in there are
   ever deleted, moved, modified etc.). The target directory, on the other
   hand, is completely owned by boot—boot will overwrite files or delete them
   in there as it sees fit. Boot ensures that the target directory always
   contains only those files the build process emits for that specific run,
   and doesn’t allow any stale files to hang out in there.

What this all means is that there is something of a tradeoff: boot never
persists files that could become stale, so there is no need for a clean
task, but on the other hand some things then need to be rebuilt instead of
just hanging out in the target dir. We think this is an okay tradeoff
because boot’s composition capabilities make it really easy to
incrementally run any build process at all using the built-in watch task.
In return you get 100% deterministic builds.

We’ll be talking about the details of the whole temporary filesystem
machinery soon. Have fun playing with boot!
​

--
Micha Niskin

On Mon, Nov 3, 2014 at 5:45 PM, Laurent PETIT laurent.pe...@gmail.com
wrote:

 And more seriously, I remember reading that you put an emphasis on
 removing the need to use a clean task.
 If I'm right, then I'd be interested in knowing how one is encouraged /
 helped to pursue this good property in its own tasks ?

 Le lundi 3 novembre 2014, Laurent PETIT laurent.pe...@gmail.com a
 écrit :

 Tongue in cheek question: if Leiningen were the maven of clojure, would
 you say boot2 is gradle ? :-)

 Le lundi 3 novembre 2014, Micha Niskin micha.nis...@gmail.com a écrit :

 Hi!

 Boot (http://github.com/boot-clj/boot) is a build tool for Clojure.
 We've pulled together lessons learned from a year or so using boot v1 in
 production and are now getting ready to release v2. To show what boot can
 do we present a very streamlined and awesome boot-based ClojureScript
 development workflow (
 http://adzerk.com/blog/2014/11/clojurescript-builds-rebooted/).

 Try it out, maybe you'll like it! We're hoping to get some feedback
 before committing to a stable release, so please if you have any comments
 or questions we'd be happy to hear them. Have fun!

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

Re: Garden defcssfn not rendering

2014-11-04 Thread Rory Douglas
Ugh, just a case of RTFM.  (css) needs a vector of CSS rules, so the 
following won't work 

(css (scale 2))


The correct minimal test is:

(css [:#testdiv {:transform (scale 2)}])
;; #testdiv {\n  transform: scale(2, 2);\n} 

-- 
You 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: Garden defcssfn not rendering

2014-11-04 Thread Rory Douglas
Ugh, just a case of RTFM.  (css) needs a vector of CSS rules, so the 
following won't work 

(css (scale 2))


The correct minimal test is:

(css [:#testdiv {:transform (scale 2)}])
;; #testdiv {\n  transform: scale(2, 2);\n} 

-- 
You 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: Neighbors function from The Joy of Clojure

2014-11-04 Thread Pierre Thibault
Ouch! I found this code hard to understand. I read to previous part of the 
book. I guess it is normal when you are new to 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: Deterministic Randomness in Functional Clojure

2014-11-04 Thread Atamert Ölçgen
clojure-lanterna is pretty cool.

https://github.com/sjl/clojure-lanterna

I'm interested in hearing about alternatives as well.


On Wed, Nov 5, 2014 at 4:09 AM, blake dsblakewat...@gmail.com wrote:

 Pardon my interruption: What are you using for screen output for your
 roguelike?

 On Tue, Oct 28, 2014 at 12:08 PM, Isaac Karth isaacka...@gmail.com
 wrote:

 I've been working on some projects (roguelikes, story-generators) that
 often have a reason to have a random outcome for things like procedurally
 generating a map. Ideally, they would be deterministically psuduorandom, so
 that I can generate the same results from the same seed. The part I'm
 having trouble with is figuring out what method to use to implement this in
 a functional way.

 The naive approach that first occurred to me was to pass a PRNG and seed
 value into each function. That would certainly keep the functions
 referentially transparent. But it would also require either rewriting a
 bunch of functions that don't directly use the randomness themselves or
 adding the RNG as part of the map that's already being passed.

 Plus, the seed should probably vary (deterministically) between calls to
 the subfunctions. It's not too useful if all the rooms on a map have the
 same type because they all pulled their die roll from the same-nth result
 of the exact same seed. Maybe the seed could be created from the contents
 of the vector or a UUID of a map object or something?

 The other suggestion I've run across is to rebind something like
 clojure.data.generators/*rnd* for each high-level procedural generation
 call. I think this requires the generation to be single threaded and
 otherwise deterministic. At the moment I don't feel like I know enough
 about how things work under the hood to say if this a good idea or not.

 I've poked around at the bigml.sampling and clojure.data.generators
 libraries, which look useful for dealing with some of this, but I haven't
 come across anything that directly addresses what kind of architecture to
 use for deterministic randomness. This may be my inexperience. I feel like
 I may be a bit too close to the problem, and I can't quite see what the
 idiomatic answer is. Re-read SICP? Implement some kind of monad? Just bite
 the bullet and pass the RNG+seed? Find the secret pure functional library
 everyone is using for repeatable stochastic simulations?

 Does anyone have any advice on this? Or prior experience with approaches
 that work? What are some best practices for approaching deterministic
 simulations in an idiomatic, functional way?

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




-- 
Kind Regards,
Atamert Ölçgen

-+-
--+
+++

www.muhuk.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: Deterministic Randomness in Functional Clojure

2014-11-04 Thread Fluid Dynamics
On Tuesday, November 4, 2014 9:54:39 PM UTC-5, Atamert Ölçgen wrote:

 clojure-lanterna is pretty cool.

 https://github.com/sjl/clojure-lanterna

 I'm interested in hearing about alternatives as well.


Terminal emulation? In this day and age?

And a quick look around reveals no sign of mouse support. Even old MS-DOS 
applications often had some kind of mouse support (QBASIC for one). With so 
many people increasingly using tablets that lack keyboards, I'd think any 
game should try to be playable with little or no keyboard input required. 

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


Re: About transients no longer being safe in 1.7-alpha2

2014-11-04 Thread Daniel Marjenburgh
Hi Alex,

I understand any concurrent use of transients violates the usage 
expectations. Of course, if you treat any piece of mutable state 
sequentially like transients, you would not run into trouble either.
My concern is purely about the safety that is taken away when transients 
'are' used wrongly. All the examples would've throw exceptions before 
1.7-alpha2, and they don't do so anymore.

Having a single go-block access a transient is valid. Having 2 go-blocks 
access the same transient is not and there is no warning.
If at a certain point you want to 'scale' up from 1 go-block to 2 and don't 
realise it was accessing transients, you are potentially in a lot of 
trouble and there is nothing to warn you.

FWIW, a flag on creating transients to make the dangers explicit would have 
my vote. It would also be in line with being explicit about 
^:volatile-mutable and have the default be safe.

-- 
You 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: About transients no longer being safe in 1.7-alpha2

2014-11-04 Thread Atamert Ölçgen
Hi Daniel,


On Wed, Nov 5, 2014 at 3:06 PM, Daniel Marjenburgh dmarjenbu...@gmail.com
wrote:

 My concern is purely about the safety that is taken away when transients
 'are' used wrongly. All the examples would've throw exceptions before
 1.7-alpha2, and they don't do so anymore.


But they would run fine, if you used delay's instead of future's. Same
wrong usage, single threaded. So the issue is not really this new change.

(See my code with delay's earlier)


-- 
Kind Regards,
Atamert Ölçgen

-+-
--+
+++

www.muhuk.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.