R10 — The terminal REPL

Goal: run the same REPL outside the browser, and know the three ways it differs.

Getting it

From a checkout of the project:

sbt repl

Or as a dependency in your own build:

libraryDependencies += "it.grypho" %% "leonardo-repl" % "0.0.0+1-92b231cd-SNAPSHOT"

Why leonardo-repl and not leonardo?

Because they are two artifacts, and the REPL is the larger one. It needs a terminal library — for line editing, history and colour — which a program that merely wants to differentiate an expression has no business downloading.

So the split runs the other way from what you might expect: leonardo is the library, and leonardo-repl adds the prompt on top of it. Depend on the first unless you specifically want to embed or extend the REPL itself. Getting Started has both coordinates, and Lessons: in your program is the branch for using the library directly.

It is the same command language

Everything from R1 to R9 works unchanged, because both REPLs run the same session underneath:

> f := x^2 + 1
f := ((x ^ 2.0) + 1.0)
> derive(f, x)
(2.0 * x)
> integral(f, x, 0, 1)
1.33333

run this session

There is no terminal dialect to learn. What follows is the complete list of differences.

Difference 1 — it cannot draw

plot, points, bode and nyquist exist only in the browser.

They are not missing by oversight. As R7 put it, a command that cannot do anything is worse than an absent one — so rather than accepting plot and printing an apology, the terminal REPL does not claim the word at all. samples is what it has instead, and it is the same computation without the picture.

Difference 2 — real files

:save and :load take a path, and what you get is a text file you can keep, edit, diff and email:

> :save ~/work/session.leo
saved to ~/work/session.leo

In the browser those same commands write to the browser’s own storage (R9). Identical spelling, different backing store — which is the point.

This is where a session being a script rather than a snapshot pays off: the file is readable, and you can edit it before loading it. And because :load runs each line as if you had typed it, a file you write yourself can do more than restore a session: a script of calculations prints each result as it goes. That is a terminal advantage — in the browser, storage and links only ever hold what :save and Share wrote, so loading there restores the environment and nothing else (R9).

Difference 3 — a terminal’s comforts

Line editing, history that survives between runs, and syntax colouring as you type:

> colors
colors = dark
> colors light
colors = light
> colors dark
colors = dark

run this session

dark, light and none are the schemes. The browser has no highlighting, so — consistently with Difference 1 — the setting is simply not offered there rather than offered and inert.

There are also Greek chords: ALT-g followed by a letter inserts the matching Greek letter, so theta can be entered as a single character where that reads better. Ordinary editing keys are untouched; ALT-b still means backward-word.

Help without leaving the prompt

help prints the whole command summary. help <topic> goes deeper on one of them:

> help exact
Exact rational arithmetic.  Off by default; both settings are persisted by :save.
  exact on            numeric literals become exact rationals
  exact off           literals are Doubles (default)
  exact precision <n> digits an irrational is approximated to (default: 30, 1..1000)
  exact               show both settings
With it on, 0.1 + 0.2 is exactly 3/10 and 1/3 * 3 is exactly 1 -- neither of which
a Double can represent.  The mode is decided at PARSE time because it has to be:
once 0.1 has been read as a Double the tenth that was meant is already gone.
WHAT STAYS EXACT: +, -, *, /, and integer powers.  Everything else -- every
transcendental function, any fractional power -- is irrational, so it is computed
and then re-approximated to the working precision.  Those kernels are still
Double-accurate (~15 digits) whatever the working precision says, so raising it
sharpens the ARITHMETIC around a sin(), not the sin() itself.
DISPLAY: a short fraction shows as n/d, a long one as a decimal at the display
precision -- but :save always writes the exact fraction, so nothing is lost.
MIXING: an exact value combined with an inexact one gives an inexact result.
That is deliberate -- absorbing the Double would be lossless but would dress up
representation error as an exact answer.

run this session

It works in both REPLs, and it is faster than coming back here to check a spelling.

Try it yourself

You have forgotten whether the factorial function is fact or factorial. Find out without leaving the prompt.

Answers ```text > help fact Factorial and the gamma family. fact(5) -> 120.0 exact for integers up to 170! fact(0.5) -> 0.88623 analytic continuation: Gamma(1.5) dfact(7) -> 105.0 double factorial 7!! = 7*5*3*1 mfact(10, 3) -> 280.0 multifactorial, step 3: 10*7*4*1 Gamma(5) -> 24.0 Gamma(n) = (n-1)! lgamma(1e5) ln|Gamma| -- finite where Gamma overflows Beta(1, 4) -> 0.25 Beta(a,b) = Gamma(a)Gamma(b)/Gamma(a+b) Gamma and Beta are capitalised so that lowercase "gamma" and "beta" stay available as ordinary variable names. Poles (0, -1, -2, ...), 171! and beyond, and complex arguments all stay symbolic rather than returning infinities. Differentiating Gamma needs the digamma function, which is not implemented, so derive(Gamma(x), x) stays symbolic. ``` *[run this session](https://lycogrypho.github.io/Leonardo/app/#s=precision%205%0Acolors%20dark%0Apretty%20off%0Alatex%20off%0Anames%20off%0Alogic%20minmax%0Alogic%20symmetric%20off%0Aexact%20precision%2030%0Aexact%20off%0Af%20%3A%3D%20((x%20%5E%202.0)%20%2B%201.0))*

Where to go next

That is the branch. You can now use Leonardo as a calculator that does algebra — in a browser tab, or at a prompt on your own machine.

To go deeper on what you have met:

To go further:

  • Lessons: in your program — the other branch, if you now want to call Leonardo from Scala rather than type at it.
  • Features — the domains these lessons did not touch: transforms, control theory, probability, logic, vector calculus.

What you learned

  • sbt repl, or the leonardo-repl artifact, gives the same command language offline — leonardo is the library, leonardo-repl adds the prompt.
  • No plotting in the terminal; use samples.
  • :save / :load use real paths there and browser storage in the page.
  • Line editing, history, colors and Greek chords are the terminal’s own.
  • help and help <topic> answer most questions without leaving the session.

Previous: R9 — Your session · All lessons · Other branch: Lessons: in your program


This site uses Just the Docs, a documentation theme for Jekyll.