Chrome Calculator

About a month ago I published a scientific calculator app to the Chrome Web Store (and I'm just now getting around to blogging about it).

I was thinking about Chromebooks one day, and realized there was no way I could use one without a good scientific calculator. So I checked the Web Store, and didn't like any of the existing ones. The best one I could find was the appropriately-named "Calculator" (or "C∞lculator"), but it appears to only be extendable with JavaScript, not it's own expression syntax. Most of the others were either way too basic or used Google and Wolfram|Alpha to do their calculations.

So after much a few minutes of thought, I decided to write my own. I already had a functional programming language I was working on (in JavaScript), so it didn't take long to get the basic language working.

The (unnamed) language is pretty simple, and still needs a few additions, but it works. It's a functional language where everything is an expression. It's mostly what you would expect from a calculator but has a few things that are kind of interesting.

Here's the download link again, if you want to try it. You'll need Google Chrome to run it for now, but eventually I'll probably make an online version that works in other browsers.

Definition operator (or, delayed assignment)

Like Mathematica, you can create lazily-evaluated variables with the := operator. For example:

y := x^2 (x doesn't have to be defined yet)
= true (always returns true, since we can't evaluate it yet)
x = 4
= 4
= 16
x = sqrt 2
= 1.4142135623730951
= 2. (whoa)

It basically creates a function that automatically calls itself whenever you need it. It even closes over the current scope. Here's a more complex example:

var counter (put counter in scope but don't define it yet)
= undefined
(function() { var current = 0; counter := (current += 1) })() (just like javascript, this is a way to hide "current" in a private scope)
= true
= 1
= 2
counter * 2
= 6

Operators can be used as functions

Most operators can be converted into functions by prefixing them with a "special" colon operator. For example, :+(1, 2, 3) is equivalent to 1 + 2 + 3. The : operator can also take a literal (:42, which gives you a function that always returns 42) or a variable name (:x, returns x).

There are some interesting non-obvious applications, like :() as a shortcut for the identity function. Or there's this: adder = :function(y) { x + y }. When applied to a function, the new function created by the : operator implicitly takes an argument, x. Since functions close over the current scope (including their arguments), adder takes x and returns a function that adds it's argument (y) to x. Here's an example of how it would be used:

adder = :function(y) { x + y }
= function(x) {function(y) {(x + y)}}
add1 = adder(1)
= function(y) {(x + y)}
add2 = adder(2)
= function(y) {(x + y)}
= 5
= 6

A more common application would be passing operators as arguments to functions like map or reduce:

map(:sqrt, [1, 4, 9])
= [1, 2, 3]

Note that sqrt is an operator (along with sin, cos, ln, etc. basically the standard unary functions) so it needs to be converted to a function.

The future

There's still a lot that I want to do with it, like a way to save and share libraries of functions with other users, big decimals instead of 64-bit floating point numbers (big integers and fractions are already supported), symbolic math (i.e. a CAS), lots more built-in functions and constants, units, etc. I'm open to other ideas and feedback, so let me know if there's anything you want to see added or improved.

Tagged In: Math, Calculator