maven-shade-plugin issues with Clojure core (or any clj) AOT compilation

2016-12-28 Thread Mike Rodriguez
Background:

This problem is specific to building jars that contain AOT (Ahead Of Time) 
compiled Clojure code using Maven and the maven-shade-plugin.

Clojure AOT compilation depends on timestamps of .class files vs .clj files 
being accurate.  When both .class files and their associated .clj files 
exist, the AOT .class files are only used by the compiler if their last 
modified timestamp is strictly greater than the last modified timestamp of 
the associated .clj file.

Also note that the Clojure core jar itself is deployed AOTed.

I know that much of the Clojure ecosystem uses Leiningen as a build tool 
(and boot now too I guess).  This problem doesn't apply to Leiningen (and I 
haven't looked at boot).

Problem:

The maven-shade-plugin is popular for building shaded/uber/standalone jars 
in Maven.  Typically this means the jar will include some/all of its 
dependency jars' files.  The maven-shade-plugin has an unfortunate property 
though.  It does not preserve the timestamps on files that are added to 
this final shaded jar.  The resulting jar actually ends up with all files 
inside of it having the same timestamp (when the jar was created).  In 
particular, if you originally had AOT Clojure .class files and .clj files 
with different last modified timestamps, now they will have the same 
timestamps in the shaded jar.

I've brought this up before @ 
http://stackoverflow.com/questions/19594360/preserving-timestamps-on-clojure-clj-files-when-building-shaded-jar-via-maven-s

I have rarely seen people bring up issues around this with 
maven-shade-plugin beyond this particular case.  I believe I have seen a 
complaint or two around the timestamp loss during shading (I can't find 
them now), but nothing that has gained any traction (I may try to bring it 
up to the plugin people soon though).

When the AOTed .class file is ignored in favor of the .clj file, the 
namespace is JIT (Just-In-Time) compiled.  There are several issues with 
this.

1) Performance:  It makes the AOT files mostly worthless since they are not 
saving you on startup time costs anymore.  Everything is JITed anyways.
2) Errors:  The reloading of the .clj files is a forced reload of the .clj 
namespaces involved.  This can cause classpath clashes among ClassLoaders.
- There are quite a few CLJ Jiras out there that faced trouble dealing with 
the mix of reloading namespaces and AOT compilation.

You may be thinking, "Just don't build your Clojure jars with Maven.  Use 
Leiningen instead perhaps?"
This is fine when it is something you control.  However, what if I want to 
use Clojure to develop a library that may be consumed by Java consumers who 
very likely will be using Maven.  If my library is going to be shaded into 
a standalone jar with maven-shade-plugin by this Java consumer (again, 
likely) then this scenario can happen.

Another thought that may occur is to just avoid AOT compilation of my 
library application to avoid the problem (this is recommended in the 
community I believe).  However, Clojure core is AOT compiled and it will 
get included in the shaded jar.  That alone is enough to cause the issue.

Example:

I have a GitHub repo to show a minimum example of where this can be a 
problem.  In particular it shows a way for the problem (2) to occur.
@ https://github.com/mrrodriguez/mvn-shade-test

This repo has a Java API through shade.ShadeJava that will cause the 
Clojure compiler to require the shade.main namespace using JIT compilation. 
 However, shade.main uses clojure.pprint, which is AOT compiled via Clojure 
core.

clojure.pprint was chosen here just because it one of the cases I've seen 
come up that actually fail with problem (2) from above.  Even if there were 
no failures though, the Clojure core namespaces would be getting recompiled 
with problem (1).

-- 
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: maven-shade-plugin issues with Clojure core (or any clj) AOT compilation

2016-12-28 Thread Gary Trakhman
My workaround in a multi-module maven shaded java project with a clojure
module was to strip out CLJ files in the top-level build (shipped with
clojure.core jar).

I had also stripped CLJ files from my project artifact, but AOT compiles
classfiles from all referenced namespaces, so I attempted to strip those
out too earlier with the maven jar plugin. This necessitated manually
whitelisting AOT'd protocol classes from some of those 3rd party deps to
resolve further classloader issues.

On Wed, Dec 28, 2016 at 8:06 AM Mike Rodriguez  wrote:

> Background:
>
> This problem is specific to building jars that contain AOT (Ahead Of Time)
> compiled Clojure code using Maven and the maven-shade-plugin.
>
> Clojure AOT compilation depends on timestamps of .class files vs .clj
> files being accurate.  When both .class files and their associated .clj
> files exist, the AOT .class files are only used by the compiler if their
> last modified timestamp is strictly greater than the last modified
> timestamp of the associated .clj file.
>
> Also note that the Clojure core jar itself is deployed AOTed.
>
> I know that much of the Clojure ecosystem uses Leiningen as a build tool
> (and boot now too I guess).  This problem doesn't apply to Leiningen (and I
> haven't looked at boot).
>
> Problem:
>
> The maven-shade-plugin is popular for building shaded/uber/standalone jars
> in Maven.  Typically this means the jar will include some/all of its
> dependency jars' files.  The maven-shade-plugin has an unfortunate property
> though.  It does not preserve the timestamps on files that are added to
> this final shaded jar.  The resulting jar actually ends up with all files
> inside of it having the same timestamp (when the jar was created).  In
> particular, if you originally had AOT Clojure .class files and .clj files
> with different last modified timestamps, now they will have the same
> timestamps in the shaded jar.
>
> I've brought this up before @
> http://stackoverflow.com/questions/19594360/preserving-timestamps-on-clojure-clj-files-when-building-shaded-jar-via-maven-s
>
> I have rarely seen people bring up issues around this with
> maven-shade-plugin beyond this particular case.  I believe I have seen a
> complaint or two around the timestamp loss during shading (I can't find
> them now), but nothing that has gained any traction (I may try to bring it
> up to the plugin people soon though).
>
> When the AOTed .class file is ignored in favor of the .clj file, the
> namespace is JIT (Just-In-Time) compiled.  There are several issues with
> this.
>
> 1) Performance:  It makes the AOT files mostly worthless since they are
> not saving you on startup time costs anymore.  Everything is JITed anyways.
> 2) Errors:  The reloading of the .clj files is a forced reload of the .clj
> namespaces involved.  This can cause classpath clashes among ClassLoaders.
> - There are quite a few CLJ Jiras out there that faced trouble dealing
> with the mix of reloading namespaces and AOT compilation.
>
> You may be thinking, "Just don't build your Clojure jars with Maven.  Use
> Leiningen instead perhaps?"
> This is fine when it is something you control.  However, what if I want to
> use Clojure to develop a library that may be consumed by Java consumers who
> very likely will be using Maven.  If my library is going to be shaded into
> a standalone jar with maven-shade-plugin by this Java consumer (again,
> likely) then this scenario can happen.
>
> Another thought that may occur is to just avoid AOT compilation of my
> library application to avoid the problem (this is recommended in the
> community I believe).  However, Clojure core is AOT compiled and it will
> get included in the shaded jar.  That alone is enough to cause the issue.
>
> Example:
>
> I have a GitHub repo to show a minimum example of where this can be a
> problem.  In particular it shows a way for the problem (2) to occur.
> @ https://github.com/mrrodriguez/mvn-shade-test
>
> This repo has a Java API through shade.ShadeJava that will cause the
> Clojure compiler to require the shade.main namespace using JIT
> compilation.  However, shade.main uses clojure.pprint, which is AOT
> compiled via Clojure core.
>
> clojure.pprint was chosen here just because it one of the cases I've seen
> come up that actually fail with problem (2) from above.  Even if there were
> no failures though, the Clojure core namespaces would be getting recompiled
> with problem (1).
>
> --
> 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.
> T

Re: maven-shade-plugin issues with Clojure core (or any clj) AOT compilation

2016-12-28 Thread Mike Rodriguez
I appreciate your input.

When we have controlled the Maven shade projects, we have been able to 
workaround the issue as well.  We actually add a 
org.codehaus.mojo/exec-maven-plugin step where we re-open the shaded jar, 
create a new jar, and re-add every file into the new jar via a script. 
 While re-adding the files, we change all .clj files' timestamps to some 
time in the past and all other files just get the current time.  This 
ensures that all .clj files will look "older" than any AOT .class file that 
happens to be in the jar.

My main problem statement is primarily concerning when you *do not* control 
the build.  If I have a Clojure lib that is not-shaded and not AOT-compiled 
and that I have a Java API exposed on (which is what I demonstrate in my 
example project as shade.ShadeJava), this problem will come up for any Java 
consumer who happens to use maven-shade-plugin.  In this sort of case it 
reflects poorly on Clojure if arbitrary consumers have to do workarounds in 
their shade builds just because in my lib I'm wanting to use Clojure as an 
"implementation detail".

So I bring up this issue to just get a sense of what others think and what 
others think should/could be done about it.  Perhaps using Clojure behind 
Java APIs is just not a very common use-case people are working with.  It 
has been a pretty common one for me.  It does seem like a good use-case 
though to be supported to allow Clojure to sneak into existing Java-centric 
ecosystems.

On Wednesday, December 28, 2016 at 7:13:57 AM UTC-6, Gary Trakhman wrote:
>
> My workaround in a multi-module maven shaded java project with a clojure 
> module was to strip out CLJ files in the top-level build (shipped with 
> clojure.core jar). 
>
> I had also stripped CLJ files from my project artifact, but AOT compiles 
> classfiles from all referenced namespaces, so I attempted to strip those 
> out too earlier with the maven jar plugin. This necessitated manually 
> whitelisting AOT'd protocol classes from some of those 3rd party deps to 
> resolve further classloader issues.
>
> On Wed, Dec 28, 2016 at 8:06 AM Mike Rodriguez  > wrote:
>
>> Background:
>>
>> This problem is specific to building jars that contain AOT (Ahead Of 
>> Time) compiled Clojure code using Maven and the maven-shade-plugin.
>>
>> Clojure AOT compilation depends on timestamps of .class files vs .clj 
>> files being accurate.  When both .class files and their associated .clj 
>> files exist, the AOT .class files are only used by the compiler if their 
>> last modified timestamp is strictly greater than the last modified 
>> timestamp of the associated .clj file.
>>
>> Also note that the Clojure core jar itself is deployed AOTed.
>>
>> I know that much of the Clojure ecosystem uses Leiningen as a build tool 
>> (and boot now too I guess).  This problem doesn't apply to Leiningen (and I 
>> haven't looked at boot).
>>
>> Problem:
>>
>> The maven-shade-plugin is popular for building shaded/uber/standalone 
>> jars in Maven.  Typically this means the jar will include some/all of its 
>> dependency jars' files.  The maven-shade-plugin has an unfortunate property 
>> though.  It does not preserve the timestamps on files that are added to 
>> this final shaded jar.  The resulting jar actually ends up with all files 
>> inside of it having the same timestamp (when the jar was created).  In 
>> particular, if you originally had AOT Clojure .class files and .clj files 
>> with different last modified timestamps, now they will have the same 
>> timestamps in the shaded jar.
>>
>> I've brought this up before @ 
>> http://stackoverflow.com/questions/19594360/preserving-timestamps-on-clojure-clj-files-when-building-shaded-jar-via-maven-s
>>
>> I have rarely seen people bring up issues around this with 
>> maven-shade-plugin beyond this particular case.  I believe I have seen a 
>> complaint or two around the timestamp loss during shading (I can't find 
>> them now), but nothing that has gained any traction (I may try to bring it 
>> up to the plugin people soon though).
>>
>> When the AOTed .class file is ignored in favor of the .clj file, the 
>> namespace is JIT (Just-In-Time) compiled.  There are several issues with 
>> this.
>>
>> 1) Performance:  It makes the AOT files mostly worthless since they are 
>> not saving you on startup time costs anymore.  Everything is JITed anyways.
>> 2) Errors:  The reloading of the .clj files is a forced reload of the 
>> .clj namespaces involved.  This can cause classpath clashes among 
>> ClassLoaders.
>> - There are quite a few CLJ Jiras out there that faced trouble dealing 
>> with the mix of reloading namespaces and AOT compilation.
>>
>> You may be thinking, "Just don't build your Clojure jars with Maven.  Use 
>> Leiningen instead perhaps?"
>> This is fine when it is something you control.  However, what if I want 
>> to use Clojure to develop a library that may be consumed by Java consumers 
>> who very likely will be using Maven.  If m

Re: maven-shade-plugin issues with Clojure core (or any clj) AOT compilation

2016-12-28 Thread Mike Rodriguez
I also forgot to include the error message from my example GitHub project, 
in case it is easier than actually running it.  I understand this issue for 
the most part.  It has still been a bit tricky for me to fully understand 
how this AOT class interface/class is being referred to by any Clojure 
ClassLoader later on causing this.  I dug some and "sort of" understood at 
this point.  I know there have been many AOT + forced reloading of certain 
Clojure namespace issues in the past.  This one doesn't directly look like 
one I've seen.

However, remember, this isn't the only problem I'm bringing up here.  It is 
that AOT files in general would be ignored after shading with 
maven-shade-plugin.

The errors:

Exception in thread "main" java.lang.ClassCastException: 
clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848 cannot be 
cast to clojure.pprint.PrettyFlush
at 
clojure.pprint$pretty_writer$fn__4700.invoke(pretty_writer.clj:391)
at 
clojure.pprint.proxy$java.io.Writer$IDeref$PrettyFlush$4923d848.flush(Unknown 
Source)
at clojure.core$flush.invokeStatic(core.clj:3609)
at clojure.core$flush.invoke(core.clj:3603)
at clojure.core$prn.invokeStatic(core.clj:3620)
at clojure.core$prn.doInvoke(core.clj:3612)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.pprint$pprint.invokeStatic(pprint_base.clj:252)
at clojure.pprint$pprint.invoke(pprint_base.clj:241)
at clojure.pprint$pprint.invokeStatic(pprint_base.clj:245)
at clojure.pprint$pprint.invoke(pprint_base.clj:241)
at shade.main$_main.invokeStatic(main.clj:6)
at shade.main$_main.doInvoke(main.clj:4)
at clojure.lang.RestFn.invoke(RestFn.java:397)
at clojure.lang.Var.invoke(Var.java:375)
at shade.ShadeJava.main(ShadeJava.java:14)

On Wednesday, December 28, 2016 at 7:06:11 AM UTC-6, Mike Rodriguez wrote:
>
> Background:
>
> This problem is specific to building jars that contain AOT (Ahead Of Time) 
> compiled Clojure code using Maven and the maven-shade-plugin.
>
> Clojure AOT compilation depends on timestamps of .class files vs .clj 
> files being accurate.  When both .class files and their associated .clj 
> files exist, the AOT .class files are only used by the compiler if their 
> last modified timestamp is strictly greater than the last modified 
> timestamp of the associated .clj file.
>
> Also note that the Clojure core jar itself is deployed AOTed.
>
> I know that much of the Clojure ecosystem uses Leiningen as a build tool 
> (and boot now too I guess).  This problem doesn't apply to Leiningen (and I 
> haven't looked at boot).
>
> Problem:
>
> The maven-shade-plugin is popular for building shaded/uber/standalone jars 
> in Maven.  Typically this means the jar will include some/all of its 
> dependency jars' files.  The maven-shade-plugin has an unfortunate property 
> though.  It does not preserve the timestamps on files that are added to 
> this final shaded jar.  The resulting jar actually ends up with all files 
> inside of it having the same timestamp (when the jar was created).  In 
> particular, if you originally had AOT Clojure .class files and .clj files 
> with different last modified timestamps, now they will have the same 
> timestamps in the shaded jar.
>
> I've brought this up before @ 
> http://stackoverflow.com/questions/19594360/preserving-timestamps-on-clojure-clj-files-when-building-shaded-jar-via-maven-s
>
> I have rarely seen people bring up issues around this with 
> maven-shade-plugin beyond this particular case.  I believe I have seen a 
> complaint or two around the timestamp loss during shading (I can't find 
> them now), but nothing that has gained any traction (I may try to bring it 
> up to the plugin people soon though).
>
> When the AOTed .class file is ignored in favor of the .clj file, the 
> namespace is JIT (Just-In-Time) compiled.  There are several issues with 
> this.
>
> 1) Performance:  It makes the AOT files mostly worthless since they are 
> not saving you on startup time costs anymore.  Everything is JITed anyways.
> 2) Errors:  The reloading of the .clj files is a forced reload of the .clj 
> namespaces involved.  This can cause classpath clashes among ClassLoaders.
> - There are quite a few CLJ Jiras out there that faced trouble dealing 
> with the mix of reloading namespaces and AOT compilation.
>
> You may be thinking, "Just don't build your Clojure jars with Maven.  Use 
> Leiningen instead perhaps?"
> This is fine when it is something you control.  However, what if I want to 
> use Clojure to develop a library that may be consumed by Java consumers who 
> very likely will be using Maven.  If my library is going to be shaded into 
> a standalone jar with maven-shade-plugin by this Java consumer (again, 
> likely) then this scenario can happen.
>
> Another thought that may occur is to just avoid AOT compilation of my 
> library application to avoid the problem (

The Micro Monolith architecture

2016-12-28 Thread Joakim Tengstrand
I have just released a new architecture that fits really nice with Clojure 
and its REPL.
Start the REPL once and continue working!
https://medium.com/@joakimtengstrand/the-micro-monolith-architecture-d135d9cafbe#.v934khjni

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


Order preservation and duplicate removal policy in `distinct`

2016-12-28 Thread Mike Rodriguez
The doc for `distinct` is:
"Returns a lazy sequence of the elements of coll with duplicates removed.
  Returns a stateful transducer when no collection is provided."

(1) In the lazy sequence case, I've thought that maybe it is assuemd there 
is a guarantee that the order of the input seq is preserved.  However, this 
isn't stated.  Is this an assumption to rely on for `distinct` and, more 
generally, the Clojure seq-based API functions?

(2) In either case, when there are duplicates, there do not seem to be any 
guarantees on which one of the duplicates will be preserved.  Should this 
be stated?  I'm thinking that maybe this is about Clojure's design 
philosophy being that equal values to not ever need to be distinguished 
between, so the API doesn't explicitly support this concern.  However, 
there are times when identity relationships can matter - performance would 
be one that comes to mind.
- This has some relationship to the Scala question @ 
http://stackoverflow.com/questions/6735568/scala-seqlike-distinct-preserves-order

There have been a few occasions where I relied on (or wanted to rely on) 
(1).  I haven't had many cases where (2) matters, but I could see it coming 
up on perhaps rare occasions. 

-- 
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: Order preservation and duplicate removal policy in `distinct`

2016-12-28 Thread Michael Blume
Also, I'm assuming distinct uses .equals semantics which might be worth
calling out in the doc

On Wed, Dec 28, 2016, 11:22 AM Mike Rodriguez  wrote:

> The doc for `distinct` is:
> "Returns a lazy sequence of the elements of coll with duplicates removed.
>   Returns a stateful transducer when no collection is provided."
>
> (1) In the lazy sequence case, I've thought that maybe it is assuemd there
> is a guarantee that the order of the input seq is preserved.  However, this
> isn't stated.  Is this an assumption to rely on for `distinct` and, more
> generally, the Clojure seq-based API functions?
>
> (2) In either case, when there are duplicates, there do not seem to be any
> guarantees on which one of the duplicates will be preserved.  Should this
> be stated?  I'm thinking that maybe this is about Clojure's design
> philosophy being that equal values to not ever need to be distinguished
> between, so the API doesn't explicitly support this concern.  However,
> there are times when identity relationships can matter - performance would
> be one that comes to mind.
> - This has some relationship to the Scala question @
> http://stackoverflow.com/questions/6735568/scala-seqlike-distinct-preserves-order
>
> There have been a few occasions where I relied on (or wanted to rely on)
> (1).  I haven't had many cases where (2) matters, but I could see it coming
> up on perhaps rare occasions.
>
> --
> 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: [moderated] I don't understand what (:t :t) means

2016-12-28 Thread John Gabriele


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

Couple other things to note:

  * `:t` is just a keyword, like `:foo` or `:bar`. (In case you were 
thinking of Scheme, where `#t` is the boolean true.)

  * you can always check what type something is by doing `(class 
that-thing)` (though, in this case, as you've already seen, `(:t :t)` 
results in `nil`).

-- John

-- 
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: Order preservation and duplicate removal policy in `distinct`

2016-12-28 Thread Timothy Baldridge
This is one of those odd questions where the answer of what "could" happen
and what "will most likely happen" are completely different. There is no
reason why `distinct` should reorder or which item will be preserved.
However there's really only one logical way to implement this (the way it's
currently implemented) and in that case the answer would be "the first
duplicate is used", and "items are not reordered".

So all that to say, there's nothing in the docs that specify this is the
way it has to be, but it is the way it is now, is most likely not going to
change. So if you're really concerned about it, I'd say write a test around
distinct and wait for it to break someday if Clojure changes the undefined
behavior.

On Wed, Dec 28, 2016 at 9:55 AM, Michael Blume  wrote:

> Also, I'm assuming distinct uses .equals semantics which might be worth
> calling out in the doc
>
> On Wed, Dec 28, 2016, 11:22 AM Mike Rodriguez  wrote:
>
>> The doc for `distinct` is:
>> "Returns a lazy sequence of the elements of coll with duplicates removed.
>>   Returns a stateful transducer when no collection is provided."
>>
>> (1) In the lazy sequence case, I've thought that maybe it is assuemd
>> there is a guarantee that the order of the input seq is preserved.
>> However, this isn't stated.  Is this an assumption to rely on for
>> `distinct` and, more generally, the Clojure seq-based API functions?
>>
>> (2) In either case, when there are duplicates, there do not seem to be
>> any guarantees on which one of the duplicates will be preserved.  Should
>> this be stated?  I'm thinking that maybe this is about Clojure's design
>> philosophy being that equal values to not ever need to be distinguished
>> between, so the API doesn't explicitly support this concern.  However,
>> there are times when identity relationships can matter - performance would
>> be one that comes to mind.
>> - This has some relationship to the Scala question @
>> http://stackoverflow.com/questions/6735568/scala-
>> seqlike-distinct-preserves-order
>>
>> There have been a few occasions where I relied on (or wanted to rely on)
>> (1).  I haven't had many cases where (2) matters, but I could see it coming
>> up on perhaps rare occasions.
>>
>> --
>> 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.
>



-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

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


core.logic: faking sets and "sufficient" results

2016-12-28 Thread Nathan Smutz
Hi All,

I work for a university and I've been commissioned to write a program that 
proves whether majors can be reasonably completed in 4 years.  core.logic 
has seemed the obvious tool.  The output should be a set of scheduled 
course-offerings satisfying major requirements, course-prereqs, etc. It 
looks like CLP(Set) is still on the wishlist.  
Could someone point me to the current best-practice for faking sets? 
The obvious thing seem to use membero operations on some list L while 
declaring (distincto L) and forcing an ordering so you get combinations 
instead of permutations.  I'm sure there's a better way than (pred L #(= % 
(some-sort-function %)).  If that's the way it's gotta be, then I suppose 
you'd sort on the object IDs to be generic.  (I recall somewhere seeing a 
function returning unique IDs for Clojure objects.)

A further goal would be to output workable education plans without any 
superfluous courses.
I have constraints like "6 credits from any of courses A, B, C, D..." In 
that case if course A is 4 credits and course B is 3 credits, then you want 
[A B] represented in the solution (one more than the six credits required; 
but both are necessary) but you don't want [A B C] for some course C (two 
courses enough and the third is noise).  The ideas I have for that seem 
kind of brute-force.  Is there a built in behavior for this I might not be 
aware of?

The more I think of it, the more complicated this kludge seems to get.  Am 
I barking up the wrong tree?

Best,
Nathan

-- 
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] lein-codeindex 0.1.0 - Easy code indexing and referencing for Emacs, Vim and other editors

2016-12-28 Thread Sanel Zukan
Hi everyone,

I'm happy to announce first version of lein-codeindex, source code indexer
that will scan and reference your project files and all dependencies
used by the project.

This is Leiningen plugin that can generate references for Emacs (with
etags) or Vim and other editors (with ctags).

You can details on github page
(https://github.com/sanel/lein-codeindex) and some common usage in
this post: 
http://acidwords.com/posts/2016-12-29-code-indexing-with-lein-codeindex.html.

Best,
Sanel

-- 
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] clj-cbor - Concise Binary Object Representation

2016-12-28 Thread Gregory Look


mvxcvi/clj-cbor  is a native Clojure 
implementation of the Concise Binary Object Representation  
format specified in RFC 7049 .

CBOR is a binary encoding with the goal of small code size, compact 
messages, and extensibility without the need for version negotiation. This 
makes it a good alternative to EDN  for 
storing and transmitting Clojure data in a more compact form.

I've been itching to write this library since first reading through the 
CBOR spec, which is clear and well thought out. This is a native 
implementation and the library has no dependencies other than Clojure 
itself, and the current code is 100% covered by tests. I wanted to write 
this over using one of the existing two or three libraries because they 
were either based on Jackson, wrapped a Java lib and required interop, were 
insufficiently flexible with adding new type extensions, or some 
combination of the three.

clj-cbor uses a read- and write-handler approach similar to the ones in EDN 
and Transit, so type extension is simple. The library uses this same 
mechanism to provide default support for common types like Dates, Instants, 
Patterns, UUIDs, URIs, BigIntegers, BigDecimals, Ratios, Keywords, Symbols, 
TaggedLiterals, and sets.

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