Re: Transitive spec generation

2018-03-03 Thread James Gatannah
In case anyone was wondering, it looks like this is probably a known issue:

https://dev.clojure.org/jira/browse/CLJ-2079

On Wednesday, February 28, 2018 at 12:05:31 AM UTC-6, James Gatannah wrote:
>
>
>
> On Tuesday, February 27, 2018 at 12:45:26 AM UTC-6, Didier wrote:
>>
>> Don't fully understand what you are doing,
>>
>
> (Slightly) bigger picture, I have a pair of functions that 
> serialize/deserialize maps where the values are mostly fixed-length byte 
> arrays.
>
> I want to verify that they round-trip correctly.
>
> This specific example is about two of those fields which really have the 
> same spec. I'm trying to define this in a way that's similar to a C typedef 
> (or possibly just something like using OOP inheritance for the sake of 
> documentation):
>
> (s/def ::extension ...)
> (s/def ::server-extension ::extension)
> (s/def ::client-extension ::extension)
>
> I'm doing this in an attempt to trying to reduce my nesting levels.
>
> This is what the weird subject is about: I'm trying to take advantage of 
> the transitive property of specs.
>
>  
>
>> but when you run test.check, it seems to not always be generating random 
>> sample, it'll grow the samples. When you run sample, it'll always start 
>> back from the beginning. 
>>
>
>> You can see that by running:
>>
>> (sgen/sample (s/gen ::test) 100)
>>
>> See how the generated samples are getting longer and longer?
>>
>
> Now instead try running this 10 times:
> (sgen/sample (s/gen ::test) 10)
>
> And notice how you always get the same short samples?
>
>  
>
> (I'm sorry about the quote mangling).
>
> Since I have to have a specific length, I'm specifying that as a parameter 
> to sgen/vector.
>
> This part of it works. I can run s/sample on my generator and validate its 
> output against the spec without any trouble.
>
> Actually, if I define the ::extension spec using with-gen, it also looks 
> as though it works (I just ran across this, so haven't tested it 
> thoroughly). But then my library has a runtime dependency on test.check. 
> That's not the end of the world, but it's a definite downside.
>
> I haven't been able to find real documentation covering the arguments to 
> s/gen. But it looks as though I can pass in a map of 0-arity functions to 
> override the different generators. The keys to that map override specs 
> being generated. I can't remember now where I found this, but it can't be 
> totally undocumented. I haven't studied the source code thoroughly enough 
> to have picked out that sort of detail.
>
> So:
>
> (s/gen (s/keys :req [::server-extension
>  ::client-extension])
>{::server-extension #(gen/fmap byte-array (gen/vector (gen/choose 
> -128 127) extension-length))
> ::client-extension #(gen/fmap byte-array (gen/vector (gen/choose 
> -128 127) extension-length))})
>
>
> calls the function in the value associated with each key to override the 
> generator for that spec.
>
> This is the part that seems to only work sometimes.
>
> When I extend this to include all the keys in the full spec, these are the 
> only two that have problems. They're also the only ones that are directly 
> defined as another spec definition. (Which is why I'm pointing my finger at 
> my attempt to use the "transitive" property, though that could totally be a 
> red herring).
>
> When I run this inside deftest, it seems fine. Really, that's all I need. 
> But I'd really like to understand the seemingly non-deterministic failures.
>
> I wrote a function called manual-check that takes that generator and calls 
> sgen/sample on it.
>
> When I call that function directly from the REPL, it very nearly always 
> fails.
>
> When I call it 40 times in a reduce inside deftest, I haven't seen it fail 
> yet.
>
> * While I was writing this, I stumbled across another piece that seems 
> like an interesting clue:
>
> If I override the generator for ::extension rather than the individual 
> specs that I've defined transitively, it seems to start working.
>
> i.e. 
>
> (s/gen (s/keys :req [::server-extension
>  ::client-extension])
>{::extension #(gen/fmap byte-array (gen/vector (gen/choose -128 
> 127) extension-length))})
>  
> seems to work.
>
> It's still less than ideal, in case I ever want to change the underlying 
> spec that's the "base" definition, since I'll have to remember to change 
> the base generator. But I really shouldn't have this sort of thing 
> scattered around everywhere. Especially since it's most interesting inside 
> deftest anyway, where both appr

Re: Transitive spec generation

2018-02-27 Thread James Gatannah


On Tuesday, February 27, 2018 at 12:45:26 AM UTC-6, Didier wrote:
>
> Don't fully understand what you are doing,
>

(Slightly) bigger picture, I have a pair of functions that 
serialize/deserialize maps where the values are mostly fixed-length byte 
arrays.

I want to verify that they round-trip correctly.

This specific example is about two of those fields which really have the 
same spec. I'm trying to define this in a way that's similar to a C typedef 
(or possibly just something like using OOP inheritance for the sake of 
documentation):

(s/def ::extension ...)
(s/def ::server-extension ::extension)
(s/def ::client-extension ::extension)

I'm doing this in an attempt to trying to reduce my nesting levels.

This is what the weird subject is about: I'm trying to take advantage of 
the transitive property of specs.

 

> but when you run test.check, it seems to not always be generating random 
> sample, it'll grow the samples. When you run sample, it'll always start 
> back from the beginning. 
>

> You can see that by running:
>
> (sgen/sample (s/gen ::test) 100)
>
> See how the generated samples are getting longer and longer?
>

Now instead try running this 10 times:
(sgen/sample (s/gen ::test) 10)

And notice how you always get the same short samples?

 

(I'm sorry about the quote mangling).

Since I have to have a specific length, I'm specifying that as a parameter 
to sgen/vector.

This part of it works. I can run s/sample on my generator and validate its 
output against the spec without any trouble.

Actually, if I define the ::extension spec using with-gen, it also looks as 
though it works (I just ran across this, so haven't tested it thoroughly). 
But then my library has a runtime dependency on test.check. That's not the 
end of the world, but it's a definite downside.

I haven't been able to find real documentation covering the arguments to 
s/gen. But it looks as though I can pass in a map of 0-arity functions to 
override the different generators. The keys to that map override specs 
being generated. I can't remember now where I found this, but it can't be 
totally undocumented. I haven't studied the source code thoroughly enough 
to have picked out that sort of detail.

So:

(s/gen (s/keys :req [::server-extension
 ::client-extension])
   {::server-extension #(gen/fmap byte-array (gen/vector (gen/choose 
-128 127) extension-length))
::client-extension #(gen/fmap byte-array (gen/vector (gen/choose 
-128 127) extension-length))})


calls the function in the value associated with each key to override the 
generator for that spec.

This is the part that seems to only work sometimes.

When I extend this to include all the keys in the full spec, these are the 
only two that have problems. They're also the only ones that are directly 
defined as another spec definition. (Which is why I'm pointing my finger at 
my attempt to use the "transitive" property, though that could totally be a 
red herring).

When I run this inside deftest, it seems fine. Really, that's all I need. 
But I'd really like to understand the seemingly non-deterministic failures.

I wrote a function called manual-check that takes that generator and calls 
sgen/sample on it.

When I call that function directly from the REPL, it very nearly always 
fails.

When I call it 40 times in a reduce inside deftest, I haven't seen it fail 
yet.

* While I was writing this, I stumbled across another piece that seems like 
an interesting clue:

If I override the generator for ::extension rather than the individual 
specs that I've defined transitively, it seems to start working.

i.e. 

(s/gen (s/keys :req [::server-extension
 ::client-extension])
   {::extension #(gen/fmap byte-array (gen/vector (gen/choose -128 127) 
extension-length))})
 
seems to work.

It's still less than ideal, in case I ever want to change the underlying 
spec that's the "base" definition, since I'll have to remember to change 
the base generator. But I really shouldn't have this sort of thing 
scattered around everywhere. Especially since it's most interesting inside 
deftest anyway, where both approaches always seem to work (I haven't tested 
this out thoroughly yet either).

My current hypothesis is that there's something about the deftest macro 
that interacts with test.check in a way that makes gen more capable in 
terms of resolving which spec I actually mean/want to override. I know 
(based on digging through internals) that it calls something (I think it's 
named specize) that resolves the spec's name. Then it has to use that 
name/those names in the overriding map parameter to pick out the 
appropriate function to call to get the generator.

I'm very skeptical, but could that possibly hold water?

Thank you to anyone who actually took the time to read this!

 

>
>
> On Monday, 26 February 2018 21:39:09 UTC-8, James Ga

Re: Transitive spec generation

2018-02-26 Thread Didier
Don't fully understand what you are doing, but when you run test.check, it 
seems to not always be generating random sample, it'll grow the samples. 
When you run sample, it'll always start back from the beginning.

You can see that by running:

(sgen/sample (s/gen ::test) 100)

See how the generated samples are getting longer and longer?

Now instead try running this 10 times:

(sgen/sample (s/gen ::test) 10)

And notice how you always get the same short samples?


On Monday, 26 February 2018 21:39:09 UTC-8, James Gatannah wrote:
>
> Fairly minimalist example available at 
> https://gist.github.com/jimrthy/21851c52a8cd6b04a31ed08b1d0a7f04
>
> When I call gen/sample from inside a unit test, it seems to pass with 
> flying colors.
>
> When I directly eval the gen/sample form or call (manual-check) from the 
> REPL (I checked both CIDER and the boot CLI, just in case), I usually get 
> the "Couldn't satisfy such-that predicate after 100 tries."
>
> To be a little more specific about this:
>
> Calling (manual-check) failed 49/50 times.
>
> Calling (transitive-indirect) passed 50 times in a row. If you haven't 
> bothered looking at the gist, each of those calls (manual-check) 40 times.
>
> I was quite surprised by this. Does anyone have any suggestions about why 
> wrapping the call in a unit test might help it succeed more often?
>
> If I just call gen/sample on the generator I'm trying to use, followed by 
> s/valid? for one of the specs I'm trying to generate, it seems fine. I 
> haven't dug into the source here (and I'm not positive what all's going on 
> inside the spec.gen namespace), but I thought that's what gen/generate does 
> when you define a custom generator for your spec.
>
> Except that isn't really what I'm doing.
>
> I'm trying to avoid adding extra runtime dependencies on a library like 
> tools.check, so I'm trying to do this with overrides in the test namespaces 
> to try to limit the extra dependencies to test time.
>
> Could that be where I'm breaking core assumptions that don't seem to cause 
> trouble for anyone else?
>
> Thanks,
> James
>
>
>
> On Sunday, February 25, 2018 at 6:45:39 PM UTC-6, James Gatannah wrote:
>>
>> I have a spec for an array of 16 bytes:
>>
>> (s/def ::extension (s/and bytes?
>>#(= (count %) 16))
>>
>> Then I have a couple of other specs that are really just renaming it:
>>
>> (s/def ::client-extension ::extension)
>> (s/def ::server-extension ::extension)
>>
>> I started doing some refactoring today, and the definitions wound up 
>> needing to move to a different namespace.
>>
>> So now the original definitions have changed to
>>
>> (s/def ::client-extension ::refactored/client-extension)
>>
>> I also started dabbling with generators, and came up with this:
>>
>> (gen/generate (s/gen ::client-extension
>>   {::client-extension #(gen/fmap 
>> byte-array (gen/vector (gen/choose -128 127) 16)}))
>>
>> When I define things this way, I get a "Couldn't satisfy such-that 
>> predicate after 100 tries." exception a little more than half the time.
>>
>> If I rearrange things so that either
>> a) The refactored namespace defines the spec directly
>> or
>> b) I change my generator override to specify the top-level spec that the 
>> others are copying
>>
>> i.e.
>> a) would mean changing the refactored ns such that I have
>> (s/def ::client-extension (s/and bytes?
>>  #(= (count %) 16))
>>
>> b) changing the generator to
>> (gen/generate (s/gen ::client-extension
>>   {::refactored/extension #(gen/fmap 
>> byte-array (gen/vector (gen/choose -128 127) 16)}))
>>
>> it seems to fail (with the same problem) about 1 time in 5.
>>
>> I haven't seen it fail yet if I undo my refactoring and move the spec 
>> back to the original location.
>>
>> I haven't collected any sorts of real numbers on this, much less tried to 
>> make enough test runs to collect a statistically significant sample. I know 
>> the next real steps are to put together a minimalist example.
>>
>> But before I do that, I figured it might be asking whether anyone sees 
>> anything obviously wrong in what I'm trying to do, or whether there's a 
>> better way to do it.
>>
>> Thanks in advance,
>> James
>>
>>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googl

Re: Transitive spec generation

2018-02-26 Thread James Gatannah
Fairly minimalist example available 
at https://gist.github.com/jimrthy/21851c52a8cd6b04a31ed08b1d0a7f04

When I call gen/sample from inside a unit test, it seems to pass with 
flying colors.

When I directly eval the gen/sample form or call (manual-check) from the 
REPL (I checked both CIDER and the boot CLI, just in case), I usually get 
the "Couldn't satisfy such-that predicate after 100 tries."

To be a little more specific about this:

Calling (manual-check) failed 49/50 times.

Calling (transitive-indirect) passed 50 times in a row. If you haven't 
bothered looking at the gist, each of those calls (manual-check) 40 times.

I was quite surprised by this. Does anyone have any suggestions about why 
wrapping the call in a unit test might help it succeed more often?

If I just call gen/sample on the generator I'm trying to use, followed by 
s/valid? for one of the specs I'm trying to generate, it seems fine. I 
haven't dug into the source here (and I'm not positive what all's going on 
inside the spec.gen namespace), but I thought that's what gen/generate does 
when you define a custom generator for your spec.

Except that isn't really what I'm doing.

I'm trying to avoid adding extra runtime dependencies on a library like 
tools.check, so I'm trying to do this with overrides in the test namespaces 
to try to limit the extra dependencies to test time.

Could that be where I'm breaking core assumptions that don't seem to cause 
trouble for anyone else?

Thanks,
James



On Sunday, February 25, 2018 at 6:45:39 PM UTC-6, James Gatannah wrote:
>
> I have a spec for an array of 16 bytes:
>
> (s/def ::extension (s/and bytes?
>#(= (count %) 16))
>
> Then I have a couple of other specs that are really just renaming it:
>
> (s/def ::client-extension ::extension)
> (s/def ::server-extension ::extension)
>
> I started doing some refactoring today, and the definitions wound up 
> needing to move to a different namespace.
>
> So now the original definitions have changed to
>
> (s/def ::client-extension ::refactored/client-extension)
>
> I also started dabbling with generators, and came up with this:
>
> (gen/generate (s/gen ::client-extension
>   {::client-extension #(gen/fmap 
> byte-array (gen/vector (gen/choose -128 127) 16)}))
>
> When I define things this way, I get a "Couldn't satisfy such-that 
> predicate after 100 tries." exception a little more than half the time.
>
> If I rearrange things so that either
> a) The refactored namespace defines the spec directly
> or
> b) I change my generator override to specify the top-level spec that the 
> others are copying
>
> i.e.
> a) would mean changing the refactored ns such that I have
> (s/def ::client-extension (s/and bytes?
>  #(= (count %) 16))
>
> b) changing the generator to
> (gen/generate (s/gen ::client-extension
>   {::refactored/extension #(gen/fmap 
> byte-array (gen/vector (gen/choose -128 127) 16)}))
>
> it seems to fail (with the same problem) about 1 time in 5.
>
> I haven't seen it fail yet if I undo my refactoring and move the spec back 
> to the original location.
>
> I haven't collected any sorts of real numbers on this, much less tried to 
> make enough test runs to collect a statistically significant sample. I know 
> the next real steps are to put together a minimalist example.
>
> But before I do that, I figured it might be asking whether anyone sees 
> anything obviously wrong in what I'm trying to do, or whether there's a 
> better way to do it.
>
> Thanks in advance,
> James
>
>

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


Transitive spec generation

2018-02-25 Thread James Gatannah
I have a spec for an array of 16 bytes:

(s/def ::extension (s/and bytes?
   #(= (count %) 16))

Then I have a couple of other specs that are really just renaming it:

(s/def ::client-extension ::extension)
(s/def ::server-extension ::extension)

I started doing some refactoring today, and the definitions wound up 
needing to move to a different namespace.

So now the original definitions have changed to

(s/def ::client-extension ::refactored/client-extension)

I also started dabbling with generators, and came up with this:

(gen/generate (s/gen ::client-extension
  {::client-extension #(gen/fmap byte-array 
(gen/vector (gen/choose -128 127) 16)}))

When I define things this way, I get a "Couldn't satisfy such-that 
predicate after 100 tries." exception a little more than half the time.

If I rearrange things so that either
a) The refactored namespace defines the spec directly
or
b) I change my generator override to specify the top-level spec that the 
others are copying

i.e.
a) would mean changing the refactored ns such that I have
(s/def ::client-extension (s/and bytes?
 #(= (count %) 16))

b) changing the generator to
(gen/generate (s/gen ::client-extension
  {::refactored/extension #(gen/fmap 
byte-array (gen/vector (gen/choose -128 127) 16)}))

it seems to fail (with the same problem) about 1 time in 5.

I haven't seen it fail yet if I undo my refactoring and move the spec back 
to the original location.

I haven't collected any sorts of real numbers on this, much less tried to 
make enough test runs to collect a statistically significant sample. I know 
the next real steps are to put together a minimalist example.

But before I do that, I figured it might be asking whether anyone sees 
anything obviously wrong in what I'm trying to do, or whether there's a 
better way to do it.

Thanks in advance,
James

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


Re: :npm-deps and transitive dependencies

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

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

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

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

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


Re: :npm-deps and transitive dependencies

2018-01-16 Thread Lucas Wiener
I now realise that this question might belong to the ClojureScript group, 
so I'm posting it there as well. Feel free to remove this thread if you 
want.

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

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


:npm-deps and transitive dependencies

2018-01-15 Thread Lucas Wiener
Hi,

I have the following clojurescript project dependency setup: X -> Y (X has 
stated Y in :dependencies). Now, I would like Y to depend on a npm 
javascript library Z. Following the guides, I added :npm-deps to one of the 
builds specified in Y. When I build and run Y, everything works fine with 
the new Z dependency. However, building/running project X now fails since 
the dependency Z cannot be found. From what I currently know, there are two 
approaches to get X running again:

1) Specify Z as an :npm-deps also in the project X builds. This is not very 
elegant since the union of all dependencies now cascade to the top level 
projects. Also, this approach would fail when transitive dependencies need 
different versions of the same dependency.
2) Compile Y into a bundle. Then X would depend on the prebuilt bundle of Y 
(which already includes Z). This is not perfect since it requires an extra 
processing step in Y, making lein checkouts a bit more troublesome etc. 
Also, my intuition tells me that this might affect code splitting, 
compilation optimizations, dead code elimination, etc. in a negative way.

Am I missing something?

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


Re: Clojure CLI tool fails to resolve weird transitive dependencies.

2017-12-11 Thread Jonathan Fischer
Yep, that looks like what I'm seeing. Thanks!

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


Re: Clojure CLI tool fails to resolve weird transitive dependencies.

2017-12-11 Thread David Bürgin
Hm, looks like this is an open issue:
https://dev.clojure.org/jira/browse/TDEPS-12


-- 
David

-- 
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 CLI tool fails to resolve weird transitive dependencies.

2017-12-11 Thread Jonathan Fischer
Ha, I think that must’ve snuck in there during editing. Fixing that particular 
typo didn’t help any. :D

> On Dec 11, 2017, at 12:22 PM, David Bürgin  wrote:
> 
> On 11/12/17 20:47, Jonathan Fischer wrote:
>> com.badlogicgames.gdx/gdx {:mvn/versin "1.9.6"}
> 
> Typo?
> 
> 
> -- 
> David
> 
> -- 
> 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 a topic in the Google 
> Groups "Clojure" group.
> To unsubscribe from this topic, visit 
> https://groups.google.com/d/topic/clojure/t_DA1T36VKQ/unsubscribe.
> To unsubscribe from this group and all its topics, 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 CLI tool fails to resolve weird transitive dependencies.

2017-12-11 Thread David Bürgin
On 11/12/17 20:47, Jonathan Fischer wrote:
> com.badlogicgames.gdx/gdx {:mvn/versin "1.9.6"}

Typo?


-- 
David

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


Clojure CLI tool fails to resolve weird transitive dependencies.

2017-12-11 Thread Jonathan Fischer
I apologize, I'm not certain of the right name for this.

I'm pulling in libgdx and its dependencies.  In Leiningen, my dependencies 
vector looks like this:

  :dependencies [[org.clojure/clojure "1.8.0"]
 [com.badlogicgames.gdx/gdx "1.9.6"]
 [com.badlogicgames.gdx/gdx-backend-lwjgl3 "1.9.6"]
 [com.badlogicgames.gdx/gdx-platform "1.9.6" :classifier 
"natives-desktop"]]


Which expands out to this (in lein deps :tree, leaving out the Clojure core 
libs and nrepl and whatnot):

 [com.badlogicgames.gdx/gdx-backend-lwjgl3 "1.9.6"]
   [com.badlogicgames.jlayer/jlayer "1.0.1-gdx"]
   [org.jcraft/jorbis "0.0.17"]
   [org.lwjgl/lwjgl-glfw "3.1.0"]
   [org.lwjgl/lwjgl-glfw "3.1.0" :classifier "natives-linux"]
   [org.lwjgl/lwjgl-glfw "3.1.0" :classifier "natives-macos"]
   [org.lwjgl/lwjgl-glfw "3.1.0" :classifier "natives-windows"]
   [org.lwjgl/lwjgl-jemalloc "3.1.0"]
   [org.lwjgl/lwjgl-jemalloc "3.1.0" :classifier "natives-linux"]
   [org.lwjgl/lwjgl-jemalloc "3.1.0" :classifier "natives-macos"]
   [org.lwjgl/lwjgl-jemalloc "3.1.0" :classifier "natives-windows"]
   [org.lwjgl/lwjgl-openal "3.1.0"]
   [org.lwjgl/lwjgl-openal "3.1.0" :classifier "natives-linux"]
   [org.lwjgl/lwjgl-openal "3.1.0" :classifier "natives-macos"]
   [org.lwjgl/lwjgl-openal "3.1.0" :classifier "natives-windows"]
   [org.lwjgl/lwjgl-opengl "3.1.0"]
   [org.lwjgl/lwjgl "3.1.0"]
   [org.lwjgl/lwjgl "3.1.0" :classifier "natives-linux"]
   [org.lwjgl/lwjgl "3.1.0" :classifier "natives-macos"]
   [org.lwjgl/lwjgl "3.1.0" :classifier "natives-windows"]
 [com.badlogicgames.gdx/gdx-platform "1.9.6" :classifier "natives-desktop"]
 [com.badlogicgames.gdx/gdx "1.9.6"]


And the classpath ends up like this:

/Users/jfischer/Desktop/Clojure/gdx-skeleton/test:/Users/jfischer/Desktop/Clojure/gdx-skeleton/src:/Users/jfischer/Desktop/Clojure/gdx-skeleton/dev-resources:/Users/jfischer/Desktop/Clojure/gdx-skeleton/resources:/Users/jfischer/Desktop/Clojure/gdx-skeleton/target/default/classes:/Users/jfischer/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar:/Users/jfischer/.m2/repository/com/badlogicgames/gdx/gdx-backend-lwjgl3/1.9.6/gdx-backend-lwjgl3-1.9.6.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-openal/3.1.0/lwjgl-openal-3.1.0.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-openal/3.1.0/lwjgl-openal-3.1.0-natives-windows.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl/3.1.0/lwjgl-3.1.0.jar:/Users/jfischer/.m2/repository/com/badlogicgames/gdx/gdx/1.9.6/gdx-1.9.6.jar:/Users/jfischer/.m2/repository/org/jcraft/jorbis/0.0.17/jorbis-0.0.17.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-openal/3.1.0/lwjgl-openal-3.1.0-natives-macos.jar:/Users/jfischer/.m2/repository/cider/cider-nrepl/0.15.0/cider-nrepl-0.15.0.jar:/Users/jfischer/.m2/repository/com/badlogicgames/gdx/gdx-platform/1.9.6/gdx-platform-1.9.6-natives-desktop.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-glfw/3.1.0/lwjgl-glfw-3.1.0.jar:/Users/jfischer/.m2/repository/clojure-complete/clojure-complete/0.2.4/clojure-complete-0.2.4.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-glfw/3.1.0/lwjgl-glfw-3.1.0-natives-macos.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-glfw/3.1.0/lwjgl-glfw-3.1.0-natives-windows.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-opengl/3.1.0/lwjgl-opengl-3.1.0.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl/3.1.0/lwjgl-3.1.0-natives-windows.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl/3.1.0/lwjgl-3.1.0-natives-linux.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-jemalloc/3.1.0/lwjgl-jemalloc-3.1.0.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-jemalloc/3.1.0/lwjgl-jemalloc-3.1.0-natives-windows.jar:/Users/jfischer/.m2/repository/com/badlogicgames/jlayer/jlayer/1.0.1-gdx/jlayer-1.0.1-gdx.jar:/Users/jfischer/.m2/repository/org/tcrawley/dynapath/0.2.5/dynapath-0.2.5.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-glfw/3.1.0/lwjgl-glfw-3.1.0-natives-linux.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl/3.1.0/lwjgl-3.1.0-natives-macos.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-jemalloc/3.1.0/lwjgl-jemalloc-3.1.0-natives-linux.jar:/Users/jfischer/.m2/repository/org/clojure/tools.nrepl/0.2.12/tools.nrepl-0.2.12.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-openal/3.1.0/lwjgl-openal-3.1.0-natives-linux.jar:/Users/jfischer/.m2/repository/org/lwjgl/lwjgl-jemalloc/3.1.0/lwjgl-jemalloc-3.1.0-natives-macos.jar


Importantly, there's a jar there for each of those classifiers.

If I try and replicate the same thing using deps.edn:

{:deps
  {org.clojure/clojure {:mvn/version "1.8.0"}
   com.badlogicgames.gdx/gdx {:mvn/versin "1.9.6"}
   com.badlogicgames.gdx/gdx-backend-lwjgl3 {:mvn/version "1.9.6"}
   com.badlogicgames.gdx/gdx-platform {:mvn/version "1.9.6" :classifier 
"natives-desktop"}}}


I don't get all of the jars with different classifiers:


core.logic - explaining transitive relationships

2012-12-18 Thread Stathis Sideris
Hello,

With the code below you can query transitive relationships between entities 
successfully. Is there any way to use core.logic explain the 
relationship? Specifically, is there any way to write a function explain so 
that:

 (explain :pitbull :chordate)

will give you:

[:pitbull :dog]
[:dog :mammal]
[:mammal :chordate]

Thanks,

Stathis


Code:

(ns test.logic
  (:refer-clojure :exclude [==])
  (:use clojure.core.logic))

(defrel is-a Entity Parent)
(fact is-a :pitbull :dog)
(fact is-a :dog :mammal)
(fact is-a :mammal :chordate)
(fact is-a :chordate :animal)

(defn transitive [r]
  (fn t [p1 p2]
(fresh [intermediate]
   (conde
  ((r p1 p2))
  ((r p1 intermediate)
   (t intermediate p2))

(defn iso [entity parent]
  ((transitive is-a) entity parent))

In the REPL:
 (run* [q] (iso :dog :animal))
(_.0)

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

Re: core.logic - explaining transitive relationships

2012-12-18 Thread Tassilo Horn
Stathis Sideris side...@gmail.com writes:

Hi Stathis,

 With the code below you can query transitive relationships between
 entities successfully. Is there any way to use core.logic explain
 the relationship? Specifically, is there any way to write a function
 explain so that:

 (explain :pitbull :chordate)

 will give you:

 [:pitbull :dog]
 [:dog :mammal]
 [:mammal :chordate]

Can't you define `iso` with 3 args, one being a list of intermediates?
E.g., something like

(defn iso [entity is parent]
  (conde
[(is-a entity parent) (== is ())]
[(fresh [i nis]
   (is-a entity i)
   (conso i nis is)
   (iso i nis parent))]))

Then you could run it like:

  test.logic (run* [q] (iso :pitbull q :animal))
  ((:dog :mammal :chordate))

Bye,
Tassilo

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


Re: core.logic - explaining transitive relationships

2012-12-18 Thread Stathis Sideris
Hello David,

Yes, I wasn't expecting for this to be built-in. Your example is exactly 
what I was looking for, thanks a lot! I'll to need to spend some time to 
figure it out :-)

Stathis


On Tuesday, 18 December 2012 15:52:47 UTC, David Nolen wrote:

 There is no general explain functionality. However the following simple 
 solution should give you some ideas:

 (defrel is-a Entity Parent)
 (fact is-a :pitbull :dog)
 (fact is-a :dog :mammal)
 (fact is-a :mammal :chordate)
 (fact is-a :chordate :animal)

 (defn transitive [r]
   (fn t
 ([x z] (t x z (lvar)))
 ([x z path]
(fresh [y]
  (conde
[(r x z) (== path '())]
[(fresh [a d]
   (r x y)
   (conso a d path)
   (== a [x y])
   (t y z d))])

 (defn iso
   ([entity parent]
  ((transitive is-a) entity parent))
   ([entity parent path]
  ((transitive is-a) entity parent path)))

 (comment
   (run* [q]
 (iso :dog :animal q))
   )


 On Tue, Dec 18, 2012 at 9:06 AM, Stathis Sideris 
 sid...@gmail.comjavascript:
  wrote:

 Hello,

 With the code below you can query transitive relationships between 
 entities successfully. Is there any way to use core.logic explain the 
 relationship? Specifically, is there any way to write a function explain so 
 that:

  (explain :pitbull :chordate)

 will give you:

 [:pitbull :dog]
 [:dog :mammal]
 [:mammal :chordate]

 Thanks,

 Stathis


 Code:

 (ns test.logic
   (:refer-clojure :exclude [==])
   (:use clojure.core.logic))

 (defrel is-a Entity Parent)
 (fact is-a :pitbull :dog)
 (fact is-a :dog :mammal)
 (fact is-a :mammal :chordate)
 (fact is-a :chordate :animal)

 (defn transitive [r]
   (fn t [p1 p2]
 (fresh [intermediate]
(conde
   ((r p1 p2))
   ((r p1 intermediate)
(t intermediate p2))

 (defn iso [entity parent]
   ((transitive is-a) entity parent))

 In the REPL:
  (run* [q] (iso :dog :animal))
 (_.0)

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




-- 
You received this message because you are subscribed to the Google
Groups Clojure group.
To 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

Re: core.logic - explaining transitive relationships

2012-12-18 Thread Stathis Sideris
Thanks for this. I didn't think about that!

On Tuesday, 18 December 2012 15:51:55 UTC, Tassilo Horn wrote:

 Stathis Sideris sid...@gmail.com javascript: writes: 

 Hi Stathis, 

  With the code below you can query transitive relationships between 
  entities successfully. Is there any way to use core.logic explain 
  the relationship? Specifically, is there any way to write a function 
  explain so that: 
  
  (explain :pitbull :chordate) 
  
  will give you: 
  
  [:pitbull :dog] 
  [:dog :mammal] 
  [:mammal :chordate] 

 Can't you define `iso` with 3 args, one being a list of intermediates? 
 E.g., something like 

 (defn iso [entity is parent] 
   (conde 
 [(is-a entity parent) (== is ())] 
 [(fresh [i nis] 
(is-a entity i) 
(conso i nis is) 
(iso i nis parent))])) 

 Then you could run it like: 

   test.logic (run* [q] (iso :pitbull q :animal)) 
   ((:dog :mammal :chordate)) 

 Bye, 
 Tassilo 


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

Re: core.logic - explaining transitive relationships

2012-12-18 Thread David Nolen
;; there is a transitive relationship between x  z if there is a
;; relationship between x  some y and some y  z
(defn transitive [r]
  (fn t
;; if passed only two args create the path logic var
([x z] (t x z (lvar)))
;; take an x, z, and a path from x to z
([x z path]
   (fresh [y]
 (conde
   ;; there is a direct relationship between x  z
   ;; update the path
   [(r x z) (== path (list [x z]))]
   ;; there is not a direct relationship between x  z
   ;; try some y that has a relationship with x, update the path
   [(fresh [a d]
  (r x y)
  (conso a d path)
  (== a [x y])
  ;; prove there is a relationship between y  z
  (t y z d))])

(defn iso
  ([entity parent]
 ((transitive is-a) entity parent))
  ([entity parent path]
 ((transitive is-a) entity parent path)))


On Tue, Dec 18, 2012 at 11:28 AM, Stathis Sideris side...@gmail.com wrote:

 Hello David,

 Yes, I wasn't expecting for this to be built-in. Your example is exactly
 what I was looking for, thanks a lot! I'll to need to spend some time to
 figure it out :-)

 Stathis


 On Tuesday, 18 December 2012 15:52:47 UTC, David Nolen wrote:

 There is no general explain functionality. However the following simple
 solution should give you some ideas:

 (defrel is-a Entity Parent)
 (fact is-a :pitbull :dog)
 (fact is-a :dog :mammal)
 (fact is-a :mammal :chordate)
 (fact is-a :chordate :animal)

 (defn transitive [r]
   (fn t
 ([x z] (t x z (lvar)))
 ([x z path]
(fresh [y]
  (conde
[(r x z) (== path '())]
[(fresh [a d]
   (r x y)
   (conso a d path)
   (== a [x y])
   (t y z d))])

 (defn iso
   ([entity parent]
  ((transitive is-a) entity parent))
   ([entity parent path]
  ((transitive is-a) entity parent path)))

 (comment
   (run* [q]
 (iso :dog :animal q))
   )


 On Tue, Dec 18, 2012 at 9:06 AM, Stathis Sideris sid...@gmail.comwrote:

 Hello,

 With the code below you can query transitive relationships between
 entities successfully. Is there any way to use core.logic explain the
 relationship? Specifically, is there any way to write a function explain so
 that:

  (explain :pitbull :chordate)

 will give you:

 [:pitbull :dog]
 [:dog :mammal]
 [:mammal :chordate]

 Thanks,

 Stathis


 Code:

 (ns test.logic
   (:refer-clojure :exclude [==])
   (:use clojure.core.logic))

 (defrel is-a Entity Parent)
 (fact is-a :pitbull :dog)
 (fact is-a :dog :mammal)
 (fact is-a :mammal :chordate)
 (fact is-a :chordate :animal)

 (defn transitive [r]
   (fn t [p1 p2]
 (fresh [intermediate]
(conde
   ((r p1 p2))
   ((r p1 intermediate)
(t intermediate p2))

 (defn iso [entity parent]
   ((transitive is-a) entity parent))

 In the REPL:
  (run* [q] (iso :dog :animal))
 (_.0)

  --
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clo...@googlegroups.com

 Note that posts from new members are moderated - please be patient with
 your first post.
 To unsubscribe from this group, send email to
 clojure+u...@**googlegroups.com

 For more options, visit this group at
 http://groups.google.com/**group/clojure?hl=enhttp://groups.google.com/group/clojure?hl=en


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

Re: == is not transitive?

2012-10-06 Thread Jean Niklas L'orange


On Friday, October 5, 2012 7:17:50 PM UTC+2, Ben wrote:

 I'm not sure what you mean by this. Transitivity means that for all x, 
 y, and z, (Fxy  Fyz) = Fxz. But there are values of x, y, and z for 
 which that does not hold. 


Yeah, sorry. What I meant was that == is only commutative if you pass it 
two arguments as of right now.

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

Re: == is not transitive?

2012-10-05 Thread Jean Niklas L'orange


On Friday, October 5, 2012 2:39:05 AM UTC+2, Ben wrote:

 user [(== 0 0.0) (== 0.0 0.0M) (== 0.0M 0)] 
 [true true false] 


When passing two arguments to ==, == will be transitive.
 

 user [(== 0 0.0 0.0M) (== 0 0.0M 0.0) (== 0.0 0 0.0M) (== 0.0 0.0M 0) 
 (== 0.0M 0.0 0) (== 0.0M 0 0.0)] 
 [true false false false true false] 


This is more of a problem with number equality, not the transitivity of ==. 
(== x1 x2 x3 ... xn) can be rewritten as (and (== x1 x2) (== x2 x3) ... (== 
xn-1 xn)). 

So if you compare (== x y z), then if x = y, then the result of (== x z) 
and (== y z) should be equivalent, considering the numbers are, well, 
numbers.

I believe the issue lies within the bigdec-parsing, which seems to have two 
zeroes: (== 0M 0.0M) returns false, and their hashcode (0 and 1, 
respectively) are different.
 

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

Re: == is not transitive?

2012-10-05 Thread Ben Smith-Mannschott
On Fri, Oct 5, 2012 at 11:08 AM, Jean Niklas L'orange
jeann...@hypirion.com wrote:


 On Friday, October 5, 2012 2:39:05 AM UTC+2, Ben wrote:

 user [(== 0 0.0) (== 0.0 0.0M) (== 0.0M 0)]
 [true true false]


 When passing two arguments to ==, == will be transitive.


 user [(== 0 0.0 0.0M) (== 0 0.0M 0.0) (== 0.0 0 0.0M) (== 0.0 0.0M 0)
 (== 0.0M 0.0 0) (== 0.0M 0 0.0)]
 [true false false false true false]


 This is more of a problem with number equality, not the transitivity of ==.
 (== x1 x2 x3 ... xn) can be rewritten as (and (== x1 x2) (== x2 x3) ... (==
 xn-1 xn)).

 So if you compare (== x y z), then if x = y, then the result of (== x z) and
 (== y z) should be equivalent, considering the numbers are, well, numbers.

 I believe the issue lies within the bigdec-parsing, which seems to have two
 zeroes: (== 0M 0.0M) returns false, and their hashcode (0 and 1,
 respectively) are different.

Yea, I think this is the peculiar definition of BigDecimal.equals()
biting us here.

http://docs.oracle.com/javase/1.4.2/docs/api/java/math/BigDecimal.html

# Note: care should be exercised if BigDecimals are to be used as keys in a
# SortedMap or elements in a SortedSet, as BigDecimal's natural ordering is
# inconsistent with equals. See Comparable, SortedMap or SortedSet for more
# information.

equals():
# Compares this BigDecimal with the specified Object for equality. Unlike
# compareTo, this method considers two BigDecimals equal only if they are
# equal in *value* and *scale* (thus 2.0 is not equal to 2.00 when compared by
# this method)

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


Re: == is not transitive?

2012-10-05 Thread Patrick Houk
I was bitten by this a year ago and posted here:
http://groups.google.com/group/clojure/browse_frm/thread/9091ad790fc96b24

My workaround is to call BigDecimal#stripTrailingZeros before passing
it to code that might compare it to some other number.

user (== 1 (.stripTrailingZeros 1.0M))
true

However, there is an edge case:

user (== 0 (.stripTrailingZeros 0.0M))
false

Which is due to this Java bug:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6480539

So I use a function like the following instead of bigdec to parse
BigDecimals.

(defn parse-stripped-bigdec [^String value-str]
  ;; Note that bigdec uses reflection (at least in Clojure 1.2.1)
  (let [n (java.math.BigDecimal. value-str)]
(if (zero? n) 0M (.stripTrailingZeros n

Be aware that stripping the zeros changes how the BigDecimal is
formatted by #toString.

user (str (parse-stripped-bigdec 10))
1E+1

So, I have a special case for BigDecimal that calls #toPlainString in
the places where I do not want exponential format.

user (.toPlainString (parse-stripped-bigdec 10))
10

I hope that helps.
- Pat

On Oct 4, 8:39 pm, Ben Wolfson wolf...@gmail.com wrote:
 user [(== 0 0.0) (== 0.0 0.0M) (== 0.0M 0)]
 [true true false]
 user [(== 0 0.0 0.0M) (== 0 0.0M 0.0) (== 0.0 0 0.0M) (== 0.0 0.0M 0)
 (== 0.0M 0.0 0) (== 0.0M 0 0.0)]
 [true false false false true false]

 --
 Ben Wolfson
 Human kind has used its intelligence to vary the flavour of drinks,
 which may be sweet, aromatic, fermented or spirit-based. ... Family
 and social life also offer numerous other occasions to consume drinks
 for pleasure. [Larousse, Drink entry]

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


Re: == is not transitive?

2012-10-05 Thread Ben Wolfson
On Fri, Oct 5, 2012 at 2:08 AM, Jean Niklas L'orange
jeann...@hypirion.com wrote:

 On Friday, October 5, 2012 2:39:05 AM UTC+2, Ben wrote:

 user [(== 0 0.0) (== 0.0 0.0M) (== 0.0M 0)]
 [true true false]

 When passing two arguments to ==, == will be transitive.

I'm not sure what you mean by this. Transitivity means that for all x,
y, and z, (Fxy  Fyz) = Fxz. But there are values of x, y, and z for
which that does not hold.

-- 
Ben Wolfson
Human kind has used its intelligence to vary the flavour of drinks,
which may be sweet, aromatic, fermented or spirit-based. ... Family
and social life also offer numerous other occasions to consume drinks
for pleasure. [Larousse, Drink entry]

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


== is not transitive?

2012-10-04 Thread Ben Wolfson
user [(== 0 0.0) (== 0.0 0.0M) (== 0.0M 0)]
[true true false]
user [(== 0 0.0 0.0M) (== 0 0.0M 0.0) (== 0.0 0 0.0M) (== 0.0 0.0M 0)
(== 0.0M 0.0 0) (== 0.0M 0 0.0)]
[true false false false true false]

-- 
Ben Wolfson
Human kind has used its intelligence to vary the flavour of drinks,
which may be sweet, aromatic, fermented or spirit-based. ... Family
and social life also offer numerous other occasions to consume drinks
for pleasure. [Larousse, Drink entry]

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


Re: == is not transitive?

2012-10-04 Thread JvJ
The only reason for this that I can think of is incomplete rules for 
casting numbers.

On Thursday, 4 October 2012 20:39:05 UTC-4, Ben wrote:

 user [(== 0 0.0) (== 0.0 0.0M) (== 0.0M 0)] 
 [true true false] 
 user [(== 0 0.0 0.0M) (== 0 0.0M 0.0) (== 0.0 0 0.0M) (== 0.0 0.0M 0) 
 (== 0.0M 0.0 0) (== 0.0M 0 0.0)] 
 [true false false false true false] 

 -- 
 Ben Wolfson 
 Human kind has used its intelligence to vary the flavour of drinks, 
 which may be sweet, aromatic, fermented or spirit-based. ... Family 
 and social life also offer numerous other occasions to consume drinks 
 for pleasure. [Larousse, Drink entry] 


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

Re: == is not always transitive

2012-04-15 Thread Andrea Chiavazza


 I must agree that the behaviour of == is not correct here.


The problem is in this method in Numbers.java:
public boolean equiv(Number x, Number y){
 return toBigDecimal(x).equals(toBigDecimal(y));
}

The behaviour we currently have is:
user= (let [ones [1 1.0 1N 1M 1.0M 1.00M] ] (doseq [a ones b ones] 
(println a == b \tab (== a b) )))
1 == 1 true
1 == 1.0   true
1 == 1N   true
1 == 1M   true
1 == 1.0M false
1 == 1.00M false
1.0 == 1   true
1.0 == 1.0 true
1.0 == 1N   true
1.0 == 1M true
1.0 == 1.0M true
1.0 == 1.00M true
1N == 1   true
1N == 1.0   true
1N == 1N   true
1N == 1M   true
1N == 1.0M false
1N == 1.00M false
1M == 1   true
1M == 1.0 true
1M == 1N   true
1M == 1M true
1M == 1.0M false
1M == 1.00M false
1.0M == 1 false
1.0M == 1.0 true
1.0M == 1N false
1.0M == 1M false
1.0M == 1.0M true
1.0M == 1.00M false
1.00M == 1 false
1.00M == 1.0 true
1.00M == 1N false
1.00M == 1M false
1.00M == 1.0M false
1.00M == 1.00M true

I propose we change the method to be:
public boolean equiv(Number x, Number y){
return toBigDecimal(x).compareTo(toBigDecimal(y)) == 0;
}
This makes the previous expression return all true, and == should also be 
transitive.

In particular, (== 1.0M 1.00M) will be true rather than false, which is 
much more in the spirit of ==.
The difference between 1.0M and 1.00M should be checked by calling the 
scale() method, which makes sense because it is quite an unusual thing to 
do.

I also noticed in test_clojure/numbers.clj the lines:
; TODO:
; ==
; and more...

So I thought of also adding the test:

(deftest equality
  (are [x y] (== x y)
4242
4242.0
4242N
4242M
4242.0M
4242.00M
42.0  42
42.0  42.0
42.0  42N
42.0  42M
42.0  42.0M
42.0  42.00M
42N   42
42N   42.0
42N   42N
42N   42M
42N   42.0M
42N   42.00M
42M   42
42M   42.0
42M   42N
42M   42M
42M   42.0M
42M   42.00M
42.0M 42
42.0M 42.0
42.0M 42N
42.0M 42M
42.0M 42.0M
42.0M 42.00M

1.23  1.23
1.23  1.23M
1.23M 1.23
1.23M 1.23M )

  (are [x y] (not (== x y))
12 12.1
1.23 123
34 3.4
1.23 1.234
123N 345N
123 345N
123N 345
12.34M 456N
12.34M 4.56
12.34 4.56M
12 4.56M
12M 4.56
12.34M 1.234M ))

I think it would be really nice to get this fixed before the 1.4 release.
The changes above can be found at 
https://github.com/andrea-chiavazza/clojure/tree/BigDecimal-equiv-fix

Can anybody defend the current behaviour against the one I propose ?

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

Re: == is not always transitive

2012-04-13 Thread Sung Pae
Leif leif.poor...@gmail.com writes:

 I'd also like to make sure people are aware of this oddity. I
 discovered this after reading an article about the bad design of PHP.
 I read that in PHP, == is not transitive. I thought Ha ha ha, that
 ridiculous PHP!

 Then I checked c.c/== ; Imagine my reaction when I learned that
 Clojure had something in common with PHP. o_O, :'[ Other emoticons
 also washed over me.

Clojure's == is numerical equivalence, not equality.

-
clojure.core/==
([x] [x y] [x y  more])
  Returns non-nil if nums all have the equivalent
  value (type-independent), otherwise false

The problem with PHP (and JavaScript's) == operator is that the type
coercion is not limited to numerical types:

PHP

1 == 1= true
1 + 1 = 2

JavaScript

1 == 1= true
1 + 1 = 11

Clojure

(== 1 1)  = java.lang.ClassCastException
(+ 1 1)   = java.lang.ClassCastException

Clojure's equality function [1], however, does what you expect when
comparing floats and integers:

(= 1.0 1)   = false

But it also does what you want when comparing _categories_ of numbers
[2] [3]:

(let [a (int 1) b (bigint 1)]
  {:equal_values? (= a b)
   :equal_types?  (= (type a) (type b))})

= {:equal_values? true, :equal_types? false}

I think Clojure does a fantastic job of being both convenient and
strongly typed.

--
guns

[1]: 
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Util.java#L23
[2]: 
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java#L213
[3]: 
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Numbers.java#L978

 If you were really concerned about whether a number is a BigInteger
 vs Integer, or Float vs Double, you would have to handle that on
 your own.

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


Re: == is not always transitive

2012-04-12 Thread Patrick Houk
Yes, that is one reason why I tend to use BigDecimal instead of float
or double.  The thing that seems wrong to me is (not (== 1 1.0M)),
since these are both exact representations of the value one and the
doc for == says that it tests for equivalent value (type-
independent).

On Apr 11, 10:00 pm, Cedric Greevey cgree...@gmail.com wrote:
 IME, it's almost never useful to perform equality tests on floating
 point values. Generally you want to know if they're near enough to one
 another without necessarily being exactly equal. For that something
 like (defn f= [f1 f2 threshold] ( (Math/abs (- f1 f2)) threshold)) is
 probably the sort of thing you want.

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


Re: == is not always transitive

2012-04-11 Thread Leif

I'd also like to make sure people are aware of this oddity.  I discovered 
this after reading an article about the bad design of PHP.  I read that in 
PHP, == is not transitive.  I thought Ha ha ha, that ridiculous PHP!

Then I checked c.c/== ;  Imagine my reaction when I learned that Clojure 
had something in common with PHP.  o_O,  :'[
Other emoticons also washed over me.

In summary, beware when comparing different numeric types, and don't throw 
stones even if your house is made of bricks, because the windows are still 
glass.

On Friday, September 2, 2011 12:50:45 PM UTC-7, Patrick Houk wrote:

 Greetings, 

 I think that I've encountered a bug in ==. 

 user= (and (== 1 1.0) (== 1.0 1.0M) (not (== 1 1.0M))) 
 true 

 This happens with 1.2.1 and 1.3-beta2.  I think it has to do with the 
 precision of the BigDecimal. 

 user= (== 1 1.0M) 
 false 
 user= (== 1 1M) 
 true 

 I think a solution would be to use BigDecimal#compareTo (or maybe 
 BigDecimal#stripTrailingZeros) in ==, so that (== 1M 1.0M) becomes 
 true.  (I would expect (= 1M 1.0M) to remain false, though.) 

 Thanks, 
 - Pat 


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

Re: == is not always transitive

2012-04-11 Thread Cedric Greevey
IME, it's almost never useful to perform equality tests on floating
point values. Generally you want to know if they're near enough to one
another without necessarily being exactly equal. For that something
like (defn f= [f1 f2 threshold] ( (Math/abs (- f1 f2)) threshold)) is
probably the sort of thing you want.

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


Re: == is not always transitive

2012-04-11 Thread Sean Corfield
On Wed, Apr 11, 2012 at 5:46 PM, Leif leif.poor...@gmail.com wrote:
 Then I checked c.c/== ;  Imagine my reaction when I learned that Clojure had
 something in common with PHP.  o_O,  :'[

It's instructive to look at the result of:

(let [ones [1 1.0 1N 1M 1.0M] ] (for [a ones b ones] (== a b)))

The first four compare equal in all combinations. 1.0M is equal to 1.0
but unequal to all the others.
-- 
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

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


== is not always transitive

2011-09-02 Thread Patrick Houk
Greetings,

I think that I've encountered a bug in ==.

user= (and (== 1 1.0) (== 1.0 1.0M) (not (== 1 1.0M)))
true

This happens with 1.2.1 and 1.3-beta2.  I think it has to do with the
precision of the BigDecimal.

user= (== 1 1.0M)
false
user= (== 1 1M)
true

I think a solution would be to use BigDecimal#compareTo (or maybe
BigDecimal#stripTrailingZeros) in ==, so that (== 1M 1.0M) becomes
true.  (I would expect (= 1M 1.0M) to remain false, though.)

Thanks,
- Pat

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