Liking cljdoc? Tell your friends :D

Axel-f codecov CircleCI

Expressions language for Clojure(Script) and JavaScript inspired by Microsoft Excel ™

Rationale

In some applications, the lion's share of business logic is concentrated in dynamic expressions. Often they are not even part of the code base and are stored in a database, files, or somewhere in the cloud. And sometimes these expressions need to be accessed non-technical personnel, like managers or call centers operators. Making them learn clojure or python is not fair. This library is designed to combine the best of two completely different worlds: the most understandable syntax from Excel and the speed of Clojure.

Installation

Clojure(Script)

  • Leiningen : [io.xapix/axel-f "0.2.5"]
  • Boot: (set-env! :dependencies #(conj % [io.xapix/axel-f "0.2.5"]))
  • deps.edn: {:deps {io.xapix/axel-f {:mvn/version "0.2.5"}}}

JavaScript

Please checkout the documentation for JavaScript package

TL;DR

(require '[axel-f.core :as axel-f])

;; Execute Excel formulas as a string
(axel-f/run "CONCATENATE(\"foo\", \"bar\")")
;; => "foobar"

(axel-f/run "=SUM(1, 2, AVERAGE({4,5,6}), foo.bar, foo.baz[*].x)"
            {:foo {:bar 1
                   :baz [{:x 5}
                         {:x 7}
                         {:x 8}]}})
;; => 29

;; Execute Excel formulas as a data
(axel-f/run [:FNCALL "SUM" [1 2 3]])
;; => 6

;; Transform Excel formulas from string to data representation
(axel-f/compile "=SUM(1, 2, AVERAGE({4,5,6}), foo.bar, foo.baz[*].x)")
;; =>
;; [:FNCALL
;;  "SUM"
;;  [1
;;   2
;;   [:FNCALL "AVERAGE" [[:VECTOR 4 5 6]]]
;;   [:OBJREF "foo" "bar"]
;;   [:OBJREF "foo" "baz" "*" "x"]]]

Difference from Excel

  • No cell-references or reference operations.

Object references

In addition to a formula, the run function can accept execution context as a second argument. Context can be any valid Clojure(Script) object. In the formula you can select the data from context by using object reference operators:

  • Dot reference operator for access nested data: foo.bar.baz
  • Array reference operator for access data in vector: foo[*].bar
    • foo[*][*] we support nested vectors (vector of vectors of vectors ...)
    • and objects in vectors foo[*].bar[*].baz
    • it is possible to use indexes to get the data inside of arrays: foo[1].bar

Data types

  • [x] Booleans as in Excel (TRUE/FALSE). In addition axel-f understands True/False/true/false
  • [x] Numbers (Integers, Floats, Exponential form)
  • [x] Strings in double or single quotes. ('Some String', "Some String")
  • [x] Arrays. Any data in curly brackets ({1, 2 TRUE})
  • [ ] Date
  • [x] Excel Error types

Operators

Any expression can be used as an operand for any operator. axel-f has the same operator precedence as in Excel. To change a precendence of operators you can use round brackets ((2+2)*2 => 8)

Unary

  • [x] Sign operator (-/+, eg. "-1") Can be used for coercing boolean into number (--TRUE => 1)
  • [x] Percent operator (2.4%) axel-f uses float as replacement (2.4% => 0.024).

Binary

  • [x] Additive operators (+/-)
  • [x] Multiplicative operators (* and /)
  • [x] Comparison operators
    • more (>)
    • more or equal (>=)
    • less (<)
    • less or equal (<=)
    • equal (=)
    • not equal (<>)
  • [x] Exponential operator (^)
  • [x] Concatenate operator (&)

Implemented excel functions

In addition we have special functions for accessing the data in context: OBJREF(arg1, [arg2...]) And a special map function for applying partially defined function for each element in collection: MAP(10 ^ _, {1, 2, 3})

Copyright and License

Copyright © 2018 Xapix GmbH, and contributors

Distributed under the Eclipse Public License, the same as Clojure.

Can you improve this documentation?Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close