<< Back to previous view

[TTRACE-1] Two convenience predicate functions useful for IDE-tools Created: 23/Apr/12  Updated: 01/Dec/12  Resolved: 01/Dec/12

Status: Resolved
Project: tools.trace
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Frank Siebenlist Assignee: Luc Préfontaine
Resolution: Completed Votes: 0
Labels: enhancement

Patch: Code and Test

 Description   

In our IDE-tool clj-ns-browser, we show the user a list of vars and make it easy to add a trace by selecting a var and clicking a button.

In order to only enable the button for a var that is traceable, we use predicate "var-traceable?".

In order to change the button text from "trace" to "untrace", we use predicate "var-traced?".

Both "var-traceable?" and "var-traced?" are aware of tools.trace internals - ideally, we would like to remain oblivious to trace's inners...

Our implementations for the predicates is at: https://gist.github.com/2472261

Thanks for the great tool!



 Comments   
Comment by Luc Préfontaine [ 14/Nov/12 5:56 PM ]

Done, however the names where changed to traced? and traceable?.

Comment by Luc Préfontaine [ 14/Nov/12 6:18 PM ]

Done is 0.7.4

Comment by Luc Préfontaine [ 01/Dec/12 3:38 PM ]

Done, "good" version is 0.7.5 (readme & comments need an update in 0.7.4")





[TNS-5] Allow any valid .clj* source file to be parsed/analysed Created: 01/Nov/12  Updated: 13/Dec/12

Status: Open
Project: tools.namespace
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Max Penet Assignee: Stuart Sierra
Resolution: Unresolved Votes: 0
Labels: enhancement

Attachments: Text File e3cd6d1fa6e0c900bc1086e4a93bbc9cb343a820.patch    

 Description   

This broadens the allowed file types to anything ending with #"\.clj.?$", meaning this would work for clj, cljs, cljc, cljx and possibly other Clojure implementations with their own extension in the future.

This allows libraries such as codox (and possibly autodoc) to work with ClojureScript and others implementations without any modification.

Note: My CA is on the way, I sent it a week ago, I am not sure if it arrived yet (it was sent from Switzerland with normal mail, with an ETA of 1 week).



 Comments   
Comment by Max Penet [ 02/Nov/12 6:51 AM ]

CA received it seems (I am listed on http://clojure.org/contributing ).

Comment by Stuart Sierra [ 02/Nov/12 3:23 PM ]

I'm not sure about this. If you're only using c.t.n.find in isolation, it's fine. But if you're using code-reloading and c.t.n.repl, it could incorrectly try to reload .cljs files in JVM Clojure.

We really need [Feature Expressions]http://dev.clojure.org/display/design/Feature+Expressions or something like it to get away from multiple file extensions.

Until then, I think it has to be optional. I don't know how best to achieve this. The APIs in c.t.n.repl and c.t.n.dir are not amenable to extension. I'll think about it.

Comment by Max Penet [ 06/Nov/12 6:11 PM ]

True, I didn't realize that.

Maybe using a dynamic var to hold the regex pattern (or a predicate?) could be a reasonable solution in the meantime, this would allow to rebind it in the case of codox & similar libs.
I don't really "like" to use dynamic vars (or regexes!), but in this case it might make sense.
Not to mention it would also allow more flexibility on projects where you don't want to have your clj codoxed, but only your cljs for instance.

Comment by Max Penet [ 24/Nov/12 7:47 AM ]

Any thoughts on my last comment/edit? I don't think there is a single doc lib that works with cljs at the moment, it is a bit painful to be honest.

Comment by Stuart Sierra [ 24/Nov/12 4:25 PM ]

Yes, I think a dynamic var would be OK. However, I would like to know of a real use case, not just a potential one.

Comment by Max Penet [ 13/Dec/12 2:40 AM ]

The idea was to be able to use codox on cljs files, I tried locally but there are other problems with this approach to be able to get to cljs vars metadata. So in the end I think you were right, maybe it's better to wait for feature expressions for this.





[TCLI-2] Allow caller-supplied parse-fn Created: 11/Nov/12  Updated: 11/Apr/13

Status: Open
Project: tools.cli
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Pierre-Yves Ritschard Assignee: Gareth Jones
Resolution: Unresolved Votes: 0
Labels: enhancement

Attachments: File TCLI-2.diff    

 Description   

As for :parse-fn, a function can be supplied, this
is useful for standard use-cases such as: -vv, or when
you want to build a list from values.

PR: https://github.com/clojure/tools.cli/pull/11



 Comments   
Comment by Andy Fingerhut [ 11/Nov/12 12:38 PM ]

Pierre-Yves, there are instructions for creating patches under the headings "Development" and "Adding patches" on this page: http://dev.clojure.org/display/design/JIRA+workflow

Submissions to this module do require the author to sign a CA. Instructions here: http://clojure.org/contributing

Comment by Pierre-Yves Ritschard [ 11/Apr/13 9:48 AM ]

Suggested Patch

Comment by Pierre-Yves Ritschard [ 11/Apr/13 9:48 AM ]

Hello, now that I'm a registered contributor, I attached a file as suggested in the workflow wiki





[LOGIC-44] ex* could expand macros in patterns Created: 19/Jul/12  Updated: 17/Mar/13

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Joe Osborn Assignee: David Nolen
Resolution: Unresolved Votes: 0
Labels: enhancement, patch, test

Attachments: Text File exstar-macros.patch    
Patch: Code and Test

 Description   

So, tagged data structures are probably interesting in a relational context. Say you have a relation with some default logic about dogs:

(defna friendlyo [Dog-Or-Breed]
    ([:Spot] succeed)
    ([:Spike] fail)
    ([Other-Dog] (fresh [Breed] (dog-breed Other-Dog Breed) (friendlyo Breed)))
    ([(breed :miniature-dachshund)] fail)
    ([(breed :golden-retriever)] succeed)
    ;. . .)

Assume there's a (defmacro breed [t] `[:breed ~t]).

That's nicer than having to drop [:breed :golden-retriever] in there or whatever, since it's compile-time-checkable, less error-prone, reduces duplication, etc.

This little patch makes ex* expand macros in patterns so it doesn't treat e.g. (breed :golden-retriever) as introducing a new LVar called "breed". Test also provided.



 Comments   
Comment by David Nolen [ 19/Jul/12 4:41 PM ]

I'm surprised that this doesn't already work. We have support for unifying expressions in the pattern already. Look at line 1230 in tests.clj in the master branch.

So this should just work, no need to explicitly support macros as far as I can tell. If it's not working, then there's a bug.

Comment by Joe Osborn [ 19/Jul/12 5:18 PM ]

At least on 0.7.5, matching against a macro gives a runtime error:

Exception in thread "main" java.lang.ClassCastException: clojure.core.logic.LVar cannot be cast to clojure.lang.IFn
	at rl.core$glyph_$fn__123$fn__144$fn__165$fn__166$_inc__167$fn__168.invoke(core.clj:61)
	at clojure.core.logic.Substitutions.bind(logic.clj:211)
	at rl.core$glyph_$fn__123$fn__144$fn__165$fn__166$_inc__167.invoke(core.clj:58)
	at clojure.core.logic$fn__1056$_inc__1057.invoke(logic.clj:1160)
	at clojure.core.logic$fn__1056$_inc__1057.invoke(logic.clj:1160)
	at clojure.core.logic$fn__898$_inc__899.invoke(logic.clj:823)
	at clojure.core.logic$fn__890$fn__891.invoke(logic.clj:828)

Using a fn instead of a macro gives the same:

Exception in thread "main" java.lang.ClassCastException: clojure.core.logic.LVar cannot be cast to clojure.lang.IFn
	at rl.core$drawable_$fn__235$fn__248$fn__249$_inc__250$fn__251.invoke(core.clj:67)
	at clojure.core.logic.Substitutions.bind(logic.clj:211)
	at rl.core$drawable_$fn__235$fn__248$fn__249$_inc__250.invoke(core.clj:65)
	at clojure.core.logic$fn__1056$_inc__1057.invoke(logic.clj:1160)
	at clojure.core.logic$fn__894$_inc__895.invoke(logic.clj:826)
	at clojure.core.logic$fn__1056$_inc__1057.invoke(logic.clj:1160)
	at clojure.core.logic$fn__898$_inc__899.invoke(logic.clj:823)
	at clojure.core.logic$fn__898$_inc__899.invoke(logic.clj:823)
	at clojure.core.logic$fn__898$_inc__899.invoke(logic.clj:823)
	at clojure.core.logic$fn__890$fn__891.invoke(logic.clj:828)

Here's (glyph-) for reference (don't mind all the extra [], I have a weird key/value thing because of some conveniences for maintaining fact identity in a temporal database):

(defna glyph- [Key Val]
	([[Thing] [Glyph]] (thing- [Thing]) (on-fire_ *turn* [Thing]) (== Glyph \δ))
	([[Thing] [Glyph]] (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (glyph- [Type] [Glyph])))
	([[(type-enum :player)] [Glyph]] (== Glyph \@))
	([[(type-enum :dragon)] [Glyph]] (== Glyph \D))
	([[Type] [Glyph]] (== Glyph \?)))

and type-enum as a macro:

(defmacro type-enum [v] `[:enum :type ~v])

and as a fn:

(defn type-enum [v] [:enum :type ~v])

I'll mess around and see if my example works in HEAD.

Comment by Joe Osborn [ 19/Jul/12 5:37 PM ]

Same exception with this test case in HEAD (sorry for all the facts):

(defrel thing- [Thing])
(defrel type- [Thing] [Type])
(fact thing- [0])
(fact thing- [1])
(fact thing- [2])
(fact type- [0] [:player])
(fact type- [1] [:dragon])
(fact type- [2] [:pig])
(defn type-enum [t] [:type t])
(defna drawable- [Key]
  ([[Thing]] (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (drawable- [Type])))
  ([[(type-enum :player)]] succeed)
  ([[(type-enum :dragon)]] succeed))

(deftest do-fns-work
	(is (= (run* [q] (drawable- [q])) '(0 1))))

Now that I look at it, I may be expecting a wrong-format return value, but the point is that I don't even get that far.

Using the REPL, I checked out how (defna drawable- . . .) expands (tidied up slightly):

(def drawable- (clojure.core/fn ([Key] 
  (clojure.core.logic/conda 
	  ((clojure.core.logic/fresh [Thing] (clojure.core.logic/== [Thing] Key) (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (drawable- [Type])))) 
		((clojure.core.logic/fresh [type-enum] 
		  (clojure.core.logic/== [(type-enum :player)] Key) succeed))
		((clojure.core.logic/fresh [type-enum] 
		  (clojure.core.logic/== [(type-enum :dragon)] Key) succeed))))))

Note the (clojure.core.logic/fresh [type-enum] . . .) forms, which are exactly what I would not want to see in this case.

I'm not really sure why this doesn't work here yet works for the matche test case.

Comment by David Nolen [ 19/Jul/12 5:47 PM ]
[(type-enum :dragon)]

This pattern make it seem like you want to match:

[[:type :dragon]]

Note extra level of brackets here. Is this the case?

Even so I agree that the expansion doesn't look quite right. We should never descend into a seq form like that.

Comment by Joe Osborn [ 19/Jul/12 5:57 PM ]

Yes, that's exactly the desired outcome in this case--a tagged value in my naive interpretation. Is the reason it fails whereas the test on :1230 doesn't the fact that it's producing a vector and not a list? Changing the fn to return a list instead of a vector didn't seem to help.

My patch, fwiw, doesn't exhibit that behavior (at least for macros, haven't tested it with fns).

Comment by David Nolen [ 19/Jul/12 9:11 PM ]

What I mean is don't you want the following instead?

(defna drawable- [Key]
  ([[Thing]] (thing- [Thing]) (fresh [Type] (type- [Thing] [Type]) (drawable- [Type])))
  ([(type-enum :player)] succeed)
  ([(type-enum :dragon)] succeed))

Note that I removed a layer of square brackets.

Comment by Joe Osborn [ 20/Jul/12 10:28 AM ]

Nope! I actually want both. I'm doing some temporal logic stuff and I wanted some conveniences for "updating" a fluent, so I wanted to distinguish between the "key part" and the "value part" of the arguments. It looks silly for facts with no "value part", but it lets me write procedures and fns something like this:

(defrel heldo Time Fluent)
(defrel ¬heldo Time Fluent)
(declare fluent-obtainedo) ; most recent 'held' not terminated by a '¬held', or fail
(defn alter-fluent [Time Rel Key NewVal]
  ;todo: error check, ensure old != new, old obtains, new does not obtain
  (doseq [old-val (run* [old-val] (fluent-obtainedo Time [Rel Key old-val]))]
    (fact ¬heldo Time [Rel Key old-val]))
  (fact heldo Time [Rel Key NewVal]))
. . .
(fact heldo 0 ['pos [0] [0 0]])
. . .
(alter-fluent 1 'pos [0] [1 1])

And I write all the non-temporal fluents that way too for consistency and to help prevent mistakes.

Comment by David Nolen [ 20/Jul/12 2:58 PM ]

I'll try to give a closer look at this issue over the weekend.

Comment by David Nolen [ 17/Mar/13 7:05 PM ]

We're thinking about a more general solution here: http://github.com/clojure/core.logic/wiki/Better-syntax-support





[LOGIC-35] Core.logic equivalent of multimethods Created: 02/Apr/12  Updated: 28/Dec/12

Status: Open
Project: core.logic
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Gabriel Pickard Assignee: David Nolen
Resolution: Unresolved Votes: 0
Labels: enhancement


 Description   

I need to define predicates to which I can later (and from other namespaces) attach further clauses (so not just facts). I couldn't find any such functionality in the source. Due to the extensive use of macros, hacking such a system onto core.logic from the outside is extremely difficult, if not impossible (to me at least).

I'd love to implement this myself too, if given an OK and rough direction.



 Comments   
Comment by Gabriel Pickard [ 03/Apr/12 6:27 PM ]

I actually did manage to tack on a prototype that covers the basic behavior I would like to see: https://github.com/werg/herpderp/blob/master/src/herpderp/multo.clj

I use a set stored in a ref in the defne's metadata to manage dynamic changes to the clauses. Upon changing that set using defclause I use eval to re-define the var using defne.

This might not be nice, but allows me to continue developing features against it.

Comment by David Nolen [ 28/Dec/12 12:48 AM ]

I don't think the current implementation can really support this and I don't think it's wise to try to hack around the current implementation. I'd be willing to consider a comprehensive solution if someone is willing to do the legwork.





[DJSON-4] Please make function write-string public Created: 22/Oct/12  Updated: 27/Oct/12  Resolved: 27/Oct/12

Status: Closed
Project: data.json
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Jan Herich Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: enhancement


 Description   

Please make function write-string in namespace clojure.data.json public, instead of private as it is now: for example, i'm extending java.sql.Timestamp with JSONWriter protocol and i need to send ISO formatted timestamp value as string:

(defn- write-timestamp [Timestamp out]
(write-string (convert-to-iso-time (.getTime Timestamp)) out))

(extend java.sql.Timestamp js/JSONWriter {:-write write-timestamp})



 Comments   
Comment by Stuart Sierra [ 27/Oct/12 1:12 PM ]

Declined. 'write-string' is an implementation detail, not something I will commit to as a public API. Use the :value-fn option of 'write' to handle extension to new types. Or copy the implementation of 'write-string' into your namespace.





[CLJS-452] clojure.browser.net: enable WebSockets? Created: 31/Dec/12  Updated: 20/Jan/13

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Linus Ericsson Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: enhancement
Environment:

clojurescript in browsers, wrapper for Google Closures WebSocket.


Attachments: Text File 0001-enabled-websockets.patch    
Patch: Code

 Description   

In https://github.com/clojure/clojurescript/blob/master/src/cljs/clojure/browser/net.cljs there's a nicely prepared support for WebSockets with the note

;; WebSocket is not supported in the 3/23/11 release of Google
;; Closure, but will be included in the next release.

is there anything preventing us from enable the support for WebSockets with the next release of ClojureScript?

patch 0001-enable-websockets.patch do just enable the functionality. No test-cases included.



 Comments   
Comment by David Nolen [ 20/Jan/13 12:51 AM ]

Have you verified that this doesn't break browser REPL? Thanks!





[CLJS-420] Unexpected behavior with dispatch on Keyword via protocols Created: 18/Nov/12  Updated: 18/Nov/12

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Minor
Reporter: Max Penet Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: bug, enhancement


 Description   

At the moment if you create a protocol and expect it to be able to dispatch on keywords you need to do it in js/String, trying to extend on cljs.core.Keyword doesn't work as keywords are just Strings.

See https://gist.github.com/4104635



 Comments   
Comment by David Nolen [ 18/Nov/12 3:14 PM ]

This is a known issue which will have to wait for if and when Keywords and Symbols become proper types in ClojureScript.

Extending js/Object is not recommended, if you actually need to add functionality to the base JS native types the convention is different from Clojure: default instead of Object, string instead of js/String. Please refer to core.cljs if you want more examples.

Comment by Max Penet [ 18/Nov/12 3:27 PM ]

Thanks for the pointer about default and string, I didn't know about that.

I reported the issue at the demand of bbloom. It does seem to be difficult to address without taking a (major) performance hit unfortunately.





[CLJS-419] Exclude cljs source file from compilation Created: 17/Nov/12  Updated: 18/Dec/12  Resolved: 18/Dec/12

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Mimmo Cosenza Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: enhancement
Environment:

every environment


Attachments: Text File 0001-CLJS-419-exclude-file-or-dir-from-compilation.patch    

 Description   

Scenario:

  1. you have a :dev build and a :prod build
  2. In the :dev build you want to have a brepl connected with the browser and you coded that connection in a isolated cljs source file.
  3. In the :prod build you do not want that connection active, meaning you don't want source cljs file enabling the connection to be included in the compilation.

Given this scenario, you need to duplicate all the cljs source files but the one that enable the connection. This mean you have to manually maintain two code bases.

It could be useful to have a way to :exclude some files from :source-path.



 Comments   
Comment by David Nolen [ 18/Nov/12 3:16 PM ]

This could easily be done by adding support for this in closure.clj - patch welcome!

Comment by Mimmo Cosenza [ 20/Nov/12 6:11 AM ]

I propose to add a new keyword/value in the optimization option map, namely :exclude-path. the value of this option should be a subdir of the source-dir.

Top level scenario:

1. you use lein-cljsbuild to define your cljs project
2. you define more builds, e.g. a :dev build and a :prod build.
(defproject ...
:cljsbuild {:builds
{:dev {:source-path "src/cljs" {:compiler {:output-to "resources/public/js/main_dbg.js"
:optimizations :whitespace
:pretty-print true}}}
:prod {:source-path "src/cljs" {:compiler {:output-to "resources/public/js/main_dbg.js"
:optimizations :advanced
:exclude-path "some-path"}}}})

3. lein-cljsbuild plugin will instruct CLJ compiler by passing it the soruce-dir (e.g. "src/cljs") and the options map which now can contain also an optional :exclude-path keyword.

4. During compilation the compiler will exclude from source-dir any cljs source which is contained in the named excluded directory.

I'll start bottom-up from 4. then I'll try to patch lein-cljsbuild too.

Mimmo

Comment by Mimmo Cosenza [ 07/Dec/12 10:30 AM ]

Hi David, here is the flattened patch relative. The two guys which worked on the patch under my direction are interns in my own company. Next monday we'll send their signed CA.

My best
Mimmo

Comment by Brenton Ashworth [ 07/Dec/12 11:13 AM ]

In general, we should not complicate the compiler with additional options when functionality can be provided by external tools.

I think this feature can be provided by external tools. The compiler will only automatically pull in things that are actually dependencies of the sources that we provide to the compiler. External tools should provide ways to limit what is handed to the compiler.

I would first attempt to modify lein-cljsbuild to do what you want.

When using the compiler directly, you can provide your own implementation of Compilable which, when given a directory, will filter out sources based on some criteria you provide. In my projects I have custom implementations of Compilable that do just this. You should be able to do the same thing in lein-cljsbuild.

-Brenton

Comment by Mimmo Cosenza [ 07/Dec/12 12:30 PM ]

Thanks for the advice Brenton. I'll try to understand from the maintainer of `lein-cljsbuild` where to start from. I agree with you about keeping the compiler clean from options that can be implemented by the tools. But I'm no so sure that patching lein-cljsbuild we'll be as easy as adding `:exclude` option to the compiler.

Mimmo

Comment by Brenton Ashworth [ 07/Dec/12 1:04 PM ]

It doesn't matter which one is easier to do. Every new option and special case that we add to the compiler makes it more difficult to understand how changes will impact users.

Comment by David Nolen [ 07/Dec/12 5:40 PM ]

I agree that anything that can be solved at higher level tools is better - it wasn't clear to me from the implementation that Compilable could be used to control this - but I see now.

Mimmo, cljs.closure/build takes a Compilable and a map of options. So lein-cljsbuild could construct the custom Compilable that understands :excludes and pass it along.

Comment by Evan Mezeske [ 09/Dec/12 9:48 PM ]

FWIW, I agree with Brenton that this should be in lein-cljsbuild.

I didn't know that cljs.closure/build was flexible enough to do this already. I always thought that it needed to be extended so that a vector of files could be passed in, or something, but it sounds like the Compilable approach should work just fine.

I will happily accept a patch for this. One thing to keep in mind, though, is that the :exclude entry should not be in the :compiler map if lein-cljsbuild is handling it. The :compiler map is passed straight through as options to cljs.closure/build. So, the :exclude entry should be a neighbor of the :compiler entry.

Comment by Mimmo Cosenza [ 10/Dec/12 4:20 AM ]

Hi all,
we all agree with Brenton and yes, the :exclude option has to be at the same hierarchical level of :source-path. I'll verify if we can also extend :source-path from taking a String to taking a vector of String, in such a way that the user could ask to compile more cljs src-dir.

Mimmo

Comment by Mimmo Cosenza [ 10/Dec/12 4:37 AM ]

Hi all,
just a small add on to the previous comment. I don't think we're going to update cljsc/cljsc.clj, which I consider a kind of tool, much more fragile and limited than cljsbuild plugin, to interoperate with CLJS compiler.

My best

Mimmo

Comment by David Nolen [ 18/Dec/12 3:09 PM ]

Should be resolved by tools that use the compiler.





[CLJS-402] Add a facility to obtain the version information of the clojurescript build that is in use Created: 21/Oct/12  Updated: 26/Feb/13

Status: Open
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Frank Siebenlist Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: enhancement

Attachments: File CLJS402-3rd-patch-file.diff    

 Description   

Currently there is no function or var defined in the clojurescript library that can be used to easily obtain the version information of the build that is in use.

Without that version information, debugging and reporting of errors is more cumbersome than needed, wastes time, causes confusion discussing issues...

A simple function and/or var like the ones used for clojure would be very helpful:

user=> (clojure-version)
"1.4.0"
user=> clojure-version
{:major 1, :minor 4, :incremental 0, :qualifier nil}



 Comments   
Comment by Frank Siebenlist [ 21/Oct/12 2:16 PM ]

Auto-generation from the build script of version_autogen.clj and version_autogen.cljs files
that both define the cljs.version-autogen/clojurescript-version
with the current version info for both the clj and cljs environments

Comment by David Nolen [ 21/Oct/12 3:43 PM ]

Why a separate namespace for this?

Comment by Frank Siebenlist [ 21/Oct/12 9:15 PM ]

Good point - probably better to add the clojurescript-version var to the cljs.core namespace.

New patch change the build script to auto-generates the clojurescript-version assignment statements in both cljs/core.clj and cljs/core.cljs to reflect the correct version info.

In that way it resembles more the clojure.core use of clojure-version.

Note that the two separate assignments for clj and cljs are needed to detect out-of-sync of repl-compiler version with the compiler used to generate the js-code that was downloaded thru the webpage.

Difficult to write a test-script, but it seems to work in my repl:


user=> (require 'cljs.core)
nil
user=> cljs.core/*clojurescript-version*
{:minor 0, :revision 1515, :major 0}
user=> (run-repl-listen)
"Type: " :cljs/quit " to quit"
ClojureScript:cljs.user> *clojurescript-version*
{:revision 1515, :major 0, :minor 0}
ClojureScript:cljs.user>

Comment by Frank Siebenlist [ 21/Oct/12 9:16 PM ]

CLJS-402: build script auto-generates the clojurescript-version assignment statements in both cljs/core.clj and cljs/core.cljs to reflect the correct version info

Comment by Frank Siebenlist [ 22/Oct/12 12:00 AM ]

When I tried to implement a "clojurescript-version" function like the "clojure-version" one, I (re)discovered that cljs/core.clj is not your average cli-file but some funky file used by the clojurescript compiler to bootstrap - in other words it's not a good file to require and run normal functions from your clj-environment.

So I moved the *clojurescript-version* var to cljs/compiler.clj as it seemed to make sense to associate the version with the compiler.

On the cljs site, I left the *clojurescript-version* in cljs/core.cljs, although I was tempted to create a cljs.compiler namespace to store that var on the cljs side to make it symmetric .

Also added a (clojurescript-version) function to both the clj and cljs sides, with an added special-fn in the cljs/repl.clj such that you can ask for the compiler version of the repl-server from the cljs-repl.

Updated 3rd patch file replaces the previous one.

Just wanted to record an example of a mismatch in compilers:

user=> (run-repl-listen)
"Type: " :cljs/quit " to quit"
ClojureScript:cljs.user> (clojurescript-version)
"0.0.1515"
ClojureScript:cljs.user> (clj-clojurescript-version)
"0.0.1516"
ClojureScript:cljs.user>

This happens when you generate the javascript from your cljs with a "lein cljsbuild once" command with compiler version "0.0.1515",
then upgrade the compiler to "0.0.1516" and then run the cljs-repl without regenerating the javascript for the webpage-download.
Very obscure things can happen after that...

Comment by Frank Siebenlist [ 22/Oct/12 12:03 AM ]

build script auto-generates the clojurescript-version assignment statements in both cljs/compiler.clj and cljs/core.cljs to reflect the correct version info
Function "clojurescript-version" is added to both compiler.clj and core.cljs to mimic equivalent "clojure-version"
Special-fn "clj-clojurescript-version was added to repl.clj to obtain the compiler's clojurescript-compiler version from the cljs-repl

Comment by David Nolen [ 22/Oct/12 7:06 AM ]

The patch uses sed, I'm not sure this is such a great idea since whatever the patch does should probably work with whatever build setup we have on Hudson.

Comment by Chouser [ 22/Oct/12 8:05 AM ]

Would it make sense to call this 'clojure-version' as well, instead of clojurescript-version? It's a map, and so various flags could be added to differentiate jvm, js, python, c, etc. runtimes. What does ClojureCLR do?

Comment by Frank Siebenlist [ 22/Oct/12 10:52 AM ]

sed was already used in the build script... a few lines down, the pom file is transformed with:

sed -e s/CLOJURESCRIPT_VERSION/0.0-$REVISION/ < "$POM_TEMPLATE" > "$POM_FILE"

Comment by Frank Siebenlist [ 22/Oct/12 11:15 AM ]

A quick scan of the src-code showed that ClojureCRL uses clojure-version and *clojure-version*.

However, there is less chance for confusion as you are supposedly running on the CLR already.

With ClojureScript you can have these three intertwined "clojure" environments that are all live at the same time: the clojure version, the repl clojurescript version, and the clojurescript version used to compile the initially loaded js. Not sure if overloading the clojure-version fn-name and relying on namespaces to differentiate will be helpful... but it's not that big of a deal and I'm easily persuaded otherwise - somebody should make the call and I'll change it.

Comment by David Nolen [ 26/Feb/13 7:51 AM ]

Sorry just now coming back to this ticket. I think it's probably preferable that the map of properties be called the same thing everywhere. I would apply the patch with this change. I note it no longer applies to master.





[CLJS-398] new macro cljs.core/extend-instance Created: 19/Oct/12  Updated: 19/Oct/12  Resolved: 19/Oct/12

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Herwig Hochleitner Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: enhancement, patch

Attachments: Text File 0001-new-macro-clojure.core-extend-instance-can-be-used-t.patch     Text File 0001-Test-for-extend-instance.patch    
Patch: Code and Test

 Description   

Patch introduces an extend-instance macro, similar to extend-type.
It doesn't extend the .prototype property, but assigns the prototype impl members to the instance itself.

This is useful to let existing instances, e.g. parsed JSON directly implement a protocol.



 Comments   
Comment by David Nolen [ 19/Oct/12 5:13 PM ]

Rich Hickey already had a good name for an operation like this - specify.

Comment by Herwig Hochleitner [ 19/Oct/12 6:10 PM ]

OK, I've declined the ticket, since not only the name but also the patches should be disregarded.

The problem with above impl is that the generated implementing fns get instantiated, every time extend-instance is evaluated. That is not acceptable on a per-instance basis.

I will work on a new macro called specify, which allows passing implementing fns.

Is a syntax similar to clojure.core/extend right for specify?
Should I create a new ticket?

Comment by David Nolen [ 19/Oct/12 7:51 PM ]

As far as I understand it the interface for specify should be the same as extend-type.





[CLJS-397] Omit var reads in statement context Created: 19/Oct/12  Updated: 23/Oct/12  Resolved: 23/Oct/12

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Herwig Hochleitner Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: enhancement, patch, size

Attachments: Text File 0001-CLJS-397-var-reads-in-a-statement-context-get-omitte.patch    
Patch: Code

 Description   

Attached patch updates cljs emitter to not emit var references in statement context.
That causes toplevel deftypes to not return their generated type, which lets gclosure strip them if unused

cljs helloworld shrinks from ~90K to ~69K

https://groups.google.com/d/topic/clojure/LNfJRw07u8I/discussion



 Comments   
Comment by David Nolen [ 19/Oct/12 5:15 PM ]

Can we get the ticket # in the commit message? Thanks!

Comment by Herwig Hochleitner [ 19/Oct/12 5:42 PM ]

Of course, sorry! Here is a new patch, if you please.

Comment by David Nolen [ 19/Oct/12 7:32 PM ]

Thanks. I'm confused about the second aspect of the patch, what do you mean by bogus error messages?

Comment by Herwig Hochleitner [ 19/Oct/12 11:23 PM ]

Well, the repl uses a :statement context to generate the javascript which gets printed out as part of a stack trace. When setting :expr back to :statement in the repl, you can try the following scenario:

  • enter into the repl (def val :worked) (if (> (Math/rand) 0.5) val (throw ""))
  • half of the time you will get :worked
  • half of the time you will get a stacktrace citing 'ns.val = ":worked"; if (Math.rand() > 0.5){}{throw ""}'
  • that makes no sense

With the full patch, the printout will be smth like '(function(){ns.val = ":worked"; if (Math.rand() > 0.5){return ns.val}{throw ""}})()', which is noisier, but more like what actually got evaluated by the repl client.

##EDIT#APPEND##

The reason the repl still works, even when analyzing in a statement context with the patch is, that in order to get the return value, the repl statement has to be evaluated in an :expr context anyway.
This happens by unquoting it into a wrapper form. With the patch the wrapper form also gets analyzed in an :expr context, which doesn't hurt.
Only when an exception gets caught, the js of the unwrapped expr is used, which now always matches the its counterpart in the wrapper form.

Comment by David Nolen [ 20/Oct/12 9:33 AM ]

I'm still confused. Does this additional modification have anything to do with the ticket? By that I mean does the patch require the second modification? If it does can you explain a further? Thanks.

Comment by Herwig Hochleitner [ 20/Oct/12 1:17 PM ]

The patch doesn't require the second modification in the sense that everything still works if it's left out.

The patch requires the modification in the sense that it would break stack traces on the REPL otherwise + the two changes should be reverted together if and when we move such optimizations out of the emitter into an optimization pass.

So the trade off is in always having the correct code in a REPL stacktrace in exchange for making it more verbose. Again, this doesn't influence behavior, so it's a matter of prioritizing requirements.

Comment by David Nolen [ 21/Oct/12 3:48 PM ]

I still don't understand why/how the part of the patch that addresses the ticket breaks stack traces. Can you explain?

Comment by Herwig Hochleitner [ 22/Oct/12 10:06 AM ]

1) var read statements get omitted
2) typing "var" into the repl still works, because it's analyzed in a wrapper form
3) if it throws, the printed generated js is the original form in a statement context, you can observe this with above code sample.

Comment by David Nolen [ 22/Oct/12 10:16 AM ]

Ok I understand now, I don't think the second part of the patch is relevant. The user entered two statements, not one combined in an implicit do which is what the other part of the patch does. Can we get a new patch that only includes the part that addresses the ticket? Thanks!

Comment by Herwig Hochleitner [ 22/Oct/12 2:58 PM ]

For the record: There was some talk in the chat, where I laid down my rationale for changing the repl specifically: "Technically repl inputs have to be in an expr context, to capture the return val. And they are, by virtue of the wrapping form. The change makes that fact explicit, thereby keeping stack traces sane."

I also discovered, that two other ops, beside a var read, don't emit in a statement context either and therefore have same issue. I created http://dev.clojure.org/jira/browse/CLJS-403 for the REPL change.

Updated attached patch contains just the optimization.

Comment by David Nolen [ 23/Oct/12 6:49 PM ]

fixed, http://github.com/clojure/clojurescript/commit/97e5fbd1e1597d58be35fd8320c8044ccc9d3a3d





[CLJS-387] Add docstring from def and ns definitions to @namespaces metadata map, and make reflect functions make use of that Created: 07/Oct/12  Updated: 17/Oct/12  Resolved: 17/Oct/12

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Frank Siebenlist Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: docs, enhancement, patch,, reflection
Environment:

clojure/clojurescript "0.0-1450"


Attachments: File add-ns-def-doc-patch.diff    
Patch: Code

 Description   

The docstrings were parsed from the definitions-forms for def and ns, but not added to the @namespaces metadata map.
There is no :doc entry used in the ns' metadata in the @namespaces.
No ns's :doc info is communicated to the browser in the reflect functions with reflect/doc.
Patch-file is attached with code-changes that add the :doc info for ns and def to the @namespaces, and enhances the reflect functions to communicate that info to the browser in the reflect/doc call.



 Comments   
Comment by David Nolen [ 15/Oct/12 11:06 PM ]

This patch no longer applies, mind updating it?

Comment by Frank Siebenlist [ 16/Oct/12 12:10 AM ]

This patch should apply to master version on Mon, 15 Oct 2012 22:03:19 -0700 (4defcbcf19112b9be6a4a27b5d8855552bf94948)

Comment by David Nolen [ 17/Oct/12 10:57 AM ]

Excellent, fixed http://github.com/clojure/clojurescript/commit/bef56a74f2eeecabfe0c0a28d89b455dce576ea3

Please at the ticket # to the commit message though, thanks!





[CLJS-260] Add clojure.core/shuffle implementation Created: 17/May/12  Updated: 20/May/12  Resolved: 20/May/12

Status: Resolved
Project: ClojureScript
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Evan Mezeske Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: enhancement, patch,, test

Attachments: Text File 0001-Add-clojure.core-shuffle-and-a-test.patch     Text File shuffle.patch     Text File shuffle.v2.patch    
Patch: Code and Test

 Description   

I added a simple implementation of clojure.core/shuffle, which uses goog.array's Fisher-Yates for its implementation. Included in the patch is a test to make sure it works.



 Comments   
Comment by David Nolen [ 17/May/12 7:07 PM ]

Why don't you return a vector like Clojure does?

Comment by Evan Mezeske [ 17/May/12 7:11 PM ]

Return a vector like Clojure.

Comment by David Nolen [ 18/May/12 9:23 PM ]

The patch is not correctly formatted with attribution.

Comment by Evan Mezeske [ 20/May/12 4:24 PM ]

Use git format-patch instead of git diff, to hopefully provide the right patch format.

Comment by David Nolen [ 20/May/12 10:28 PM ]

fixed, http://github.com/clojure/clojurescript/commit/b06905863a9b0ce3618634d8fe0effb3aefd4063





[CLJ-1203] Fallback to hash-based comparison for non-Comparables in Util.compare() Created: 17/Apr/13  Updated: 29/Apr/13  Resolved: 29/Apr/13

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Tassilo Horn Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: enhancement, patch

Attachments: Text File 0001-Add-hasheq-based-fallback-to-Util.compare.patch    
Patch: Code

 Description   

I oftentimes use sorted collections, and my comparator functions usually look like that:

(fn [a b]
  (let [x (compare-according-to-my-use-case a b)]
    (if (zero? x)
       (compare a b)
       x)))

That is, I define the sorting order depending on the requirements of my use-case, and if that doesn't suffice to make a distinction, I simply fall back to the standard `compare` function in order to get a stable ordering anyhow. I think that's a widely used idiom, e.g., also used in "Clojure Programming" (for example page 109).

The problem with this approach is that several data structures don't implement Comparable, and thus aren't applicable to `compare` (you'll get a ClassCastException). Examples are maps, records, deftypes, and sequences.

The patch I'm going to attach extends `Util.compare()` with a fallback clause that performs a `hasheq()`-based comparison. This results in a meaningless but at least stable sorting order which suffices for use-cases like the one shown above.



 Comments   
Comment by Andy Fingerhut [ 18/Apr/13 9:01 PM ]

Patch 0001-Add-hasheq-based-fallback-to-Util.compare.patch dated Apr 17 2013 applies cleanly to latest master, but causes several unit tests in data_structures.clj to fail. These are the kinds of things you would expect to fail with the change made in the patch, because the failing tests expect an exception to be thrown when comparing objects that don't implement Comparable, and with this patch's changes they no longer do. If this patch's change is desired, those tests should probably be removed.

Comment by Tassilo Horn [ 19/Apr/13 2:34 AM ]

Thanks Andy, I can't believe I've forgotten to re-run the tests.

Anyway, I'm attaching a new version of the patch that deletes the few sorted-set and sorted-set-by invocations that check that an exception is thrown when creating sorted sets containing non-Comparables.

Comment by Tassilo Horn [ 19/Apr/13 2:35 AM ]

New version of the patch.

Comment by Andy Fingerhut [ 26/Apr/13 2:47 PM ]

Tassilo, you say that one of your use cases is sorted collections. Note that any compare function that returns 0 for two values will cause sorted sets and maps to treat the two compared values as equal, and at most one of them will get into the ordered set/map, the second treated as a duplicate, even though the values are not equal. See https://github.com/jafingerhut/thalia/blob/master/doc/other-topics/comparators.md#comparators-for-sorted-sets-and-maps-are-easy-to-get-wrong for an example (not based on your modified compare, but on a comparator that returns 0 for non-equal items).

With your proposed change to compare, this occurrence would become very dependent upon the hash function used. Probably quite rare, but it would crop up from time to time, and could potentially be very difficult to detect and track down the source.

Comment by Tassilo Horn [ 29/Apr/13 2:29 AM ]

Hi Andy, you are right. It's possible to add an explicit equals()-check in cases the hashcodes are the same, but I think there's nothing you can do in the hashcodes-equal-but-objects-are-not case. That is, there's no way to ensure the rule sgn(compare(x, y)) == -sgn(compare(y, x)), the transitivity rule, and the compare(x, y)==0 ==> sgn(compare(x, z))==sgn(compare(y, z)) for all z rule.

I'm closing that ticket.





[CLJ-1177] clojure.java.io/resource and non-ASCII characters Created: 07/Mar/13  Updated: 10/Mar/13

Status: Open
Project: Clojure
Component/s: None
Affects Version/s: Release 1.5
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Trevor Wennblom Assignee: Unassigned
Resolution: Unresolved Votes: 1
Labels: bug, enhancement

Attachments: Text File clj-1177-patch-v1.txt    
Patch: Code

 Description   

clojure.java.io/resource corrupts path containing UTF-8 characters without issuing warning.

user=> (System/getProperty "java.runtime.version")
"1.8.0-ea-b79"
user=> (clojure-version)
"1.5.0"
user=> (System/getProperty "user.dir")
"/dir/déf"
user=> (clojure.java.io/resource "myfile.txt")
#<URL file:/dir/d%c3%a9f/resources/myfile.txt>
user=> (slurp (clojure.java.io/resource "myfile.txt") :encoding "UTF-8")
FileNotFoundException /dir/déf/resources/myfile.txt (No such file or directory)  java.io.FileInputStream.open (FileInputStream.java:-2)


 Comments   
Comment by Andy Fingerhut [ 08/Mar/13 12:10 AM ]

Below is a workaround, at least. I don't know, but perhaps the as-file method for URLs in io.clj of Clojure, the part that converts %hh sequences to a character with code point in the range 0 through 255, is at least partly at fault here. I don't know right now if it is possible to modify that code to handle the general case of whatever character encoding munging is going on here to when .getResource creates the URL object.

clojure.java.io/resource is documented to return a Java object of type java.net.URL, which seems like it does %hh escaping of many characters. Reference [1] to a Java bug from 2001 where a Java user was surprised by the then-recent change in behavior of the getResource method [2].

Doing a little searching I found this StackOverflow question [3], which has what might be a workaround. I tried it on my Mac OS X 10.6 system running JDK 1.6 and it seemed to work:

(slurp (.getContent (clojure.java.io/resource "abcíd/foo.txt")))

That getContent is a method for class java.net.URL [4]

[1] http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4466485
[2] http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#getResource%28java.lang.String%29
[3] http://stackoverflow.com/questions/13013629/best-international-alternative-to-javas-getclass-getresource
[4] http://docs.oracle.com/javase/1.5.0/docs/api/java/net/URL.html#getContent%28%29

Comment by Trevor Wennblom [ 08/Mar/13 9:56 AM ]

Hi Andy,

Thanks for the background and suggestions, that's very helpful.

I'm gradually learning Clojure with no Java experience. In this case I was searching for the preferred Clojure way to access items in directories declared under :resource-paths in a Leiningen project.clj file. Perhaps clojure.java.io/resource isn't the best way to do this as it's possibly too tied to the expectation for a URI instead of a more general IRI.

You're suggested workaround did work for my use case:

(slurp (.getContent (clojure.java.io/resource "abcíd/foo.txt")))

but hopefully there would be more native/direct Clojure way to accomplish the same eventually.

I don't know if java.net.IDN would be useful internally as a fix in clojure.java.io/resource — I'm assuming not since it wasn't added until Java 6.[1]

user=> (import 'java.net.IDN)
java.net.IDN
user=> (java.net.IDN/toASCII "/dir/déf")
"xn--/dir/df-gya"
user=> (java.net.IDN/toUnicode "xn--/dir/df-gya")
"/dir/déf"

[1]: http://docs.oracle.com/javase/6/docs/api/java/net/IDN.html

Comment by Andy Fingerhut [ 08/Mar/13 1:30 PM ]

Patch clj-1177-patch-v1.txt dated Mar 8 2013 is an attempt to solve this issue, in what I think may be a correct way. As specified in RFC 3986, when taking a Unicode string and making a URL of it, it should be encoded in UTF-8 and then each individual byte is subject to the %HH hex encoding. This patch reverses that to turn URLs into file names.

Tested on Mac OS X 10.6 with a command line like this (it doesn't work without the -Dfile.encoding=UTF-8 option on my Mac, probably because the default encoding is MacRoman):

% java -cp clojure.jar:path/to/resource -Dfile.encoding=UTF-8 clojure.main
user=> (require '[clojure.java.io :as io])
nil
user=> (io/resource "abcíd/foo.txt")
#<URL file:/Users/jafinger/clj/clj-ns-browser/resource/abc%c3%add/foo.txt>
user=> (slurp (io/resource "abcíd/foo.txt"))
"The quick brown fox jumped over the lázy dög!\n"





[CLJ-1165] Forbid varargs defprotocol/definterface method declarations because those cannot be defined anyway Created: 15/Feb/13  Updated: 04/Apr/13

Status: Open
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Major
Reporter: Tassilo Horn Assignee: Stuart Halloway
Resolution: Unresolved Votes: 0
Labels: enhancement, patch

Attachments: Text File 0001-Protocol-interface-method-declarations-don-t-allow-f.patch    
Patch: Code

 Description   

Protocol, interface method declarations don't allow for varags. Currently, for example

  (defprotocol FooBar
    (foo [this & more]))

compiles just fine, and & is interpreted as a usual argument that happens to be
named & without special meaning. But clearly, the user wanted to specify a
varags parameter here. The same applies to definterface.

Similarly, providing method implementations via defrecord, deftype, and reify
don't allow for varags (but dynamic extensions via extend do).

So this patch makes defprotocol and definterface throw an
IllegalArgumentException if a user tries to use varargs in method signatures.

Similarly, defrecord, deftype, and reify throw an IllegalArgumentException if
any method implementation arglist contains a varargs argument.

This patch is a cut-down variant of my patch to http://dev.clojure.org/jira/browse/CLJ-1024
which has been reverted shortly before Clojure 1.5 was released. The CLJ-1024 patch
was the same as this one, but it has also forbidden destructuring in defprotocol and
definterface. This was a bit too much, because although destructuring has no
semantic meaning with method declarations, it still can serve a documentation purpose.

This has been discussed on the list: https://groups.google.com/d/topic/clojure-dev/qjkW-cv8nog/discussion



 Comments   
Comment by Stuart Halloway [ 29/Mar/13 5:27 AM ]

I think that this patch would be much more helpful to users if it reported the problem form (both name and params).

(And I wonder if we should be using ex-info for all errors going forward.)

Comment by Tassilo Horn [ 31/Mar/13 5:17 AM ]

New version of the patch that mentions both method name and argument vector, and uses ex-info as Stu suggested.

Comment by Andy Fingerhut [ 04/Apr/13 7:24 PM ]

Presumuptuously changing Approval from Incomplete back to None, since the reason for marking it Incomplete seems to have been addressed with a new patch.





[CLJ-1155] Suppress tracebacks from clojure.core Created: 01/Feb/13  Updated: 29/Mar/13  Resolved: 29/Mar/13

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Wilfred Hughes Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: enhancement

Attachments: Text File suppress_tracebacks.patch    
Patch: Code

 Description   

It would be really nice if we could hide the Java traceback from the compiler when it's not relevant. When there's no Java interop, it's not useful. I can't see any case where we want the tracebacks from the compiler referencing clojure.core.

Here's how a syntax error traceback looks at the moment on trunk:

$ more dodgy-map.clj
(defn dodgy-map []
  {:1 :2 :3})
$ java -cp target/clojure-1.5.0-master-SNAPSHOT.jar clojure.main dodgy-map.clj
Exception in thread "main" java.lang.RuntimeException: Map literal must contain an even number of forms, compiling:(/home/wilfred/src/clojure/dodgy-map.clj:2:13)
	at clojure.lang.Compiler.load(Compiler.java:7070)
	at clojure.lang.Compiler.loadFile(Compiler.java:7020)
	at clojure.main$load_script.invoke(main.clj:286)
	at clojure.main$script_opt.invoke(main.clj:348)
	at clojure.main$main$fn__6682.invoke(main.clj:432)
	at clojure.main$main.doInvoke(main.clj:429)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.lang.Var.invoke(Var.java:415)
	at clojure.lang.AFn.applyToHelper(AFn.java:161)
	at clojure.lang.Var.applyTo(Var.java:532)
	at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Map literal must contain an even number of forms
	at clojure.lang.Util.runtimeException(Util.java:219)
	at clojure.lang.LispReader$MapReader.invoke(LispReader.java:1090)
	at clojure.lang.LispReader.readDelimitedList(LispReader.java:1145)
	at clojure.lang.LispReader$ListReader.invoke(LispReader.java:979)
	at clojure.lang.LispReader.read(LispReader.java:182)
	at clojure.lang.Compiler.load(Compiler.java:7058)
	... 10 more

With my patch, this is simplified to:

$ java -cp target/clojure-1.5.0-master-SNAPSHOT.jar clojure.main dodgy-map.clj
java.lang.RuntimeException: Map literal must contain an even number of forms, compiling:(/home/wilfred/src/clojure/dodgy-map.clj:2:13)

Another example: here's how name errors appear on trunk:

$ more i-dont-exist.clj
(defn no-such-variable []
  i-dont-exist)
$ java -cp target/clojure-1.5.0-master-SNAPSHOT.jar clojure.main i-dont-exist.clj
Exception in thread "main" java.lang.RuntimeException: Unable to resolve symbol: i-dont-exist in this context, compiling:(/home/wilfred/src/clojure/i-dont-exist.clj:1:1)
	at clojure.lang.Compiler.analyze(Compiler.java:6380)
	at clojure.lang.Compiler.analyze(Compiler.java:6322)
	at clojure.lang.Compiler$BodyExpr$Parser.parse(Compiler.java:5708)
	at clojure.lang.Compiler$FnMethod.parse(Compiler.java:5139)
	at clojure.lang.Compiler$FnExpr.parse(Compiler.java:3751)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:6558)
	at clojure.lang.Compiler.analyze(Compiler.java:6361)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:6548)
	at clojure.lang.Compiler.analyze(Compiler.java:6361)
	at clojure.lang.Compiler.access$100(Compiler.java:37)
	at clojure.lang.Compiler$DefExpr$Parser.parse(Compiler.java:529)
	at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
	at clojure.lang.Compiler.analyze(Compiler.java:6361)
	at clojure.lang.Compiler.analyze(Compiler.java:6322)
	at clojure.lang.Compiler.eval(Compiler.java:6623)
	at clojure.lang.Compiler.load(Compiler.java:7063)
	at clojure.lang.Compiler.loadFile(Compiler.java:7020)
	at clojure.main$load_script.invoke(main.clj:286)
	at clojure.main$script_opt.invoke(main.clj:348)
	at clojure.main$main$fn__6682.invoke(main.clj:432)
	at clojure.main$main.doInvoke(main.clj:429)
	at clojure.lang.RestFn.invoke(RestFn.java:408)
	at clojure.lang.Var.invoke(Var.java:415)
	at clojure.lang.AFn.applyToHelper(AFn.java:161)
	at clojure.lang.Var.applyTo(Var.java:532)
	at clojure.main.main(main.java:37)
Caused by: java.lang.RuntimeException: Unable to resolve symbol: i-dont-exist in this context
	at clojure.lang.Util.runtimeException(Util.java:219)
	at clojure.lang.Compiler.resolveIn(Compiler.java:6874)
	at clojure.lang.Compiler.resolve(Compiler.java:6818)
	at clojure.lang.Compiler.analyzeSymbol(Compiler.java:6779)
	at clojure.lang.Compiler.analyze(Compiler.java:6343)
	... 25 more

With patch:

$ java -cp target/clojure-1.5.0-master-SNAPSHOT.jar clojure.main i-dont-exist.clj
java.lang.RuntimeException: Unable to resolve symbol: i-dont-exist in this context, compiling:(/home/wilfred/src/clojure/i-dont-exist.clj:1:1)

I'm not familiar with the compiler internals, but I've attached a tentative patch. Undoubtedly it isn't perfect. For one, it would be nicer to say 'Syntax error' rather than 'java.lang.RuntimeException'. All the tests pass with this change.

Relevant mailing list discussion: https://groups.google.com/forum/?fromgroups=#!searchin/clojure/wilfred/clojure/M5NlEW7HJ_c/joUY6mo6Rd8J

Please let me know what you think. This would make my life easier when developing.



 Comments   
Comment by Stuart Halloway [ 29/Mar/13 6:06 AM ]

It is easy for tools that consume Clojure to hide stack traces for those who do not want to see them. If Clojure itself eats stack traces, it is impossible for those of us who do want to see them to get them back.

Please do this kind of work in tool (if at all) and make it optional for users.





[CLJ-1050] Remove a lock in the common case of deref of delay Created: 26/Aug/12  Updated: 18/Sep/12  Resolved: 18/Sep/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.4
Fix Version/s: None

Type: Enhancement Priority: Trivial
Reporter: Nicolas Oury Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: enhancement, patch, performance

Attachments: Text File 0001-No-lock-in-the-common-path-for-delays.patch    

 Description   

Currently, when deref is called in Delay.java, a lock on the Delay is always acquired.
This is wasteful as most of the time you just want to read the val.

The attached patch changes this behaviour to the following:

  • val is initialised to a known secret value. (During its constructor so it is visible from any thread).
  • When deref is called, val is checked to the known secret value.
  • If it is not the secret value, then it has to be the value computed by the function and we return it.
  • If it is the secret value, then we lock this object and revert to the current behaviour.

This is faster than what is done currently and can be very much faster if there is contention on the delay.



 Comments   
Comment by Nicolas Oury [ 27/Aug/12 2:37 AM ]

Please close and reject. The patch is not working if val has non final fields.





[CLJ-1042] [PATCH] Allow negative substring indices for (subs) Created: 14/Aug/12  Updated: 19/Sep/12  Resolved: 17/Sep/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.5
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Ian Eure Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: enhancement, patch

Attachments: Text File clj-1042-negative-indices-patch3.txt     Text File negative-subs.patch    
Patch: Code and Test

 Description   

This adds Python-style negative string indices for (subs), e.g.:

(subs "foo bar" -3) ;; -> "bar"



 Comments   
Comment by Andy Fingerhut [ 16/Aug/12 7:17 PM ]

Ian, thanks for the patch. It is Rich Hickey's policy only to consider applying patches to Clojure from those who have signed a Clojure contributor agreement: http://clojure.org/contributing

Were you interested in doing so, or perhaps it is already in progress?

Comment by Ian Eure [ 20/Aug/12 11:44 AM ]

I wasn't aware that this was necessary. I'm mailing the form in.

Comment by Andy Fingerhut [ 27/Aug/12 7:56 PM ]

Patch clj-1042-negative-subs-patch2.txt dated Aug 27 2012 is identical to Ian Eure's negative-subs.patch, except it is in the desired git format.

Ian, for future reference on creating patches in the desired format, see the instructions under the heading "Development" on this page: http://dev.clojure.org/display/design/JIRA+workflow

Comment by Ian Eure [ 28/Aug/12 11:47 AM ]

Thanks, will do.

Comment by Steve Miner [ 04/Sep/12 3:53 PM ]

If Clojure decides to support Python-style negative indices, you should also consider adding support to subvec.

Comment by Ian Eure [ 06/Sep/12 12:17 PM ]

Patch extended to support negative indices on (subvec) as well.

Comment by Adrian Bendel [ 07/Sep/12 8:01 AM ]

The arg to rindex should probably be tagged with ^clojure.lang.Counted instead of ^String now.

Comment by Steve Miner [ 07/Sep/12 1:31 PM ]

Regarding the previous comment, String is a Java class so it isn't a clojure.lang.Counted. Is the type hint necessary? Maybe it should be on the call rather than the defn.

Ignoring the type hinting, I'll suggest a slightly simpler way to implement the rindex logic:

(defn rindex [coll i]
(if (neg? i) (+ (count coll) i) i))

In any case, I'm not sure rindex should be public even if you want the subs and subvec enhancements. Someone needs to make the case for adding a new function to core.

The Pythonic negative index is a debatable feature since it's pretty easy to implement for yourself if you want it.

Comment by Adrian Bendel [ 07/Sep/12 11:05 PM ]

Sorry, the type hint on rindex args isn't necessary at all. Just looked up in the source, calling count should never be reflective, since (count ..) emits calls to clojure.lang.RT/count.

Your solution looks good.

Comment by Stuart Halloway [ 17/Sep/12 7:07 AM ]

Negative indices were considered and rejected a long time ago. (I am merely conveying information--I have no strong opinion on this one.)

Comment by Andy Fingerhut [ 17/Sep/12 12:07 PM ]

Note: If some people really like negative index behavior as in Perl or Python, it is straightforward to create a library of functions in a different namespace, perhaps with different names, that can do it. Perhaps a "pythonisms" library?

Comment by Ian Eure [ 18/Sep/12 12:31 PM ]

Would this be accepted as part of clojure.string instead? I considered putting it there, but thought it would be confusing to have multiple substring functions in different namespaces.

This is very helpful in practice, and I'd really like to see at least the (subs) stuff in Clojure.

Comment by Andy Fingerhut [ 18/Sep/12 2:52 PM ]

Disclaimer: I'm no Clojure/core member, so can't speak authoritatively on whether something would or would not be accepted into clojure.string.

However, given that clojure.string is distributed with clojure.core, my guess is it would not be accepted. You'd be able to get things like this out for you and others as a separate library distributed on Clojars. That would also make it easy to include other Python-like things that you don't find in Clojure already.

Comment by Ian Eure [ 18/Sep/12 4:02 PM ]

This isn't about "python-like things," this is about a useful feature. Lots of languages support this: Perl, PHP, Ruby, Python, JavaScript, to name a few. Are you really suggesting that I should create a whole package for a version of a function in clojure.core with slightly different semantics? That's insane.

Anyway, I'm done wasting my time trying to navigate this hopelessly broken process. Maybe it would have been accepted if I included yet another way to interoperate with Java types.

Comment by Michael Klishin [ 18/Sep/12 5:09 PM ]

Stuart, do you remember why specifically negative indexes were rejected? Developing a separate library for a minor improvement to an existing function sounds unreasonable.

Comment by Carlos [ 18/Sep/12 5:10 PM ]

some explanation about this topic was given by Rich Hickey himself here: http://news.ycombinator.com/item?id=2053908

citation:
"...Yes, there is a backlog from when it was just me, and it will take a while to whittle down. We have finite resources and have to prioritize. I can assure you we have more important things to concentrate on than your negative index substring enhancement, and are doing so. You'll just have to be patient. Or, if you insist, I'll just reject it now because a) IMO it's goofy, b) you can make your own function that works that way c) we don't get a free ride from j.l.String, d) it begs the question of negative indices elsewhere..."

i've been following this thread hoping this feature would be included. but whatever the reason was for the rejection, i'm sure it was thoughtful. great thanks for this wonderful language, and thanks Ian Eure for his effort.

Comment by Steve Miner [ 18/Sep/12 5:25 PM ]

That HN link eventually leads back to CLJ-688 which was rejected.

Comment by Stuart Halloway [ 19/Sep/12 12:03 PM ]

Michael: A proposal for negative indexes would need to be systematic in considering implications for all functions that have index arguments.

Ian: Clojure is driven by design, not incremental piling of features.

All: clojure.string is incomplete in more important and fundamental ways than negative indexes. This sucks now, and will suck worse as more code is written in different dialects. I find myself wishing string was a contrib, so we could iterate faster.

Comment by Andy Fingerhut [ 19/Sep/12 1:34 PM ]

Stuart: Any specific proposals for how you'd like to see clojure.string improve? If it can be made a contrib, that would be cool, but understood if that would be considered too breaking of a change. Even if it isn't made a contrib, having tickets for improvement ideas you are willing to see means patches might get written, and they'll get in some time.





[CLJ-1011] clojure.data/diff should cope with null and false values in maps Created: 12/Jun/12  Updated: 18/Aug/12  Resolved: 18/Aug/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.3, Release 1.4
Fix Version/s: Release 1.5

Type: Defect Priority: Minor
Reporter: Philip Aston Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: enhancement, patch

Attachments: Text File 0001-clojure.data-diff-cope-with-falsey-values-in-maps.patch    
Patch: Code and Test
Approval: Ok

 Description   

Current behaviour of clojure.data/diff:

=> (diff {:a false} {:a true})
(nil {:a true} nil)
=> (diff {:a false} {:a nil})
(nil nil nil)

Proposed behaviour:

=> (diff {:a false} {:a true})
({:a false} {:a true} nil)
=> (diff {:a false} {:a nil})
({:a false} {:a nil} nil)


 Comments   
Comment by Philip Aston [ 12/Jun/12 5:04 AM ]
 
From e03a8060214d122ea2ebadf9e8a368f7f593d9f4 Mon Sep 17 00:00:00 2001
From: Philip Aston <philipa@mail.com>
Date: Sun, 10 Jun 2012 13:11:36 +0100
Subject: [PATCH] clojure.data/diff: cope with falsey values in maps

---
 src/clj/clojure/data.clj           |   18 +++++++++++++++++-
 test/clojure/test_clojure/data.clj |    3 ++-
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/src/clj/clojure/data.clj b/src/clj/clojure/data.clj
index 6e8dbcf..345b234 100644
--- a/src/clj/clojure/data.clj
+++ b/src/clj/clojure/data.clj
@@ -30,6 +30,22 @@
      (vec (repeat (apply max (keys m))  nil))
      m)))
 
+(defn- diff-associative-key
+  "Diff associative things a and b, comparing only the key k."
+  [a b k]
+  (let [va (get a k)
+        vb (get b k)
+        [a* b* ab] (diff va vb)
+        in-a (contains? a k)
+        in-b (contains? b k)
+        same (and in-a in-b
+                  (or (not (nil? ab))
+                      (and (nil? va) (nil? vb))))]
+    [(when (and in-a (or (not (nil? a*)) (not same))) {k a*})
+     (when (and in-b (or (not (nil? b*)) (not same))) {k b*})
+     (when same {k ab})
+     ]))
+
 (defn- diff-associative
   "Diff associative things a and b, comparing only keys in ks."
   [a b ks]
@@ -38,7 +54,7 @@
      (doall (map merge diff1 diff2)))
    [nil nil nil]
    (map
-    (fn [k] (map #(when % {k %}) (diff (get a k) (get b k))))
+    (partial diff-associative-key a b)
     ks)))
 
 (defn- diff-sequential
diff --git a/test/clojure/test_clojure/data.clj b/test/clojure/test_clojure/data.clj
index 9bab766..5a241e0 100644
--- a/test/clojure/test_clojure/data.clj
+++ b/test/clojure/test_clojure/data.clj
@@ -27,5 +27,6 @@
        [#{1} #{3} #{2}] (HashSet. [1 2]) (HashSet. [2 3])
        [nil nil [1 2]] [1 2] (into-array [1 2])
        [nil nil [1 2]] (into-array [1 2]) [1 2]
-       [{:a {:c [1]}} {:a {:c [0]}} {:a {:c [nil 2] :b 1}}] {:a {:b 1 :c [1 2]}} {:a {:b 1 :c [0 2]}}))
+       [{:a {:c [1]}} {:a {:c [0]}} {:a {:c [nil 2] :b 1}}] {:a {:b 1 :c [1 2]}} {:a {:b 1 :c [0 2]}}
+       [{:a nil} {:a false} {:b nil :c false}] {:a nil :b nil :c false} {:a false :b nil :c false}))
 
-- 
1.7.9.5
Comment by Andy Fingerhut [ 12/Jun/12 12:43 PM ]

Philip, thanks for writing that patch. Could you please attach it as a file to this ticket, instead of copying and pasting it into a comment? Instructions are under the heading "Adding patches" on this page:

http://dev.clojure.org/display/design/JIRA+workflow

Rich Hickey's policy is only to include code in Clojure that is written by those who have signed a contributor agreement. You can find out more at http://clojure.org/contributing

Comment by Philip Aston [ 12/Jun/12 2:51 PM ]

Thanks Andy. Patch attached:

0001-clojure.data-diff-cope-with-falsey-values-in-maps.patch

I'll send in a CA.

Comment by Philip Aston [ 16/Jun/12 5:27 AM ]

CA snail-mailed yesterday, I guess it will take a week to arrive.

Comment by Philip Aston [ 23/Jun/12 5:00 AM ]

I now have a CA in place.

Comment by Stuart Halloway [ 20/Jul/12 4:51 PM ]

Yeah, this should be fixed.

Comment by Aaron Bedra [ 14/Aug/12 9:42 PM ]

Patch applies cleanly against 4004d267e124f12b65b0d7fb6522f32a75e3c4fb. Submitter is a confirmed CA signer.





[CLJ-1010] A left-to-right-variant of `comp` Created: 11/Jun/12  Updated: 14/Jun/12

Status: Open
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Tassilo Horn Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: enhancement, patch

Attachments: Text File 0001-CLJ-1010-Add-a-left-to-right-version-of-comp-comp.patch    
Patch: Code

 Description   

The function composition function `comp` is quite inefficient in cases like `(apply comp large-seq-of-fns)`, because its arity-greater-than-3 version reverses the seq.

I would be great if there was an alternative `comp*` (or whatever) function which is just like `comp` but composes left-to-right.



 Comments   
Comment by Tassilo Horn [ 11/Jun/12 5:16 AM ]

Here's an implementation.

Comment by Tassilo Horn [ 11/Jun/12 12:41 PM ]

There's something strange with my patch. The creation of a composition of a huge seq of functions is much faster with `comp*` than with `comp`, which is expected, because the seq doesn't need to be reversed.

The strange thing however is that the compositions created with `comp` evaluate about 10-20% faster than those created with `comp*` although the arbitrary-arity version of `comp` is defined in terms of `comp*`: `(apply comp* (reverse (list* f1 f2 f3 fs)))`.

For some benchmarking details, see: https://groups.google.com/d/msg/clojure/MizwTxHwLE4/hGLrMfetlP8J

Comment by Tassilo Horn [ 14/Jun/12 2:32 AM ]

Here's some benchmark:

user> (use 'criterium.core)
nil
user> (let [coll (doall (take 1000000 (repeat inc)))
	   f1 (apply comp* coll) 
	   f2 (apply comp coll)] 
	   (bench (f1 0) :verbose) 
	   (println "---------------------------------------")
	   (bench (f2 0) :verbose))
amd64 Linux 3.4.2-gentoo 2 cpu(s)
OpenJDK 64-Bit Server VM 22.0-b10
Runtime arguments: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n -XX:+TieredCompilation -Xmx1G -Dclojure.compile.path=/home/horn/Repos/clj/testi/target/classes -Dtesti.version=0.1.0-SNAPSHOT -Dclojure.debug=false
Evaluation count             : 600
             Execution time mean : 112.324465 ms  95.0% CI: (112.247218 ms, 112.380682 ms)
    Execution time std-deviation : 6.513809 ms  95.0% CI: (6.477450 ms, 6.553029 ms)
         Execution time lower ci : 105.609401 ms  95.0% CI: (105.609401 ms, 105.622918 ms)
         Execution time upper ci : 122.353763 ms  95.0% CI: (122.353763 ms, 122.405315 ms)
---------------------------------------
amd64 Linux 3.4.2-gentoo 2 cpu(s)
OpenJDK 64-Bit Server VM 22.0-b10
Runtime arguments: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n -XX:+TieredCompilation -Xmx1G -Dclojure.compile.path=/home/horn/Repos/clj/testi/target/classes -Dtesti.version=0.1.0-SNAPSHOT -Dclojure.debug=false
Evaluation count             : 1440
             Execution time mean : 43.519663 ms  95.0% CI: (43.516732 ms, 43.524062 ms)
    Execution time std-deviation : 492.299089 us  95.0% CI: (490.829889 us, 494.198137 us)
         Execution time lower ci : 42.781398 ms  95.0% CI: (42.781398 ms, 42.781398 ms)
         Execution time upper ci : 44.157311 ms  95.0% CI: (44.157311 ms, 44.158513 ms)
nil
Comment by Tassilo Horn [ 14/Jun/12 3:40 AM ]

Ok, I've tracked down the performance difference. This comes from the fact that `reverse` creates a clojure.lang.PersistentList which can be iterated much faster than a (fully realized) LazySeq. If you provide your fncoll in `(apply comp* fncoll)` as vector or list, the application of the created composition is as fast as for `comp`.

So for me, the patch is good and makes sense.





[CLJ-991] partition-by reducer Created: 10/May/12  Updated: 04/Mar/13

Status: Open
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Kevin Downey Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: enhancement, patch, patch,

Attachments: File reducer-partition-by2.diff     File reducer-partition-by3.diff     File reducer-partition-by4.diff     File reducer-partition-by.diff    
Patch: Code and Test

 Comments   
Comment by Rich Hickey [ 14/Aug/12 1:52 PM ]

I'd like to see something much faster than this.

Comment by Kevin Downey [ 15/Aug/12 1:58 AM ]

For reference here is a benchmark of a non-reducers (seq based) process that uses partition-by

user=> (def x (vec (range 1e6)))
#'user/x
user=> (bench (reduce + (map count (partition-by #(or (zero? (mod % 3)) (zero? (mod % 5))) x))))
Evaluation count             : 60
             Execution time mean : 1.072157 sec  95.0% CI: (1.070606 sec, 1.073381 sec)
    Execution time std-deviation : 165.818282 ms  95.0% CI: (163.873585 ms, 168.271261 ms)
         Execution time lower ci : 972.562000 ms  95.0% CI: (972.562000 ms, 973.301850 ms)
         Execution time upper ci : 1.419148 sec  95.0% CI: (1.419148 sec, 1.419148 sec)

Found 7 outliers in 60 samples (11.6667 %)
	low-severe	 2 (3.3333 %)
	low-mild	 5 (8.3333 %)
 Variance from outliers : 85.8489 % Variance is severely inflated by outliers
nil
user=>

Same again using r/partition-by from reducer-partition-by.diff

user=> (bench (r/reduce + (r/map count (r/partition-by #(or (zero? (mod % 3)) (zero? (mod % 5))) x))))
Evaluation count             : 60
             Execution time mean : 1.418350 sec  95.0% CI: (1.417738 sec, 1.418948 sec)
    Execution time std-deviation : 66.736477 ms  95.0% CI: (66.186568 ms, 67.610777 ms)
         Execution time lower ci : 1.370419 sec  95.0% CI: (1.370419 sec, 1.370419 sec)
         Execution time upper ci : 1.544151 sec  95.0% CI: (1.544151 sec, 1.544156 sec)

Found 10 outliers in 60 samples (16.6667 %)
	low-severe	 2 (3.3333 %)
	low-mild	 8 (13.3333 %)
 Variance from outliers : 33.5591 % Variance is moderately inflated by outliers
nil
user=> 

(using https://github.com/hugoduncan/criterium for benchmarking)

Comment by Kevin Downey [ 15/Aug/12 2:17 AM ]

same again for r/partition-by from reducers-partition-by2.diff

user=> (bench (r/reduce + (r/map count (r/partition-by #(or (zero? (mod % 3)) (zero? (mod % 5))) x))))
Evaluation count             : 180
             Execution time mean : 307.596806 ms  95.0% CI: (307.271339 ms, 307.961550 ms)
    Execution time std-deviation : 34.060809 ms  95.0% CI: (33.613169 ms, 34.416837 ms)
         Execution time lower ci : 285.339333 ms  95.0% CI: (285.339333 ms, 285.339333 ms)
         Execution time upper ci : 385.087950 ms  95.0% CI: (385.087950 ms, 385.087950 ms)

Found 10 outliers in 60 samples (16.6667 %)
	low-severe	 4 (6.6667 %)
	low-mild	 6 (10.0000 %)
 Variance from outliers : 73.8053 % Variance is severely inflated by outliers
nil
user=> 

same again driven using r/fold (for grins) instead of r/reduce

user=> (bench (r/fold + (r/map count (r/partition-by #(or (zero? (mod % 3)) (zero? (mod % 5))) x))))
Evaluation count             : 360
             Execution time mean : 215.214486 ms  95.0% CI: (214.915417 ms, 215.664236 ms)
    Execution time std-deviation : 36.588464 ms  95.0% CI: (36.305548 ms, 36.847846 ms)
         Execution time lower ci : 185.575000 ms  95.0% CI: (185.575000 ms, 185.575000 ms)
         Execution time upper ci : 287.605175 ms  95.0% CI: (286.547833 ms, 287.605175 ms)

Found 6 outliers in 60 samples (10.0000 %)
	low-severe	 3 (5.0000 %)
	low-mild	 3 (5.0000 %)
 Variance from outliers : 87.6303 % Variance is severely inflated by outliers
nil
user=> 

reducers-partition-by2.diff is faster, but I am not wild about introducing a type and a protocol. also not sure about the CollFold impl.

Comment by Rich Hickey [ 15/Aug/12 6:58 AM ]

Let's leave fold out for this first patch, please.

Comment by Kevin Downey [ 15/Aug/12 2:34 PM ]

reducer-partition-by3.diff is a cleaned up version of reducer-partition-by2.diff without fold

Comment by Devin Walters [ 20/Oct/12 7:07 PM ]

Per Andy Fingerhut's email reducer-partition-by3.diff was failing to apply. This patch should apply cleanly to current master.

Comment by Andy Fingerhut [ 01/Nov/12 6:59 PM ]

Presumptuously changing Approval from Incomplete to None, since the reason for its being marked Incomplete seems to have been addressed with the latest patch.

Comment by Kevin Downey [ 04/Mar/13 2:49 PM ]

should this be assigned to someone?





[CLJ-982] Implement an interface? predicate to balance class? Created: 04/May/12  Updated: 09/Jun/12  Resolved: 08/Jun/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.5
Fix Version/s: None

Type: Enhancement Priority: Trivial
Reporter: David Rupp Assignee: Unassigned
Resolution: Declined Votes: 0
Labels: enhancement, patch, test
Environment:

Any


Attachments: File drupp-add-interface-predicate.diff    
Patch: Code and Test

 Description   

clojure.core implements a class? predicate to detect if a thing is an instance of java.lang.Class. The attached patch implements interface? to further distinguish classes that are also interfaces. This gives us Clojure api for e.g., enumerating all interfaces a thing's base class implements; as in, (filter #(interface? %) (supers (class my-thing))).



 Comments   
Comment by Stuart Halloway [ 08/Jun/12 12:28 PM ]

I would prefer to see this, and other interop/reflective items, in a separate contrib lib.

Comment by David Rupp [ 09/Jun/12 9:08 AM ]

Thanks for the feedback, Stu. Is there an existing contrib lib for stuff like this? Or should I create one?





[CLJ-920] Adds support for FreeDesktop's xdg-open in clojure.java.browse/browse-url. Created: 28/Jan/12  Updated: 01/Mar/13  Resolved: 29/Feb/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: Release 1.3
Fix Version/s: None

Type: Enhancement Priority: Minor
Reporter: Jeremy Heiler Assignee: Unassigned
Resolution: Completed Votes: 0
Labels: enhancement
Environment:

Any environment that supports FreeDesktop, so Linux and BSD mainly.


Attachments: Text File browseurl.patch    
Patch: Code

 Description   

This patch allows environments that support FreeDesktop to browse a URL in their default browser. This is important because unless the desktop environment bridges to Java (like Gnome does) the URL will be opened in a Swing window, which is not always desired.

See: https://github.com/clojure/clojure/pull/14



 Comments   
Comment by Andy Fingerhut [ 10/Feb/12 5:08 AM ]

Is this a duplicate of CLJ-896? Can you look at the patch there and see if there is any advantage to the patch for it vs. the one here? Or perhaps some combination that is an improvement on them both?

Comment by Andy Fingerhut [ 29/Feb/12 1:19 PM ]

The issue is definitely a duplicate of CLJ-896. The proposed patches were different. CLJ-896 now has an attached patch that is an enhancement of what Jeremy Heiler created.





[CLJ-918] Vars with {:macro true} meta data do not work when loaded from AOT compiled file Created: 23/Jan/12  Updated: 13/Sep/12  Resolved: 13/Sep/12

Status: Closed
Project: Clojure
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Trivial
Reporter: Jannik Schorg Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: Compiler, enhancement, metadata
Environment:

Tested with 1.3.0 and 1.4.0


Patch: New

 Description   

When defining a var with ^{:macro true} the call of the binded macro does emit a warning when the definition has been AOT compiled.

See example outputs with demo code here: https://refheap.com/paste/389

Bronsa on #clojure created a patch: http://sprunge.us/bWcc



 Comments   
Comment by Andy Fingerhut [ 13/Sep/12 2:29 PM ]

Duplicate of CLJ-1021. Later ticket kept in preference to this one, because it has a patch and this one does not.





[CCACHE-27] Missing LU and LRU is linear complexity - performance Created: 04/Sep/12  Updated: 12/Sep/12

Status: Open
Project: core.cache
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Ghadi Shayban Assignee: Fogus
Resolution: Unresolved Votes: 0
Labels: enhancement, performance
Environment:

Mac Oracle JDK, Linux OpenJDK


Attachments: Text File priority-map-fixed.patch     Text File priority-map.patch    
Patch: Code

 Description   

Profiling some code with YourKit showed a hotspot in cache statistics on (miss) for LU and LRU caches.

Basically two issues: (count (keys {....})) is a count of a seq, not efficient. Replaced with a count of the map.

Secondly, (apply f anything) is slow. Profiler showed that the (apply min-key) was really slow. This is mitigated by using a c.d.priority-map instead. On a priority-map, (ffirst {}) or (first (peek {}).

Also inverted the logic for threshold comparison. Since there is a (build-leastness-queue) that populates statistics, should caches should favor codepaths for the state of being full all the time?



 Comments   
Comment by Ghadi Shayban [ 06/Sep/12 10:49 PM ]

I take back the part about (apply) being slow. I think it's more the fact that it's doing a linear scan on keys every single time.

(apply) does show up a lot in a profiler, but I haven't figured out why. (apply + (range big)) seems to even be slightly faster than (reduce +) on the same range.

Comment by Ghadi Shayban [ 12/Sep/12 9:27 AM ]

Patch in proper format





[CCACHE-22] Change limit parameter name in TTLCache Created: 30/Mar/12  Updated: 15/Jun/12  Resolved: 15/Jun/12

Status: Resolved
Project: core.cache
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Enhancement Priority: Trivial
Reporter: Sebastián Bernardo Galkin Assignee: Fogus
Resolution: Completed Votes: 0
Labels: enhancement, patch,, ttl

Attachments: Text File Changed-limit-parameter-name-in-TTLCache.patch    
Patch: Code

 Description   

"limit" is used in other caches to represent quantity, for TTL it represents time. Using the same name is confusing



 Comments   
Comment by Fogus [ 15/Jun/12 1:48 PM ]

Changed to :ttl-ms





[CCACHE-4] Added LIRS factory fn Created: 06/Dec/11  Updated: 08/Dec/11  Resolved: 08/Dec/11

Status: Resolved
Project: core.cache
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Task Priority: Major
Reporter: Fogus Assignee: Fogus
Resolution: Completed Votes: 0
Labels: cache, enhancement


 Description   

LIRS is implemented as a type only ATM. There should also be a corresponding factory fn.



 Comments   
Comment by Fogus [ 08/Dec/11 12:11 PM ]

Completed in f4d1bf9f1069ba875a7a6a8a65646b35c6fbfd8f





Generated at Sat May 18 22:22:54 CDT 2013 using JIRA 4.4#649-r158309.