The StackOverflow 2021 survey is open and they have re-included Clojure this year! A great opportunity to make our representation known... https://stackoverflow.com/dev-survey/start
I filled it out 👍
Calva version 2.0.199 is out with an improvement to the debugger call stack. Additional stack frames are now shown in VS Code's call stack view during a debug session and some can be clicked to navigate to the relevant line of code. See a https://calva.io/debugger/#viewing-the-call-stack.
I’ve just released v0.19.0 of the #sicmutils computer algebra system! This release adds a bunch of performance improvements, speeding up simplification by up to 60x for more complicated problems. The whole library is much zippier. Specific additions: • a powerful, extensible https://github.com/sicmutils/sicmutils/blob/master/src/pattern/rule.cljc with a huge number of simplifier rules built-in. The design is based on the pattern matcher in Gerald Sussman’“s https://amzn.to/34PU3h6”, but designed for Clojure vs MIT Scheme. • high-performance multivariate https://github.com/sicmutils/sicmutils/blob/master/src/sicmutils/polynomial.cljc and https://github.com/sicmutils/sicmutils/blob/master/src/sicmutils/rational_function.cljc implementations • slimmer build, and features like a-la-carte simplification and expression factoring Clojars: https://clojars.org/sicmutils/sicmutils detailed release notes: https://github.com/sicmutils/sicmutils/releases/tag/v0.19.0 cljdoc: https://cljdoc.org/d/sicmutils/sicmutils/0.19.0 Cheers!
It would be nice to have a textual explanation and few examples for the patter matching. Reading the multiple ns isn't so simple 🙏
@holyjak yup, lots to do! the pattern matcher is in service of symbolic expression simplification, so even though it’s a pretty big project on its own I’m having to prioritize how deep I can go on this first pass
@holyjak but I am happy to point at lots of examples from the namespaces and tests!
(let [r (rule (+ ?x ?x) => (* 2 ?x))]
(r '(+ z z)))
a short tour:
• the “rule” macro is the main thing: https://cljdoc.org/d/sicmutils/sicmutils/0.19.0/api/pattern.rule#rule
• the “syntax” namespace defines most what you can include in the matching part, ie, the first form you pass to rule
: https://github.com/sicmutils/sicmutils/blob/master/src/pattern/syntax.cljc#L25
• the form is “(rule <pattern> <predicate> <template>)“, all explained in the rule
docs. =>
is a function that just always returns true.
• the rule
has a bunch of “combinators” that let you do things like, take a rule, and return a NEW rule that tries to apply its rule to every nested form, bottom up, in a nested data structure… and lots more stuff.
Here’s an example of a macro called ruleset
that takes LOTS of rule forms, and tries each one down the list; the whole rule returns on the first match, and if none match, it returns its input.
(ruleset
(sin (asin ?x)) => ?x
(cos (acos ?x)) => ?x
(tan (atan ?x)) => ?x
(sin (acos ?x)) => (sqrt (- 1 (expt ?x 2)))
(cos (asin ?y)) => (sqrt (- 1 (expt ?y 2)))
(tan (asin ?y)) => (/ ?y (sqrt (- 1 (expt ?y 2))))
(tan (acos ?x)) => (/ (sqrt (- 1 (expt ?x 2))) ?x))
maybe a more fun example, these two are equivalent, and I WOULD ARGUE that the second is clearer:
(defn- mul [a b]
(cond (and (v/number? a) (v/number? b)) (g/mul a b)
(v/number? a) (cond (v/zero? a) a
(v/one? a) b
(product? b) `(~'* ~a ~@(operands b))
:else `(~'* ~a ~b))
(v/number? b) (cond (v/zero? b) b
(v/one? b) a
(product? a) `(~'* ~@(operands a) ~b)
:else `(~'* ~a ~b))
(product? a) (cond (product? b) `(~'* ~@(operands a) ~@(operands b))
:else `(~'* ~@(operands a) ~b))
(product? b) `(~'* ~a ~@(operands b))
:else `(~'* ~a ~b)))
(def mul
(ruleset
(* (? a v/number?) (? b v/number?)) => (fn [{a 'a b 'b}] (g/mul a b))
(* (? ?a v/zero?) _ ) => ?a
(* _ (? ?b v/zero?) ) => ?b
(* (? _ v/one?) ?b ) => ?b
(* ?a (? _ v/one?) ) => ?a
(* (* ??xs) (* ??ys) ) => (* ?xs ??ys)
(* ?x (* ??xs) ) => (* ?x ??xs)
(* (* ?xs) ??x ) => (* ??xs ?x)))
thanks a lot! it is much clearer already! 🙂 Examples help a lot.
totally! there are a ton more in the tests: https://github.com/sicmutils/sicmutils/blob/master/test/pattern/rule_test.cljc
and then a huge number of rules, organized not-terribly-well, in https://github.com/sicmutils/sicmutils/blob/master/src/sicmutils/simplify/rules.cljc#L275. These are all from the original scmutils library; a goal of mine is to organize these into clear buckets, then publish them separate from this library so anyone wanting to deal with mathematical expressions can have a huge set to choose from