How to extend numerical protocols in Clojure - clojure

I'm trying to use protocols to create an engineering number type (a "knumber"), so I can say (+ "1k" "2Meg") and get something like "2.001Meg". I should be able to get the floating point value from the knumber like so (:val my-knumber), but normally the printer should display the string, which is also accessible like so (:string my-knumber). This number will support all the usual p, n, u, m, k, Meg, G suffixes, and convert as required among them, such as (/ "1Meg" "1G") -> "1m"). I want to be able to pass this to any function which expects a number.
Anyway, Can someone suggest a strategy for this? I think I need to use protocols. I currently have a (defrecord knumber [val string]) but I'm not sure what's next.
What protocols do clojure numbers satsify? I'm thinking I need to extend some existing protocols/interfaces for this.
Thanks

I think your strategy should probably be as follows:
Define the record KNumber as something like (defrecord knumber [value unit-map])
Make unit-map a map of units to integer exponents (you are going to want units like m/s^2 if these are engineering numbers, right?). It might look something like {"m" 1 "s" -2},
Have KNumber implement java.lang.Number so that you can use it with other mathematical functions that already exist in Clojure. You'll need to implement doubleValue, longValue etc.
Define a protocol NumberWithUnits that you can extend to both KNumbers and normal clojure numbers. At a minimum it should have methods (numeric-value [number]) and (get-units [number])
Then define your mathematical functions +, *, - etc. in your own namespace that operate on anything that implements the NumberWithUnits protocol and return a KNumber.
Regarding different unit scales (e.g. "m" vs. "km") I would suggest standardising on a single scale for internal representation for each unit type (e.g. "m" for distances) but providing options for conversion to other unit scales for input/output purposes.

The frinj library is a Clojure library for calculations with units. Looking into the source will probably give you some nice ideas.

Related

use-cases for BigInt versus BigInteger in Clojure

I'm looking for guidance on when to use Clojure BigInt versus Java BigInteger in Clojure. Both work just fine, and I am assuming that the main reason to use BigInt is to take advantage of operators like + and =, which have to be accessed via the Java instance methods .add and .equals, for instance. But there are few operators, such as isProbablePrime, that I can only access from BigInteger.
It seems pretty easy to shift from BigInt to BigInteger or vice versa, but the presence of both makes the use-cases unclear for me. My knee-jerk reaction is just to stick with BigInteger in the absence of clear criteria since some of the suggested usages seem not to work. From clojuredocs here:
user=> (def x (bigint 97))
user=> (.isProbablePrime x 1)
IllegalArgumentException No matching method found: isProbablePrime for class
clojure.lang.BigInt clojure.lang.Reflector.invokeMatchingMethod (Reflector.java:53)
In "Clojure Programming" by C. Emerick et. al., p.428, there is a sidebar topic, "Why Does Clojure Have Its Own BigInt Class When Java Already Provides One in BigInteger?"
They note two reasons to prefer BigInt to Java's BigInteger. First, the latter's .hashCode implementation is inconsistent with that of Long (the same number expressed in each type gives a different hash value). This is generally not what you want when comparing equivalent values in e.g. hash maps.
The other reason is that BigInts are optimized to use primitive types when possible, so performance should be better for many cases.
I would use Clojure's numeric types unless you have a good reason not to (your use of .isProbablePrime suggests you might have a good enough reason).

How would you idiomatically extend arithmetric functions for other datatypes in Clojure?

So I want to use java.awt.Color for something, and I'd like to be able to write code like this:
(use 'java.awt.Color)
(= Color/BLUE (- Color/WHITE Color/RED Color/GREEN))
Looking at the core implementation of -, it talks specifically about clojure.lang.Numbers, which to me implies that there is nothing I do to 'hook' into the core implementation and extend it.
Looking around on the Internet, there seems to be two different things people do:
Write their own defn - function, which only knows about the data type they're interested in. To use you'd probably end up prefixing a namespace, so something like:
(= Color/BLUE (scdf.color/- Color/WHITE Color/RED Color/GREEN))
Or alternatively useing the namespace and use clojure.core/- when you want number math.
Code a special case into your - implementation that passes through to clojure.core/- when your implementation is passed a Number.
Unfortunately, I don't like either of these. The first is probably the cleanest, as the second makes the presumption that the only things you care about doing maths on is their new datatype and numbers.
I'm new to Clojure, but shouldn't we be able to use Protocols or Multimethods here, so that when people create / use custom types they can 'extend' these functions so they work seemlessly? Is there a reason that +,- etc doesn't support this? (or do they? They don't seem to from my reading of the code, but maybe I'm reading it wrong).
If I want to write my own extensions to common existing functions such as + for other datatypes, how should I do it so it plays nicely with existing functions and potentially other datatypes?
It wasn't exactly designed for this, but core.matrix might be of interest to you here, for a few reasons:
The source code provides examples of how to use protocols to define operations that work with with various different types. For example, (+ [1 2] [3 4]) => [4 6]). It's worth studying how this is done: basically the operators are regular functions that call a protocol, and each data type provides an implementation of the protocol via extend-protocol
You might be interested in making java.awt.Color work as a core.matrix implementation (i.e. as a 4D RGBA vector). I did something simiilar with BufferedImage here: https://github.com/clojure-numerics/image-matrix. If you implement the basic core.matrix protocols, then you will get the whole core.matrix API to work with Color objects. Which will save you a lot of work implementing different operations.
The probable reason for not making arithmetic operation in core based on protocols (and making them only work of numbers) is performance. A protocol implementation require an additional lookup for choosing the correct implementation of the desired function. Although from design point of view it may feel nice to have protocol based implementations and extend them whenever required, but when you have a tight loop that does these operations many times (and this is very common use case with arithmetic operations) you will start feeling the performance issues because of the additional lookup on each operation that happen at runtime.
If you have separate implementation for your own data types (ex: color/-) in their own namespace then it will be more performant due to a direct call to that function and it also make things more explicit and customizable for specific cases.
Another issue with these functions will be their variadic nature (i.e they can take any number of arguments). This is a serious issue in providing a protocol implementation as protocol extended type check only works on first parameter.
You can have a look at algo.generic.arithmetic in algo.generic. It uses multimethods.

Avoid name clashes in a Clojure DSL

As a side project I'm creating a Clojure DSL for image synthesis (clisk).
I'm a little unsure on the best approach to function naming where I have functions in the DSL that are analogous to functions in Clojure core, for example the + function or something similar is needed in my DSL to additively compose images / perform vector maths operations.
As far as I can see it there are a few options:
Use the same name (+) in my own namespace. Looks nice in DSL code but will override the clojure.core version, which may cause issues. People could get confused.
Use the same name but require it to be qualified (my-ns/+). Avoids conflicts, but prevents people from useing the namespace for convenience and looks a bit ugly.
Use a different short name e.g. (v+). Can be used easily and avoid clashes, but the name is a bit ugly and might prove hard to remember.
Use a different long name e.g. (vector-add). Verbose but descriptive, no clashes.
Exclude clojure.core/+ and redefine with a multimethod + (as georgek suggests).
Example code might look something like:
(show (v+ [0.9 0.6 0.3]
(dot [0.2 0.2 0]
(vgradient (vseamless 1.0 plasma) ))))
What is the best/most idiomatic approach?
first, the repeated appearance of operators in an infix expression requires a nice syntax, but for a lisp, with prefix syntax, i don't think this is as important. so it's not such a crime to have the user type a few more characters for an explicit namespace. and clojure has very good support for namespaces and aliasing. so it's very easy for a user to select their own short prefix: (x/+ ...) for example.
second, looking at the reader docs there are not many non-alphanumeric symbols to play with, so something like :+ is out. so there's no "cute" solution - if you choose a prefix it's going to have to be a letter. that means something like x+ - better to let the user choose an alias, at the price of one more character, and have x/+.
so i would say: ignore core, but expect the user to (:require .... :as ...). if they love your package so much they want it to be default then they can (:use ...) and handle core explicitly. but you choosing a prefix to operators seems like a poor compromise.
(and i don't think i have seen any library that does use single letter prefixes).
one other possibility is to provide the above and also a separate package with long names instead of operators (which are simply def'ed to match the values in the original package). then if people do want to (:use ...) but want to avoid clashes, they can use that (but really what's the advantage of (vector-add ...) over (vector/+ ...)?)
and finally i would check how + is implemented, since if it already involves some kind of dispatch on types then georgek's comment makes a lot of sense.
(by "operator" above i just mean single-character, non-alphanumeric symbol)

Data format safety in clojure

Coming from a Java background, I'm quite fond of static type safety and wonder how clojure programmers deal with the problem of data format definitions (perhaps not just types but general invariants, because types are just a special case of that.)
This is similar to an existing question "Type Safety in Clojure", but that one focuses more on the aspect of how to check types at compile time, while I'm more interested in how the problem is pragmatically addressed.
As a practical example I'm considering an editor application which handles a particular document format. Each document consists of elements that come in several different varieties (graphics elements, font elements etc.) There would be editors for the different element types, and also of course functions to transform a document from/to a byte stream in its native on-disk format.
The basic problem I am interested in is that the editors and the read/write functions have to agree on a common data format. In Java, I would model the document's data as an object graph, e.g. with one class representing a document and one class for each element variety. This way, I get a compile-time guarantee about what the structure of my data looks like, and that the field "width" of a graphics element is an integer and not a float. It does not guarantee that width is positive - but using a getter/setter interface would allow the corresponding class to add invariant guarantees like that.
Being able to rely on this makes the code dealing with this data simpler, and format violations can be caught at compile-time or early at runtime (where some code attempts to modify data that would violate invariants).
How can you achieve a similar "data format reliability" in Clojure? As far as I know, there is no way to perform compile-time checking and hiding domain data behind a function interface seems to be discouraged as non-idiomatic (or maybe I misunderstand?), so what do Clojure developers do to feel safe about the format of data handed into their functions? How do you get your code to error out as quickly as possible, and not after the user edited for 20 more minutes and tries to save to disk, when the save function notices that there is a graphics element in the list of fonts due to an editor bug?
Please note that I'm interested in Clojure and learning, but didn't write any actual software with it yet, so it's possible that I'm just confused and the answer is very simple - if so, sorry for wasting your time :).
I don't see anything wrong or unidiomatic about using a validating API to construct and manipulate your data as in the following.
(defn text-box [text height width]
{:pre [(string? text) (integer? height) (integer? width)]}
{:type 'text-box :text text :height height :width width})
(defn colorize [thing color]
{:pre [(valid-color? color)]}
(assoc thing :color color))
... (colorize (text-box "Hi!" 20 30) :green) ...
In addition, references (vars, refs, atoms, agents) can have an associated validator function that can be used to ensure a valid state at all times.
Good question - I also find that moving from a statically typed language to a dynamic one requires a bit more care about type safety. Fortunately TDD techniques help a huge amount here.
I typically write a "validate" function which checks all your assumptions about the data structure. I often do this in Java too for invariant assumptions, but in Clojure it's more important because you need to check thinks like types as well.
You can then use the validate function in several ways:
As a quick check at the REPL: (validate foo)
In unit tests: (is (validate (new-foo-from-template a b c)))
As a run-time check for key functions, e.g. checking that (read-foo some-foo-input-stream) is valid
If you have a complex data structure which is a tree of multiple different component types, you can write a validate function for each component type and have the validate function for the whole document call validate for each sub-component recursively. A nice trick is to use either protocols or multimethods to make the validate function polymorphic for each component type.

calculating user defined formulas (with c++)

We would like to have user defined formulas in our c++ program.
e.g. The value v = x + ( y - (z - 2)) / 2. Later in the program the user would define x,y and z -> the program should return the result of the calculation. Somewhen later the formula may get changed, so the next time the program should parse the formula and add the new values. Any ideas / hints how to do something like this ? So far I just came to the solution to write a parser to calculate these formulas - maybe any ideas about that ?
If it will be used frequently and if it will be extended in the future, I would almost recommend adding either Python or Lua into your code. Lua is a very lightweight scripting language which you can hook into and provide new functions, operators etc. If you want to do more robust and complicated things, use Python instead.
You can represent your formula as a tree of operations and sub-expressions. You may want to define types or constants for Operation types and Variables.
You can then easily enough write a method that recurses through the tree, applying the appropriate operations to whatever values you pass in.
Building your own parser for this should be a straight-forward operation:
) convert the equation from infix to postfix notation (a typical compsci assignment) (I'd use a stack)
) wait to get the values you want
) pop the stack of infix items, dropping the value for the variable in where needed
) display results
Using Spirit (for example) to parse (and the 'semantic actions' it provides to construct an expression tree that you can then manipulate, e.g., evaluate) seems like quite a simple solution. You can find a grammar for arithmetic expressions there for example, if needed... (it's quite simple to come up with your own).
Note: Spirit is very simple to learn, and quite adapted for such tasks.
There's generally two ways of doing it, with three possible implementations:
as you've touched on yourself, a library to evaluate formulas
compiling the formula into code
The second option here is usually done either by compiling something that can be loaded in as a kind of plugin, or it can be compiled into a separate program that is then invoked and produces the necessary output.
For C++ I would guess that a library for evaluation would probably exist somewhere so that's where I would start.
If you want to write your own, search for "formal automata" and/or "finite state machine grammar"
In general what you will do is parse the string, pushing characters on a stack as you go. Then start popping the characters off and perform tasks based on what is popped. It's easier to code if you force equations to reverse-polish notation.
To make your life easier, I think getting this kind of input is best done through a GUI where users are restricted in what they can type in.
If you plan on doing it from the command line (that is the impression I get from your post), then you should probably define a strict set of allowable inputs (e.g. only single letter variables, no whitespace, and only certain mathematical symbols: ()+-*/ etc.).
Then, you will need to:
Read in the input char array
Parse it in order to build up a list of variables and actions
Carry out those actions - in BOMDAS order
With ANTLR you can create a parser/compiler that will interpret the user input, then execute the calculations using the Visitor pattern. A good example is here, but it is in C#. You should be able to adapt it quickly to your needs and remain using C++ as your development platform.