Hacker News new | past | comments | ask | show | jobs | submit login
A calculator for the Terminal that renders beautiful math (kary.us)
245 points by pmkary on Jan 11, 2020 | hide | past | favorite | 84 comments



Ah, such a nice set of features, and case-insensitive identifiers?..

I mean, if I do math or physics, I usually follow conventions, so I expect G to be usable as the gravitational constant, while g to be usable as the free-fall acceleration, maybe in the same formula.


Yes, that seems a very strange choice (stranger than spaces in identifiers!). TikZ allows spaces in some identifiers, and it can be quite nice.


Stay tuned and I will push an update for you guys to have lowercase/uppercase single letters. You can currently use single letter latin instances like Beta and Beta'


Why "Beta" and "Beta'", not "beta" and "Beta"? (Following e.g. Latex.) It seems like it would be useful to be able to define identifiers like "Φ'" (though maybe that's "Phi''"). It also seems a bit inconsistent to not allow an identifier π to be defined - some people use the symbol π for other purposes.


That is because the language is case insensitive and therefore normalizes the words so Beta and beta will not differ once they pass the parser.


That's a bad idea - every system that is case insensitive has eventually regretted it because it just leads to confusion. E.g. Mac's filesystem, Cmake (https://stackoverflow.com/a/35034125/265521). Almost all modern languages are fully case sensitive.


I've been making languages for quite a while now. And between all of them I've really like the idea of case insensitivity. Nota is mostly about what I wanted to have and couldn't find in other places. It's way of identifiers too was an important thing that I wanted to have. Having apostrophes, case insensitivity and spaces was an important thing that actually even effected the rest of the grammar design


I think what you've done is very beautiful and I hope you'll accept some feedback with equanimity.

You haven't made a language here, you have implemented one. That language is mathematical "Nota"tion.

You've implemented it incorrectly, because mathematical notation is case sensitive. A doesn't mean a, any more than it means α.

It is, of course, your project, and your sense of aesthetics which must ultimately be satisfied. I hope you will consider what I and others are trying to communicate to you, because I would use this, if it weren't broken from my perspective.


It is not that I don’t like or respect your ideas. Truth is that what I ultimately wanted on my end was to do the challenge of rendering notations with Unicode and then I thought let’s have a simple calculator with it. Nota is not a super capable calculator, to what I see it’s only the bare minimum. It’s for the times when you need quick thinking and wanna do a few quick calculations.

I personally love case insensitivity because it is really hard for me to remember the cases. I love macOS for its case insensitive file format and each time I design a language—and Nota is not mathematical notation, it is its own language with its own grammar. Just like the way Mathematica is its own language—I seek to see if having case insensitivity is possible. I loved it that with Nota, because the language was so simple I could even have spaces in the names. These are awesome for quick doings.

I haven’t resisted to the idea of case sensitivity though. But to be honest never thought about it.

For the sake of beauty nota renders each word in first-letter-Upper/rest-Lower since this was the most beautiful representation I experimented with. I will add the A and A’ to have both a and A (and the rest of the letters) this was if someone really loves to have the distinguished cases they can and I can keep my easy to write and beautiful in print style.

I think this solution is the win-win. And also I think if you regard Nota as a separate language with separate ideas; You can have more fun with it. It’s like watching How I met your Mother and trying to use it to replace Friends, it’ll make a bad experience, but regard it as a its own series and you then can see its beauty


As a mathematician, case sensitivity is non-negotiable. You'll pry A=(a,b) from my cold, dead hands.


How hard is it to have an option for either? Might be a win win opportunity. :)


I was thinking of having A for a and A’ for A and. It’ll easily fix the problem for the ones who wanna have different cases for single letters


I feel like case insensitivity is a great UX choice, really everything should be case insensitive. It just falls so badly apart when you get into the guts of things that case sensitivity is the only practical choice.


thank you!


> TikZ allows spaces in some identifiers, and it can be quite nice.

That's horrifying. Spaces between identifiers should of course mean products.


I see that one would have to quote space-containing identifiers with parens. I think this strikes a good balance.


I use Insect[0][1] as my calculator and it is great and does not have the odd choice of having case-insensitive identifiers plus does not require me to have Haskell installed. I would prefer if Insect was written in a compiled language but I am glad that it exists and JavaScript is really not a deal breaker for me as I need nodejs installed anyway (the same cannot be said for Haskell and this is going to be true for most people) plus you can get "compiled" single binaries for it from the release page[2] that you can put in `~/.local/bin` and not worry about it. I highly recommend trying it out. A bit slow to start but if your window manager supports hiding/showing bound windows through user defined shortcuts (like bspwm, awesomewm, i3, sway, herbstluft and most other tiling window managers) then you can just have it launch in the background on startup and you will have a convenient calculator just a few keystrokes away.

[0] https://insect.sh/?q=%3F

[1] https://github.com/sharkdp/insect

[2] https://github.com/sharkdp/insect/releases


Also python with pint installed can be a handy calculator similar to this. Many people have python installed, but don't use it as a quick calculator.


And sympy installed of course...


I hope that we will eventually get image support in terminals, and then projects like this can be much easier and still much nicer and more powerful, e.g. also plotting graphs, and much more, similar as what you get in a Jupyter notebook.

There is a long ongoing discussion about an upcoming standard for image support in terminals: https://gitlab.freedesktop.org/terminal-wg/specifications/is...


Nota is not much about calculator itself, it's about fun with ASCII art. there exists tons of more powerful calculators with much much better rendering. But I really agree, if we had a better system than text-only terminals it would have been sooo amazing


Kitty


Kitty also has their own custom protocol for images. That's exactly what they try to accomplish in this discussion thread, to get one common protocol which is used by all modern terminals. The developer of Kitty is also in there.


We've had image support in terms possible for years. I don't think that's what's needed to make a nice command line math program.

Instead, we need term programs that can handle type ligatures better. Being able to use something like FF Chartwell in a terminal would be amazing .. and would lead the way to having properly formatted mathematical notation in the terminal, without requiring a new standard to implement. Ligatures are already a thing - they just need to be better supported by the term apps.


You probably mean SIXEL? That is very limited, has drawbacks, and is not supported by many terminals (not exactly sure why, maybe too complicated, or too ugly). It's also discussed exactly in that thread. Developers from tmux, iTerm, mintty, xterm.js, Kitty, and others are in there.



SIXEL for displaying bitmap images, yes.

But I mean that term apps should have better support for ligatures - as in font/type ligatures - for doing proper mathematics.


Also there is a deep need for better fonts. Currently only Menlo renders things right.



My favorite tool to double-check O:) my math homework was derive https://en.wikipedia.org/wiki/Derive_(computer_algebra_syste...


I guess the Unicode output is nice but I feel like my biggest issue is one with input. One thing that is annoying is you get half way through your line and realise you need an opening paren several terms ago. It can take a load of time to find the place to put it and a load of effort to make sure things are correctly balanced. I feel like the operator I wish I had is something like “extend the left operand leftwards” e.g. go from this (with cursor represented by a bar):

  a + b * x + c /|
  to this:
  a + (b * x + c) /|
  And apply again to get this:
  (a + b * x + c) /|
It (e.g.) let’s you write fractions without needing to use loads of parens (which have a cost as they must be balanced) or needing to think about whether the numerator will have more than one term.

I guess with rich input I’d also want to see the output in “big” mode.

Another way to try to make input easier is to use rpn. This has advantages and disadvantages.

Currently the calculator I most use is gnu Calc (I also use R occasionally for calculating quantiles). GNU Calc is the calculator built into emacs. It has an rpn interface and an algebraic one. A nice feature of the algebraic interface is that you can use $ to mean “the top entry on the stack” and so you can incrementally build up an equation. A second feature is selections. Their internal implementation is weird (based on hidden “functions” and rewrite rules) but they work fantastically well for modifying and manipulating the inside of a formula or equation. It also has a “big” display format which looks a bit like this one except that it predates Unicode symbols being common and so is pure ascii. (It also has tex output and emacs has image support but no one has put the two together yet)

Mainly I use Calc because I’m in emacs anyway and it has a ton of features that are easy to access (eg arbitrary precision floats, bignums, modular arithmetic support, complex numbers, interval arithmetic, vectors, matrices, algebra, curve plotting/fitting, unit conversions, ...). I feel like the variable support isn’t great. I feel like I want to eg have some set of variables, defined to be various input numbers, and write formulae in terms of them and then get the formula on the left without variables substituted and it’s numeric evaluation (with them substituted) on the right. There’s something weakly like this using => but it doesn’t compose well. If you add a => 1 to b => 3, you don’t get a + b => 4, you get (a => 1) + (b => 3). (I think. My memory is a bit rusty for the last example).


Looks really cool, but this statement

> Nota approaches identifiers much differently than any other language.

is not actually true. Goldman Sachs have an internal language, Slang, which also allows internal spaces in identifiers, and where identifiers are case insensitive. I believe it originated as an MIT research language so probably there are others with a similar approach.


> Goldman Sachs have an internal language

I think we can forgive them for saying that if the exception is not readily available.


Very good design skills.


I slapped my forehead seeing the dashed borders... Why didn't I think of that before?


Thanks a lot :D


Nice to have all that power on the command line. The system uses the notation with square brackets for function calls, e.g. Sin[x], so ppl familiar with Mathematica will feel right at home.

The SymPy Unicode output mode also does a pretty good job on the command line. You can try here https://live.sympy.org, for example https://live.sympy.org/?evaluate=(1%2F2)%2F3%20%2B%202%2Fsqr... (see Settings on the side to turn off LaTeX rendering)


Yeah but it wasn't the prettiest. What I learned through my experiments was that not all of the notations render beautifully and so I chose a subset that is pretty and kept the rest rendered just as functions. This honestly wasn't a try to have full mathematical notation rendering, but rather my own preferences of notation rendering. Yet, I hope you enjoy it :D


This looks very neat, but why does the project have zero tags or releases? I also notice the GitLab instance isn't even accessible over https.


Quite right. I used to be on GitHub and they banned me because of my nationality. So I had to make my own server. I still haven't had the chance to made the SSL work, sorry for that, but issues were really bigger than that so...


Oh, hey! I worked with you on a Racket VSCode project a while ago and wondered why you suddenly stopped responding. The GitHub ban might've been the culprit there. Glad to see you working on another interesting project!


How cool! Nice to see you again. Yeah I had an overflow of issues coming and github ban and then a personal trauma that made me put down so many of the project. Please email me and I'll add you to my GitLab. We can resume the progress there if you still like :D


It's amusing to see lot of people will write so much code and then skimp on just few lines of install script. The author here expects that everyone knows Haskel and how to install its "stack". 5 stupid lines of the install script. What fractions of time that would have taken in the total time spent on this project?


Hey, sorry for that. I made you the single line installation script :D reload the page and hope you like it :D


Looks like something broke and the page is now a single messy line with a <monodraw> tag in the source.


oh. shift reload!


You’re quite right, but one thing to note here is that Haskell Stack refers to a specific build tool for Haskell. Not its “stack”. But your point still stands.


The use of brackets to denote function arguments and pretty text output in the terminal reminds me very strongly of using Mathematica from the command line.

https://reference.wolfram.com/language/tutorial/UsingATextBa...


You are very right. I studied the screenshots of Stephen Wolfram's earlier project SMP and later the early versions of Mathematica. And the Calca later was a language inspiration.


I always found it odd about Mathematica that a low level programming language like C gets closer to mathematical notation with sin(x) than Mathematica with Sin[x]


In Mahematica any keyword can be used as an unbound variable. So you need a way to disambiguate f(x) meaning f multiplied by x vs. f[x] meaning f applied to x. If you use parentheses for both you'd have to give up the ability to express multiplication as a(b) which would be a bigger loss I think.


There are two reasons; first is that I tried to render parentheses in the terminal and they didn’t look good, it was brackets that looked good. So that is the actual reason but also writing brackets do not require shift so I prefer it myself to type more easily


Whatever your initial motivation, distinguishing between precedence modification and function application is an unmitigated good in my opinion, so good on you.

Do you plan to extend the language with symbolic capabilities?


Actually Id love to. I did a bad choice of writing Nota in Haskell. I will rewrite it in JavaScript so that I can also port it to the web and then if possible I will add as much more capability as I can. Symbolic is super cool but hard to implement, I should see how much time I have and how much others are willing to help.


> but also writing brackets do not require shift

So your target audience is strictly (US) English?


This, and issues like it, bug me so much. So many keyboard shortcuts are unusable by default on QWERTZ, for example any shortcuts involving /, [ or ]. They require modifiers to be typed, so those are swallowed for shortcut purposes.

Of course, it is (almost) impossible to account for the enormous amount of keyboard layouts that exist, so I wish we could agree to use key positions over the characters they produce for shortcuts, so we can cover a significant portion of the population with ANSI/ISO layouts. I'm honestly not sure what keyboard layouts are used in countries with entirely different scripts, but my cursory Google searches suggest the physical layout is the same as ours.

Sure, you might lose some mnemonics on layouts that aren't QWERTY, but at least the majority of shortcuts would be usable by default compared to having to remap them in every application. The application could even resolve what keys are actually mapped to the physical keys and display the correct shortcut in menus.

Destiny 2 actually seems to do this and does, as far as I was able to tell, an excellent job of it.


As I told, it's manly because of the the rendering. Brackets render much more pretty, but the other is true as much. Yeah people with normal layouts.


Mathematics notation only uses parenthesis for function application in a few cases.



Or fix the SSL. One of those must occur before this works.


I'm surprised the gitlab page has no issues, and the Nota.cabal file still points to what appears to be a stale github repo.


Parts of this reminded me of Calca (https://calca.io)


Wow you're absolutely right! It was a big inspiration for me


A beautiful language with a beautiful notation and beautiful ideas is perhaps a bit too much beauty for my taste


A mirror for those who are unable to git clone:

  https://github.com/pmkary/nota


That is out of date.

* http://codes.kary.us/nota/nota


Please don't use this, because this one is an old version.


Shameless plug: If you prefer java, try https://github.com/stefanhaustein/expressionparser/blob/mast...

Bonus feature: symbolic derivation


It does look nice, but it seems to be missing complex numbers.


Yeah. those beasts. I really like to have them implemented someday!


Neat!

One documentation nit: “Parenthesis” is singular; the plural is “parentheses”.


"Expect for the Pi" instead of "except for pi" is another.


thanks I'll fix that too :D


Fixed :D Thank you for the feedback!


Beauty sure has a low standard these days.


Or we may call it different tastes :D


It's beautiful! It's a real shame that Haskell isn't portable.


What do you mean? Haskell has, last time I checked, an LLVM IR and a C backend, so it should be very portable.


What modern desktop or server platforms does it not run on?


It seems not to run well on some platforms like the minds of developers who don't want to take the time learn it.


It seems to build on all the Debian ports, except SuperH and kFreeBSD, neither of which are modern desktop or server platforms.

https://buildd.debian.org/status/package.php?p=ghc


When I have the time I will port it to JavaScript to make it universal on all systems. But for now it only works on desktop machines that run Haskell. The installation script is only good for the UNIX for the time but I will add for windows


There’s ghcjs right? So maybe not super hard to port the core. I have basically no idea though.


Haskell can build for Linux, Mac, Windows, iOS, Android, and it can also compile to JavaScript. I don't know what your particular need is, but that fits my definition of portable.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: