Fork me on GitHub
#announcements
<
2021-06-04
>
Alex Miller (Clojure team)03:06:21

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

👍 101
✔️ 47
12
clojure-spin 56
3
raspasov07:06:24

I filled it out 👍

bringe17:06:06

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.

calva 44
metal 15
Sam Ritchie21:06:39

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!

🎉 52
🆒 5
🚀 6
Jakub Holý (HolyJak)12:06:26

It would be nice to have a textual explanation and few examples for the patter matching. Reading the multiple ns isn't so simple 🙏

Sam Ritchie14:06:05

@U0522TWDA 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

👍 2
Sam Ritchie14:06:36

@U0522TWDA 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)))

Sam Ritchie14:06:33

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))

Sam Ritchie14:06:13

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)))

Jakub Holý (HolyJak)15:06:09

thanks a lot! it is much clearer already! 🙂 Examples help a lot.

Sam Ritchie17:06:31

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