Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would you structure a spreadsheet app in elm?

Tags:

elm

I've been looking at elm and I really enjoy learning the language. I've been thinking about doing a spreadsheet application, but i can't wrap my head how it would be structured.

Let's say we have three cells; A, B and C. If I enter 4 in cell A and =A in cell B how would i get cell B to always equal cell A? If i then enter =A+B in cell C, can that be evaluated to 8, and also be updated when A or B changes? Not sure how to lever Signals for such dynamic behavior.. Regards Oskar

like image 802
oskbor Avatar asked Nov 06 '15 22:11

oskbor


People also ask

What is Elm framework?

Elm is a framework and typed functional programming language aimed at front-end development. It inspires itself in a programming language called Haskell to bring more maintainability to Javascript, though keeping itself as simple and close to Javascript as possible.

What is an elm application?

Introduction. Elm is a functional programming language meant for building reliable web applications. It compiles to JavaScript and is well-known for its helpful compiler that promises no runtime errors.

What is Elm architecture?

The Elm Architecture is a pattern for architecting interactive programs, like webapps and games. This architecture seems to emerge naturally in Elm. Rather than someone inventing it, early Elm programmers kept discovering the same basic patterns in their code.

Does Elm have objects?

It would be odd to start using Elm and wonder "how do I structure my application with objects?" There are no objects in Elm! Folks in the community would recommend using custom types and functions instead.


1 Answers

First you need to decide how to represent your spreadsheet grid. If you come from a C background, you may want to use a 2D array, but I've found that a dictionary actually works better in Elm. So you can define type alias Grid a = Dict (Int, Int) a.

As for the a, what each cell holds... this is an opportunity to define a domain-specific language. So something like

type Expr = Lit Float | Ref (Int, Int) | Op2 (Float -> Float -> Float) Expr Expr

This means an expression is either a literal float, a reference to another cell location, or an operator. An operator can be any function on two floats, and two other expressions which get recursively evaluated. Depending on what you're going for, you can instead define specific tags for each operation, like Plus Expr Expr | Times Expr Expr, or you can add extra opN tags for operations of different arity (like negate).

So then you might define type alias Spreadsheet = Grid Expr, and if you want to alias (Int, Int) to something, that might help too. I'm also assuming you only want floats in your spreadsheet.

Now you need functions to convert strings to expressions and back. The traditional names for these functions are parse and eval.

parse : String -> Maybe Expr -- Result can also work
eval : Spreadsheet -> Grid Float
evalOne : Expr -> Spreadsheet -> Maybe Float

Parse will be a little tricky; the String module is your friend. Eval will involve chasing references through the spreadsheet and filling in the results, recursively. At first you'll want to ignore the possibility of catching infinite loops. Also, this is just a sketch, if you find that different type signatures work better, use them.

As for the view, I'd start with read-only, so you can verify hard-coded spreadsheets are evaluated properly. Then you can worry about editing, with the idea being that you just rerun the parser and evaluator and get a new spreadsheet to render. It should work because a spreadsheet has no state other than the contents of each cell. (Minimizing the recomputed work is one of many different ways you can extend this.) If you're using elm-html, table elements ought to be fine.

Hope this sets you off in the right direction. This is an ambitious project and I'd love to see it when you're done (post it to the mailing list). Good luck!

like image 72
mgold Avatar answered Oct 19 '22 20:10

mgold