diff --git a/LOG.md b/LOG.md new file mode 100644 index 0000000..7a482ea --- /dev/null +++ b/LOG.md @@ -0,0 +1,75 @@ +# Development Log + +## Initial Project Idea and Planning + +I decided to make a basic symbolic differentiation engine. The +essence of this is that you can provide mathematical expressions as +input, and the program can compute the derivative of them. For the +sake of simplicity, it will be command-line based, so its input and +output will both be text. An example interation might look something +like: + +``` +> 2x^2 + 3x +4x + 3 +> x^3 - x^2 +3x^2 - 2x +``` + +### Architecture + +The program will have three major components: the reader, which will +take user input and parse it into a convenient internal representation +(generally an AST of some kind); the solver, which will transform the +input expression into an output expression; and the printer which will +format output expressions back to human-readable text. This is +essentially a standard architecture for a simple interpreter. + +![Top-level architecture diagram](./top-level-architecture.png) + +The reader will be composed of two passes: a simple state machine +lexer to tokenise user input and a parser to build an AST from the +tokens. For simplicity here, I will only be supporting basic latin +characters in UTF-8 (i.e. ASCII-compatible text). + +Since I am only implementing differentiation, the solver can be +relatively simple, consisting of a pattern-matching loop with an +accompanying ruleset. + +The printer is the simplest of the three components and will consist +only of a procedure to walk an AST and emit a serialisation of it +equivalent to the input language. + +In addition to the major components, a harness will be needed to tie +them together and handle errors. This will be in the form of a simple +REPL (Read Eval Print Loop). + +### Implementation and Testing Strategy + +I'll begin by implementing the reader and printer, as this will allow +me to get to a working end-to-end demo as quickly as possible by +initially skipping the solver and simply printing the input +expressions unmodified. This will then enable easy and fast iteration +when implementing the solver logic. + +I will be writing a suite of unit tests to accompany every module of +the system, following a TDD (Test-Driven Development) methodology. +This system is quite simple and well-defined, so the advantage of TDD +(as opposed to writing tests after-the-fact) is probably relatively +minimal here, especially since it will not be being modified or +maintained after its initial development and will not be being worked +on by multiple people, but the practise will be beneficial regardless +in tightening the feedback loop of the development process and +ensuring that the code is structured to be amenable to testing. If I +have time I'll also implement some automated integration tests to +verify end-to-end functionality. + +I'll be using Rust as the implementation language, as I am fairly +familiar with it and it is well-suited to such tasks. In addition, +its strong type system and borrow checker are useful in catching many +classes of bugs at compile time and it has unit testing support +provided in the base language, which is convenient for doing TDD. + +### LLM / AI Usage + +I will not be using any LLM coding assistants for this project. diff --git a/top-level-architecture.png b/top-level-architecture.png new file mode 100644 index 0000000..4ac35ce Binary files /dev/null and b/top-level-architecture.png differ