-
-
Notifications
You must be signed in to change notification settings - Fork 68
/
util.cljc
135 lines (114 loc) · 3.77 KB
/
util.cljc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
;;
;; Copyright © 2020 Sam Ritchie.
;; This work is based on the Scmutils system of MIT/GNU Scheme:
;; Copyright © 2002 Massachusetts Institute of Technology
;;
;; This is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3 of the License, or (at
;; your option) any later version.
;;
;; This software is distributed in the hope that it will be useful, but
;; WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
;; General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with this code; if not, see <http://www.gnu.org/licenses/>.
;;
(ns sicmutils.util
"Shared utilities between clojure and clojurescript."
(:refer-clojure :rename {bigint core-bigint
biginteger core-biginteger
int core-int
long core-long
double core-double}
#?@(:cljs [:exclude [bigint double long int]]))
(:require #?(:clj [clojure.math.numeric-tower :as nt])
#?(:cljs goog.math.Integer)
#?(:cljs goog.math.Long)
[taoensso.timbre :as log])
#?(:clj
(:import (clojure.lang BigInt)
(java.util.concurrent TimeUnit TimeoutException))))
(defn counted
"Takes a function and returns a pair of:
- an atom that keeps track of fn invocation counts,
- the instrumented fn"
([f] (counted f 0))
([f initial-count]
(let [count (atom initial-count)]
[count (fn [x]
(swap! count inc)
(f x))])))
(def compute-sqrt #?(:clj nt/sqrt :cljs Math/sqrt))
(def compute-expt #?(:clj nt/expt :cljs Math/pow))
(def compute-abs #?(:clj nt/abs :cljs Math/abs))
(def biginttype #?(:clj BigInt :cljs js/BigInt))
(def inttype #?(:clj Integer :cljs goog.math.Integer))
(def longtype #?(:clj Long :cljs goog.math.Long))
(defn keyset [m]
(into #{} (keys m)))
(defn map-vals
"Returns a map of identical type and key set to `m`, with each value `v`
transformed by the supplied function`f` into `(f v)`."
[f m]
(reduce-kv (fn [acc k v]
(assoc acc k (f v)))
(empty m)
m))
(defn re-matches?
"Returns true if s matches the regex pattern re, false otherwise."
[re s]
#?(:clj (.matches (re-matcher re s))
:cljs (.test re s)))
(defn bigint [x]
#?(:clj (core-bigint x)
:cljs (js/BigInt x)))
(defn ^boolean bigint?
"Returns true if the supplied `x` is a `BigInt`, false otherwise."
[x]
#?(:clj (instance? BigInt x)
:cljs (= "bigint" (goog/typeOf x))))
(defn parse-bigint [x]
`(bigint ~x))
(defn biginteger [x]
#?(:clj (core-biginteger x)
:cljs (js/BigInt x)))
(defn int [x]
#?(:clj (core-int x)
:cljs (.fromNumber goog.math.Integer x)))
(defn long [x]
#?(:clj (core-long x)
:cljs (.fromNumber goog.math.Long x)))
(defn double [x]
#?(:clj (core-double x)
:cljs (if (number? x) x (js/Number x))))
(defn unsupported [s]
(throw
#?(:clj (UnsupportedOperationException. ^String s)
:cljs (js/Error s))))
(defn exception [s]
(throw
#?(:clj (Exception. ^String s)
:cljs (js/Error s))))
(defn illegal [s]
(throw
#?(:clj (IllegalArgumentException. ^String s)
:cljs (js/Error s))))
(defn illegal-state [s]
(throw
#?(:clj (IllegalStateException. ^String s)
:cljs (js/Error s))))
(defn arithmetic-ex [s]
(throw
#?(:clj (ArithmeticException. s)
:cljs (js/Error s))))
(defn timeout-ex [s]
(throw
#?(:clj (TimeoutException. s)
:cljs (js/Error s))))
(defn failure-to-converge [s]
(throw
#?(:clj (Exception. ^String s)
:cljs (js/Error s))))