Import upstream version 1.11.1
Debian Janitor
2 years ago
0 | Hi! This project does not accept pull requests. | |
1 | ||
2 | Please see the guidelines for contribution on how to file issues or provide patches: | |
3 | ||
4 | https://github.com/clojure/clojure/blob/master/CONTRIBUTING.md |
0 | If you'd like to submit a patch, please follow the [contributing guidelines](http://clojure.org/contributing). | |
0 | Hi! Thanks for your interest in Clojure! | |
1 | ||
2 | ## I want to ask a question | |
3 | ||
4 | If you have a question about Clojure, please use the official Ask Clojure forum at https://ask.clojure.org. This forum is monitored by the Clojure maintainers. | |
5 | ||
6 | ## I want to discuss an idea | |
7 | ||
8 | There are many interactive Clojure forums for discussion and you can find a list at [Clojure Discussion](https://clojure.org/community/resources#_clojure_discussion). | |
9 | ||
10 | ## I want to file a bug / suggest an enhancement | |
11 | ||
12 | Please file it as a question on https://ask.clojure.org with the tag "problem" (possible bugs) or "request" (enhancements). | |
13 | ||
14 | ## I want to provide a patch / PR | |
15 | ||
16 | If you would like to contribute patches, the Clojure dev process is described in detail at https://clojure.org/dev. | |
17 | ||
18 | In short, this process requires: | |
19 | ||
20 | - [Signing the Contributor Agreement](https://clojure.org/dev/contributor_agreement) | |
21 | - [Requesting jira access](https://clojure.atlassian.net/servicedesk/customer/portal/1) | |
22 | ||
23 | This project does not accept pull requests. | |
24 | ||
25 | ## I am looking for official documentation | |
26 | ||
27 | You can find official documentation on the Clojure web site: | |
28 | ||
29 | * Reference docs https://clojure.org/reference | |
30 | * Tutorials and guides: https://clojure.org/guides | |
31 | * API: https://clojure.org/api/api | |
32 | ||
33 | ## What release should I use? | |
34 | ||
35 | Find the current release info here: | |
36 | ||
37 | https://clojure.org/releases/downloads | |
38 | ||
39 | A list of all releases can be found here: | |
40 | ||
41 | https://clojure.org/releases/downloads_older |
81 | 81 | <arg value="clojure.data"/> |
82 | 82 | <arg value="clojure.reflect"/> |
83 | 83 | <arg value="clojure.datafy"/> |
84 | <arg value="clojure.instant"/> | |
85 | <arg value="clojure.uuid"/> | |
86 | <arg value="clojure.core.reducers"/> | |
87 | <arg value="clojure.math"/> | |
84 | 88 | </java> |
85 | 89 | </target> |
86 | 90 | |
100 | 104 | <!--<sysproperty key="clojure.compiler.disable-locals-clearing" value="true"/>--> |
101 | 105 | <sysproperty key="clojure.compiler.direct-linking" value="${directlinking}"/> |
102 | 106 | <arg value="clojure.test-clojure.protocols.examples"/> |
107 | <arg value="clojure.test-clojure.proxy.examples"/> | |
103 | 108 | <arg value="clojure.test-clojure.genclass.examples"/> |
104 | 109 | <arg value="clojure.test-clojure.compilation.load-ns"/> |
105 | 110 | <arg value="clojure.test-clojure.annotations"/> |
112 | 117 | unless="maven.test.skip"> |
113 | 118 | <java classname="clojure.main" failonerror="true" fork="true"> |
114 | 119 | <sysproperty key="clojure.test-clojure.exclude-namespaces" |
115 | value="#{clojure.test-clojure.compilation.load-ns}"/> | |
120 | value="#{clojure.test-clojure.compilation.load-ns clojure.test-clojure.ns-libs-load-later}"/> | |
116 | 121 | <sysproperty key="clojure.compiler.direct-linking" value="${directlinking}"/> |
117 | 122 | <classpath> |
118 | 123 | <pathelement path="${maven.test.classpath}"/> |
0 | 0 | <!-- -*- mode: markdown ; mode: visual-line ; coding: utf-8 -*- --> |
1 | ||
2 | # Changes to Clojure in Version 1.11.1 | |
3 | ||
4 | * [CLJ-2701](https://clojure.atlassian.net/browse/CLJ-2701) | |
5 | Pin serialVersionUID for Keyword and ArraySeq back to 1.10.3 values to retain binary serialization | |
6 | ||
7 | # Changes to Clojure in Version 1.11.0 | |
8 | ||
9 | ## 1 Compatibility | |
10 | ||
11 | ### 1.1 Security | |
12 | ||
13 | Because XML external entity (XXE) attacks can be used to disclose local files using file schemes or relative paths in the system identifier, `clojure.xml/parse` now disables external entity processing by default. | |
14 | ||
15 | See: https://owasp.org/www-community/vulnerabilities/XML_External_Entity_(XXE)_Processing | |
16 | ||
17 | This change disables the following SAX parser features: | |
18 | ||
19 | * `http://apache.org/xml/features/nonvalidating/load-external-dtd` | |
20 | * `http://xml.org/sax/features/external-general-entities` | |
21 | * `http://xml.org/sax/features/external-parameter-entities` | |
22 | ||
23 | If you rely on these features, modify your calls to `clojure.xml/parse` to explicitly | |
24 | supply `startparse-sax` function as the final argument: | |
25 | `(clojure.xml/parse the-string clojure.xml/startparse-sax)` | |
26 | This modification also works on prior Clojure versions. | |
27 | ||
28 | * [CLJ-2611](http://dev.clojure.org/jira/browse/CLJ-2611) clojure.xml now disables XXE processing by default | |
29 | ||
30 | ### 1.2 Dependencies | |
31 | ||
32 | Updated dependencies: | |
33 | ||
34 | * spec.alpha dependency to 0.3.218 - [changes](https://github.com/clojure/spec.alpha/blob/master/CHANGES.md) | |
35 | * core.specs.alpha dependency to 0.2.62 - [changes](https://github.com/clojure/core.specs.alpha/blob/master/CHANGES.md) | |
36 | ||
37 | ## 2 Features | |
38 | ||
39 | ### 2.1 Keyword argument functions take a trailing map | |
40 | ||
41 | Keyword arguments are optional trailing variadic arguments of the form *akey aval bkey bval...*. | |
42 | In Clojure 1.11, functions taking keyword arguments can now be passed a map instead of or in addition | |
43 | to and following the key/value pairs. When a lone map is passed, it is used for destructuring, else | |
44 | a trailing map is added to the key/value pair map by `conj`. | |
45 | ||
46 | Also see: https://clojure.org/news/2021/03/18/apis-serving-people-and-programs | |
47 | ||
48 | * [CLJ-2603](https://clojure.atlassian.net/browse/CLJ-2603) Clojure keyword argument functions now also accept a map | |
49 | ||
50 | ### 2.2 `:as-alias` in `require` | |
51 | ||
52 | Spec (and other libs) rely on qualified keywords as spec names. | |
53 | Namespace aliasing in `ns` makes long names shorter but required namespaces to be loadable. | |
54 | This change adds `:as-alias` to `require`, which is like `:as` but does not require the namespace to load. | |
55 | ||
56 | * [CLJ-2123](https://clojure.atlassian.net/browse/CLJ-2123) Add :as-alias option to require like :as but not load | |
57 | * [CLJ-2665](https://clojure.atlassian.net/browse/CLJ-2665) Fix require with :as and :as-alias to load | |
58 | ||
59 | ## 3 New functions and namespaces | |
60 | ||
61 | ### 3.1 clojure.math and numeric helper functions | |
62 | ||
63 | Added a new clojure.math namespace which provides wrappers for the functions available in java.lang.Math. | |
64 | These functions are narrowed to only `long` and `double` overloads and provide primitive support without reflection. | |
65 | ||
66 | In addition, the following functions were added to clojure.core: | |
67 | ||
68 | * `abs` - absolute value in optimized form for all Clojure numeric types (long, double, ratio, bigint, bigdecimal) | |
69 | * `NaN?` - predicate for doubles to check whether "not a number" | |
70 | * `infinite?` - predicate for doubles to check whether positive or negative infinity | |
71 | ||
72 | * [CLJ-2668](https://clojure.atlassian.net/browse/CLJ-2668) Add NaN? and infinite? predicates | |
73 | * [CLJ-2664](https://clojure.atlassian.net/browse/CLJ-2664) Add clojure.java.math namespace, wrappers for java.lang.Math | |
74 | * [CLJ-2673](https://clojure.atlassian.net/browse/CLJ-2673) Add `abs`, and update `min` and `max` to use Math impls when possible | |
75 | * [CLJ-2677](https://clojure.atlassian.net/browse/CLJ-2677) clojure.math - fix method reflection in bodies and inlines, fix docstrings, renamed | |
76 | * [CLJ-2689](https://clojure.atlassian.net/browse/CLJ-2689) Fix clojure.math tests to be more tolerant of floating point comparisons | |
77 | ||
78 | ### 3.2 Parser functions | |
79 | ||
80 | Added the following parsing functions to clojure.core: | |
81 | ||
82 | * `parse-double` - parses floating point number, including scientific notation | |
83 | * `parse-long` - parses integer in long range | |
84 | * `parse-boolean` - parses `"true"` or `"false"` to the canonical boolean values | |
85 | * `parse-uuid` - parses a UUID string to java.util.UUID | |
86 | ||
87 | All of these functions expect a string argument and return either the parsed value or `nil` if the value | |
88 | is in invalid format. | |
89 | ||
90 | * [CLJ-2667](https://clojure.atlassian.net/browse/CLJ-2667) Add functions to parse a single long/double/uuid/boolean from a string | |
91 | ||
92 | ### 3.2 `random-uuid` | |
93 | ||
94 | Added `random-uuid`, a function to construct a random java.util.UUID. | |
95 | ||
96 | * [CLJ-1925](https://clojure.atlassian.net/browse/CLJ-1925) Add random-uuid | |
97 | ||
98 | ### 3.3 `update-keys` and `update-vals` | |
99 | ||
100 | Added: | |
101 | ||
102 | * `update-keys` - applies a function to every key in a map, `m f => {(f k) v ...}` | |
103 | * `update-vals` - applies a function to every value in a map, `m f => {k (f v) ...}` | |
104 | ||
105 | * [CLJ-1959](https://clojure.atlassian.net/browse/CLJ-1959) Add implementation of update-keys | |
106 | * [CLJ-2651](https://clojure.atlassian.net/browse/CLJ-2651) Add implementation of update-vals | |
107 | ||
108 | ### 3.4 `iteration` | |
109 | ||
110 | Added `iteration`, to repeatedly apply a (possibly impure) step function with continuation state. | |
111 | This can be used e.g. to consume APIs that return paginated or batched data. | |
112 | ||
113 | * [CLJ-2555](https://clojure.atlassian.net/browse/CLJ-2555) Add `iteration` generator function | |
114 | * [CLJ-2690](https://clojure.atlassian.net/browse/CLJ-2690) Improve `iteration` docstring and arg names | |
115 | * [CLJ-2685](https://clojure.atlassian.net/browse/CLJ-2685) Fix `iteration` generative test failure | |
116 | ||
117 | ## 4 Fixes | |
118 | ||
119 | ### 4.1 Compiler | |
120 | ||
121 | * [CLJ-2680](https://clojure.atlassian.net/browse/CLJ-2680) Fix type hinting a primitive local with matching type hint to not error | |
122 | * [CLJ-1180](https://clojure.atlassian.net/browse/CLJ-1180) Fix resolution of class type hints in `defprotocol` | |
123 | * [CLJ-1973](https://clojure.atlassian.net/browse/CLJ-1973) Make order of emitted protocol methods in generated classes reproducible | |
124 | ||
125 | ### 4.2 Core | |
126 | ||
127 | * [CLJ-1879](https://clojure.atlassian.net/browse/CLJ-1879) IKVReduce - make IPersistentMap case faster and extend to Object, detaching it from any fully enumerable set of types | |
128 | * [CLJ-2065](https://clojure.atlassian.net/browse/CLJ-2065) IKVReduce - add direct support for SubVector | |
129 | * [CLJ-2663](https://clojure.atlassian.net/browse/CLJ-2663) Fix vector `=` not terminating when called with infinite sequence | |
130 | * [CLJ-2679](https://clojure.atlassian.net/browse/CLJ-2679) Fix hash collisions in `case` expressions on symbols | |
131 | * [CLJ-2600](https://clojure.atlassian.net/browse/CLJ-2600) Don't block `realized?` of `delay` on pending result | |
132 | * [CLJ-2649](https://clojure.atlassian.net/browse/CLJ-2649) Fix order of checks in `some-fn` and `every-pred` for 3 predicate case to match other unrollings | |
133 | * [CLJ-2234](https://clojure.atlassian.net/browse/CLJ-2234) Fix multimethod preferences to correctly use local hierarchy when it exists | |
134 | * [CLJ-2556](https://clojure.atlassian.net/browse/CLJ-2556) Fix `into` completion so `halt-when` works | |
135 | ||
136 | ### 4.3 Performance | |
137 | ||
138 | * [CLJ-1808](https://clojure.atlassian.net/browse/CLJ-1808) `map-invert` should use `reduce-kv` and transient | |
139 | * [CLJ-2621](https://clojure.atlassian.net/browse/CLJ-2621) Fix unnecessary boxing of unused return in statement context for instance method expr | |
140 | * [CLJ-2670](https://clojure.atlassian.net/browse/CLJ-2670) Use Math.exact... methods for checked long math ops for performance | |
141 | * [CLJ-2636](https://clojure.atlassian.net/browse/CLJ-2636) Get rid of reflection on java.util.Properties when defining `*clojure-version*` | |
142 | * [CLJ-1509](https://clojure.atlassian.net/browse/CLJ-1509) AOT compile clojure.instant, clojure.uuid, clojure.core.reducers in build | |
143 | ||
144 | ### 4.4 Error messages | |
145 | ||
146 | * [CLJ-2529](https://clojure.atlassian.net/browse/CLJ-2529) Fix incorrect reporting of runtime errors as compiler errors in calls through `Compiler.load()` | |
147 | * [CLJ-2350](https://clojure.atlassian.net/browse/CLJ-2350) Improve keyword arity exception message | |
148 | ||
149 | ### 4.5 Docstrings | |
150 | ||
151 | * [CLJ-2249](https://clojure.atlassian.net/browse/CLJ-2249) Clarify `get` docstring regarding sets, strings, arrays, ILookup | |
152 | * [CLJ-2488](https://clojure.atlassian.net/browse/CLJ-2488) Add definition to `reify` docstring | |
153 | * [CLJ-1360](https://clojure.atlassian.net/browse/CLJ-1360) Update `clojure.string/split` docstring regarding trailing empty parts | |
154 | * [CLJ-2444](https://clojure.atlassian.net/browse/CLJ-2444) Fix typo in `test-vars` docstring | |
155 | * [CLJ-2666](https://clojure.atlassian.net/browse/CLJ-2666) Make Clojure Java API javadoc text match the example | |
156 | ||
157 | ### 4.6 Other enhancements | |
158 | ||
159 | * [CLJ-2493](https://clojure.atlassian.net/browse/CLJ-2493) clojure.java.browse - Fix `browse-url` hanging on call to xdg-open | |
160 | * [CLJ-1908](https://clojure.atlassian.net/browse/CLJ-1908) clojure.test - Add `run-test` and `run-test-var` to run single test with fixtures and report | |
161 | * [CLJ-1379](https://clojure.atlassian.net/browse/CLJ-1379) clojure.test - Fix quoting of `:actual` form in `:pass` maps | |
162 | * [CLJ-2620](https://clojure.atlassian.net/browse/CLJ-2620) clojure.server - Fix asymmetric handling of `:exception` `:val`s in `prepl` | |
163 | * [CLJ-2387](https://clojure.atlassian.net/browse/CLJ-2387) clojure.server - Fix off-by-one in socket server port validation | |
164 | ||
165 | ||
166 | # Changes to Clojure in Version 1.10.3 | |
167 | ||
168 | ## 1 Changes reverted | |
169 | ||
170 | * [CLJ-2564](https://clojure.atlassian.net/browse/CLJ-2564) | |
171 | Improve error message for case | |
172 | ||
173 | ## 2 Fixes | |
174 | ||
175 | * [CLJ-2453](https://clojure.atlassian.net/browse/CLJ-2453) | |
176 | Enable reader conditionals in Clojure prepl | |
1 | 177 | |
2 | 178 | # Changes to Clojure in Version 1.10.2 |
3 | 179 |
0 | <?xml version="1.0" encoding="UTF-8"?> | |
1 | <module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4"> | |
2 | <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_6" inherit-compiler-output="false"> | |
3 | <output url="file://$MODULE_DIR$/target/classes" /> | |
4 | <output-test url="file://$MODULE_DIR$/target/test-classes" /> | |
5 | <content url="file://$MODULE_DIR$"> | |
6 | <sourceFolder url="file://$MODULE_DIR$/src/jvm" isTestSource="false" /> | |
7 | <sourceFolder url="file://$MODULE_DIR$/test/java" isTestSource="true" /> | |
8 | <sourceFolder url="file://$MODULE_DIR$/src/resources" type="java-resource" /> | |
9 | <sourceFolder url="file://$MODULE_DIR$/test/clojure" isTestSource="true" /> | |
10 | <sourceFolder url="file://$MODULE_DIR$/src/clj" type="java-resource" /> | |
11 | <excludeFolder url="file://$MODULE_DIR$/target" /> | |
12 | <excludeFolder url="file://$MODULE_DIR$/test-classes" /> | |
13 | </content> | |
14 | <orderEntry type="inheritedJdk" /> | |
15 | <orderEntry type="sourceFolder" forTests="false" /> | |
16 | <orderEntry type="library" scope="PROVIDED" name="Maven: org.codehaus.jsr166-mirror:jsr166y:1.7.0" level="project" /> | |
17 | <orderEntry type="library" scope="TEST" name="Maven: org.clojure:test.generative:0.5.2" level="project" /> | |
18 | <orderEntry type="library" scope="TEST" name="Maven: org.clojure:tools.namespace:0.2.10" level="project" /> | |
19 | <orderEntry type="library" scope="TEST" name="Maven: org.clojure:data.generators:0.1.2" level="project" /> | |
20 | <orderEntry type="library" scope="TEST" name="Maven: org.clojure:test.check:0.5.9" level="project" /> | |
21 | </component> | |
22 | </module>⏎ |
0 | ;; This code was used to generate the clojure.math namespace in | |
1 | ;; Clojure 1.11 to wrap Java 1.8 java.lang.Math methods. There are | |
2 | ;; many small tweaks in this to get exactly the output that was | |
3 | ;; desired and it was not intended to be reused in any way, it is | |
4 | ;; included here for future reference. | |
5 | ||
6 | (ns gen-math | |
7 | (:require | |
8 | [clojure.reflect :as reflect] | |
9 | [clojure.set :as set] | |
10 | [clojure.string :as str]) | |
11 | (:import | |
12 | [java.io StringWriter Writer])) | |
13 | ||
14 | ;; manually created | |
15 | (declare HEADER) | |
16 | (declare FNS) | |
17 | (declare DOCS) | |
18 | (declare ARGS) | |
19 | (declare ARGTYPES) | |
20 | ||
21 | (def const-template | |
22 | "(def | |
23 | ^{:doc %s | |
24 | :added %s | |
25 | :const true | |
26 | :tag %s} | |
27 | %s | |
28 | %s)\n\n") | |
29 | ||
30 | (defn- emit-constant | |
31 | [^Writer writer {:keys [cname name added type]}] | |
32 | (let [sym (symbol (str cname) (str name)) | |
33 | doc (str "\"" (get DOCS (symbol name)) "\"") | |
34 | tag (str "'" type)] | |
35 | (.write writer | |
36 | (format const-template doc (pr-str added) tag name sym)))) | |
37 | ||
38 | (def fn-template | |
39 | "(defn %s | |
40 | {:doc %s | |
41 | :inline-arities %s | |
42 | :inline %s | |
43 | :added %s} | |
44 | %s%s | |
45 | %s)\n\n") | |
46 | ||
47 | (defn- clojurize | |
48 | [sym] | |
49 | (or | |
50 | (get '{IEEEremainder IEEE-remainder} sym) | |
51 | (let [s (name sym)] | |
52 | (symbol | |
53 | (str | |
54 | (reduce | |
55 | (fn [^StringBuilder b ^Character c] | |
56 | (if (Character/isUpperCase c) | |
57 | (.. b (append "-") (append (Character/toLowerCase c))) | |
58 | (.append b c))) | |
59 | (StringBuilder.) | |
60 | s)))))) | |
61 | ||
62 | (defn- inline-body | |
63 | [params param-types] | |
64 | (str/join " " | |
65 | (map (fn [p pt] (format "(%s ~%s)" pt p)) | |
66 | params param-types))) | |
67 | ||
68 | (defn- body | |
69 | [params param-types on-types] | |
70 | (map (fn [p pt] (if (contains? on-types pt) `(~pt ~p) p)) | |
71 | params param-types)) | |
72 | ||
73 | (defn- emit-fn | |
74 | [^Writer writer {:keys [cname fname sigs]}] | |
75 | (let [sym (symbol (str cname) (str fname)) | |
76 | arities (group-by #(-> % :parameter-types count) sigs) | |
77 | arity (-> arities keys first) ;; NOTE: ignore multiple arities, none in Math | |
78 | arity-sigs (get arities arity) | |
79 | cname (clojurize fname) | |
80 | doc (str "\"" (get DOCS cname) "\"") | |
81 | sig (if (= 1 (count arity-sigs)) (first arity-sigs) (get ARGTYPES cname)) | |
82 | {pts :parameter-types, rt :return-type} sig | |
83 | ps (get ARGS cname) | |
84 | ;; coerce all args in inline body | |
85 | inline-body (format "(fn %s `(%s%s))" (pr-str ps) (if (< 0 (count ps)) (str sym " ") sym) (inline-body ps pts)) | |
86 | ;; ps are hinted, so coerce only ps that can't be hinted - int type | |
87 | body `(~sym ~@(body ps pts #{'int})) | |
88 | rts (if (#{'long 'double} rt) (str "^" rt " ") "") | |
89 | hints (map #(if (#{'long 'double} %) (symbol (str "^" %)) nil) pts) | |
90 | pst (vec (remove nil? (interleave hints ps)))] | |
91 | (.write writer | |
92 | (format fn-template cname doc #{arity} inline-body (pr-str "1.11") rts pst body)))) | |
93 | ||
94 | (defn gen-static-wrappers | |
95 | [csym] | |
96 | (let [added "1.11" | |
97 | members (:members (reflect/type-reflect (resolve csym))) | |
98 | statics (filter #(set/subset? #{:public :static} (:flags %)) members) | |
99 | {fs false, ms true} (group-by #(contains? % :return-type) statics) | |
100 | methods (->> ms (filter (fn [m] | |
101 | (or (= 'scalb (:name m)) | |
102 | (empty? (set/intersection #{'int 'float} (set (:parameter-types m)))))))) | |
103 | by-name (group-by :name methods) | |
104 | writer (StringWriter.)] | |
105 | (.write writer HEADER) | |
106 | (doseq [f fs] | |
107 | (emit-constant writer (merge f {:cname csym, :added added}))) | |
108 | (doseq [n FNS] | |
109 | (emit-fn writer {:cname csym, :fname n, :added added, :sigs (get by-name n)})) | |
110 | (spit "src/clj/clojure/math.clj" (str writer)))) | |
111 | ||
112 | (comment | |
113 | (gen-static-wrappers 'Math) | |
114 | ) | |
115 | ||
116 | ;;;; Manually provided info used during the generator | |
117 | ||
118 | (def ^String HEADER | |
119 | "; Copyright (c) Rich Hickey. All rights reserved. | |
120 | ; The use and distribution terms for this software are covered by the | |
121 | ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | |
122 | ; which can be found in the file epl-v10.html at the root of this distribution. | |
123 | ; By using this software in any fashion, you are agreeing to be bound by | |
124 | ; the terms of this license. | |
125 | ; You must not remove this notice, or any other, from this software. | |
126 | ||
127 | (ns | |
128 | ^{:author \"Alex Miller\", | |
129 | :doc \"Clojure wrapper functions for java.lang.Math static methods. | |
130 | ||
131 | Function calls are inlined for performance, and type hinted for primitive | |
132 | long or double parameters where appropriate. In general, Math methods are | |
133 | optimized for performance and have bounds for error tolerance. If | |
134 | greater precision is needed, use java.lang.StrictMath directly instead. | |
135 | ||
136 | For more complete information, see: | |
137 | https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html\"} | |
138 | clojure.math) | |
139 | ||
140 | (set! *warn-on-reflection* true) | |
141 | ||
142 | ") | |
143 | ||
144 | ;; fns | |
145 | ||
146 | ;; omitted: toIntExact | |
147 | ;; omitted but include in core w/polymorphic impl: abs, min, max | |
148 | (def FNS | |
149 | '[sin cos tan asin acos atan toRadians toDegrees exp log log10 | |
150 | sqrt cbrt IEEEremainder ceil floor rint atan2 pow round random | |
151 | addExact subtractExact multiplyExact incrementExact decrementExact negateExact | |
152 | floorDiv floorMod ulp signum sinh cosh tanh hypot expm1 log1p copySign getExponent | |
153 | nextAfter nextUp nextDown scalb]) | |
154 | ||
155 | ;; docstrings to use | |
156 | (def DOCS | |
157 | '{ | |
158 | E "Constant for e, the base for natural logarithms.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#E" | |
159 | PI "Constant for pi, the ratio of the circumference of a circle to its diameter.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#PI" | |
160 | sin "Returns the sine of an angle.\n If a is ##NaN, ##-Inf, ##Inf => ##NaN\n If a is zero => zero with the same sign as a\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#sin-double-" | |
161 | cos "Returns the cosine of an angle.\n If a is ##NaN, ##-Inf, ##Inf => ##NaN\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#cos-double-" | |
162 | tan "Returns the tangent of an angle.\n If a is ##NaN, ##-Inf, ##Inf => ##NaN\n If a is zero => zero with the same sign as a\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#tan-double-" | |
163 | asin "Returns the arc sine of an angle, in the range -pi/2 to pi/2.\n If a is ##NaN or |a|>1 => ##NaN\n If a is zero => zero with the same sign as a\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#asin-double-" | |
164 | acos "Returns the arc cosine of a, in the range 0.0 to pi.\n If a is ##NaN or |a|>1 => ##NaN\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#acos-double-" | |
165 | atan "Returns the arc tangent of a, in the range of -pi/2 to pi/2.\n If a is ##NaN => ##NaN\n If a is zero => zero with the same sign as a\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#atan-double-" | |
166 | to-radians "Converts an angle in degrees to an approximate equivalent angle in radians.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#toRadians-double-" | |
167 | to-degrees "Converts an angle in radians to an approximate equivalent angle in degrees.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#toDegrees-double-" | |
168 | exp "Returns Euler's number e raised to the power of a.\n If a is ##NaN => ##NaN\n If a is ##Inf => ##Inf\n If a is ##-Inf => +0.0\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#exp-double-" | |
169 | log "Returns the natural logarithm (base e) of a.\n If a is ##NaN or negative => ##NaN\n If a is ##Inf => ##Inf\n If a is zero => ##-Inf\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#log-double-" | |
170 | log10 "Returns the logarithm (base 10) of a.\n If a is ##NaN or negative => ##NaN\n If a is ##Inf => ##Inf\n If a is zero => ##-Inf\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#log10-double-" | |
171 | sqrt "Returns the positive square root of a.\n If a is ##NaN or negative => ##NaN\n If a is ##Inf => ##Inf\n If a is zero => a\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#sqrt-double-" | |
172 | cbrt "Returns the cube root of a.\n If a is ##NaN => ##NaN\n If a is ##Inf or ##-Inf => a\n If a is zero => zero with sign matching a\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#cbrt-double-" | |
173 | IEEE-remainder "Returns the remainder per IEEE 754 such that\n remainder = dividend - divisor * n\n where n is the integer closest to the exact value of dividend / divisor.\n If two integers are equally close, then n is the even one.\n If the remainder is zero, sign will match dividend.\n If dividend or divisor is ##NaN, or dividend is ##Inf or ##-Inf, or divisor is zero => ##NaN\n If dividend is finite and divisor is infinite => dividend\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#IEEEremainder-double-double-" | |
174 | ceil "Returns the smallest double greater than or equal to a, and equal to a\n mathematical integer.\n If a is ##NaN or ##Inf or ##-Inf or already equal to an integer => a\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#ceil-double-" | |
175 | floor "Returns the largest double less than or equal to a, and equal to a\n mathematical integer.\n If a is ##NaN or ##Inf or ##-Inf or already equal to an integer => a\n If a is less than zero but greater than -1.0 => -0.0\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floor-double-" | |
176 | rint "Returns the double closest to a and equal to a mathematical integer.\n If two values are equally close, return the even one.\n If a is ##NaN or ##Inf or ##-Inf or zero => a\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#rint-double-" | |
177 | atan2 "Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta).\n Computes the phase theta by computing an arc tangent of y/x in the range of -pi to pi.\n For more details on special cases, see:\n https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#atan2-double-double-" | |
178 | pow "Returns the value of a raised to the power of b.\n For more details on special cases, see:\n https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#pow-double-double-" | |
179 | round "Returns the closest long to a. If equally close to two values, return the one\n closer to ##Inf.\n If a is ##NaN => 0\n If a is ##-Inf or < Long/MIN_VALUE => Long/MIN_VALUE\n If a is ##Inf or > Long/MAX_VALUE => Long/MAX_VALUE\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-double-" | |
180 | random "Returns a positive double between 0.0 and 1.0, chosen pseudorandomly with\n approximately random distribution.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#random--" | |
181 | add-exact "Returns the sum of x and y, throws ArithmeticException on overflow.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#addExact-long-long-" | |
182 | subtract-exact "Returns the difference of x and y, throws ArithmeticException on overflow.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#subtractExact-long-long-" | |
183 | multiply-exact "Returns the product of x and y, throws ArithmeticException on overflow.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#multiplyExact-long-long-" | |
184 | increment-exact "Returns a incremented by 1, throws ArithmeticException on overflow.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#incrementExact-long-" | |
185 | decrement-exact "Returns a decremented by 1, throws ArithmeticException on overflow.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#decrementExact-long-" | |
186 | negate-exact "Returns the negation of a, throws ArithmeticException on overflow.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#negateExact-long-" | |
187 | floor-div "Integer division that rounds to negative infinity (as opposed to zero).\n The special case (floorDiv Long/MIN_VALUE -1) overflows and returns Long/MIN_VALUE.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floorDiv-long-long-" | |
188 | floor-mod "Integer modulus x - (floorDiv(x, y) * y). Sign matches y and is in the\n range -|y| < r < |y|.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floorMod-long-long-" | |
189 | ulp "Returns the size of an ulp (unit in last place) for d.\n If d is ##NaN => ##NaN\n If d is ##Inf or ##-Inf => ##Inf\n If d is zero => Double/MIN_VALUE\n If d is +/- Double/MAX_VALUE => 2^971\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#ulp-double-" | |
190 | signum "Returns the signum function of d - zero for zero, 1.0 if >0, -1.0 if <0.\n If d is ##NaN => ##NaN\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#signum-double-" | |
191 | sinh "Returns the hyperbolic sine of x, (e^x - e^-x)/2.\n If x is ##NaN => ##NaN\n If x is ##Inf or ##-Inf or zero => x\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#sinh-double-" | |
192 | cosh "Returns the hyperbolic cosine of x, (e^x + e^-x)/2.\n If x is ##NaN => ##NaN\n If x is ##Inf or ##-Inf => ##Inf\n If x is zero => 1.0\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#cosh-double-" | |
193 | tanh "Returns the hyperbolic tangent of x, sinh(x)/cosh(x).\n If x is ##NaN => ##NaN\n If x is zero => zero, with same sign\n If x is ##Inf => +1.0\n If x is ##-Inf => -1.0\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#tanh-double-" | |
194 | hypot "Returns sqrt(x^2 + y^2) without intermediate underflow or overflow.\n If x or y is ##Inf or ##-Inf => ##Inf\n If x or y is ##NaN and neither is ##Inf or ##-Inf => ##NaN\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#hypot-double-double-" | |
195 | expm1 "Returns e^x - 1. Near 0, expm1(x)+1 is more accurate to e^x than exp(x).\n If x is ##NaN => ##NaN\n If x is ##Inf => #Inf\n If x is ##-Inf => -1.0\n If x is zero => x\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#expm1-double-" | |
196 | log1p "Returns ln(1+x). For small values of x, log1p(x) is more accurate than\n log(1.0+x).\n If x is ##NaN or < -1 => ##NaN\n If x is ##Inf => ##Inf\n If x is -1 => ##-Inf\n If x is 0 => 0 with sign matching x\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#log1p-double-" | |
197 | copy-sign "Returns a double with the magnitude of the first argument and the sign of\n the second.\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#copySign-double-double-" | |
198 | get-exponent "Returns the exponent of d.\n If d is ##NaN, ##Inf, ##-Inf => Double/MAX_EXPONENT + 1\n If d is zero or subnormal => Double/MIN_EXPONENT - 1\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#getExponent-double-" | |
199 | next-after "Returns the adjacent floating point number to start in the direction of\n the second argument. If the arguments are equal, the second is returned.\n If either arg is #NaN => #NaN\n If both arguments are signed zeros => direction\n If start is +-Double/MIN_VALUE and direction would cause a smaller magnitude\n => zero with sign matching start\n If start is ##Inf or ##-Inf and direction would cause a smaller magnitude\n => Double/MAX_VALUE with same sign as start\n If start is equal to +=Double/MAX_VALUE and direction would cause a larger magnitude\n => ##Inf or ##-Inf with sign matching start\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#nextAfter-double-double-" | |
200 | next-up "Returns the adjacent double of d in the direction of ##Inf.\n If d is ##NaN => ##NaN\n If d is ##Inf => ##Inf\n If d is zero => Double/MIN_VALUE\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#nextUp-double-" | |
201 | next-down "Returns the adjacent double of d in the direction of ##-Inf.\n If d is ##NaN => ##NaN\n If d is ##-Inf => ##-Inf\n If d is zero => -Double/MIN_VALUE\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#nextDown-double-" | |
202 | scalb "Returns d * 2^scaleFactor, scaling by a factor of 2. If the exponent\n is between Double/MIN_EXPONENT and Double/MAX_EXPONENT, the answer is exact.\n If d is ##NaN => ##NaN\n If d is ##Inf or ##-Inf => ##Inf or ##-Inf respectively\n If d is zero => zero of same sign as d\n See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#nextDown-double-" | |
203 | }) | |
204 | ||
205 | (def FNS | |
206 | '[sin cos tan asin acos atan toRadians toDegrees exp log log10 | |
207 | sqrt cbrt IEEEremainder ceil floor rint atan2 pow round random | |
208 | addExact subtractExact multiplyExact incrementExact decrementExact negateExact | |
209 | floorDiv floorMod ulp signum sinh cosh tanh hypot expm1 log1p copySign getExponent | |
210 | nextAfter nextUp nextDown scalb]) | |
211 | ||
212 | ;; arg names to use (match java.lang.Math signatures) | |
213 | (def ARGS | |
214 | '{ | |
215 | sin [a] | |
216 | cos [a] | |
217 | tan [a] | |
218 | asin [a] | |
219 | acos [a] | |
220 | atan [a] | |
221 | to-radians [deg] | |
222 | to-degrees [r] | |
223 | exp [a] | |
224 | log [a] | |
225 | log10 [a] | |
226 | sqrt [a] | |
227 | cbrt [a] | |
228 | IEEE-remainder [dividend divisor] | |
229 | ceil [a] | |
230 | floor [a] | |
231 | rint [a] | |
232 | atan2 [y x] | |
233 | pow [a b] | |
234 | round [a] | |
235 | random [] | |
236 | add-exact [x y] | |
237 | subtract-exact [x y] | |
238 | multiply-exact [x y] | |
239 | increment-exact [a] | |
240 | decrement-exact [a] | |
241 | negate-exact [a] | |
242 | floor-div [x y] | |
243 | floor-mod [x y] | |
244 | ulp [d] | |
245 | signum [d] | |
246 | sinh [x] | |
247 | cosh [x] | |
248 | tanh [x] | |
249 | hypot [x y] | |
250 | expm1 [x] | |
251 | log1p [x] | |
252 | copy-sign [magnitude sign] | |
253 | get-exponent [d] | |
254 | next-after [start direction] | |
255 | next-up [d] | |
256 | next-down [d] | |
257 | scalb [d scaleFactor] | |
258 | }) | |
259 | ||
260 | ;; type signature to use (otherwise automatically determined) | |
261 | (def ARGTYPES | |
262 | '{scalb {:parameter-types [double int] :return-type double}}) |
4 | 4 | <artifactId>clojure</artifactId> |
5 | 5 | <name>clojure</name> |
6 | 6 | <packaging>jar</packaging> |
7 | <version>1.10.2</version> | |
7 | <version>1.11.1</version> | |
8 | 8 | |
9 | 9 | <url>http://clojure.org/</url> |
10 | 10 | <description>Clojure core environment and runtime library.</description> |
29 | 29 | <connection>scm:git:git@github.com:clojure/clojure.git</connection> |
30 | 30 | <developerConnection>scm:git:git@github.com:clojure/clojure.git</developerConnection> |
31 | 31 | <url>git@github.com:clojure/clojure.git</url> |
32 | <tag>clojure-1.10.2</tag> | |
32 | <tag>clojure-1.11.1</tag> | |
33 | 33 | </scm> |
34 | 34 | |
35 | 35 | <properties> |
40 | 40 | <dependency> |
41 | 41 | <groupId>org.clojure</groupId> |
42 | 42 | <artifactId>spec.alpha</artifactId> |
43 | <version>0.2.194</version> | |
43 | <version>0.3.218</version> | |
44 | 44 | </dependency> |
45 | 45 | <dependency> |
46 | 46 | <groupId>org.clojure</groupId> |
47 | 47 | <artifactId>core.specs.alpha</artifactId> |
48 | <version>0.2.56</version> | |
48 | <version>0.2.62</version> | |
49 | 49 | </dependency> |
50 | 50 | <dependency> |
51 | 51 | <groupId>org.clojure</groupId> |
52 | 52 | <artifactId>test.generative</artifactId> |
53 | <version>0.5.2</version> | |
53 | <version>1.0.0</version> | |
54 | 54 | <scope>test</scope> |
55 | 55 | <exclusions> |
56 | 56 | <exclusion> |
62 | 62 | <dependency> |
63 | 63 | <groupId>org.clojure</groupId> |
64 | 64 | <artifactId>test.check</artifactId> |
65 | <version>0.9.0</version> | |
65 | <version>1.1.1</version> | |
66 | 66 | <scope>test</scope> |
67 | 67 | <exclusions> |
68 | 68 | <exclusion> |
206 | 206 | instead, push SCM changes in Hudson configuration --> |
207 | 207 | <groupId>org.apache.maven.plugins</groupId> |
208 | 208 | <artifactId>maven-release-plugin</artifactId> |
209 | <version>2.4.1</version> | |
209 | <version>2.5.3</version> | |
210 | 210 | <configuration> |
211 | 211 | <pushChanges>false</pushChanges> |
212 | 212 | <localCheckout>true</localCheckout> |
226 | 226 | <plugin> |
227 | 227 | <groupId>org.sonatype.plugins</groupId> |
228 | 228 | <artifactId>nexus-staging-maven-plugin</artifactId> |
229 | <version>1.6.7</version> | |
229 | <version>1.6.8</version> | |
230 | 230 | <extensions>true</extensions> |
231 | 231 | <configuration> |
232 | 232 | <!-- The server "id" element from settings to use authentication from --> |
50 | 50 | "Validate server config options" |
51 | 51 | [{:keys [name port accept] :as opts}] |
52 | 52 | (doseq [prop [:name :port :accept]] (required opts prop)) |
53 | (when (or (not (integer? port)) (not (< -1 port 65535))) | |
53 | (when (or (not (integer? port)) (not (<= 0 port 65535))) | |
54 | 54 | (throw (ex-info (str "Invalid socket server port: " port) opts)))) |
55 | 55 | |
56 | 56 | (defn- accept-connection |
225 | 225 | (add-tap tapfn) |
226 | 226 | (loop [] |
227 | 227 | (when (try |
228 | (let [[form s] (read+string in-reader false EOF)] | |
228 | (let [[form s] (read+string {:eof EOF :read-cond :allow} in-reader)] | |
229 | 229 | (try |
230 | 230 | (when-not (identical? form EOF) |
231 | 231 | (let [start (System/nanoTime) |
287 | 287 | (try |
288 | 288 | (assoc m :val (valf (:val m))) |
289 | 289 | (catch Throwable ex |
290 | (assoc m :val (ex->data ex :print-eval-result) | |
290 | (assoc m :val (valf (ex->data ex :print-eval-result)) | |
291 | 291 | :exception true))) |
292 | 292 | m)))))))) |
293 | 293 |
1133 | 1133 | ([x y & more] |
1134 | 1134 | (reduce1 min (min x y) more))) |
1135 | 1135 | |
1136 | (defn abs | |
1137 | {:doc "Returns the absolute value of a. | |
1138 | If a is Long/MIN_VALUE => Long/MIN_VALUE | |
1139 | If a is a double and zero => +0.0 | |
1140 | If a is a double and ##Inf or ##-Inf => ##Inf | |
1141 | If a is a double and ##NaN => ##NaN" | |
1142 | :inline-arities #{1} | |
1143 | :inline (fn [a] `(clojure.lang.Numbers/abs ~a)) | |
1144 | :added "1.11"} | |
1145 | [a] | |
1146 | (clojure.lang.Numbers/abs a)) | |
1147 | ||
1136 | 1148 | (defn dec' |
1137 | 1149 | "Returns a number one less than num. Supports arbitrary precision. |
1138 | 1150 | See also: dec" |
1493 | 1505 | [coll key] (. clojure.lang.RT (contains coll key))) |
1494 | 1506 | |
1495 | 1507 | (defn get |
1496 | "Returns the value mapped to key, not-found or nil if key not present." | |
1508 | "Returns the value mapped to key, not-found or nil if key not present | |
1509 | in associative collection, set, string, array, or ILookup instance." | |
1497 | 1510 | {:inline (fn [m k & nf] `(. clojure.lang.RT (get ~m ~k ~@nf))) |
1498 | 1511 | :inline-arities #{2 3} |
1499 | 1512 | :added "1.0"} |
4370 | 4383 | :static true} |
4371 | 4384 | ([] (. clojure.lang.PersistentArrayMap EMPTY)) |
4372 | 4385 | ([& keyvals] |
4373 | (clojure.lang.PersistentArrayMap/createAsIfByAssoc (to-array keyvals)))) | |
4386 | (let [ary (to-array keyvals)] | |
4387 | (if (odd? (alength ary)) | |
4388 | (throw (IllegalArgumentException. (str "No value supplied for key: " (last keyvals)))) | |
4389 | (clojure.lang.PersistentArrayMap/createAsIfByAssoc ary))))) | |
4390 | ||
4391 | (defn seq-to-map-for-destructuring | |
4392 | "Builds a map from a seq as described in | |
4393 | https://clojure.org/reference/special_forms#keyword-arguments" | |
4394 | {:added "1.11"} | |
4395 | [s] | |
4396 | (if (next s) | |
4397 | (clojure.lang.PersistentArrayMap/createAsIfByAssoc (to-array s)) | |
4398 | (if (seq s) (first s) clojure.lang.PersistentArrayMap/EMPTY))) | |
4374 | 4399 | |
4375 | 4400 | ;;redefine let and loop with destructuring |
4376 | 4401 | (defn destructure [bindings] |
4418 | 4443 | gmapseq (with-meta gmap {:tag 'clojure.lang.ISeq}) |
4419 | 4444 | defaults (:or b)] |
4420 | 4445 | (loop [ret (-> bvec (conj gmap) (conj v) |
4421 | (conj gmap) (conj `(if (seq? ~gmap) (clojure.lang.PersistentHashMap/create (seq ~gmapseq)) ~gmap)) | |
4446 | (conj gmap) (conj `(if (seq? ~gmap) | |
4447 | (if (next ~gmapseq) | |
4448 | (clojure.lang.PersistentArrayMap/createAsIfByAssoc (to-array ~gmapseq)) | |
4449 | (if (seq ~gmapseq) (first ~gmapseq) clojure.lang.PersistentArrayMap/EMPTY)) | |
4450 | ~gmap)) | |
4422 | 4451 | ((fn [ret] |
4423 | 4452 | (if (:as b) |
4424 | 4453 | (conj ret (:as b) gmap) |
4467 | 4496 | |
4468 | 4497 | (defmacro let |
4469 | 4498 | "binding => binding-form init-expr |
4499 | binding-form => name, or destructuring-form | |
4500 | destructuring-form => map-destructure-form, or seq-destructure-form | |
4470 | 4501 | |
4471 | 4502 | Evaluates the exprs in a lexical context in which the symbols in |
4472 | 4503 | the binding-forms are bound to their respective init-exprs or parts |
4473 | therein." | |
4504 | therein. | |
4505 | ||
4506 | See https://clojure.org/reference/special_forms#binding-forms for | |
4507 | more information about destructuring." | |
4474 | 4508 | {:added "1.0", :special-form true, :forms '[(let [bindings*] exprs*)]} |
4475 | 4509 | [bindings & body] |
4476 | 4510 | (assert-args |
4498 | 4532 | |
4499 | 4533 | ;redefine fn with destructuring and pre/post conditions |
4500 | 4534 | (defmacro fn |
4501 | "params => positional-params* , or positional-params* & next-param | |
4535 | "params => positional-params*, or positional-params* & rest-param | |
4502 | 4536 | positional-param => binding-form |
4503 | next-param => binding-form | |
4504 | name => symbol | |
4505 | ||
4506 | Defines a function" | |
4537 | rest-param => binding-form | |
4538 | binding-form => name, or destructuring-form | |
4539 | ||
4540 | Defines a function. | |
4541 | ||
4542 | See https://clojure.org/reference/special_forms#fn for more information" | |
4507 | 4543 | {:added "1.0", :special-form true, |
4508 | 4544 | :forms '[(fn name? [params* ] exprs*) (fn name? ([params* ] exprs*)+)]} |
4509 | 4545 | [& sigs] |
5921 | 5957 | (name lib) prefix) |
5922 | 5958 | (let [lib (if prefix (symbol (str prefix \. lib)) lib) |
5923 | 5959 | opts (apply hash-map options) |
5924 | {:keys [as reload reload-all require use verbose]} opts | |
5960 | {:keys [as reload reload-all require use verbose as-alias]} opts | |
5925 | 5961 | loaded (contains? @*loaded-libs* lib) |
5926 | load (cond reload-all | |
5927 | load-all | |
5928 | (or reload (not require) (not loaded)) | |
5929 | load-one) | |
5930 | 5962 | need-ns (or as use) |
5963 | load (cond reload-all load-all | |
5964 | reload load-one | |
5965 | (not loaded) (cond need-ns load-one | |
5966 | as-alias (fn [lib _need _require] (create-ns lib)) | |
5967 | :else load-one)) | |
5968 | ||
5931 | 5969 | filter-opts (select-keys opts '(:exclude :only :rename :refer)) |
5932 | 5970 | undefined-on-entry (not (find-ns lib))] |
5933 | 5971 | (binding [*loading-verbosely* (or *loading-verbosely* verbose)] |
5939 | 5977 | (remove-ns lib)) |
5940 | 5978 | (throw e))) |
5941 | 5979 | (throw-if (and need-ns (not (find-ns lib))) |
5942 | "namespace '%s' not found" lib)) | |
5980 | "namespace '%s' not found" lib)) | |
5943 | 5981 | (when (and need-ns *loading-verbosely*) |
5944 | 5982 | (printf "(clojure.core/in-ns '%s)\n" (ns-name *ns*))) |
5945 | 5983 | (when as |
5946 | 5984 | (when *loading-verbosely* |
5947 | 5985 | (printf "(clojure.core/alias '%s '%s)\n" as lib)) |
5948 | 5986 | (alias as lib)) |
5987 | (when as-alias | |
5988 | (when *loading-verbosely* | |
5989 | (printf "(clojure.core/alias '%s '%s)\n" as-alias lib)) | |
5990 | (alias as-alias lib)) | |
5949 | 5991 | (when (or use (:refer filter-opts)) |
5950 | 5992 | (when *loading-verbosely* |
5951 | 5993 | (printf "(clojure.core/refer '%s" lib) |
5962 | 6004 | opts (interleave flags (repeat true)) |
5963 | 6005 | args (filter (complement keyword?) args)] |
5964 | 6006 | ; check for unsupported options |
5965 | (let [supported #{:as :reload :reload-all :require :use :verbose :refer} | |
6007 | (let [supported #{:as :reload :reload-all :require :use :verbose :refer :as-alias} | |
5966 | 6008 | unsupported (seq (remove supported flags))] |
5967 | 6009 | (throw-if unsupported |
5968 | 6010 | (apply str "Unsupported option(s) supplied: " |
6026 | 6068 | Recognized options: |
6027 | 6069 | :as takes a symbol as its argument and makes that symbol an alias to the |
6028 | 6070 | lib's namespace in the current namespace. |
6071 | :as-alias takes a symbol as its argument and aliases like :as, however | |
6072 | the lib will not be loaded. If the lib has not been loaded, a new | |
6073 | empty namespace will be created (as with create-ns). | |
6029 | 6074 | :refer takes a list of symbols to refer from the namespace or the :all |
6030 | 6075 | keyword to bring in all public vars. |
6031 | 6076 | |
6042 | 6087 | A flag is a keyword. |
6043 | 6088 | Recognized flags: :reload, :reload-all, :verbose |
6044 | 6089 | :reload forces loading of all the identified libs even if they are |
6045 | already loaded | |
6090 | already loaded (has no effect on libspecs using :as-alias) | |
6046 | 6091 | :reload-all implies :reload and also forces loading of all libs that the |
6047 | 6092 | identified libs directly or indirectly load via require or use |
6093 | (has no effect on libspecs using :as-alias) | |
6048 | 6094 | :verbose triggers printing information about each load, alias, and refer |
6049 | 6095 | |
6050 | 6096 | Example: |
6437 | 6483 | Supported options: |
6438 | 6484 | :elide-meta - a collection of metadata keys to elide during compilation. |
6439 | 6485 | :disable-locals-clearing - set to true to disable clearing, useful for using a debugger |
6440 | Alpha, subject to change." | |
6486 | :direct-linking - set to true to use direct static invocation of functions, rather than vars | |
6487 | Note that call sites compiled with direct linking will not be affected by var redefinition. | |
6488 | Use ^:redef (or ^:dynamic) on a var to prevent direct linking and allow redefinition. | |
6489 | See https://clojure.org/reference/compilation for more information." | |
6441 | 6490 | {:added "1.4"}) |
6442 | 6491 | |
6443 | 6492 | (add-doc-and-meta *ns* |
6651 | 6700 | (next ks) (next vs)) |
6652 | 6701 | m)) |
6653 | 6702 | assoc-multi (fn [m h bucket] |
6654 | (let [testexprs (apply concat bucket) | |
6703 | (let [testexprs (mapcat (fn [kv] [(list 'quote (first kv)) (second kv)]) bucket) | |
6655 | 6704 | expr `(condp = ~expr-sym ~@testexprs ~default)] |
6656 | 6705 | (assoc m h expr))) |
6657 | 6706 | hmap (reduce1 |
6694 | 6743 | (into1 #{} (map #(shift-mask shift mask %) skip-check)))] |
6695 | 6744 | [shift mask case-map switch-type skip-check])))) |
6696 | 6745 | |
6697 | (defn case-fallthrough-err-impl | |
6698 | [val] | |
6699 | (IllegalArgumentException. (str "No matching clause: " (pr-str val)))) | |
6700 | 6746 | |
6701 | 6747 | (defmacro case |
6702 | 6748 | "Takes an expression, and a set of clauses. |
6727 | 6773 | (let [ge (with-meta (gensym) {:tag Object}) |
6728 | 6774 | default (if (odd? (count clauses)) |
6729 | 6775 | (last clauses) |
6730 | `(throw (case-fallthrough-err-impl ~ge)))] | |
6776 | `(throw (IllegalArgumentException. (str "No matching clause: " ~ge))))] | |
6731 | 6777 | (if (> 2 (count clauses)) |
6732 | 6778 | `(let [~ge ~e] ~default) |
6733 | 6779 | (let [pairs (partition 2 clauses) |
6811 | 6857 | {:added "1.9"} |
6812 | 6858 | [x] (instance? java.util.UUID x)) |
6813 | 6859 | |
6860 | (defn random-uuid | |
6861 | {:doc "Returns a pseudo-randomly generated java.util.UUID instance (i.e. type 4). | |
6862 | ||
6863 | See: https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html#randomUUID--" | |
6864 | :added "1.11"} | |
6865 | ^java.util.UUID [] (java.util.UUID/randomUUID)) | |
6866 | ||
6814 | 6867 | (defn reduce |
6815 | 6868 | "f should be a function of 2 arguments. If val is not supplied, |
6816 | 6869 | returns the result of applying f to the first 2 items in coll, then |
6838 | 6891 | init) |
6839 | 6892 | |
6840 | 6893 | ;;slow path default |
6841 | clojure.lang.IPersistentMap | |
6842 | (kv-reduce | |
6894 | java.lang.Object | |
6895 | (kv-reduce | |
6843 | 6896 | [amap f init] |
6844 | (reduce (fn [ret [k v]] (f ret k v)) init amap)) | |
6897 | (reduce (fn [ret ^java.util.Map$Entry me] | |
6898 | (f ret | |
6899 | (.getKey me) | |
6900 | (.getValue me))) | |
6901 | init | |
6902 | amap)) | |
6845 | 6903 | |
6846 | 6904 | clojure.lang.IKVReduce |
6847 | (kv-reduce | |
6905 | (kv-reduce | |
6848 | 6906 | [amap f init] |
6849 | 6907 | (.kvreduce amap f init))) |
6850 | 6908 | |
6901 | 6959 | (reduce conj to from))) |
6902 | 6960 | ([to xform from] |
6903 | 6961 | (if (instance? clojure.lang.IEditableCollection to) |
6904 | (with-meta (persistent! (transduce xform conj! (transient to) from)) (meta to)) | |
6962 | (let [tm (meta to) | |
6963 | rf (fn | |
6964 | ([coll] (-> (persistent! coll) (with-meta tm))) | |
6965 | ([coll v] (conj! coll v)))] | |
6966 | (transduce xform rf (transient to) from)) | |
6905 | 6967 | (transduce xform conj to from)))) |
6906 | 6968 | |
6907 | 6969 | (defn mapv |
7056 | 7118 | |
7057 | 7119 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; clojure version number ;;;;;;;;;;;;;;;;;;;;;; |
7058 | 7120 | |
7059 | (let [properties (with-open [version-stream (.getResourceAsStream | |
7121 | (let [^java.util.Properties | |
7122 | properties (with-open [version-stream (.getResourceAsStream | |
7060 | 7123 | (clojure.lang.RT/baseLoader) |
7061 | 7124 | "clojure/version.properties")] |
7062 | 7125 | (doto (new java.util.Properties) |
7423 | 7486 | (fn ep3 |
7424 | 7487 | ([] true) |
7425 | 7488 | ([x] (boolean (and (p1 x) (p2 x) (p3 x)))) |
7426 | ([x y] (boolean (and (p1 x) (p2 x) (p3 x) (p1 y) (p2 y) (p3 y)))) | |
7427 | ([x y z] (boolean (and (p1 x) (p2 x) (p3 x) (p1 y) (p2 y) (p3 y) (p1 z) (p2 z) (p3 z)))) | |
7489 | ([x y] (boolean (and (p1 x) (p1 y) (p2 x) (p2 y) (p3 x) (p3 y)))) | |
7490 | ([x y z] (boolean (and (p1 x) (p1 y) (p1 z) (p2 x) (p2 y) (p2 z) (p3 x) (p3 y) (p3 z)))) | |
7428 | 7491 | ([x y z & args] (boolean (and (ep3 x y z) |
7429 | 7492 | (every? #(and (p1 %) (p2 %) (p3 %)) args)))))) |
7430 | 7493 | ([p1 p2 p3 & ps] |
7463 | 7526 | (fn sp3 |
7464 | 7527 | ([] nil) |
7465 | 7528 | ([x] (or (p1 x) (p2 x) (p3 x))) |
7466 | ([x y] (or (p1 x) (p2 x) (p3 x) (p1 y) (p2 y) (p3 y))) | |
7467 | ([x y z] (or (p1 x) (p2 x) (p3 x) (p1 y) (p2 y) (p3 y) (p1 z) (p2 z) (p3 z))) | |
7529 | ([x y] (or (p1 x) (p1 y) (p2 x) (p2 y) (p3 x) (p3 y))) | |
7530 | ([x y z] (or (p1 x) (p1 y) (p1 z) (p2 x) (p2 y) (p2 z) (p3 x) (p3 y) (p3 z))) | |
7468 | 7531 | ([x y z & args] (or (sp3 x y z) |
7469 | 7532 | (some #(or (p1 %) (p2 %) (p3 %)) args))))) |
7470 | 7533 | ([p1 p2 p3 & ps] |
7719 | 7782 | (reduce #(proc %2) nil coll) |
7720 | 7783 | nil) |
7721 | 7784 | |
7785 | (defn iteration | |
7786 | "Creates a seqable/reducible via repeated calls to step, | |
7787 | a function of some (continuation token) 'k'. The first call to step | |
7788 | will be passed initk, returning 'ret'. Iff (somef ret) is true, | |
7789 | (vf ret) will be included in the iteration, else iteration will | |
7790 | terminate and vf/kf will not be called. If (kf ret) is non-nil it | |
7791 | will be passed to the next step call, else iteration will terminate. | |
7792 | ||
7793 | This can be used e.g. to consume APIs that return paginated or batched data. | |
7794 | ||
7795 | step - (possibly impure) fn of 'k' -> 'ret' | |
7796 | ||
7797 | :somef - fn of 'ret' -> logical true/false, default 'some?' | |
7798 | :vf - fn of 'ret' -> 'v', a value produced by the iteration, default 'identity' | |
7799 | :kf - fn of 'ret' -> 'next-k' or nil (signaling 'do not continue'), default 'identity' | |
7800 | :initk - the first value passed to step, default 'nil' | |
7801 | ||
7802 | It is presumed that step with non-initk is unreproducible/non-idempotent. | |
7803 | If step with initk is unreproducible it is on the consumer to not consume twice." | |
7804 | {:added "1.11"} | |
7805 | [step & {:keys [somef vf kf initk] | |
7806 | :or {vf identity | |
7807 | kf identity | |
7808 | somef some? | |
7809 | initk nil}}] | |
7810 | (reify | |
7811 | clojure.lang.Seqable | |
7812 | (seq [_] | |
7813 | ((fn next [ret] | |
7814 | (when (somef ret) | |
7815 | (cons (vf ret) | |
7816 | (when-some [k (kf ret)] | |
7817 | (lazy-seq (next (step k))))))) | |
7818 | (step initk))) | |
7819 | clojure.lang.IReduceInit | |
7820 | (reduce [_ rf init] | |
7821 | (loop [acc init | |
7822 | ret (step initk)] | |
7823 | (if (somef ret) | |
7824 | (let [acc (rf acc (vf ret))] | |
7825 | (if (reduced? acc) | |
7826 | @acc | |
7827 | (if-some [k (kf ret)] | |
7828 | (recur acc (step k)) | |
7829 | acc))) | |
7830 | acc))))) | |
7722 | 7831 | |
7723 | 7832 | (defn tagged-literal? |
7724 | 7833 | "Return true if the value is the data representation of a tagged literal" |
7894 | 8003 | [x] |
7895 | 8004 | (force tap-loop) |
7896 | 8005 | (.offer tapq (if (nil? x) ::tap-nil x))) |
8006 | ||
8007 | (defn update-vals | |
8008 | "m f => {k (f v) ...} | |
8009 | ||
8010 | Given a map m and a function f of 1-argument, returns a new map where the keys of m | |
8011 | are mapped to result of applying f to the corresponding values of m." | |
8012 | {:added "1.11"} | |
8013 | [m f] | |
8014 | (with-meta | |
8015 | (persistent! | |
8016 | (reduce-kv (fn [acc k v] (assoc! acc k (f v))) | |
8017 | (if (instance? clojure.lang.IEditableCollection m) | |
8018 | (transient m) | |
8019 | (transient {})) | |
8020 | m)) | |
8021 | (meta m))) | |
8022 | ||
8023 | (defn update-keys | |
8024 | "m f => {(f k) v ...} | |
8025 | ||
8026 | Given a map m and a function f of 1-argument, returns a new map whose | |
8027 | keys are the result of applying f to the keys of m, mapped to the | |
8028 | corresponding values of m. | |
8029 | f must return a unique key for each key of m, else the behavior is undefined." | |
8030 | {:added "1.11"} | |
8031 | [m f] | |
8032 | (let [ret (persistent! | |
8033 | (reduce-kv (fn [acc k v] (assoc! acc (f k) v)) | |
8034 | (transient {}) | |
8035 | m))] | |
8036 | (with-meta ret (meta m)))) | |
8037 | ||
8038 | (defn- parsing-err | |
8039 | "Construct message for parsing for non-string parsing error" | |
8040 | ^String [val] | |
8041 | (str "Expected string, got " (if (nil? val) "nil" (-> val class .getName)))) | |
8042 | ||
8043 | (defn parse-long | |
8044 | {:doc "Parse string of decimal digits with optional leading -/+ and return a | |
8045 | Long value, or nil if parse fails" | |
8046 | :added "1.11"} | |
8047 | ^Long [^String s] | |
8048 | (if (string? s) | |
8049 | (try | |
8050 | (Long/valueOf s) | |
8051 | (catch NumberFormatException _ nil)) | |
8052 | (throw (IllegalArgumentException. (parsing-err s))))) | |
8053 | ||
8054 | (defn parse-double | |
8055 | {:doc "Parse string with floating point components and return a Double value, | |
8056 | or nil if parse fails. | |
8057 | ||
8058 | Grammar: https://docs.oracle.com/javase/8/docs/api/java/lang/Double.html#valueOf-java.lang.String-" | |
8059 | :added "1.11"} | |
8060 | ^Double [^String s] | |
8061 | (if (string? s) | |
8062 | (try | |
8063 | (Double/valueOf s) | |
8064 | (catch NumberFormatException _ nil)) | |
8065 | (throw (IllegalArgumentException. (parsing-err s))))) | |
8066 | ||
8067 | (defn parse-uuid | |
8068 | {:doc "Parse a string representing a UUID and return a java.util.UUID instance, | |
8069 | or nil if parse fails. | |
8070 | ||
8071 | Grammar: https://docs.oracle.com/javase/8/docs/api/java/util/UUID.html#toString--" | |
8072 | :added "1.11"} | |
8073 | ^java.util.UUID [^String s] | |
8074 | (try | |
8075 | (java.util.UUID/fromString s) | |
8076 | (catch IllegalArgumentException _ nil))) | |
8077 | ||
8078 | (defn parse-boolean | |
8079 | {:doc "Parse strings \"true\" or \"false\" and return a boolean, or nil if invalid" | |
8080 | :added "1.11"} | |
8081 | [^String s] | |
8082 | (if (string? s) | |
8083 | (case s | |
8084 | "true" true | |
8085 | "false" false | |
8086 | nil) | |
8087 | (throw (IllegalArgumentException. (parsing-err s))))) | |
8088 | ||
8089 | (defn NaN? | |
8090 | {:doc "Returns true if num is NaN, else false" | |
8091 | :inline-arities #{1} | |
8092 | :inline (fn [num] `(Double/isNaN ~num)) | |
8093 | :added "1.11"} | |
8094 | ||
8095 | [^double num] | |
8096 | (Double/isNaN num)) | |
8097 | ||
8098 | (defn infinite? | |
8099 | {:doc "Returns true if num is negative or positive infinity, else false" | |
8100 | :inline-arities #{1} | |
8101 | :inline (fn [num] `(Double/isInfinite ~num)) | |
8102 | :added "1.11"} | |
8103 | [^double num] | |
8104 | (Double/isInfinite num)) |
66 | 66 | (throw (IllegalArgumentException. (apply print-str "Unsupported option(s) -" bad-opts)))) |
67 | 67 | [interfaces methods opts])) |
68 | 68 | |
69 | (defmacro reify | |
70 | "reify is a macro with the following structure: | |
69 | (defmacro reify | |
70 | "reify creates an object implementing a protocol or interface. | |
71 | reify is a macro with the following structure: | |
71 | 72 | |
72 | 73 | (reify options* specs*) |
73 | 74 | |
650 | 651 | [opts sigs])) |
651 | 652 | sigs (when sigs |
652 | 653 | (reduce1 (fn [m s] |
653 | (let [name-meta (meta (first s)) | |
654 | (let [tag-to-class (fn [tag] | |
655 | (if-let [c (and (instance? clojure.lang.Symbol tag) | |
656 | (= (.indexOf (.getName ^clojure.lang.Symbol tag) ".") -1) | |
657 | (not (contains? '#{int long float double char short byte boolean void | |
658 | ints longs floats doubles chars shorts bytes booleans objects} tag)) | |
659 | (resolve tag))] | |
660 | (symbol (.getName c)) | |
661 | tag)) | |
662 | name-meta (update-in (meta (first s)) [:tag] tag-to-class) | |
654 | 663 | mname (with-meta (first s) nil) |
655 | 664 | [arglists doc] |
656 | 665 | (loop [as [] rs (rest s)] |
240 | 240 | mb (map #(vector (%1 %2) (vals (dissoc %1 %2))) mgroups rtypes) |
241 | 241 | bridge? (reduce1 into1 #{} (map second mb)) |
242 | 242 | ifaces-meths (remove bridge? (vals ifaces-meths)) |
243 | mm (remove bridge? (vals mm))] | |
243 | mm (remove bridge? (vals mm)) | |
244 | reflect-Method-keyfn (fn [meth] | |
245 | (let [[name param-types ^Class return-type] (method-sig meth)] | |
246 | (-> [name] | |
247 | (into1 (map #(.getName ^Class %) param-types)) | |
248 | (conj (.getName return-type)))))] | |
244 | 249 | ;add methods matching supers', if no mapping -> call super |
245 | (doseq [[^java.lang.reflect.Method dest bridges] mb | |
246 | ^java.lang.reflect.Method meth bridges] | |
250 | (doseq [[^java.lang.reflect.Method dest bridges] (sort-by (comp reflect-Method-keyfn first) mb) | |
251 | ^java.lang.reflect.Method meth (sort-by reflect-Method-keyfn bridges)] | |
247 | 252 | (gen-bridge meth dest)) |
248 | (doseq [^java.lang.reflect.Method meth mm] | |
253 | (doseq [^java.lang.reflect.Method meth (sort-by reflect-Method-keyfn mm)] | |
249 | 254 | (gen-method meth |
250 | 255 | (fn [^GeneratorAdapter gen ^Method m] |
251 | 256 | (. gen (loadThis)) |
258 | 263 | (. m (getDescriptor))))))) |
259 | 264 | |
260 | 265 | ;add methods matching interfaces', if no mapping -> throw |
261 | (doseq [^java.lang.reflect.Method meth ifaces-meths] | |
266 | (doseq [^java.lang.reflect.Method meth (sort-by reflect-Method-keyfn ifaces-meths)] | |
262 | 267 | (gen-method meth |
263 | 268 | (fn [^GeneratorAdapter gen ^Method m] |
264 | 269 | (. gen (throwException ex-type (. m (getName)))))))) |
11 | 11 | clojure.java.browse |
12 | 12 | (:require [clojure.java.shell :as sh] |
13 | 13 | [clojure.string :as str]) |
14 | (:import (java.net URI))) | |
14 | (:import (java.io File) | |
15 | (java.net URI) | |
16 | (java.lang ProcessBuilder ProcessBuilder$Redirect))) | |
15 | 17 | |
16 | 18 | (defn- macosx? [] |
17 | 19 | (-> "os.name" System/getProperty .toLowerCase |
70 | 72 | script (if (= :uninitialized script) |
71 | 73 | (reset! *open-url-script* (open-url-script-val)) |
72 | 74 | script)] |
73 | (or (when script (sh/sh script (str url)) true) | |
75 | (or (when script | |
76 | (try | |
77 | (let [command [script (str url)] | |
78 | null-file (File. (if (.startsWith (System/getProperty "os.name") "Windows") "NUL" "/dev/null")) | |
79 | pb (doto (ProcessBuilder. ^java.util.List command) | |
80 | ;; emulate ProcessBuilder.Redirect.DISCARD added in Java 9 | |
81 | (.redirectOutput null-file) | |
82 | (.redirectError null-file))] | |
83 | (.start pb) ;; do not wait for the process | |
84 | true) | |
85 | (catch Throwable _ false))) | |
74 | 86 | (open-url-in-browser url) |
75 | 87 | (open-url-in-swing url)))) |
0 | ; Copyright (c) Rich Hickey. All rights reserved. | |
1 | ; The use and distribution terms for this software are covered by the | |
2 | ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | |
3 | ; which can be found in the file epl-v10.html at the root of this distribution. | |
4 | ; By using this software in any fashion, you are agreeing to be bound by | |
5 | ; the terms of this license. | |
6 | ; You must not remove this notice, or any other, from this software. | |
7 | ||
8 | (ns | |
9 | ^{:author "Alex Miller", | |
10 | :doc "Clojure wrapper functions for java.lang.Math static methods. | |
11 | ||
12 | Function calls are inlined for performance, and type hinted for primitive | |
13 | long or double parameters where appropriate. In general, Math methods are | |
14 | optimized for performance and have bounds for error tolerance. If | |
15 | greater precision is needed, use java.lang.StrictMath directly instead. | |
16 | ||
17 | For more complete information, see: | |
18 | https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html"} | |
19 | clojure.math) | |
20 | ||
21 | (set! *warn-on-reflection* true) | |
22 | ||
23 | (def | |
24 | ^{:doc "Constant for e, the base for natural logarithms. | |
25 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#E" | |
26 | :added "1.11" | |
27 | :const true | |
28 | :tag 'double} | |
29 | E | |
30 | Math/E) | |
31 | ||
32 | (def | |
33 | ^{:doc "Constant for pi, the ratio of the circumference of a circle to its diameter. | |
34 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#PI" | |
35 | :added "1.11" | |
36 | :const true | |
37 | :tag 'double} | |
38 | PI | |
39 | Math/PI) | |
40 | ||
41 | (defn sin | |
42 | {:doc "Returns the sine of an angle. | |
43 | If a is ##NaN, ##-Inf, ##Inf => ##NaN | |
44 | If a is zero => zero with the same sign as a | |
45 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#sin-double-" | |
46 | :inline-arities #{1} | |
47 | :inline (fn [a] `(Math/sin (double ~a))) | |
48 | :added "1.11"} | |
49 | ^double [^double a] | |
50 | (Math/sin a)) | |
51 | ||
52 | (defn cos | |
53 | {:doc "Returns the cosine of an angle. | |
54 | If a is ##NaN, ##-Inf, ##Inf => ##NaN | |
55 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#cos-double-" | |
56 | :inline-arities #{1} | |
57 | :inline (fn [a] `(Math/cos (double ~a))) | |
58 | :added "1.11"} | |
59 | ^double [^double a] | |
60 | (Math/cos a)) | |
61 | ||
62 | (defn tan | |
63 | {:doc "Returns the tangent of an angle. | |
64 | If a is ##NaN, ##-Inf, ##Inf => ##NaN | |
65 | If a is zero => zero with the same sign as a | |
66 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#tan-double-" | |
67 | :inline-arities #{1} | |
68 | :inline (fn [a] `(Math/tan (double ~a))) | |
69 | :added "1.11"} | |
70 | ^double [^double a] | |
71 | (Math/tan a)) | |
72 | ||
73 | (defn asin | |
74 | {:doc "Returns the arc sine of an angle, in the range -pi/2 to pi/2. | |
75 | If a is ##NaN or |a|>1 => ##NaN | |
76 | If a is zero => zero with the same sign as a | |
77 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#asin-double-" | |
78 | :inline-arities #{1} | |
79 | :inline (fn [a] `(Math/asin (double ~a))) | |
80 | :added "1.11"} | |
81 | ^double [^double a] | |
82 | (Math/asin a)) | |
83 | ||
84 | (defn acos | |
85 | {:doc "Returns the arc cosine of a, in the range 0.0 to pi. | |
86 | If a is ##NaN or |a|>1 => ##NaN | |
87 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#acos-double-" | |
88 | :inline-arities #{1} | |
89 | :inline (fn [a] `(Math/acos (double ~a))) | |
90 | :added "1.11"} | |
91 | ^double [^double a] | |
92 | (Math/acos a)) | |
93 | ||
94 | (defn atan | |
95 | {:doc "Returns the arc tangent of a, in the range of -pi/2 to pi/2. | |
96 | If a is ##NaN => ##NaN | |
97 | If a is zero => zero with the same sign as a | |
98 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#atan-double-" | |
99 | :inline-arities #{1} | |
100 | :inline (fn [a] `(Math/atan (double ~a))) | |
101 | :added "1.11"} | |
102 | ^double [^double a] | |
103 | (Math/atan a)) | |
104 | ||
105 | (defn to-radians | |
106 | {:doc "Converts an angle in degrees to an approximate equivalent angle in radians. | |
107 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#toRadians-double-" | |
108 | :inline-arities #{1} | |
109 | :inline (fn [deg] `(Math/toRadians (double ~deg))) | |
110 | :added "1.11"} | |
111 | ^double [^double deg] | |
112 | (Math/toRadians deg)) | |
113 | ||
114 | (defn to-degrees | |
115 | {:doc "Converts an angle in radians to an approximate equivalent angle in degrees. | |
116 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#toDegrees-double-" | |
117 | :inline-arities #{1} | |
118 | :inline (fn [r] `(Math/toDegrees (double ~r))) | |
119 | :added "1.11"} | |
120 | ^double [^double r] | |
121 | (Math/toDegrees r)) | |
122 | ||
123 | (defn exp | |
124 | {:doc "Returns Euler's number e raised to the power of a. | |
125 | If a is ##NaN => ##NaN | |
126 | If a is ##Inf => ##Inf | |
127 | If a is ##-Inf => +0.0 | |
128 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#exp-double-" | |
129 | :inline-arities #{1} | |
130 | :inline (fn [a] `(Math/exp (double ~a))) | |
131 | :added "1.11"} | |
132 | ^double [^double a] | |
133 | (Math/exp a)) | |
134 | ||
135 | (defn log | |
136 | {:doc "Returns the natural logarithm (base e) of a. | |
137 | If a is ##NaN or negative => ##NaN | |
138 | If a is ##Inf => ##Inf | |
139 | If a is zero => ##-Inf | |
140 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#log-double-" | |
141 | :inline-arities #{1} | |
142 | :inline (fn [a] `(Math/log (double ~a))) | |
143 | :added "1.11"} | |
144 | ^double [^double a] | |
145 | (Math/log a)) | |
146 | ||
147 | (defn log10 | |
148 | {:doc "Returns the logarithm (base 10) of a. | |
149 | If a is ##NaN or negative => ##NaN | |
150 | If a is ##Inf => ##Inf | |
151 | If a is zero => ##-Inf | |
152 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#log10-double-" | |
153 | :inline-arities #{1} | |
154 | :inline (fn [a] `(Math/log10 (double ~a))) | |
155 | :added "1.11"} | |
156 | ^double [^double a] | |
157 | (Math/log10 a)) | |
158 | ||
159 | (defn sqrt | |
160 | {:doc "Returns the positive square root of a. | |
161 | If a is ##NaN or negative => ##NaN | |
162 | If a is ##Inf => ##Inf | |
163 | If a is zero => a | |
164 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#sqrt-double-" | |
165 | :inline-arities #{1} | |
166 | :inline (fn [a] `(Math/sqrt (double ~a))) | |
167 | :added "1.11"} | |
168 | ^double [^double a] | |
169 | (Math/sqrt a)) | |
170 | ||
171 | (defn cbrt | |
172 | {:doc "Returns the cube root of a. | |
173 | If a is ##NaN => ##NaN | |
174 | If a is ##Inf or ##-Inf => a | |
175 | If a is zero => zero with sign matching a | |
176 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#cbrt-double-" | |
177 | :inline-arities #{1} | |
178 | :inline (fn [a] `(Math/cbrt (double ~a))) | |
179 | :added "1.11"} | |
180 | ^double [^double a] | |
181 | (Math/cbrt a)) | |
182 | ||
183 | (defn IEEE-remainder | |
184 | {:doc "Returns the remainder per IEEE 754 such that | |
185 | remainder = dividend - divisor * n | |
186 | where n is the integer closest to the exact value of dividend / divisor. | |
187 | If two integers are equally close, then n is the even one. | |
188 | If the remainder is zero, sign will match dividend. | |
189 | If dividend or divisor is ##NaN, or dividend is ##Inf or ##-Inf, or divisor is zero => ##NaN | |
190 | If dividend is finite and divisor is infinite => dividend | |
191 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#IEEEremainder-double-double-" | |
192 | :inline-arities #{2} | |
193 | :inline (fn [dividend divisor] `(Math/IEEEremainder (double ~dividend) (double ~divisor))) | |
194 | :added "1.11"} | |
195 | ^double [^double dividend ^double divisor] | |
196 | (Math/IEEEremainder dividend divisor)) | |
197 | ||
198 | (defn ceil | |
199 | {:doc "Returns the smallest double greater than or equal to a, and equal to a | |
200 | mathematical integer. | |
201 | If a is ##NaN or ##Inf or ##-Inf or already equal to an integer => a | |
202 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#ceil-double-" | |
203 | :inline-arities #{1} | |
204 | :inline (fn [a] `(Math/ceil (double ~a))) | |
205 | :added "1.11"} | |
206 | ^double [^double a] | |
207 | (Math/ceil a)) | |
208 | ||
209 | (defn floor | |
210 | {:doc "Returns the largest double less than or equal to a, and equal to a | |
211 | mathematical integer. | |
212 | If a is ##NaN or ##Inf or ##-Inf or already equal to an integer => a | |
213 | If a is less than zero but greater than -1.0 => -0.0 | |
214 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floor-double-" | |
215 | :inline-arities #{1} | |
216 | :inline (fn [a] `(Math/floor (double ~a))) | |
217 | :added "1.11"} | |
218 | ^double [^double a] | |
219 | (Math/floor a)) | |
220 | ||
221 | (defn rint | |
222 | {:doc "Returns the double closest to a and equal to a mathematical integer. | |
223 | If two values are equally close, return the even one. | |
224 | If a is ##NaN or ##Inf or ##-Inf or zero => a | |
225 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#rint-double-" | |
226 | :inline-arities #{1} | |
227 | :inline (fn [a] `(Math/rint (double ~a))) | |
228 | :added "1.11"} | |
229 | ^double [^double a] | |
230 | (Math/rint a)) | |
231 | ||
232 | (defn atan2 | |
233 | {:doc "Returns the angle theta from the conversion of rectangular coordinates (x, y) to polar coordinates (r, theta). | |
234 | Computes the phase theta by computing an arc tangent of y/x in the range of -pi to pi. | |
235 | For more details on special cases, see: | |
236 | https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#atan2-double-double-" | |
237 | :inline-arities #{2} | |
238 | :inline (fn [y x] `(Math/atan2 (double ~y) (double ~x))) | |
239 | :added "1.11"} | |
240 | ^double [^double y ^double x] | |
241 | (Math/atan2 y x)) | |
242 | ||
243 | (defn pow | |
244 | {:doc "Returns the value of a raised to the power of b. | |
245 | For more details on special cases, see: | |
246 | https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#pow-double-double-" | |
247 | :inline-arities #{2} | |
248 | :inline (fn [a b] `(Math/pow (double ~a) (double ~b))) | |
249 | :added "1.11"} | |
250 | ^double [^double a ^double b] | |
251 | (Math/pow a b)) | |
252 | ||
253 | (defn round | |
254 | {:doc "Returns the closest long to a. If equally close to two values, return the one | |
255 | closer to ##Inf. | |
256 | If a is ##NaN => 0 | |
257 | If a is ##-Inf or < Long/MIN_VALUE => Long/MIN_VALUE | |
258 | If a is ##Inf or > Long/MAX_VALUE => Long/MAX_VALUE | |
259 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#round-double-" | |
260 | :inline-arities #{1} | |
261 | :inline (fn [a] `(Math/round (double ~a))) | |
262 | :added "1.11"} | |
263 | ^long [^double a] | |
264 | (Math/round a)) | |
265 | ||
266 | (defn random | |
267 | {:doc "Returns a positive double between 0.0 and 1.0, chosen pseudorandomly with | |
268 | approximately random distribution. | |
269 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#random--" | |
270 | :inline-arities #{0} | |
271 | :inline (fn [] `(Math/random)) | |
272 | :added "1.11"} | |
273 | ^double [] | |
274 | (Math/random)) | |
275 | ||
276 | (defn add-exact | |
277 | {:doc "Returns the sum of x and y, throws ArithmeticException on overflow. | |
278 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#addExact-long-long-" | |
279 | :inline-arities #{2} | |
280 | :inline (fn [x y] `(Math/addExact (long ~x) (long ~y))) | |
281 | :added "1.11"} | |
282 | ^long [^long x ^long y] | |
283 | (Math/addExact x y)) | |
284 | ||
285 | (defn subtract-exact | |
286 | {:doc "Returns the difference of x and y, throws ArithmeticException on overflow. | |
287 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#subtractExact-long-long-" | |
288 | :inline-arities #{2} | |
289 | :inline (fn [x y] `(Math/subtractExact (long ~x) (long ~y))) | |
290 | :added "1.11"} | |
291 | ^long [^long x ^long y] | |
292 | (Math/subtractExact x y)) | |
293 | ||
294 | (defn multiply-exact | |
295 | {:doc "Returns the product of x and y, throws ArithmeticException on overflow. | |
296 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#multiplyExact-long-long-" | |
297 | :inline-arities #{2} | |
298 | :inline (fn [x y] `(Math/multiplyExact (long ~x) (long ~y))) | |
299 | :added "1.11"} | |
300 | ^long [^long x ^long y] | |
301 | (Math/multiplyExact x y)) | |
302 | ||
303 | (defn increment-exact | |
304 | {:doc "Returns a incremented by 1, throws ArithmeticException on overflow. | |
305 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#incrementExact-long-" | |
306 | :inline-arities #{1} | |
307 | :inline (fn [a] `(Math/incrementExact (long ~a))) | |
308 | :added "1.11"} | |
309 | ^long [^long a] | |
310 | (Math/incrementExact a)) | |
311 | ||
312 | (defn decrement-exact | |
313 | {:doc "Returns a decremented by 1, throws ArithmeticException on overflow. | |
314 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#decrementExact-long-" | |
315 | :inline-arities #{1} | |
316 | :inline (fn [a] `(Math/decrementExact (long ~a))) | |
317 | :added "1.11"} | |
318 | ^long [^long a] | |
319 | (Math/decrementExact a)) | |
320 | ||
321 | (defn negate-exact | |
322 | {:doc "Returns the negation of a, throws ArithmeticException on overflow. | |
323 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#negateExact-long-" | |
324 | :inline-arities #{1} | |
325 | :inline (fn [a] `(Math/negateExact (long ~a))) | |
326 | :added "1.11"} | |
327 | ^long [^long a] | |
328 | (Math/negateExact a)) | |
329 | ||
330 | (defn floor-div | |
331 | {:doc "Integer division that rounds to negative infinity (as opposed to zero). | |
332 | The special case (floorDiv Long/MIN_VALUE -1) overflows and returns Long/MIN_VALUE. | |
333 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floorDiv-long-long-" | |
334 | :inline-arities #{2} | |
335 | :inline (fn [x y] `(Math/floorDiv (long ~x) (long ~y))) | |
336 | :added "1.11"} | |
337 | ^long [^long x ^long y] | |
338 | (Math/floorDiv x y)) | |
339 | ||
340 | (defn floor-mod | |
341 | {:doc "Integer modulus x - (floorDiv(x, y) * y). Sign matches y and is in the | |
342 | range -|y| < r < |y|. | |
343 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floorMod-long-long-" | |
344 | :inline-arities #{2} | |
345 | :inline (fn [x y] `(Math/floorMod (long ~x) (long ~y))) | |
346 | :added "1.11"} | |
347 | ^long [^long x ^long y] | |
348 | (Math/floorMod x y)) | |
349 | ||
350 | (defn ulp | |
351 | {:doc "Returns the size of an ulp (unit in last place) for d. | |
352 | If d is ##NaN => ##NaN | |
353 | If d is ##Inf or ##-Inf => ##Inf | |
354 | If d is zero => Double/MIN_VALUE | |
355 | If d is +/- Double/MAX_VALUE => 2^971 | |
356 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#ulp-double-" | |
357 | :inline-arities #{1} | |
358 | :inline (fn [d] `(Math/ulp (double ~d))) | |
359 | :added "1.11"} | |
360 | ^double [^double d] | |
361 | (Math/ulp d)) | |
362 | ||
363 | (defn signum | |
364 | {:doc "Returns the signum function of d - zero for zero, 1.0 if >0, -1.0 if <0. | |
365 | If d is ##NaN => ##NaN | |
366 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#signum-double-" | |
367 | :inline-arities #{1} | |
368 | :inline (fn [d] `(Math/signum (double ~d))) | |
369 | :added "1.11"} | |
370 | ^double [^double d] | |
371 | (Math/signum d)) | |
372 | ||
373 | (defn sinh | |
374 | {:doc "Returns the hyperbolic sine of x, (e^x - e^-x)/2. | |
375 | If x is ##NaN => ##NaN | |
376 | If x is ##Inf or ##-Inf or zero => x | |
377 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#sinh-double-" | |
378 | :inline-arities #{1} | |
379 | :inline (fn [x] `(Math/sinh (double ~x))) | |
380 | :added "1.11"} | |
381 | ^double [^double x] | |
382 | (Math/sinh x)) | |
383 | ||
384 | (defn cosh | |
385 | {:doc "Returns the hyperbolic cosine of x, (e^x + e^-x)/2. | |
386 | If x is ##NaN => ##NaN | |
387 | If x is ##Inf or ##-Inf => ##Inf | |
388 | If x is zero => 1.0 | |
389 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#cosh-double-" | |
390 | :inline-arities #{1} | |
391 | :inline (fn [x] `(Math/cosh (double ~x))) | |
392 | :added "1.11"} | |
393 | ^double [^double x] | |
394 | (Math/cosh x)) | |
395 | ||
396 | (defn tanh | |
397 | {:doc "Returns the hyperbolic tangent of x, sinh(x)/cosh(x). | |
398 | If x is ##NaN => ##NaN | |
399 | If x is zero => zero, with same sign | |
400 | If x is ##Inf => +1.0 | |
401 | If x is ##-Inf => -1.0 | |
402 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#tanh-double-" | |
403 | :inline-arities #{1} | |
404 | :inline (fn [x] `(Math/tanh (double ~x))) | |
405 | :added "1.11"} | |
406 | ^double [^double x] | |
407 | (Math/tanh x)) | |
408 | ||
409 | (defn hypot | |
410 | {:doc "Returns sqrt(x^2 + y^2) without intermediate underflow or overflow. | |
411 | If x or y is ##Inf or ##-Inf => ##Inf | |
412 | If x or y is ##NaN and neither is ##Inf or ##-Inf => ##NaN | |
413 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#hypot-double-double-" | |
414 | :inline-arities #{2} | |
415 | :inline (fn [x y] `(Math/hypot (double ~x) (double ~y))) | |
416 | :added "1.11"} | |
417 | ^double [^double x ^double y] | |
418 | (Math/hypot x y)) | |
419 | ||
420 | (defn expm1 | |
421 | {:doc "Returns e^x - 1. Near 0, expm1(x)+1 is more accurate to e^x than exp(x). | |
422 | If x is ##NaN => ##NaN | |
423 | If x is ##Inf => #Inf | |
424 | If x is ##-Inf => -1.0 | |
425 | If x is zero => x | |
426 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#expm1-double-" | |
427 | :inline-arities #{1} | |
428 | :inline (fn [x] `(Math/expm1 (double ~x))) | |
429 | :added "1.11"} | |
430 | ^double [^double x] | |
431 | (Math/expm1 x)) | |
432 | ||
433 | (defn log1p | |
434 | {:doc "Returns ln(1+x). For small values of x, log1p(x) is more accurate than | |
435 | log(1.0+x). | |
436 | If x is ##NaN or < -1 => ##NaN | |
437 | If x is ##Inf => ##Inf | |
438 | If x is -1 => ##-Inf | |
439 | If x is 0 => 0 with sign matching x | |
440 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#log1p-double-" | |
441 | :inline-arities #{1} | |
442 | :inline (fn [x] `(Math/log1p (double ~x))) | |
443 | :added "1.11"} | |
444 | ^double [^double x] | |
445 | (Math/log1p x)) | |
446 | ||
447 | (defn copy-sign | |
448 | {:doc "Returns a double with the magnitude of the first argument and the sign of | |
449 | the second. | |
450 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#copySign-double-double-" | |
451 | :inline-arities #{2} | |
452 | :inline (fn [magnitude sign] `(Math/copySign (double ~magnitude) (double ~sign))) | |
453 | :added "1.11"} | |
454 | ^double [^double magnitude ^double sign] | |
455 | (Math/copySign magnitude sign)) | |
456 | ||
457 | (defn get-exponent | |
458 | {:doc "Returns the exponent of d. | |
459 | If d is ##NaN, ##Inf, ##-Inf => Double/MAX_EXPONENT + 1 | |
460 | If d is zero or subnormal => Double/MIN_EXPONENT - 1 | |
461 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#getExponent-double-" | |
462 | :inline-arities #{1} | |
463 | :inline (fn [d] `(Math/getExponent (double ~d))) | |
464 | :added "1.11"} | |
465 | [^double d] | |
466 | (Math/getExponent d)) | |
467 | ||
468 | (defn next-after | |
469 | {:doc "Returns the adjacent floating point number to start in the direction of | |
470 | the second argument. If the arguments are equal, the second is returned. | |
471 | If either arg is #NaN => #NaN | |
472 | If both arguments are signed zeros => direction | |
473 | If start is +-Double/MIN_VALUE and direction would cause a smaller magnitude | |
474 | => zero with sign matching start | |
475 | If start is ##Inf or ##-Inf and direction would cause a smaller magnitude | |
476 | => Double/MAX_VALUE with same sign as start | |
477 | If start is equal to +=Double/MAX_VALUE and direction would cause a larger magnitude | |
478 | => ##Inf or ##-Inf with sign matching start | |
479 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#nextAfter-double-double-" | |
480 | :inline-arities #{2} | |
481 | :inline (fn [start direction] `(Math/nextAfter (double ~start) (double ~direction))) | |
482 | :added "1.11"} | |
483 | ^double [^double start ^double direction] | |
484 | (Math/nextAfter start direction)) | |
485 | ||
486 | (defn next-up | |
487 | {:doc "Returns the adjacent double of d in the direction of ##Inf. | |
488 | If d is ##NaN => ##NaN | |
489 | If d is ##Inf => ##Inf | |
490 | If d is zero => Double/MIN_VALUE | |
491 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#nextUp-double-" | |
492 | :inline-arities #{1} | |
493 | :inline (fn [d] `(Math/nextUp (double ~d))) | |
494 | :added "1.11"} | |
495 | ^double [^double d] | |
496 | (Math/nextUp d)) | |
497 | ||
498 | (defn next-down | |
499 | {:doc "Returns the adjacent double of d in the direction of ##-Inf. | |
500 | If d is ##NaN => ##NaN | |
501 | If d is ##-Inf => ##-Inf | |
502 | If d is zero => -Double/MIN_VALUE | |
503 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#nextDown-double-" | |
504 | :inline-arities #{1} | |
505 | :inline (fn [d] `(Math/nextDown (double ~d))) | |
506 | :added "1.11"} | |
507 | ^double [^double d] | |
508 | (Math/nextDown d)) | |
509 | ||
510 | (defn scalb | |
511 | {:doc "Returns d * 2^scaleFactor, scaling by a factor of 2. If the exponent | |
512 | is between Double/MIN_EXPONENT and Double/MAX_EXPONENT, the answer is exact. | |
513 | If d is ##NaN => ##NaN | |
514 | If d is ##Inf or ##-Inf => ##Inf or ##-Inf respectively | |
515 | If d is zero => zero of same sign as d | |
516 | See: https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#nextDown-double-" | |
517 | :inline-arities #{2} | |
518 | :inline (fn [d scaleFactor] `(Math/scalb (double ~d) (int ~scaleFactor))) | |
519 | :added "1.11"} | |
520 | ^double [^double d scaleFactor] | |
521 | (Math/scalb d (int scaleFactor))) | |
522 |
105 | 105 | (defn map-invert |
106 | 106 | "Returns the map with the vals mapped to the keys." |
107 | 107 | {:added "1.0"} |
108 | [m] (reduce (fn [m [k v]] (assoc m v k)) {} m)) | |
108 | [m] | |
109 | (persistent! | |
110 | (reduce-kv (fn [m k v] (assoc! m v k)) | |
111 | (transient {}) | |
112 | m))) | |
109 | 113 | |
110 | 114 | (defn join |
111 | 115 | "When passed 2 rels, returns the rel corresponding to the natural |
217 | 217 | |
218 | 218 | (defn split |
219 | 219 | "Splits string on a regular expression. Optional argument limit is |
220 | the maximum number of splits. Not lazy. Returns vector of the splits." | |
220 | the maximum number of parts. Not lazy. Returns vector of the parts. | |
221 | Trailing empty strings are not returned - pass limit of -1 to return all." | |
221 | 222 | {:added "1.2"} |
222 | 223 | ([^CharSequence s ^Pattern re] |
223 | 224 | (LazilyPersistentVector/createOwning (.split re s))) |
225 | 226 | (LazilyPersistentVector/createOwning (.split re s limit)))) |
226 | 227 | |
227 | 228 | (defn split-lines |
228 | "Splits s on \\n or \\r\\n." | |
229 | "Splits s on \\n or \\r\\n. Trailing empty lines are not returned." | |
229 | 230 | {:added "1.2"} |
230 | 231 | [^CharSequence s] |
231 | 232 | (split s #"\r?\n")) |
446 | 446 | result# (apply ~pred values#)] |
447 | 447 | (if result# |
448 | 448 | (do-report {:type :pass, :message ~msg, |
449 | :expected '~form, :actual (cons ~pred values#)}) | |
449 | :expected '~form, :actual (cons '~pred values#)}) | |
450 | 450 | (do-report {:type :fail, :message ~msg, |
451 | 451 | :expected '~form, :actual (list '~'not (cons '~pred values#))})) |
452 | 452 | result#))) |
720 | 720 | (do-report {:type :end-test-var, :var v})))) |
721 | 721 | |
722 | 722 | (defn test-vars |
723 | "Groups vars by their namespace and runs test-vars on them with | |
724 | appropriate fixtures applied." | |
723 | "Groups vars by their namespace and runs test-var on them with | |
724 | appropriate fixtures applied." | |
725 | 725 | {:added "1.6"} |
726 | 726 | [vars] |
727 | 727 | (doseq [[ns vars] (group-by (comp :ns meta) vars)] |
792 | 792 | [summary] |
793 | 793 | (and (zero? (:fail summary 0)) |
794 | 794 | (zero? (:error summary 0)))) |
795 | ||
796 | (defn run-test-var | |
797 | "Runs the tests for a single Var, with fixtures executed around the test, and summary output after." | |
798 | {:added "1.11"} | |
799 | [v] | |
800 | (binding [*report-counters* (ref *initial-report-counters*)] | |
801 | (let [ns-obj (-> v meta :ns) | |
802 | summary (do | |
803 | (do-report {:type :begin-test-ns | |
804 | :ns ns-obj}) | |
805 | (test-vars [v]) | |
806 | (do-report {:type :end-test-ns | |
807 | :ns ns-obj}) | |
808 | (assoc @*report-counters* :type :summary))] | |
809 | (do-report summary) | |
810 | summary))) | |
811 | ||
812 | (defmacro run-test | |
813 | "Runs a single test. | |
814 | ||
815 | Because the intent is to run a single test, there is no check for the namespace test-ns-hook." | |
816 | {:added "1.11"} | |
817 | [test-symbol] | |
818 | (let [test-var (resolve test-symbol)] | |
819 | (cond | |
820 | (nil? test-var) | |
821 | (binding [*out* *err*] | |
822 | (println "Unable to resolve" test-symbol "to a test function.")) | |
823 | ||
824 | (not (-> test-var meta :test)) | |
825 | (binding [*out* *err*] | |
826 | (println test-symbol "is not a test.")) | |
827 | ||
828 | :else | |
829 | `(run-test-var ~test-var)))) |
71 | 71 | (skippedEntity [name]) |
72 | 72 | )))) |
73 | 73 | |
74 | (defn startparse-sax [s ch] | |
75 | (.. SAXParserFactory (newInstance) (newSAXParser) (parse s ch))) | |
74 | (defn sax-parser | |
75 | "Create a new SAXParser" | |
76 | {:added "1.11"} | |
77 | ^SAXParser [] | |
78 | (.newSAXParser (SAXParserFactory/newInstance))) | |
79 | ||
80 | (defn disable-external-entities | |
81 | "Modifies a SAXParser to disable external entity resolution to prevent XXE attacks" | |
82 | {:added "1.11"} | |
83 | ^SAXParser [^SAXParser parser] | |
84 | (let [reader (.getXMLReader parser)] | |
85 | ;; as per https://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html | |
86 | (.setFeature reader "http://apache.org/xml/features/nonvalidating/load-external-dtd" false) | |
87 | (.setFeature reader "http://xml.org/sax/features/external-general-entities", false) | |
88 | (.setFeature reader "http://xml.org/sax/features/external-parameter-entities" false) | |
89 | parser)) | |
90 | ||
91 | (defn startparse-sax | |
92 | "A startparse function suitable for use with clojure.xml/parse. | |
93 | Note that this function is open to XXE entity attacks, see startparse-sax-safe." | |
94 | {:added "1.0"} | |
95 | [s ch] | |
96 | (.parse (sax-parser) s ch)) | |
97 | ||
98 | (defn startparse-sax-safe | |
99 | "A startparse function suitable for use with clojure.xml/parse. | |
100 | External entity resolution is disabled to prevent XXE entity attacks." | |
101 | {:added "1.11"} | |
102 | [s ch] | |
103 | (.parse (disable-external-entities (sax-parser)) s ch)) | |
76 | 104 | |
77 | 105 | (defn parse |
78 | 106 | "Parses and loads the source s, which can be a File, InputStream or |
80 | 108 | which has the keys :tag, :attrs, and :content. and accessor fns tag, |
81 | 109 | attrs, and content. Other parsers can be supplied by passing |
82 | 110 | startparse, a fn taking a source and a ContentHandler and returning |
83 | a parser" | |
111 | a parser. | |
112 | ||
113 | Prior to 1.11, used startparse-sax by default. As of 1.11, uses | |
114 | startparse-sax-safe, which disables XXE (XML External Entity) | |
115 | processing. Pass startparse-sax to revert to prior behavior." | |
84 | 116 | {:added "1.0"} |
85 | ([s] (parse s startparse-sax)) | |
117 | ([s] (parse s startparse-sax-safe)) | |
86 | 118 | ([s startparse] |
87 | 119 | (binding [*stack* nil |
88 | 120 | *current* (struct element) |
40 | 40 | * require.invoke(Clojure.read("clojure.set"));</pre> |
41 | 41 | * |
42 | 42 | * <p><code>IFn</code>s can be passed to higher order functions, e.g. the |
43 | * example below passes <code>plus</code> to <code>read</code>:</p> | |
43 | * example below passes <code>inc</code> to <code>map</code>:</p> | |
44 | 44 | * |
45 | 45 | * <pre> |
46 | 46 | * IFn map = Clojure.var("clojure.core", "map"); |
56 | 56 | </p> |
57 | 57 | |
58 | 58 | <p><code>IFn</code>s can be passed to higher order functions, e.g. the |
59 | example below passes <code>plus</code> to <code>read</code>: | |
59 | example below passes <code>inc</code> to <code>map</code>: | |
60 | 60 | <pre> |
61 | 61 | IFn map = Clojure.var("clojure.core", "map"); |
62 | 62 | IFn inc = Clojure.var("clojure.core", "inc"); |
97 | 97 | else if(obj instanceof List) |
98 | 98 | { |
99 | 99 | Collection ma = (Collection) obj; |
100 | if(ma.size() != v.count()) | |
100 | ||
101 | if((!(ma instanceof IPersistentCollection) || (ma instanceof Counted)) && (ma.size() != v.count())) | |
101 | 102 | return false; |
102 | for(Iterator i1 = ((List) v).iterator(), i2 = ma.iterator(); | |
103 | i1.hasNext();) | |
103 | ||
104 | Iterator i2 = ma.iterator(); | |
105 | ||
106 | for(Iterator i1 = ((List) v).iterator(); i1.hasNext();) | |
104 | 107 | { |
105 | if(!Util.equiv(i1.next(), i2.next())) | |
108 | if(!i2.hasNext() || !Util.equiv(i1.next(), i2.next())) | |
106 | 109 | return false; |
107 | 110 | } |
108 | return true; | |
111 | return !i2.hasNext(); | |
109 | 112 | } |
110 | 113 | else |
111 | 114 | { |
543 | 546 | } |
544 | 547 | } |
545 | 548 | |
546 | public static class SubVector extends APersistentVector implements IObj{ | |
549 | public static class SubVector extends APersistentVector implements IObj, IKVReduce{ | |
547 | 550 | public final IPersistentVector v; |
548 | 551 | public final int start; |
549 | 552 | public final int end; |
573 | 576 | return super.iterator(); |
574 | 577 | } |
575 | 578 | |
579 | public Object kvreduce(IFn f, Object init){ | |
580 | int cnt = count(); | |
581 | for (int i=0; i<cnt; i++){ | |
582 | init = f.invoke(init, i, v.nth(start + i)); | |
583 | if (RT.isReduced(init)) | |
584 | return ((IDeref)init).deref(); | |
585 | } | |
586 | return init; | |
587 | } | |
588 | ||
576 | 589 | public Object nth(int i){ |
577 | 590 | if((start + i >= end) || (i < 0)) |
578 | 591 | throw new IndexOutOfBoundsException(); |
36 | 36 | |
37 | 37 | if(!(obj instanceof Sequential || obj instanceof List)) |
38 | 38 | return false; |
39 | ||
40 | if(this instanceof Counted && obj instanceof Counted && | |
41 | ((Counted)this).count() != ((Counted)obj).count()) | |
42 | return false; | |
43 | ||
39 | 44 | ISeq ms = RT.seq(obj); |
40 | 45 | for(ISeq s = seq(); s != null; s = s.next(), ms = ms.next()) |
41 | 46 | { |
14 | 14 | import java.lang.reflect.Array; |
15 | 15 | |
16 | 16 | public class ArraySeq extends ASeq implements IndexedSeq, IReduce{ |
17 | ||
18 | private static final long serialVersionUID = -9069152683729302290L; | |
19 | ||
17 | 20 | public final Object[] array; |
18 | 21 | final int i; |
19 | 22 | //ISeq _rest; |
141 | 144 | return -1; |
142 | 145 | } |
143 | 146 | |
147 | public Object[] toArray(){ | |
148 | int sz = this.array.length - this.i; | |
149 | Object[] ret = new Object[sz]; | |
150 | System.arraycopy(this.array, i, ret, 0, sz); | |
151 | return ret; | |
152 | } | |
153 | ||
144 | 154 | //////////////////////////////////// specialized primitive versions /////////////////////////////// |
145 | 155 | |
146 | 156 | static public class ArraySeq_int extends ASeq implements IndexedSeq, IReduce{ |
1611 | 1611 | gen.invokeInterface(type, m); |
1612 | 1612 | else |
1613 | 1613 | gen.invokeVirtual(type, m); |
1614 | //if(context != C.STATEMENT || method.getReturnType() == Void.TYPE) | |
1615 | HostExpr.emitBoxReturn(objx, gen, method.getReturnType()); | |
1614 | Class retClass = method.getReturnType(); | |
1615 | if(context == C.STATEMENT) | |
1616 | { | |
1617 | if(retClass == long.class || retClass == double.class) | |
1618 | gen.pop2(); | |
1619 | else if(retClass != void.class) | |
1620 | gen.pop(); | |
1621 | } | |
1622 | else | |
1623 | HostExpr.emitBoxReturn(objx, gen, retClass); | |
1616 | 1624 | } |
1617 | 1625 | else |
1618 | 1626 | { |
1626 | 1634 | method.emitClearLocals(gen); |
1627 | 1635 | } |
1628 | 1636 | gen.invokeStatic(REFLECTOR_TYPE, invokeInstanceMethodMethod); |
1629 | } | |
1630 | if(context == C.STATEMENT) | |
1631 | gen.pop(); | |
1637 | if(context == C.STATEMENT) | |
1638 | gen.pop(); | |
1639 | } | |
1632 | 1640 | } |
1633 | 1641 | |
1634 | 1642 | public boolean hasJavaClass(){ |
6015 | 6023 | public LocalBindingExpr(LocalBinding b, Symbol tag) |
6016 | 6024 | { |
6017 | 6025 | if(b.getPrimitiveType() != null && tag != null) |
6018 | throw new UnsupportedOperationException("Can't type hint a primitive local"); | |
6026 | if(! b.getPrimitiveType().equals(tagClass(tag))) | |
6027 | throw new UnsupportedOperationException("Can't type hint a primitive local with a different type"); | |
6028 | else | |
6029 | this.tag = null; | |
6030 | else | |
6031 | this.tag = tag; | |
6032 | ||
6019 | 6033 | this.b = b; |
6020 | this.tag = tag; | |
6021 | 6034 | |
6022 | 6035 | this.clearPath = (PathNode)CLEAR_PATH.get(); |
6023 | 6036 | this.clearRoot = (PathNode)CLEAR_ROOT.get(); |
7648 | 7661 | catch(Throwable e) |
7649 | 7662 | { |
7650 | 7663 | if(!(e instanceof CompilerException)) |
7651 | throw new CompilerException(sourcePath, (Integer) LINE_BEFORE.deref(), (Integer) COLUMN_BEFORE.deref(), e); | |
7664 | throw new CompilerException(sourcePath, (Integer) LINE_BEFORE.deref(), (Integer) COLUMN_BEFORE.deref(), null, CompilerException.PHASE_EXECUTION, e); | |
7652 | 7665 | else |
7653 | 7666 | throw (CompilerException) e; |
7654 | 7667 | } |
53 | 53 | return val; |
54 | 54 | } |
55 | 55 | |
56 | synchronized public boolean isRealized(){ | |
56 | public boolean isRealized(){ | |
57 | 57 | return fn == null; |
58 | 58 | } |
59 | 59 | } |
21 | 21 | |
22 | 22 | |
23 | 23 | public class Keyword implements IFn, Comparable, Named, Serializable, IHashEq { |
24 | ||
25 | private static final long serialVersionUID = -2105088845257724163L; | |
24 | 26 | |
25 | 27 | private static ConcurrentHashMap<Symbol, Reference<Keyword>> table = new ConcurrentHashMap(); |
26 | 28 | static final ReferenceQueue rq = new ReferenceQueue(); |
92 | 94 | return _str; |
93 | 95 | } |
94 | 96 | |
97 | /** | |
98 | * @deprecated CLJ-2350: This function is no longer called, but has not been | |
99 | * removed to maintain the public interface. | |
100 | */ | |
95 | 101 | public Object throwArity(){ |
96 | 102 | throw new IllegalArgumentException("Wrong number of args passed to keyword: " |
97 | 103 | + toString()); |
98 | 104 | } |
99 | 105 | |
106 | Object throwArity(int n) { | |
107 | throw new ArityException(n, toString()); | |
108 | } | |
109 | ||
100 | 110 | public Object call() { |
101 | return throwArity(); | |
111 | return throwArity(0); | |
102 | 112 | } |
103 | 113 | |
104 | 114 | public void run(){ |
106 | 116 | } |
107 | 117 | |
108 | 118 | public Object invoke() { |
109 | return throwArity(); | |
119 | return throwArity(0); | |
110 | 120 | } |
111 | 121 | |
112 | 122 | public int compareTo(Object o){ |
145 | 155 | } |
146 | 156 | |
147 | 157 | public Object invoke(Object arg1, Object arg2, Object arg3) { |
148 | return throwArity(); | |
158 | return throwArity(3); | |
149 | 159 | } |
150 | 160 | |
151 | 161 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4) { |
152 | return throwArity(); | |
162 | return throwArity(4); | |
153 | 163 | } |
154 | 164 | |
155 | 165 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { |
156 | return throwArity(); | |
166 | return throwArity(5); | |
157 | 167 | } |
158 | 168 | |
159 | 169 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { |
160 | return throwArity(); | |
170 | return throwArity(6); | |
161 | 171 | } |
162 | 172 | |
163 | 173 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7) |
164 | 174 | { |
165 | return throwArity(); | |
175 | return throwArity(7); | |
166 | 176 | } |
167 | 177 | |
168 | 178 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
169 | 179 | Object arg8) { |
170 | return throwArity(); | |
180 | return throwArity(8); | |
171 | 181 | } |
172 | 182 | |
173 | 183 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
174 | 184 | Object arg8, Object arg9) { |
175 | return throwArity(); | |
185 | return throwArity(9); | |
176 | 186 | } |
177 | 187 | |
178 | 188 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
179 | 189 | Object arg8, Object arg9, Object arg10) { |
180 | return throwArity(); | |
190 | return throwArity(10); | |
181 | 191 | } |
182 | 192 | |
183 | 193 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
184 | 194 | Object arg8, Object arg9, Object arg10, Object arg11) { |
185 | return throwArity(); | |
195 | return throwArity(11); | |
186 | 196 | } |
187 | 197 | |
188 | 198 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
189 | 199 | Object arg8, Object arg9, Object arg10, Object arg11, Object arg12) { |
190 | return throwArity(); | |
200 | return throwArity(12); | |
191 | 201 | } |
192 | 202 | |
193 | 203 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
194 | 204 | Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13) |
195 | 205 | { |
196 | return throwArity(); | |
206 | return throwArity(13); | |
197 | 207 | } |
198 | 208 | |
199 | 209 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
200 | 210 | Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14) |
201 | 211 | { |
202 | return throwArity(); | |
212 | return throwArity(14); | |
203 | 213 | } |
204 | 214 | |
205 | 215 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
206 | 216 | Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14, |
207 | 217 | Object arg15) { |
208 | return throwArity(); | |
218 | return throwArity(15); | |
209 | 219 | } |
210 | 220 | |
211 | 221 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
212 | 222 | Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14, |
213 | 223 | Object arg15, Object arg16) { |
214 | return throwArity(); | |
224 | return throwArity(16); | |
215 | 225 | } |
216 | 226 | |
217 | 227 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
218 | 228 | Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14, |
219 | 229 | Object arg15, Object arg16, Object arg17) { |
220 | return throwArity(); | |
230 | return throwArity(17); | |
221 | 231 | } |
222 | 232 | |
223 | 233 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
224 | 234 | Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14, |
225 | 235 | Object arg15, Object arg16, Object arg17, Object arg18) { |
226 | return throwArity(); | |
236 | return throwArity(18); | |
227 | 237 | } |
228 | 238 | |
229 | 239 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
230 | 240 | Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14, |
231 | 241 | Object arg15, Object arg16, Object arg17, Object arg18, Object arg19) { |
232 | return throwArity(); | |
242 | return throwArity(19); | |
233 | 243 | } |
234 | 244 | |
235 | 245 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
236 | 246 | Object arg8, Object arg9, Object arg10, Object arg11, Object arg12, Object arg13, Object arg14, |
237 | 247 | Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20) |
238 | 248 | { |
239 | return throwArity(); | |
249 | return throwArity(20); | |
240 | 250 | } |
241 | 251 | |
242 | 252 | public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6, Object arg7, |
244 | 254 | Object arg15, Object arg16, Object arg17, Object arg18, Object arg19, Object arg20, |
245 | 255 | Object... args) |
246 | 256 | { |
247 | return throwArity(); | |
257 | return throwArity(20 + args.length); | |
248 | 258 | } |
249 | 259 | |
250 | 260 |
84 | 84 | rw.writeLock().lock(); |
85 | 85 | try |
86 | 86 | { |
87 | if(prefers(dispatchValY, dispatchValX)) | |
87 | if(prefers(hierarchy.deref(), dispatchValY, dispatchValX)) | |
88 | 88 | throw new IllegalStateException( |
89 | 89 | String.format("Preference conflict in multimethod '%s': %s is already preferred to %s", |
90 | 90 | name, dispatchValY, dispatchValX)); |
101 | 101 | } |
102 | 102 | } |
103 | 103 | |
104 | private boolean prefers(Object x, Object y) { | |
104 | private boolean prefers(Object hierarchy, Object x, Object y) { | |
105 | 105 | IPersistentSet xprefs = (IPersistentSet) getPreferTable().valAt(x); |
106 | 106 | if(xprefs != null && xprefs.contains(y)) |
107 | 107 | return true; |
108 | for(ISeq ps = RT.seq(parents.invoke(y)); ps != null; ps = ps.next()) | |
109 | { | |
110 | if(prefers(x, ps.first())) | |
108 | for(ISeq ps = RT.seq(parents.invoke(hierarchy, y)); ps != null; ps = ps.next()) | |
109 | { | |
110 | if(prefers(hierarchy, x, ps.first())) | |
111 | 111 | return true; |
112 | 112 | } |
113 | for(ISeq ps = RT.seq(parents.invoke(x)); ps != null; ps = ps.next()) | |
114 | { | |
115 | if(prefers(ps.first(), y)) | |
113 | for(ISeq ps = RT.seq(parents.invoke(hierarchy, x)); ps != null; ps = ps.next()) | |
114 | { | |
115 | if(prefers(hierarchy, ps.first(), y)) | |
116 | 116 | return true; |
117 | 117 | } |
118 | 118 | return false; |
119 | 119 | } |
120 | 120 | |
121 | private boolean isA(Object x, Object y) { | |
122 | return RT.booleanCast(isa.invoke(hierarchy.deref(), x, y)); | |
123 | } | |
124 | ||
125 | private boolean dominates(Object x, Object y) { | |
126 | return prefers(x, y) || isA(x, y); | |
121 | private boolean isA(Object hierarchy, Object x, Object y) { | |
122 | return RT.booleanCast(isa.invoke(hierarchy, x, y)); | |
123 | } | |
124 | ||
125 | private boolean dominates(Object hierarchy, Object x, Object y) { | |
126 | return prefers(hierarchy, x, y) || isA(hierarchy, x, y); | |
127 | 127 | } |
128 | 128 | |
129 | 129 | private IPersistentMap resetCache() { |
169 | 169 | for(Object o : getMethodTable()) |
170 | 170 | { |
171 | 171 | Map.Entry e = (Map.Entry) o; |
172 | if(isA(dispatchVal, e.getKey())) | |
172 | if(isA(ch, dispatchVal, e.getKey())) | |
173 | 173 | { |
174 | if(bestEntry == null || dominates(e.getKey(), bestEntry.getKey())) | |
174 | if(bestEntry == null || dominates(ch, e.getKey(), bestEntry.getKey())) | |
175 | 175 | bestEntry = e; |
176 | if(!dominates(bestEntry.getKey(), e.getKey())) | |
176 | if(!dominates(ch, bestEntry.getKey(), e.getKey())) | |
177 | 177 | throw new IllegalArgumentException( |
178 | 178 | String.format( |
179 | 179 | "Multiple methods in multimethod '%s' match dispatch value: %s -> %s and %s, and neither is preferred", |
67 | 67 | public Number dec(Number x); |
68 | 68 | public Number decP(Number x); |
69 | 69 | public Number unchecked_dec(Number x); |
70 | ||
71 | public Number abs(Number x); | |
70 | 72 | } |
71 | 73 | |
72 | 74 | static abstract class OpsP implements Ops{ |
618 | 620 | long val = x.longValue(); |
619 | 621 | return num(Numbers.unchecked_dec(val)); |
620 | 622 | } |
623 | ||
624 | public Number abs(Number x){ | |
625 | return num(Math.abs(x.longValue())); | |
626 | } | |
621 | 627 | } |
622 | 628 | |
623 | 629 | final static class DoubleOps extends OpsP{ |
704 | 710 | |
705 | 711 | public Number dec(Number x){ |
706 | 712 | return Double.valueOf(x.doubleValue() - 1); |
713 | } | |
714 | ||
715 | public Number abs(Number x) { | |
716 | return num(Math.abs(x.doubleValue())); | |
707 | 717 | } |
708 | 718 | } |
709 | 719 | |
836 | 846 | return Numbers.add(x, -1); |
837 | 847 | } |
838 | 848 | |
849 | public Number abs(Number x) { | |
850 | Ratio r = (Ratio) x; | |
851 | return new Ratio(r.numerator.abs(), r.denominator); | |
852 | } | |
853 | ||
839 | 854 | } |
840 | 855 | |
841 | 856 | final static class BigIntOps extends OpsP{ |
933 | 948 | public Number dec(Number x){ |
934 | 949 | BigInteger bx = toBigInteger(x); |
935 | 950 | return BigInt.fromBigInteger(bx.subtract(BigInteger.ONE)); |
951 | } | |
952 | ||
953 | public Number abs(Number x) { | |
954 | return BigInt.fromBigInteger(toBigInteger(x).abs()); | |
936 | 955 | } |
937 | 956 | } |
938 | 957 | |
1052 | 1071 | return mc == null |
1053 | 1072 | ? bx.subtract(BigDecimal.ONE) |
1054 | 1073 | : bx.subtract(BigDecimal.ONE, mc); |
1074 | } | |
1075 | ||
1076 | public Number abs(Number x) { | |
1077 | MathContext mc = (MathContext) MATH_CONTEXT.deref(); | |
1078 | BigDecimal bx = (BigDecimal) x; | |
1079 | return mc == null | |
1080 | ? ((BigDecimal) x).abs() | |
1081 | : ((BigDecimal) x).abs(mc); | |
1055 | 1082 | } |
1056 | 1083 | } |
1057 | 1084 | |
1887 | 1914 | static public double remainder(long x, double y){return remainder((double)x,y);} |
1888 | 1915 | |
1889 | 1916 | static public long add(long x, long y){ |
1890 | long ret = x + y; | |
1891 | if ((ret ^ x) < 0 && (ret ^ y) < 0) | |
1892 | return throwIntOverflow(); | |
1893 | return ret; | |
1917 | return Math.addExact(x, y); | |
1894 | 1918 | } |
1895 | 1919 | |
1896 | 1920 | static public Number addP(long x, long y){ |
1901 | 1925 | } |
1902 | 1926 | |
1903 | 1927 | static public long minus(long x, long y){ |
1904 | long ret = x - y; | |
1905 | if (((ret ^ x) < 0 && (ret ^ ~y) < 0)) | |
1906 | return throwIntOverflow(); | |
1907 | return ret; | |
1928 | return Math.subtractExact(x, y); | |
1908 | 1929 | } |
1909 | 1930 | |
1910 | 1931 | static public Number minusP(long x, long y){ |
1915 | 1936 | } |
1916 | 1937 | |
1917 | 1938 | static public long minus(long x){ |
1918 | if(x == Long.MIN_VALUE) | |
1919 | return throwIntOverflow(); | |
1920 | return -x; | |
1939 | return Math.negateExact(x); | |
1921 | 1940 | } |
1922 | 1941 | |
1923 | 1942 | static public Number minusP(long x){ |
1927 | 1946 | } |
1928 | 1947 | |
1929 | 1948 | static public long inc(long x){ |
1930 | if(x == Long.MAX_VALUE) | |
1931 | return throwIntOverflow(); | |
1932 | return x + 1; | |
1949 | return Math.incrementExact(x); | |
1933 | 1950 | } |
1934 | 1951 | |
1935 | 1952 | static public Number incP(long x){ |
1939 | 1956 | } |
1940 | 1957 | |
1941 | 1958 | static public long dec(long x){ |
1942 | if(x == Long.MIN_VALUE) | |
1943 | return throwIntOverflow(); | |
1944 | return x - 1; | |
1959 | return Math.decrementExact(x); | |
1945 | 1960 | } |
1946 | 1961 | |
1947 | 1962 | static public Number decP(long x){ |
1952 | 1967 | |
1953 | 1968 | |
1954 | 1969 | static public long multiply(long x, long y){ |
1955 | if (x == Long.MIN_VALUE && y < 0) | |
1956 | return throwIntOverflow(); | |
1957 | long ret = x * y; | |
1958 | if (y != 0 && ret/y != x) | |
1959 | return throwIntOverflow(); | |
1960 | return ret; | |
1970 | return Math.multiplyExact(x, y); | |
1961 | 1971 | } |
1962 | 1972 | |
1963 | 1973 | static public Number multiplyP(long x, long y){ |
4067 | 4077 | |
4068 | 4078 | |
4069 | 4079 | static public long max(long x, long y){ |
4070 | if(x > y) { | |
4071 | return x; | |
4072 | } else { | |
4073 | return y; | |
4074 | } | |
4080 | return Math.max(x, y); | |
4075 | 4081 | } |
4076 | 4082 | |
4077 | 4083 | |
4165 | 4171 | |
4166 | 4172 | |
4167 | 4173 | static public long min(long x, long y){ |
4168 | if(x < y) { | |
4169 | return x; | |
4170 | } else { | |
4171 | return y; | |
4172 | } | |
4174 | return Math.min(x, y); | |
4173 | 4175 | } |
4174 | 4176 | |
4175 | 4177 | static public Object min(long x, Object y){ |
4220 | 4222 | } |
4221 | 4223 | } |
4222 | 4224 | |
4223 | } | |
4225 | static public long abs(long x){ | |
4226 | return Math.abs(x); | |
4227 | } | |
4228 | ||
4229 | static public double abs(double x){ | |
4230 | return Math.abs(x); | |
4231 | } | |
4232 | ||
4233 | static public Number abs(Object x) { | |
4234 | return ops(x).abs((Number)x); | |
4235 | } | |
4236 | ||
4237 | } |
75 | 75 | return new PersistentArrayMap(init); |
76 | 76 | } |
77 | 77 | |
78 | /** | |
79 | * <p>This method attempts to find resue the given array as the basis for an array map as quickly as possible.</p> | |
80 | * | |
81 | * <p>If a trailing element exists in the array or it contains duplicate keys then it delegates to the complex path.</p> | |
82 | **/ | |
78 | 83 | static public PersistentArrayMap createAsIfByAssoc(Object[] init){ |
79 | if ((init.length & 1) == 1) | |
80 | throw new IllegalArgumentException(String.format("No value supplied for key: %s", init[init.length-1])); | |
84 | boolean complexPath, hasTrailing; | |
85 | complexPath = hasTrailing = ((init.length & 1) == 1); | |
86 | ||
87 | for(int i=0;((i< init.length) && !complexPath);i += 2) | |
88 | { | |
89 | for(int j=0;j<i;j += 2) | |
90 | { | |
91 | if(equalKey(init[i],init[j])) | |
92 | { | |
93 | complexPath = true; | |
94 | break; | |
95 | } | |
96 | } | |
97 | } | |
98 | ||
99 | if (complexPath) return createAsIfByAssocComplexPath(init, hasTrailing); | |
100 | ||
101 | return new PersistentArrayMap(init); | |
102 | } | |
103 | ||
104 | private static Object[] growSeedArray(Object[] seed, IPersistentCollection trailing){ | |
105 | ISeq extraKVs = trailing.seq(); | |
106 | int seedCount = seed.length - 1; | |
107 | Object[] result = Arrays.copyOf(seed, seedCount + (trailing.count() * 2)); | |
108 | ||
109 | for(int i=seedCount; extraKVs != null; extraKVs = extraKVs.next(), i+=2) | |
110 | { | |
111 | Map.Entry e = (Entry) extraKVs.first(); | |
112 | result[i] = e.getKey(); | |
113 | result[i+1] = e.getValue(); | |
114 | } | |
115 | ||
116 | return result; | |
117 | } | |
118 | ||
119 | /** | |
120 | * <p>This method handles the default case of an array containing alternating key/value pairs.</p> | |
121 | * <p>It will reallocate a smaller init array if duplicate keys are found.</p> | |
122 | * | |
123 | * <p>If a trailing element is found then will attempt to add it to the resulting map as if by conj.</p> | |
124 | * <p>No guarantees about the order of the keys in the trailing element are made.</p> | |
125 | **/ | |
126 | private static PersistentArrayMap createAsIfByAssocComplexPath(Object[] init, boolean hasTrailing){ | |
127 | if(hasTrailing) | |
128 | { | |
129 | IPersistentCollection trailing = PersistentArrayMap.EMPTY.cons(init[init.length-1]); | |
130 | init = growSeedArray(init, trailing); | |
131 | } | |
132 | ||
81 | 133 | // If this looks like it is doing busy-work, it is because it |
82 | 134 | // is achieving these goals: O(n^2) run time like |
83 | 135 | // createWithCheck(), never modify init arg, and only |
1243 | 1243 | } |
1244 | 1244 | |
1245 | 1245 | static public int intCast(long x){ |
1246 | int i = (int) x; | |
1247 | if(i != x) | |
1248 | throw new IllegalArgumentException("Value out of range for int: " + x); | |
1249 | return i; | |
1246 | return Math.toIntExact(x); | |
1250 | 1247 | } |
1251 | 1248 | |
1252 | 1249 | static public int intCast(double x){ |
10 | 10 | |
11 | 11 | (ns clojure.test-clojure.clojure-xml |
12 | 12 | (:use clojure.test) |
13 | (:require [clojure.xml :as xml])) | |
13 | (:require [clojure.xml :as xml]) | |
14 | (:import [java.io ByteArrayInputStream])) | |
14 | 15 | |
15 | ||
16 | (deftest CLJ-2611-avoid-XXE | |
17 | (let [xml-str "<?xml version=\"1.0\" encoding=\"UTF-8\" ?> | |
18 | <!DOCTYPE foo [ | |
19 | <!ELEMENT foo ANY > | |
20 | <!ENTITY xxe SYSTEM \"file:///etc/hostname\" >]> | |
21 | <foo>&xxe;</foo>"] | |
22 | (is (= {:tag :foo, :attrs nil, :content nil} | |
23 | (with-open [input (ByteArrayInputStream. (.getBytes xml-str))] | |
24 | (xml/parse input)))))) | |
16 | 25 | ; parse |
17 | 26 | |
18 | 27 | ; emit-element |
420 | 420 | :b 1 |
421 | 421 | :c -2 |
422 | 422 | :d 4294967296 |
423 | :d 3)) | |
423 | :d 3) | |
424 | (are [result input] (= result (case input | |
425 | #{a} :set | |
426 | :foo :keyword | |
427 | a :symbol)) | |
428 | :symbol 'a | |
429 | :keyword :foo | |
430 | :set '#{a})) | |
424 | 431 | (testing "test warn for hash collision" |
425 | 432 | (should-print-err-message |
426 | 433 | #"Performance warning, .*:\d+ - hash collision of some case test constants; if selected, those entries will be tested sequentially..*\r?\n" |
1329 | 1329 | (is (= (hash (->Rec 1 1)) (hash (assoc r :a 1)))) |
1330 | 1330 | (is (= (hash (->Rec 1 1)) (hash (dissoc r2 :c)))) |
1331 | 1331 | (is (= (hash (->Rec 1 1)) (hash (dissoc (assoc r :c 1) :c)))))) |
1332 | ||
1333 | (deftest singleton-map-in-destructure-context | |
1334 | (let [sample-map {:a 1 :b 2} | |
1335 | {:keys [a] :as m1} (list sample-map)] | |
1336 | (is (= m1 sample-map)) | |
1337 | (is (= a 1)))) | |
1338 | ||
1339 | (deftest trailing-map-destructuring | |
1340 | (let [sample-map {:a 1 :b 2} | |
1341 | add (fn [& {:keys [a b]}] (+ a b)) | |
1342 | addn (fn [n & {:keys [a b]}] (+ n a b))] | |
1343 | (testing "that kwargs are applied properly given a map in place of the key/val pairs" | |
1344 | (is (= 3 (add :a 1 :b 2))) | |
1345 | (is (= 3 (add {:a 1 :b 2}))) | |
1346 | (is (= 13 (addn 10 :a 1 :b 2))) | |
1347 | (is (= 13 (addn 10 {:a 1 :b 2}))) | |
1348 | (is (= 103 ((partial addn 100) :a 1 {:b 2}))) | |
1349 | (is (= 103 ((partial addn 100 :a 1) {:b 2}))) | |
1350 | (is (= 107 ((partial addn 100 :a 1) {:a 5 :b 2})))) | |
1351 | (testing "built maps" | |
1352 | (let [{:as m1} (list :a 1 :b 2) | |
1353 | {:as m2} (list :a 1 :b 2 {:c 3}) | |
1354 | {:as m3} (list :a 1 :b 2 {:a 0}) | |
1355 | {:keys [a4] :as m4} (list nil)] | |
1356 | (= m1 {:a 1 :b 2}) | |
1357 | (= m2 {:a 1 :b 2 :c 3}) | |
1358 | (= m3 {:a 0 :b 2}) | |
1359 | (= m1 (seq-to-map-for-destructuring (list :a 1 :b 2))) | |
1360 | (= m2 (seq-to-map-for-destructuring (list :a 1 :b 2 {:c 3}))) | |
1361 | (= m3 (seq-to-map-for-destructuring (list :a 1 :b 2 {:a 0}))) | |
1362 | (= a4 nil))))) |
10 | 10 | |
11 | 11 | (ns clojure.test-clojure.java-interop |
12 | 12 | (:use clojure.test) |
13 | (:require [clojure.inspector] | |
14 | [clojure.set :as set]) | |
15 | (:import java.util.Base64)) | |
13 | (:require [clojure.data :as data] | |
14 | [clojure.inspector] | |
15 | [clojure.pprint :as pp] | |
16 | [clojure.set :as set] | |
17 | [clojure.test-clojure.proxy.examples :as proxy-examples]) | |
18 | (:import java.util.Base64 | |
19 | (java.util.concurrent.atomic AtomicLong AtomicInteger))) | |
16 | 20 | |
17 | 21 | ; http://clojure.org/java_interop |
18 | 22 | ; http://clojure.org/compilation |
174 | 178 | str) |
175 | 179 | "chain chain chain"))) |
176 | 180 | |
181 | ;https://clojure.atlassian.net/browse/CLJ-1973 | |
182 | (deftest test-proxy-method-order | |
183 | (let [class-reader (clojure.asm.ClassReader. proxy-examples/proxy1-class-name) | |
184 | method-order (atom []) | |
185 | method-visitor (proxy [clojure.asm.ClassVisitor] [clojure.asm.Opcodes/ASM4 nil] | |
186 | (visitMethod [access name descriptor signature exceptions] | |
187 | (swap! method-order conj {:name name :descriptor descriptor}) | |
188 | nil)) | |
189 | _ (.accept class-reader method-visitor 0) | |
190 | expected [{:name "<init>", :descriptor "()V"} | |
191 | {:name "__initClojureFnMappings", :descriptor "(Lclojure/lang/IPersistentMap;)V"} | |
192 | {:name "__updateClojureFnMappings", :descriptor "(Lclojure/lang/IPersistentMap;)V"} | |
193 | {:name "__getClojureFnMappings", :descriptor "()Lclojure/lang/IPersistentMap;"} | |
194 | {:name "clone", :descriptor "()Ljava/lang/Object;"} | |
195 | {:name "hashCode", :descriptor "()I"} | |
196 | {:name "toString", :descriptor "()Ljava/lang/String;"} | |
197 | {:name "equals", :descriptor "(Ljava/lang/Object;)Z"} | |
198 | {:name "a", :descriptor "(Ljava/io/File;)Z"} | |
199 | {:name "a", :descriptor "(Ljava/lang/Boolean;)Ljava/lang/Object;"} | |
200 | {:name "a", :descriptor "(Ljava/lang/Runnable;)Z"} | |
201 | {:name "a", :descriptor "(Ljava/lang/String;)I"} | |
202 | {:name "b", :descriptor "(Ljava/lang/String;)Ljava/lang/Object;"} | |
203 | {:name "c", :descriptor "(Ljava/lang/String;)Ljava/lang/Object;"} | |
204 | {:name "d", :descriptor "(Ljava/lang/String;)Ljava/lang/Object;"} | |
205 | {:name "a", :descriptor "(Ljava/lang/Boolean;Ljava/lang/String;)I"} | |
206 | {:name "a", :descriptor "(Ljava/lang/String;Ljava/io/File;)Z"} | |
207 | {:name "a", :descriptor "(Ljava/lang/String;Ljava/lang/Runnable;)Z"} | |
208 | {:name "a", :descriptor "(Ljava/lang/String;Ljava/lang/String;)I"}] | |
209 | actual @method-order] | |
210 | (is (= expected actual) | |
211 | (with-out-str (pp/pprint (data/diff expected actual)))))) | |
177 | 212 | |
178 | 213 | ;; serialized-proxy can be regenerated using a modified version of |
179 | 214 | ;; Clojure with the proxy serialization prohibition disabled and the |
588 | 623 | (is (= (char \a) \a))) |
589 | 624 | |
590 | 625 | ;; Note: More coercions in numbers.clj |
626 | ||
627 | ; Test that primitive boxing elision in statement context works | |
628 | ; correctly (CLJ-2621) | |
629 | ||
630 | (defn inc-atomic-int [^AtomicInteger l] | |
631 | (.incrementAndGet l) | |
632 | nil) | |
633 | ||
634 | (defn inc-atomic-long [^AtomicLong l] | |
635 | (.incrementAndGet l) | |
636 | nil) | |
637 | ||
638 | (deftest test-boxing-prevention-when-compiling-statements | |
639 | (is (= 1 (.get (doto (AtomicInteger. 0) inc-atomic-int)))) | |
640 | (is (= 1 (.get (doto (AtomicLong. 0) inc-atomic-long))))) |
22 | 22 | (are [result lookup] (= result (find-keyword this-ns lookup)) |
23 | 23 | ::foo "foo" |
24 | 24 | nil (str absent-keyword-sym))))) |
25 | ||
26 | (deftest arity-exceptions | |
27 | (is (thrown-with-msg? IllegalArgumentException #"Wrong number of args \(0\) passed to: :kw" (:kw))) | |
28 | (is (thrown-with-msg? IllegalArgumentException #"Wrong number of args \(20\) passed to: :foo/bar" (apply :foo/bar (range 20)))) | |
29 | (is (thrown-with-msg? IllegalArgumentException #"Wrong number of args \(21\) passed to: :foo/bar" (apply :foo/bar (range 21)))) | |
30 | (is (thrown-with-msg? IllegalArgumentException #"Wrong number of args \(22\) passed to: :foo/bar" (apply :foo/bar (range 22))))) |
0 | ; Copyright (c) Rich Hickey. All rights reserved. | |
1 | ; The use and distribution terms for this software are covered by the | |
2 | ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | |
3 | ; which can be found in the file epl-v10.html at the root of this distribution. | |
4 | ; By using this software in any fashion, you are agreeing to be bound by | |
5 | ; the terms of this license. | |
6 | ; You must not remove this notice, or any other, from this software. | |
7 | ||
8 | (ns clojure.test-clojure.math | |
9 | (:require | |
10 | [clojure.test :refer :all] | |
11 | [clojure.math :as m])) | |
12 | ||
13 | (set! *warn-on-reflection* true) | |
14 | ||
15 | (defn neg-zero? | |
16 | [^double d] | |
17 | (and (zero? d) (< (Double/compare d 0.0) 0))) | |
18 | ||
19 | (defn pos-zero? | |
20 | [^double d] | |
21 | (and (zero? d) (not (< (Double/compare d 0.0) 0)))) | |
22 | ||
23 | (defn ulp= | |
24 | "Tests that y = x +/- m*ulp(x)" | |
25 | [x y ^double m] | |
26 | (let [mu (* (m/ulp x) m)] | |
27 | (<= (- x mu) y (+ x mu)))) | |
28 | ||
29 | (deftest test-sin | |
30 | (is (NaN? (m/sin ##NaN))) | |
31 | (is (NaN? (m/sin ##-Inf))) | |
32 | (is (NaN? (m/sin ##Inf))) | |
33 | (is (pos-zero? (m/sin 0.0))) | |
34 | (is (neg-zero? (m/sin -0.0))) | |
35 | (is (ulp= (m/sin m/PI) (- (m/sin (- m/PI))) 1))) | |
36 | ||
37 | (deftest test-cos | |
38 | (is (NaN? (m/cos ##NaN))) | |
39 | (is (NaN? (m/cos ##-Inf))) | |
40 | (is (NaN? (m/cos ##Inf))) | |
41 | (is (= 1.0 (m/cos 0.0) (m/cos -0.0))) | |
42 | (is (ulp= (m/cos m/PI) (m/cos (- m/PI)) 1))) | |
43 | ||
44 | (deftest test-tan | |
45 | (is (NaN? (m/tan ##NaN))) | |
46 | (is (NaN? (m/tan ##-Inf))) | |
47 | (is (NaN? (m/tan ##Inf))) | |
48 | (is (pos-zero? (m/tan 0.0))) | |
49 | (is (neg-zero? (m/tan -0.0))) | |
50 | (is (ulp= (- (m/tan m/PI)) (m/tan (- m/PI)) 1))) | |
51 | ||
52 | (deftest test-asin | |
53 | (is (NaN? (m/asin ##NaN))) | |
54 | (is (NaN? (m/asin 2.0))) | |
55 | (is (NaN? (m/asin -2.0))) | |
56 | (is (zero? (m/asin -0.0)))) | |
57 | ||
58 | (deftest test-acos | |
59 | (is (NaN? (m/acos ##NaN))) | |
60 | (is (NaN? (m/acos -2.0))) | |
61 | (is (NaN? (m/acos 2.0))) | |
62 | (is (ulp= (* 2 (m/acos 0.0)) m/PI 1))) | |
63 | ||
64 | (deftest test-atan | |
65 | (is (NaN? (m/atan ##NaN))) | |
66 | (is (pos-zero? (m/atan 0.0))) | |
67 | (is (neg-zero? (m/atan -0.0))) | |
68 | (is (ulp= (m/atan 1) 0.7853981633974483 1))) | |
69 | ||
70 | (deftest test-radians-degrees-roundtrip | |
71 | (doseq [d (range 0.0 360.0 5.0)] | |
72 | (is (ulp= (m/round d) (m/round (-> d m/to-radians m/to-degrees)) 1)))) | |
73 | ||
74 | (deftest test-exp | |
75 | (is (NaN? (m/exp ##NaN))) | |
76 | (is (= ##Inf (m/exp ##Inf))) | |
77 | (is (pos-zero? (m/exp ##-Inf))) | |
78 | (is (ulp= (m/exp 0.0) 1.0 1)) | |
79 | (is (ulp= (m/exp 1) m/E 1))) | |
80 | ||
81 | (deftest test-log | |
82 | (is (NaN? (m/log ##NaN))) | |
83 | (is (NaN? (m/log -1.0))) | |
84 | (is (= ##Inf (m/log ##Inf))) | |
85 | (is (= ##-Inf (m/log 0.0))) | |
86 | (is (ulp= (m/log m/E) 1.0 1))) | |
87 | ||
88 | (deftest test-log10 | |
89 | (is (NaN? (m/log10 ##NaN))) | |
90 | (is (NaN? (m/log10 -1.0))) | |
91 | (is (= ##Inf (m/log10 ##Inf))) | |
92 | (is (= ##-Inf (m/log10 0.0))) | |
93 | (is (ulp= (m/log10 10) 1.0 1))) | |
94 | ||
95 | (deftest test-sqrt | |
96 | (is (NaN? (m/sqrt ##NaN))) | |
97 | (is (NaN? (m/sqrt -1.0))) | |
98 | (is (= ##Inf (m/sqrt ##Inf))) | |
99 | (is (pos-zero? (m/sqrt 0))) | |
100 | (is (= (m/sqrt 4.0) 2.0))) | |
101 | ||
102 | (deftest test-cbrt | |
103 | (is (NaN? (m/cbrt ##NaN))) | |
104 | (is (= ##-Inf (m/cbrt ##-Inf))) | |
105 | (is (= ##Inf (m/cbrt ##Inf))) | |
106 | (is (pos-zero? (m/cbrt 0))) | |
107 | (is (= 2.0 (m/cbrt 8.0)))) | |
108 | ||
109 | (deftest test-IEEE-remainder | |
110 | (is (NaN? (m/IEEE-remainder ##NaN 1.0))) | |
111 | (is (NaN? (m/IEEE-remainder 1.0 ##NaN))) | |
112 | (is (NaN? (m/IEEE-remainder ##Inf 2.0))) | |
113 | (is (NaN? (m/IEEE-remainder ##-Inf 2.0))) | |
114 | (is (NaN? (m/IEEE-remainder 2 0.0))) | |
115 | (is (= 1.0 (m/IEEE-remainder 5.0 4.0)))) | |
116 | ||
117 | (deftest test-ceil | |
118 | (is (NaN? (m/ceil ##NaN))) | |
119 | (is (= ##Inf (m/ceil ##Inf))) | |
120 | (is (= ##-Inf (m/ceil ##-Inf))) | |
121 | (is (= 4.0 (m/ceil m/PI)))) | |
122 | ||
123 | (deftest test-floor | |
124 | (is (NaN? (m/floor ##NaN))) | |
125 | (is (= ##Inf (m/floor ##Inf))) | |
126 | (is (= ##-Inf (m/floor ##-Inf))) | |
127 | (is (= 3.0 (m/floor m/PI)))) | |
128 | ||
129 | (deftest test-rint | |
130 | (is (NaN? (m/rint ##NaN))) | |
131 | (is (= ##Inf (m/rint ##Inf))) | |
132 | (is (= ##-Inf (m/rint ##-Inf))) | |
133 | (is (= 1.0 (m/rint 1.2))) | |
134 | (is (neg-zero? (m/rint -0.01)))) | |
135 | ||
136 | (deftest test-atan2 | |
137 | (is (NaN? (m/atan2 ##NaN 1.0))) | |
138 | (is (NaN? (m/atan2 1.0 ##NaN))) | |
139 | (is (pos-zero? (m/atan2 0.0 1.0))) | |
140 | (is (neg-zero? (m/atan2 -0.0 1.0))) | |
141 | (is (ulp= (m/atan2 0.0 -1.0) m/PI 2)) | |
142 | (is (ulp= (m/atan2 -0.0 -1.0) (- m/PI) 2)) | |
143 | (is (ulp= (* 2.0 (m/atan2 1.0 0.0)) m/PI 2)) | |
144 | (is (ulp= (* -2.0 (m/atan2 -1.0 0.0)) m/PI 2)) | |
145 | (is (ulp= (* 4.0 (m/atan2 ##Inf ##Inf)) m/PI 2)) | |
146 | (is (ulp= (/ (* 4.0 (m/atan2 ##Inf ##-Inf)) 3.0) m/PI 2)) | |
147 | (is (ulp= (* -4.0 (m/atan2 ##-Inf ##Inf)) m/PI 2)) | |
148 | (is (ulp= (/ (* -4.0 (m/atan2 ##-Inf ##-Inf)) 3.0) m/PI 2))) | |
149 | ||
150 | (deftest test-pow | |
151 | (is (= 1.0 (m/pow 4.0 0.0))) | |
152 | (is (= 1.0 (m/pow 4.0 -0.0))) | |
153 | (is (= 4.2 (m/pow 4.2 1.0))) | |
154 | (is (NaN? (m/pow 4.2 ##NaN))) | |
155 | (is (NaN? (m/pow ##NaN 2.0))) | |
156 | (is (= ##Inf (m/pow 2.0 ##Inf))) | |
157 | (is (= ##Inf (m/pow 0.5 ##-Inf))) | |
158 | (is (= 0.0 (m/pow 2.0 ##-Inf))) | |
159 | (is (= 0.0 (m/pow 0.5 ##Inf))) | |
160 | (is (NaN? (m/pow 1.0 ##Inf))) | |
161 | (is (pos-zero? (m/pow 0.0 1.5))) | |
162 | (is (pos-zero? (m/pow ##Inf -2.0))) | |
163 | (is (= ##Inf (m/pow 0.0 -2.0))) | |
164 | (is (= ##Inf (m/pow ##Inf 2.0))) | |
165 | (is (pos-zero? (m/pow -0.0 1.5))) | |
166 | (is (pos-zero? (m/pow ##-Inf -1.5))) | |
167 | (is (neg-zero? (m/pow -0.0 3.0))) | |
168 | (is (neg-zero? (m/pow ##-Inf -3.0))) | |
169 | (is (= ##Inf (m/pow -0.0 -1.5))) | |
170 | (is (= ##Inf (m/pow ##-Inf 2.5))) | |
171 | (is (= ##-Inf (m/pow -0.0 -3.0))) | |
172 | (is (= ##-Inf (m/pow ##-Inf 3.0))) | |
173 | (is (= 4.0 (m/pow -2.0 2.0))) | |
174 | (is (= -8.0 (m/pow -2.0 3.0))) | |
175 | (is (= 8.0 (m/pow 2.0 3.0)))) | |
176 | ||
177 | (deftest test-round | |
178 | (is (= 0 (m/round ##NaN))) | |
179 | (is (= Long/MIN_VALUE (m/round ##-Inf))) | |
180 | (is (= Long/MIN_VALUE (m/round (- Long/MIN_VALUE 2.0)))) | |
181 | (is (= Long/MAX_VALUE (m/round ##Inf))) | |
182 | (is (= Long/MAX_VALUE (m/round (+ Long/MAX_VALUE 2.0)))) | |
183 | (is (= 4 (m/round 3.5)))) | |
184 | ||
185 | (deftest test-add-exact | |
186 | (try | |
187 | (m/add-exact Long/MAX_VALUE 1) | |
188 | (is false) | |
189 | (catch ArithmeticException _ | |
190 | (is true)))) | |
191 | ||
192 | (deftest test-subtract-exact | |
193 | (try | |
194 | (m/subtract-exact Long/MIN_VALUE 1) | |
195 | (is false) | |
196 | (catch ArithmeticException _ | |
197 | (is true)))) | |
198 | ||
199 | (deftest test-multiply-exact | |
200 | (try | |
201 | (m/multiply-exact Long/MAX_VALUE 2) | |
202 | (is false) | |
203 | (catch ArithmeticException _ | |
204 | (is true)))) | |
205 | ||
206 | (deftest test-increment-exact | |
207 | (try | |
208 | (m/increment-exact Long/MAX_VALUE) | |
209 | (is false) | |
210 | (catch ArithmeticException _ | |
211 | (is true)))) | |
212 | ||
213 | (deftest test-decrement-exact | |
214 | (try | |
215 | (m/decrement-exact Long/MIN_VALUE) | |
216 | (is false) | |
217 | (catch ArithmeticException _ | |
218 | (is true)))) | |
219 | ||
220 | (deftest test-negate-exact | |
221 | (is (= (inc Long/MIN_VALUE) (m/negate-exact Long/MAX_VALUE))) | |
222 | (try | |
223 | (m/negate-exact Long/MIN_VALUE) | |
224 | (is false) | |
225 | (catch ArithmeticException _ | |
226 | (is true)))) | |
227 | ||
228 | (deftest test-floor-div | |
229 | (is (= Long/MIN_VALUE (m/floor-div Long/MIN_VALUE -1))) | |
230 | (is (= -1 (m/floor-div -2 5)))) | |
231 | ||
232 | (deftest test-floor-mod | |
233 | (is (= 3 (m/floor-mod -2 5)))) | |
234 | ||
235 | (deftest test-ulp | |
236 | (is (NaN? (m/ulp ##NaN))) | |
237 | (is (= ##Inf (m/ulp ##Inf))) | |
238 | (is (= ##Inf (m/ulp ##-Inf))) | |
239 | (is (= Double/MIN_VALUE (m/ulp 0.0))) | |
240 | (is (= (m/pow 2 971) (m/ulp Double/MAX_VALUE))) | |
241 | (is (= (m/pow 2 971) (m/ulp (- Double/MAX_VALUE))))) | |
242 | ||
243 | (deftest test-signum | |
244 | (is (NaN? (m/signum ##NaN))) | |
245 | (is (zero? (m/signum 0.0))) | |
246 | (is (zero? (m/signum -0.0))) | |
247 | (is (= 1.0 (m/signum 42.0))) | |
248 | (is (= -1.0 (m/signum -42.0)))) | |
249 | ||
250 | (deftest test-sinh | |
251 | (is (NaN? (m/sinh ##NaN))) | |
252 | (is (= ##Inf (m/sinh ##Inf))) | |
253 | (is (= ##-Inf (m/sinh ##-Inf))) | |
254 | (is (= 0.0 (m/sinh 0.0)))) | |
255 | ||
256 | (deftest test-cosh | |
257 | (is (NaN? (m/cosh ##NaN))) | |
258 | (is (= ##Inf (m/cosh ##Inf))) | |
259 | (is (= ##Inf (m/cosh ##-Inf))) | |
260 | (is (= 1.0 (m/cosh 0.0)))) | |
261 | ||
262 | (deftest test-tanh | |
263 | (is (NaN? (m/tanh ##NaN))) | |
264 | (is (= 1.0 (m/tanh ##Inf))) | |
265 | (is (= -1.0 (m/tanh ##-Inf))) | |
266 | (is (= 0.0 (m/tanh 0.0)))) | |
267 | ||
268 | (deftest test-hypot | |
269 | (is (= ##Inf (m/hypot 1.0 ##Inf))) | |
270 | (is (= ##Inf (m/hypot ##Inf 1.0))) | |
271 | (is (NaN? (m/hypot ##NaN 1.0))) | |
272 | (is (NaN? (m/hypot 1.0 ##NaN))) | |
273 | (is (= 13.0 (m/hypot 5.0 12.0)))) | |
274 | ||
275 | (deftest test-expm1 | |
276 | (is (NaN? (m/expm1 ##NaN))) | |
277 | (is (= ##Inf (m/expm1 ##Inf))) | |
278 | (is (= -1.0 (m/expm1 ##-Inf))) | |
279 | (is (= 0.0 (m/expm1 0.0)))) | |
280 | ||
281 | (deftest test-log1p | |
282 | (is (NaN? (m/log1p ##NaN))) | |
283 | (is (= ##Inf (m/log1p ##Inf))) | |
284 | (is (= ##-Inf (m/log1p -1.0))) | |
285 | (is (pos-zero? (m/log1p 0.0))) | |
286 | (is (neg-zero? (m/log1p -0.0)))) | |
287 | ||
288 | (deftest test-copy-sign | |
289 | (is (= 1.0 (m/copy-sign 1.0 42.0))) | |
290 | (is (= -1.0 (m/copy-sign 1.0 -42.0))) | |
291 | (is (= -1.0 (m/copy-sign 1.0 ##-Inf)))) | |
292 | ||
293 | (deftest test-get-exponent | |
294 | (is (= (inc Double/MAX_EXPONENT) (m/get-exponent ##NaN))) | |
295 | (is (= (inc Double/MAX_EXPONENT) (m/get-exponent ##Inf))) | |
296 | (is (= (inc Double/MAX_EXPONENT) (m/get-exponent ##-Inf))) | |
297 | (is (= (dec Double/MIN_EXPONENT) (m/get-exponent 0.0))) | |
298 | (is (= 0 (m/get-exponent 1.0))) | |
299 | (is (= 13 (m/get-exponent 12345.678)))) | |
300 | ||
301 | (deftest test-next-after | |
302 | (is (NaN? (m/next-after ##NaN 1))) | |
303 | (is (NaN? (m/next-after 1 ##NaN))) | |
304 | (is (pos-zero? (m/next-after 0.0 0.0))) | |
305 | (is (neg-zero? (m/next-after -0.0 -0.0))) | |
306 | (is (= Double/MAX_VALUE (m/next-after ##Inf 1.0))) | |
307 | (is (pos-zero? (m/next-after Double/MIN_VALUE -1.0)))) | |
308 | ||
309 | (deftest test-next-up | |
310 | (is (NaN? (m/next-up ##NaN))) | |
311 | (is (= ##Inf (m/next-up ##Inf))) | |
312 | (is (= Double/MIN_VALUE (m/next-up 0.0)))) | |
313 | ||
314 | (deftest test-next-down | |
315 | (is (NaN? (m/next-down ##NaN))) | |
316 | (is (= ##-Inf (m/next-down ##-Inf))) | |
317 | (is (= (- Double/MIN_VALUE) (m/next-down 0.0)))) | |
318 | ||
319 | (deftest test-scalb | |
320 | (is (NaN? (m/scalb ##NaN 1))) | |
321 | (is (= ##Inf (m/scalb ##Inf 1))) | |
322 | (is (= ##-Inf (m/scalb ##-Inf 1))) | |
323 | (is (pos-zero? (m/scalb 0.0 2))) | |
324 | (is (neg-zero? (m/scalb -0.0 2))) | |
325 | (is (= 32.0 (m/scalb 2.0 4)))) |
202 | 202 | (testing "The prefers method now returns the correct table" |
203 | 203 | (is (= {[::rect ::shape] #{[::shape ::rect]}} (prefers bar))))) |
204 | 204 | |
205 | (deftest indirect-preferences-mulitmethod-test | |
206 | (testing "Using global hierarchy" | |
207 | (derive ::parent-1 ::grandparent-1) | |
208 | (derive ::parent-2 ::grandparent-2) | |
209 | (derive ::child ::parent-1) | |
210 | (derive ::child ::parent-2) | |
211 | (testing "x should be preferred over y if x is preferred over an ancestor of y" | |
212 | (defmulti indirect-1 keyword) | |
213 | (prefer-method indirect-1 ::parent-1 ::grandparent-2) | |
214 | (defmethod indirect-1 ::parent-1 [_] ::parent-1) | |
215 | (defmethod indirect-1 ::parent-2 [_] ::parent-2) | |
216 | (is (= ::parent-1 (indirect-1 ::child)))) | |
217 | (testing "x should be preferred over y if an ancestor of x is preferred over y" | |
218 | (defmulti indirect-2 keyword) | |
219 | (prefer-method indirect-2 ::grandparent-1 ::parent-2) | |
220 | (defmethod indirect-2 ::parent-1 [_] ::parent-1) | |
221 | (defmethod indirect-2 ::parent-2 [_] ::parent-2) | |
222 | (is (= ::parent-1 (indirect-2 ::child))))) | |
223 | (testing "Using custom hierarchy" | |
224 | (def local-h (-> (make-hierarchy) | |
225 | (derive :parent-1 :grandparent-1) | |
226 | (derive :parent-2 :grandparent-2) | |
227 | (derive :child :parent-1) | |
228 | (derive :child :parent-2))) | |
229 | (testing "x should be preferred over y if x is preferred over an ancestor of y" | |
230 | (defmulti indirect-3 keyword :hierarchy #'local-h) | |
231 | (prefer-method indirect-3 :parent-1 :grandparent-2) | |
232 | (defmethod indirect-3 :parent-1 [_] :parent-1) | |
233 | (defmethod indirect-3 :parent-2 [_] :parent-2) | |
234 | (is (= :parent-1 (indirect-3 :child)))) | |
235 | (testing "x should be preferred over y if an ancestor of x is preferred over y" | |
236 | (defmulti indirect-4 keyword :hierarchy #'local-h) | |
237 | (prefer-method indirect-4 :grandparent-1 :parent-2) | |
238 | (defmethod indirect-4 :parent-1 [_] :parent-1) | |
239 | (defmethod indirect-4 :parent-2 [_] :parent-2) | |
240 | (is (= :parent-1 (indirect-4 :child)))))) | |
241 | ||
205 | 242 | (deftest remove-all-methods-test |
206 | 243 | (testing "Core function remove-all-methods works" |
207 | 244 | (defmulti simple1 identity) |
102 | 102 | (is (thrown-with-cause-msg? clojure.lang.Compiler$CompilerException |
103 | 103 | #"defrecord and deftype fields must be symbols, user\.MyType had: :key1" |
104 | 104 | (eval '(deftype MyType [:key1]))))) |
105 | ||
106 | (deftest require-as-alias | |
107 | ;; :as-alias does not load | |
108 | (require '[not.a.real.ns [foo :as-alias foo] | |
109 | [bar :as-alias bar]]) | |
110 | (let [aliases (ns-aliases *ns*) | |
111 | foo-ns (get aliases 'foo) | |
112 | bar-ns (get aliases 'bar)] | |
113 | (is (= 'not.a.real.ns.foo (ns-name foo-ns))) | |
114 | (is (= 'not.a.real.ns.bar (ns-name bar-ns)))) | |
115 | ||
116 | (is (= :not.a.real.ns.foo/baz (read-string "::foo/baz"))) | |
117 | ||
118 | ;; can use :as-alias in use, but load will occur | |
119 | (use '[clojure.walk :as-alias e1]) | |
120 | (is (= 'clojure.walk (ns-name (get (ns-aliases *ns*) 'e1)))) | |
121 | (is (= :clojure.walk/walk (read-string "::e1/walk"))) | |
122 | ||
123 | ;; can use both :as and :as-alias | |
124 | (require '[clojure.set :as n1 :as-alias n2]) | |
125 | (let [aliases (ns-aliases *ns*)] | |
126 | (is (= 'clojure.set (ns-name (get aliases 'n1)))) | |
127 | (is (= 'clojure.set (ns-name (get aliases 'n2)))) | |
128 | (is (= (resolve 'n1/union) #'clojure.set/union)) | |
129 | (is (= (resolve 'n2/union) #'clojure.set/union)))) | |
130 | ||
131 | (deftest require-as-alias-then-load-later | |
132 | ;; alias but don't load | |
133 | (require '[clojure.test-clojure.ns-libs-load-later :as-alias alias-now]) | |
134 | (is (contains? (ns-aliases *ns*) 'alias-now)) | |
135 | (is (not (nil? (find-ns 'clojure.test-clojure.ns-libs-load-later)))) | |
136 | ||
137 | ;; not loaded! | |
138 | (is (nil? (resolve 'alias-now/example))) | |
139 | ||
140 | ;; load | |
141 | (require 'clojure.test-clojure.ns-libs-load-later) | |
142 | ||
143 | ;; now loaded! | |
144 | (is (not (nil? (resolve 'alias-now/example)))))⏎ |
0 | ; Copyright (c) Rich Hickey. All rights reserved. | |
1 | ; The use and distribution terms for this software are covered by the | |
2 | ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | |
3 | ; which can be found in the file epl-v10.html at the root of this distribution. | |
4 | ; By using this software in any fashion, you are agreeing to be bound by | |
5 | ; the terms of this license. | |
6 | ; You must not remove this notice, or any other, from this software. | |
7 | ||
8 | ;; used by clojure.test-clojure.ns-libs/require-as-alias-then-load-later | |
9 | (ns clojure.test-clojure.ns-libs-load-later) | |
10 | ||
11 | (defn example [] true) |
180 | 180 | (let [wrapped (fn [x] |
181 | 181 | (try |
182 | 182 | (f x) |
183 | (catch IllegalArgumentException e :error)))] | |
183 | (catch RuntimeException e :error)))] | |
184 | 184 | (is (= vals (map wrapped inputs))))))) |
185 | ||
186 | (deftest test-prim-with-matching-hint | |
187 | (is (= 1 (let [x 1.2] (Math/round ^double x))))) | |
185 | 188 | |
186 | 189 | ;; *** Functions *** |
187 | 190 | |
642 | 645 | (is (= java.lang.Long (class (min 1.0 -10 2.0)))) |
643 | 646 | (is (= java.lang.Long (class (min 1.0 2.0 -10)))) |
644 | 647 | (is (= java.lang.Double (class (min 1 2 -10.0 3 4 5)))))) |
648 | ||
649 | (deftest test-abs | |
650 | (are [in ex] (= ex (abs in)) | |
651 | -1 1 | |
652 | 1 1 | |
653 | Long/MIN_VALUE Long/MIN_VALUE ;; special case! | |
654 | -1.0 1.0 | |
655 | -0.0 0.0 | |
656 | ##-Inf ##Inf | |
657 | ##Inf ##Inf | |
658 | -123.456M 123.456M | |
659 | -123N 123N | |
660 | -1/5 1/5) | |
661 | (is (NaN? (abs ##NaN)))) | |
645 | 662 | |
646 | 663 | (deftest clj-868 |
647 | 664 | (testing "min/max: NaN is contagious" |
276 | 276 | ((some-fn number? odd? #(> % 0)) 2 4 6 8 -10) |
277 | 277 | ;; 3 preds, short-circuiting |
278 | 278 | ((some-fn number? odd? #(> % 0)) 1 :a) |
279 | ((some-fn number? odd? #(> % 0)) :a 1) | |
279 | 280 | ((some-fn number? odd? #(> % 0)) 1 3 :a) |
281 | ((some-fn number? odd? #(> % 0)) :a 1 3) | |
280 | 282 | ((some-fn number? odd? #(> % 0)) 1 3 5 :a) |
281 | 283 | ((some-fn number? odd? #(> % 0)) 1 :a 3 5 7) |
282 | 284 | ;; 4 preds |
378 | 380 | ;; rest arity |
379 | 381 | {:a 5} (update {:a 1} :a + 1 1 1 1) |
380 | 382 | {:a 6} (update {:a 1} :a + 1 1 1 1 1))) |
383 | ||
384 | (deftest test-update-vals | |
385 | (let [inm (with-meta {:a 1 :b 2} {:has :meta})] | |
386 | (are [result expr] (= result expr) | |
387 | {:a 2 :b 3} (update-vals inm inc) | |
388 | {:has :meta} (meta (update-vals inm inc)) | |
389 | {0 2 2 4} (update-vals (hash-map 0 1 2 3) inc) | |
390 | {0 2 2 4} (update-vals (array-map 0 1 2 3) inc) | |
391 | {0 2 2 4} (update-vals (sorted-map 2 3 0 1) inc)))) | |
392 | ||
393 | (deftest test-update-keys | |
394 | (let [inm (with-meta {:a 1 :b 2} {:has :meta})] | |
395 | (are [result expr] (= result expr) | |
396 | {"a" 1 "b" 2} (update-keys inm name) | |
397 | {:has :meta} (meta (update-keys inm name)) | |
398 | {1 1 3 3} (update-keys (hash-map 0 1 2 3) inc) | |
399 | {1 1 3 3} (update-keys (array-map 0 1 2 3) inc) | |
400 | {1 1 3 3} (update-keys (sorted-map 2 3 0 1) inc)))) |
0 | (ns clojure.test-clojure.parse | |
1 | (:require | |
2 | [clojure.test :refer :all] | |
3 | [clojure.test.check :as chk] | |
4 | [clojure.test.check.generators :as gen] | |
5 | [clojure.test.check.properties :as prop]) | |
6 | (:import | |
7 | [java.util UUID])) | |
8 | ||
9 | (deftest test-parse-long | |
10 | (are [s expected] | |
11 | (= expected (parse-long s)) | |
12 | "100" 100 | |
13 | "+100" 100 | |
14 | "0" 0 | |
15 | "+0" 0 | |
16 | "-0" 0 | |
17 | "-42" -42 | |
18 | "9223372036854775807" Long/MAX_VALUE | |
19 | "+9223372036854775807" Long/MAX_VALUE | |
20 | "-9223372036854775808" Long/MIN_VALUE | |
21 | "077" 77) ;; leading 0s are ignored! (not octal) | |
22 | ||
23 | (are [s] ;; do not parse | |
24 | (nil? (parse-long s)) | |
25 | "0.3" ;; no float | |
26 | "9223372036854775808" ;; past max long | |
27 | "-9223372036854775809" ;; past min long | |
28 | "0xA0" ;; no hex | |
29 | "2r010")) ;; no radix support | |
30 | ||
31 | ;; generative test - gen long -> str -> parse, compare | |
32 | (deftest test-gen-parse-long | |
33 | (let [res (chk/quick-check | |
34 | 100000 | |
35 | (prop/for-all* [gen/large-integer] | |
36 | #(= % (-> % str parse-long))))] | |
37 | (if (:result res) | |
38 | (is true) ;; pass | |
39 | (is (:result res) (pr-str res))))) | |
40 | ||
41 | (deftest test-parse-double | |
42 | (are [s expected] | |
43 | (= expected (parse-double s)) | |
44 | "1.234" 1.234 | |
45 | "+1.234" 1.234 | |
46 | "-1.234" -1.234 | |
47 | "+0" +0.0 | |
48 | "-0.0" -0.0 | |
49 | "0.0" 0.0 | |
50 | "5" 5.0 | |
51 | "Infinity" Double/POSITIVE_INFINITY | |
52 | "-Infinity" Double/NEGATIVE_INFINITY | |
53 | "1.7976931348623157E308" Double/MAX_VALUE | |
54 | "4.9E-324" Double/MIN_VALUE | |
55 | "1.7976931348623157E309" Double/POSITIVE_INFINITY ;; past max double | |
56 | "2.5e-324" Double/MIN_VALUE ;; past min double, above half minimum | |
57 | "2.4e-324" 0.0) ;; below minimum double | |
58 | (is (Double/isNaN (parse-double "NaN"))) | |
59 | (are [s] ;; nil on invalid string | |
60 | (nil? (parse-double s)) | |
61 | "double" ;; invalid string | |
62 | "1.7976931348623157G309")) ;; invalid, but similar to valid | |
63 | ||
64 | ;; generative test - gen double -> str -> parse, compare | |
65 | (deftest test-gen-parse-double | |
66 | (let [res (chk/quick-check | |
67 | 100000 | |
68 | (prop/for-all* [gen/double] | |
69 | #(let [parsed (-> % str parse-double)] | |
70 | (if (Double/isNaN %) | |
71 | (Double/isNaN parsed) | |
72 | (= % parsed)))))] | |
73 | (if (:result res) | |
74 | (is true) ;; pass | |
75 | (is (:result res) (pr-str res))))) | |
76 | ||
77 | (deftest test-parse-uuid | |
78 | (is (parse-uuid (.toString (UUID/randomUUID)))) | |
79 | (is (nil? (parse-uuid "BOGUS"))) ;; nil on invalid uuid string | |
80 | (are [s] ;; throw on invalid type (not string) | |
81 | (try (parse-uuid s) (is false) (catch Throwable _ (is true))) | |
82 | 123 | |
83 | nil)) | |
84 | ||
85 | (deftest test-parse-boolean | |
86 | (is (identical? true (parse-boolean "true"))) | |
87 | (is (identical? false (parse-boolean "false"))) | |
88 | ||
89 | (are [s] ;; nil on invalid string | |
90 | (nil? (parse-boolean s)) | |
91 | "abc" | |
92 | "TRUE" | |
93 | "FALSE" | |
94 | " true ") | |
95 | ||
96 | (are [s] ;; throw on invalid type (not string) | |
97 | (try (parse-boolean s) (is false) (catch Throwable _ (is true))) | |
98 | nil | |
99 | false | |
100 | true | |
101 | 100)) |
171 | 171 | (dotimes [i (count row)] |
172 | 172 | (is (= ((resolve (nth preds i)) v) (nth row i)) |
173 | 173 | (pr-str (list (nth preds i) v)))))))) |
174 | ||
175 | ;; Special double predicates | |
176 | ||
177 | (deftest test-double-preds | |
178 | (is (NaN? ##NaN)) | |
179 | (is (NaN? (Double/parseDouble "NaN"))) | |
180 | (is (NaN? (Float/parseFloat "NaN"))) | |
181 | (is (NaN? Float/NaN)) | |
182 | (is (not (NaN? 5))) | |
183 | (is (thrown? Throwable (NaN? nil))) | |
184 | (is (thrown? Throwable (NaN? :xyz))) | |
185 | ||
186 | (is (infinite? ##Inf)) | |
187 | (is (infinite? ##-Inf)) | |
188 | (is (infinite? Double/POSITIVE_INFINITY)) | |
189 | (is (infinite? Double/NEGATIVE_INFINITY)) | |
190 | (is (infinite? Float/POSITIVE_INFINITY)) | |
191 | (is (infinite? Float/NEGATIVE_INFINITY)) | |
192 | (is (thrown? Throwable (infinite? nil))) | |
193 | (is (thrown? Throwable (infinite? :xyz))))⏎ |
16 | 16 | (hinted [^int i]) |
17 | 17 | (hinted [^String s])) |
18 | 18 | |
19 | (defprotocol LongsHintedProto | |
20 | (^longs longs-hinted [_])) |
46 | 46 | (deftest protocols-test |
47 | 47 | (testing "protocol fns have useful metadata" |
48 | 48 | (let [common-meta {:ns (find-ns 'clojure.test-clojure.protocols.examples) |
49 | :protocol #'ExampleProtocol}] | |
50 | (are [m f] (= (merge (quote m) common-meta) | |
49 | :protocol #'ExampleProtocol :tag nil}] | |
50 | (are [m f] (= (merge common-meta m) | |
51 | 51 | (meta (var f))) |
52 | {:name foo :arglists ([a]) :doc "method with one arg"} foo | |
53 | {:name bar :arglists ([a b]) :doc "method with two args"} bar | |
54 | {:name baz :arglists ([a] [a b]) :doc "method with multiple arities" :tag String} baz | |
55 | {:name with-quux :arglists ([a]) :doc "method name with a hyphen"} with-quux))) | |
52 | {:name 'foo :arglists '([a]) :doc "method with one arg"} foo | |
53 | {:name 'bar :arglists '([a b]) :doc "method with two args"} bar | |
54 | {:name 'baz :arglists '([a] [a b]) :doc "method with multiple arities" :tag 'java.lang.String} baz | |
55 | {:name 'with-quux :arglists '([a]) :doc "method name with a hyphen"} with-quux))) | |
56 | 56 | (testing "protocol fns throw IllegalArgumentException if no impl matches" |
57 | 57 | (is (thrown-with-msg? |
58 | 58 | IllegalArgumentException |
673 | 673 | (deftest test-leading-dashes |
674 | 674 | (is (= 10 (-do-dashed (Dashed.)))) |
675 | 675 | (is (= [10] (map -do-dashed [(Dashed.)])))) |
676 | ||
677 | ;; see CLJ-1879 | |
678 | ||
679 | (deftest test-base-reduce-kv | |
680 | (is (= {1 :a 2 :b} | |
681 | (reduce-kv #(assoc %1 %3 %2) | |
682 | {} | |
683 | (seq {:a 1 :b 2}))))) | |
684 | ||
685 | (defn aget-long-hinted ^long [x] (aget (longs-hinted x) 0)) | |
686 | ||
687 | (deftest test-longs-hinted-proto | |
688 | (is (= 1 | |
689 | (aget-long-hinted | |
690 | (reify LongsHintedProto | |
691 | (longs-hinted [_] (long-array [1]))))))) | |
692 | ||
693 | ;; CLJ-1180 - resolve type hints in protocol methods | |
694 | ||
695 | (import 'clojure.lang.ISeq) | |
696 | (defprotocol P | |
697 | (^ISeq f [_])) | |
698 | (ns clojure.test-clojure.protocols.other | |
699 | (:use clojure.test)) | |
700 | (defn cf [val] | |
701 | (let [aseq (clojure.test-clojure.protocols/f val)] | |
702 | (count aseq))) | |
703 | (extend-protocol clojure.test-clojure.protocols/P String | |
704 | (f [s] (seq s))) | |
705 | (deftest test-resolve-type-hints-in-protocol-methods | |
706 | (is (= 4 (clojure.test-clojure.protocols/f "test")))) |
0 | ; Copyright (c) Rich Hickey. All rights reserved. | |
1 | ; The use and distribution terms for this software are covered by the | |
2 | ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | |
3 | ; which can be found in the file epl-v10.html at the root of this distribution. | |
4 | ; By using this software in any fashion, you are agreeing to be bound by | |
5 | ; the terms of this license. | |
6 | ; You must not remove this notice, or any other, from this software. | |
7 | ||
8 | (ns ^{:doc "Test proxy classes that are AOT-compiled for the tests in | |
9 | clojure.test-clojure.java-interop." | |
10 | :author "Ambrose Bonnaire-Sergeant"} | |
11 | clojure.test-clojure.proxy.examples) | |
12 | ||
13 | (definterface A | |
14 | (^int a [^String x]) | |
15 | (^boolean a [^java.io.File x]) | |
16 | (^boolean a [^Runnable x]) | |
17 | (a [^Boolean x]) | |
18 | (^int a [^Boolean x ^String y]) | |
19 | (^int a [^String x ^String y]) | |
20 | (^boolean a [^String x ^java.io.File y]) | |
21 | (^boolean a [^String x ^Runnable y]) | |
22 | (b [^String x]) | |
23 | (c [^String x]) | |
24 | (d [^String x])) | |
25 | ||
26 | (def ^String proxy1-class-name | |
27 | (-> (proxy [A] []) | |
28 | class | |
29 | .getName)) |
0 | ; Copyright (c) Rich Hickey. All rights reserved. | |
1 | ; The use and distribution terms for this software are covered by the | |
2 | ; Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) | |
3 | ; which can be found in the file epl-v10.html at the root of this distribution. | |
4 | ; By using this software in any fashion, you are agreeing to be bound by | |
5 | ; the terms of this license. | |
6 | ; You must not remove this notice, or any other, from this software. | |
7 | ||
8 | (ns clojure.test-clojure.run-single-test | |
9 | (:require [clojure.test :refer [is deftest run-test run-tests]] | |
10 | [clojure.test-helper :refer [with-err-string-writer]] | |
11 | [clojure.test-clojure.test-fixtures :as tf])) | |
12 | ||
13 | (defn not-a-test | |
14 | []) | |
15 | ||
16 | (defmacro should-print-to-err | |
17 | [re & body] | |
18 | `(is (re-find ~re (with-err-string-writer ~@body)))) | |
19 | ||
20 | (deftest reports-missing-var | |
21 | (should-print-to-err #"^Unable to resolve .*/function-missing to a test function.*" | |
22 | (let [result (eval `(run-test function-missing))] | |
23 | (is (nil? result))))) | |
24 | ||
25 | (deftest reports-non-test-var | |
26 | (should-print-to-err #"^.*/not-a-test is not a test.*" | |
27 | (let [result (eval `(run-test not-a-test))] | |
28 | (is (nil? result))))) | |
29 | ||
30 | (deftest can-run-test-with-fixtures | |
31 | (is (= {:test 1, :pass 2, :fail 0, :error 0, :type :summary} | |
32 | (run-test tf/can-use-once-fixtures)))) |
987 | 987 | {} {:a 1 :b 2} |
988 | 988 | #{} #{1 2} )) |
989 | 989 | |
990 | (defspec longrange-equals-range 100 | |
990 | (defspec longrange-equals-range 1000 | |
991 | 991 | (prop/for-all [start gen/int |
992 | 992 | end gen/int |
993 | 993 | step gen/s-pos-int] |
1383 | 1383 | (when (reversible? coll) |
1384 | 1384 | (is (= true (instance? clojure.lang.IMeta (rseq coll)))) |
1385 | 1385 | (is (= {:a true} (meta (with-meta (rseq coll) {:a true}))))))) |
1386 | ||
1387 | (deftest test-iteration-opts | |
1388 | (let [genstep (fn [steps] | |
1389 | (fn [k] (swap! steps inc) (inc k))) | |
1390 | test (fn [expect & iteropts] | |
1391 | (is (= expect | |
1392 | (let [nsteps (atom 0) | |
1393 | iter (apply iteration (genstep nsteps) iteropts) | |
1394 | ret (doall (seq iter))] | |
1395 | {:ret ret :steps @nsteps}) | |
1396 | (let [nsteps (atom 0) | |
1397 | iter (apply iteration (genstep nsteps) iteropts) | |
1398 | ret (into [] iter)] | |
1399 | {:ret ret :steps @nsteps}))))] | |
1400 | (test {:ret [1 2 3 4] | |
1401 | :steps 5} | |
1402 | :initk 0 :somef #(< % 5)) | |
1403 | (test {:ret [1 2 3 4 5] | |
1404 | :steps 5} | |
1405 | :initk 0 :kf (fn [ret] (when (< ret 5) ret))) | |
1406 | (test {:ret ["1"] | |
1407 | :steps 2} | |
1408 | :initk 0 :somef #(< % 2) :vf str)) | |
1409 | ||
1410 | ;; kf does not stop on false | |
1411 | (let [iter #(iteration (fn [k] | |
1412 | (if (boolean? k) | |
1413 | [10 :boolean] | |
1414 | [k k])) | |
1415 | :vf second | |
1416 | :kf (fn [[k v]] | |
1417 | (cond | |
1418 | (= k 3) false | |
1419 | (< k 14) (inc k))) | |
1420 | :initk 0)] | |
1421 | (is (= [0 1 2 3 :boolean 11 12 13 14] | |
1422 | (into [] (iter)) | |
1423 | (seq (iter)))))) | |
1424 | ||
1425 | (deftest test-iteration | |
1426 | ;; equivalence to line-seq | |
1427 | (let [readme #(java.nio.file.Files/newBufferedReader (.toPath (java.io.File. "readme.txt")))] | |
1428 | (is (= (with-open [r (readme)] | |
1429 | (vec (iteration (fn [_] (.readLine r))))) | |
1430 | (with-open [r (readme)] | |
1431 | (doall (line-seq r)))))) | |
1432 | ||
1433 | ;; paginated API | |
1434 | (let [items 12 pgsize 5 | |
1435 | src (vec (repeatedly items #(java.util.UUID/randomUUID))) | |
1436 | api (fn [tok] | |
1437 | (let [tok (or tok 0)] | |
1438 | (when (< tok items) | |
1439 | {:tok (+ tok pgsize) | |
1440 | :ret (subvec src tok (min (+ tok pgsize) items))})))] | |
1441 | (is (= src | |
1442 | (mapcat identity (iteration api :kf :tok :vf :ret)) | |
1443 | (into [] cat (iteration api :kf :tok :vf :ret))))) | |
1444 | ||
1445 | (let [src [:a :b :c :d :e] | |
1446 | api (fn [k] | |
1447 | (let [k (or k 0)] | |
1448 | (if (< k (count src)) | |
1449 | {:item (nth src k) | |
1450 | :k (inc k)})))] | |
1451 | (is (= [:a :b :c] | |
1452 | (vec (iteration api | |
1453 | :somef (comp #{:a :b :c} :item) | |
1454 | :kf :k | |
1455 | :vf :item)) | |
1456 | (vec (iteration api | |
1457 | :kf #(some-> % :k #{0 1 2}) | |
1458 | :vf :item)))))) | |
1459 | ||
1460 | (defspec iteration-seq-equals-reduce 1000 | |
1461 | (prop/for-all [initk gen/int | |
1462 | seed gen/int] | |
1463 | (let [src (fn [] | |
1464 | (let [rng (java.util.Random. seed)] | |
1465 | (iteration #(unchecked-add % (.nextLong rng)) | |
1466 | :somef (complement #(zero? (mod % 1000))) | |
1467 | :vf str | |
1468 | :initk initk)))] | |
1469 | (= (into [] (src)) | |
1470 | (into [] (seq (src))))))) |
397 | 397 | (sequence (map-indexed vector) []))) |
398 | 398 | (is (= [[0 1] [1 2] [2 3] [3 4]] |
399 | 399 | (sequence (map-indexed vector) (range 1 5))))) |
400 | ||
401 | (deftest test-into+halt-when | |
402 | (is (= :anomaly (into [] (comp (filter some?) (halt-when #{:anomaly})) | |
403 | [1 2 3 :anomaly 4]))) | |
404 | (is (= {:anomaly :oh-no!, | |
405 | :partial-results [1 2]} | |
406 | (into [] | |
407 | (halt-when :anomaly #(assoc %2 :partial-results %1)) | |
408 | [1 2 {:anomaly :oh-no!} 3 4])))) | |
409 |
415 | 415 | (is (= [0 1 2 3] (vec (reify clojure.lang.IReduceInit |
416 | 416 | (reduce [_ f start] |
417 | 417 | (reduce f start (range 4)))))))) |
418 | ||
419 | (deftest test-reduce-kv-vectors | |
420 | (is (= 25 (reduce-kv + 10 [2 4 6]))) | |
421 | (is (= 25 (reduce-kv + 10 (subvec [0 2 4 6] 1))))) | |
422 | ||
423 | (deftest test-vector-eqv-to-non-counted-types | |
424 | (is (not= (range) [0 1 2])) | |
425 | (is (not= [0 1 2] (range))) | |
426 | (is (= [0 1 2] (take 3 (range)))) | |
427 | (is (= [0 1 2] (new java.util.ArrayList [0 1 2]))) | |
428 | (is (not= [1 2] (take 1 (cycle [1 2])))) | |
429 | (is (= [1 2 3 nil 4 5 6 nil] (eduction cat [[1 2 3 nil] [4 5 6 nil]])))) |