Platform-independent math functions in Clojure(script)
Asked Answered
L

3

9

How to access things like sin, cos or PI in a pure Clojure way?

For example, if I want to write a pure library, I mustn’t use anything like (.PI Math) (Java) or (.‑PI js/Math) (JS).

Littlejohn answered 16/1, 2014 at 11:23 Comment(1)
The "pure Clojure way" is to use interop with the host language when appropriate, as in this case. Are you asking (a) whether there is a host-language-neutral math library or (b) how to write code for both Clojure and ClojureScript? If the latter, have a look at github.com/lynaghk/cljx.Boyne
P
6

The easiest way is to use Cljx: https://github.com/lynaghk/cljx

With it you can write something like:

(* 5 #+clj (.PI Math) #+cljs (.‑PI js/Math))

and have this code compiled properly to Clojure and ClojureScript.

As far as I know there’s no better way to write one code to be runned as Clojure/ClojureScript.

There are some plans to include platform detection in Clojure itself but I think it’s not ready yet.

Pinkiepinkish answered 16/1, 2014 at 16:52 Comment(1)
I got some weird characters copying and pasting the js interop for Math/PI here, might be worth typing it yourself. Good answer though, thanks.Interfile
S
1

Official wrapper APIs: clojure.math & cljs.math

For simple constants or common mathematical functions, the first thing I'd reach for (other than interop) would be the clojure.math and cljs.math libs, which provide cljs.math/PI, clojure.math/sin, and so on.

Cljx

Another answer suggests Cljx, which has been deprecated for a few years. See the transition guide, which is also a good overview of the new solution:

.cljc

Code targeting multiple Clojure platforms is written in .cljc files using reader conditionals (introduced in Clojure 1.7).

The excellent kixi.stats implements platform-independent Clojure math using cljc, providing us not only a useful library but also a nice example of the approach. An excerpt:

(def PI
  #?(:clj Math/PI
     :cljs js/Math.PI))

(defn sin [x]
  #?(:clj  (Math/sin x)
     :cljs (js/Math.sin x)))

(def infinity
  #?(:clj Double/POSITIVE_INFINITY
     :cljs js/Infinity))

This code is from kixi.stats.math.

Scarborough answered 18/4, 2020 at 18:45 Comment(0)
H
-3

Sin example:

(.sin js/Math 3) 

PI example:

(aget js/Math "PI")

Displaying in console:

(.log js/console (aget js/Math "PI"))

Hope that helps.

Headboard answered 16/1, 2014 at 14:21 Comment(6)
How is that platform independent ?Kellda
Hi,Please read the title (I.E. it states "Clojurescript" :) The term "platform independent" is not definitive. Generally speaking, javascript is considered "platform independent" (as in, most modern OS's support standard jsvascript). The javascript Math library is standard. Thus, I would need to ask what platforms are you concerned about that don't support javascript? More importantly, why are you using Clojurescript on a platform that doesn't include standard javascript?Headboard
Did you even read the question? Platform in this case is the implementation of Clojure of course. You just showed how to do it on the Javascript platform (which I did in the question already, btw.).Littlejohn
Hi, Please edit the question so that includes your definition of "platform". Please edit the title :) Folks can only answer the question you ask:) The more specific your question, the less ambiguities, the better the answers :) Good Luck :)Headboard
IMHO it’s pretty clear from the question. yonki seems to think that, too, because his answer relates to the right thing.Littlejohn
Thanks for leaving the answer in here, it helped me.Ancestor

© 2022 - 2024 — McMap. All rights reserved.