LastCalc: A web-based REPL for a pure functional programming language with a flexible syntax and parser

LastCalc is a very experimental web-based tool that started out as a kind of Google Calculator but with a "REPL"-style user interface that permits variable assignment.

Like Google Calculator it supports basic math, and conversions between different measurement types like miles or kilograms (relying on the Java JScience library for this functionality), all with a relatively natural language syntax.

Along the way we added the ability to define parameterized functions, and then pattern matching on datastructures like lists and maps (inspired by ML), including recursively defined functions, all in a friendly AJAX-based web user interface.

LastCalc's parser is extremely robust, doing a reasonably efficient best-first search with backtracking to interpret its input. Anything it can't interpret is ignored.

Soon people will be able to share the parameterized functions they've designed, ultimately allowing people to collaboratively "teach" LastCalc how to interpret things that it currently cannot.

The link above provides a quick walk through of the system along with a link to it so that you can try it for yourself.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Here's my playing with it,

Here's my playing with it, along with my though process.

I like the idea a lot, but you need to knead it a bit further. Your parser may be extremely robust in the sense that it doesn't produce parse errors, but that just makes it so that it becomes virtually impossible to learn by trial and error. The "produce some result at all cost"-approach seems nice at first, but the result is probably wrong if your tool didn't completely understand the input. This causes users to learn not to trust results. An error message or indication is more helpful than a wrong result. The semantics of the language seem very inconsistent, at least in regard to the behavior of units (I didn't try much else). Editing previously entered commands triggered a bug. I think the bug stopped occurring once I edited again: "speed of light in meter/second" to "speed of light in meter".

If you use a more strict parser and better indication of error in addition to more consistent semantics this could be a very useful tool.

Jules, thanks for your

Jules, thanks for your feedback.

I definitely realize that I've got quite a bit of progress to make.

To your point, right now the response to an error is simply to fail to parse it, which obviously provides inadequate feedback to the user.

Editing previously entered commands triggered a bug. I think the bug stopped occurring once I edited again: "speed of light in meter/second" to "speed of light in meter".

What was the bug exactly? By which I mean, what happened versus what did you expect to happen?

If you use a more strict parser and better indication of error in addition to more consistent semantics this could be a very useful tool.

Well, I think it's important to use a heuristic parser to capture the "Google Calculator", "Wolfram Alpha" or "Siri" user bases, but I agree that it needs decent error reporting.

I'm not entirely sure what

I'm not entirely sure what the bug is, but if you look at the screenshot you can see that something went wrong from the line starting with "4 electronvolt ..." up to "c = 3". Or perhaps this is the intended behavior?

Well, I think it's important to use a heuristic parser to capture the "Google Calculator", "Wolfram Alpha" or "Siri" user bases, but I agree that it needs decent error reporting.

Perhaps. Personally I've found those parsers annoying as well. Google Calculator often interprets precedence counter intuitively. Wolfram Alpha's natural language input works okay for simple things, but when I try something slightly less basic I find myself fighting with the parser. IMO a simple, consistent language + good documentation and feedback beats a parser that guesses. Wolfram Alpha also has such a syntax, and I love it. Perhaps you could do a compromise where you have a simple and strict core, and a heuristic parser on top that tries to interpret the input and displays "did you mean X?" (Wolfram Alpha does this with its "input interpretation" feature).

As for the units, how about the following. Represent a value as (number,unit). Define constants like "meter" as (1,Meter). Let "per" do the same as division. This would let you interpret "1 meter per second" and "1 meter/second" correctly, instead of having to type "1 meter / 1 second".

Something else I've always wanted is whitespace for precedence.

a/b * c = (a/b)*c
a / b*c = a/(b*c)

Space sensitive syntax

I've seen that go either way, really. It can get a bit confusing or behave unpredictably if you start adding units or other data:

a meters / b seconds * c kilograms

In general, I can't recommend it after having used in a few toy languages.

Perhaps you could do a

Perhaps you could do a compromise where you have a simple and strict core, and a heuristic parser on top that tries to interpret the input and displays "did you mean X?" (Wolfram Alpha does this with its "input interpretation" feature).

That is exactly what I have in mind, actually. It will come up with a best-guess interpretation, but rather than just using that it will ask the user to confirm that it's what they meant.

This has the dual advantage of teaching the user the canonical syntax, while also providing useful data that can be used to train a machine learning algorithm to make better guesses in future.

Wolfram alpha's parser is

Wolfram alpha's parser is incredibly error tolerant, where this spills over in semantic processing (name/intent resolution). The make up for it by displaying a canonical understanding after each parse. Something like that could work for a robust REPL.