How Numi Turns Typed Sentences Into Answers

How Numi Turns Typed Sentences Into Answers

Numi parses plain English by tokenizing your line, matching each token against dictionaries of numbers, operators, units, currencies, and date words, then building an expression tree it executes locally. There's no language model involved and no network round trip for the parsing itself. The whole pipeline runs in under a few milliseconds per line, which is why results appear as you type rather than after you finish.

Key takeaways

  • Numi's parser is a deterministic grammar, not an AI model, so identical input always produces identical output and everything runs offline except currency rate fetches.
  • Parsing happens in four stages: tokenize, resolve units and entities, disambiguate by context, then build and evaluate an expression tree.
  • Most parsing failures come from three sources: variable names that collide with unit abbreviations, ambiguous prepositions, and phrasings with no numeric anchor.
  • Numi returns nothing rather than guessing when a line falls outside its grammar, which prevents confidently wrong answers but produces silent no-result lines.
  • Explicit parentheses and longer variable names fix the large majority of real-world parsing problems.

The four stages of the pipeline

Every line you type moves through the same sequence. Understanding the order matters, because most confusing behavior comes from a decision made in stage two that only becomes visible in stage four.

Stage What it does Example on "120 usd in eur" Typical failure here
1. Tokenize Splits the raw string into numbers, words, symbols, and operators [120] [usd] [in] [eur] Unusual characters or mixed separators break the split
2. Resolve Matches word tokens against unit, currency, date, and function dictionaries usd → currency, eur → currency A word matches a unit when you meant a variable
3. Disambiguate Uses surrounding tokens to pick a meaning for context-dependent words "in" → conversion operator, not inches Genuinely ambiguous phrasing resolves the wrong way
4. Evaluate Builds an expression tree and executes it with unit checking Fetch rate, multiply, return EUR amount Incompatible units cause the line to return nothing

Notice that no stage involves anything resembling comprehension. Stage three is the closest thing to "understanding," and it's a set of contextual rules, not inference. The word "in" between two currency codes means conversion. The word "in" after a bare number followed by nothing means inches. These are conditions in a grammar, written and tested by hand.

Stage one: tokenizing

Tokenizing splits your raw text into meaningful chunks. It sounds trivial and isn't. Take the line $4,200/mo * 14 months. A naive splitter breaks on whitespace and produces $4,200/mo as a single unusable blob. Numi's tokenizer instead separates the currency symbol, strips the thousands comma without treating it as a decimal, recognizes the slash as a rate separator rather than division, and pulls "mo" out as a time-unit abbreviation.

Three tokenizing behaviors are worth knowing because they explain a lot of otherwise puzzling results:

  1. Commas are contextual. In 4,200 the comma is a thousands separator. In max(3, 9) it's an argument delimiter. Numi decides based on what surrounds it, and a comma in an unexpected position can silently change how the number reads.
  2. Currency symbols bind to the number that follows them. $50 tokenizes as one value. 50 $ also works. $ 50 $ does not, and returns no result.
  3. Slashes are ambiguous by design. 100/4 is division. 100 km/h is a compound unit. The tokenizer looks at whether the tokens on either side are units before deciding.

You can watch stage one at work by typing a line slowly and noticing exactly which keystroke makes the answer appear or disappear. Type 5 km and you get a value with a unit. Add / and the result vanishes because the expression is incomplete. Add h and it resolves to a speed. That flicker is the tokenizer re-running on every keystroke, which it does cheaply enough that the delay is imperceptible on any Apple Silicon Mac.

For the full operator and abbreviation list this stage works from, the Numi syntax reference covers every recognized token.

Stage two: resolving words to entities

Once the line is tokenized, each word token gets looked up. Numi checks dictionaries in a fixed priority order, and that order is the single most useful thing to know about the parser:

  1. Reserved keywords and functions, such as sum, total, prev, round
  2. Currency codes and symbols
  3. Unit names and abbreviations
  4. Date and time words
  5. User-defined variable names

Variables come last. That's the source of a surprising number of complaints, and once you know the ordering it stops being surprising. Write in = 12 hoping to store a value called "in," and the parser has already matched "in" as a unit before it ever considers your variable. Same story with s, m, h, t, and c, all of which are legitimate unit abbreviations in one measurement family or another.

The fix is boring and effective: name variables with words that aren't units. rate, subtotal, deposit, hours_worked. Two syllables or more, no single letters. I've never had a collision with a variable name over four characters that wasn't itself a unit word like meters.

Unit resolution and canonicalization

Unit resolution deserves its own note because it's where a broad dictionary pays off. Numi maps many spellings to one canonical internal unit, so km, kilometer, kilometers, and kilometres all resolve to the same thing before any math runs. The conversion factor is then applied once, against a single tested table, rather than being reimplemented per spelling.

This canonicalization is also why compound units work. mbps resolves to megabits per second, a composite of a data unit and a time unit, which lets stage four cancel the time component when you divide a file size by it. Type 18 gb / 40 mbps in minutes and the unit algebra does the work: gigabits over gigabits-per-second leaves seconds, which then converts to minutes. If the units don't cancel to something compatible with your requested output, the line returns nothing rather than a meaningless number.

Stage three: disambiguation

English is ambiguous and a calculator can't be. Stage three resolves context-dependent tokens by looking at neighbors.

Token Possible meanings How context decides
in Conversion operator, or inches Followed by a unit or currency → conversion. Preceded by a number and ending the line → inches
% Percentage value, or modulo Followed by "of" or attached to a number in an additive context → percentage. Between two integers with no unit → modulo in some contexts
Subtraction, or negative sign, or date separator Position relative to numbers and date-shaped patterns
m Meters, minutes, or million Neighboring units and whether the line is length-shaped or time-shaped
/ Division, or compound unit separator, or date separator Whether both sides are units, both numbers, or a date pattern

That table is also a map of where things go wrong. The m row is the worst offender in practice. Type 5 m + 30 s and you'll get a result only if both tokens resolve into the same family, and "m" resolving to meters while "s" resolves to seconds gives you an incompatible-unit line with no answer. Writing 5 min + 30 sec removes the guesswork entirely.

The precedence question

Once tokens have meanings, Numi builds an expression tree using standard mathematical precedence. Worded operators sit on the same tree as symbolic ones. 10 plus 5 times 2 evaluates as 20, not 30, because "times" binds tighter than "plus" exactly as * binds tighter than +.

This trips people up specifically because natural phrasing implies left-to-right reading. When you say "ten plus five times two" out loud, plenty of listeners hear a sequence. The parser hears precedence. Parentheses are the only fix that works every time: (10 plus 5) times 2 gives 30. If a line's result surprises you, adding explicit parentheses is the first thing to try, before assuming a bug.

Stage four: evaluation and unit checking

The final stage walks the expression tree and executes it, checking unit compatibility at each node. This is where Numi refuses to do nonsense arithmetic. Adding a length to a duration produces no result, because there's no sensible answer. Multiplying a rate by a matching duration cancels the shared unit and returns a plain value.

Rounding happens at display time, not during evaluation, which matters for chained calculations. The full-precision value is what gets carried forward when a later line references an earlier one. The number you see is a rendering of it. That distinction protects you from the compounding-rounding problem that bites people building long calculation documents, though it also means a displayed total can differ by a cent from what you'd get adding the displayed line values by hand.

Anyone using a natural language calculator for Mac for invoicing or tax work should check the decimal precision setting before trusting a final figure without a sanity check.

What reliably fails

Here's the honest part. These phrasings either return nothing or return something other than what a reasonable person would expect, tested on Numi 3.31 under macOS 15.5:

  • Fully conversational questions. what is twenty percent of eighty five dollars spelled out in words with no digits does not resolve. Numi needs numeric tokens.
  • Variable names that shadow units. in = 12, m = 5, s = 60. All lose to the unit dictionary.
  • Nested conditional logic. There's no if-then construct. Anything requiring a branch belongs in a spreadsheet or a script.
  • Symbolic algebra. solve x + 15 = 40 is Calca territory. Numi computes fixed expressions, it doesn't solve for unknowns.
  • Deep scientific and statistical functions. Trigonometry is present, but the statistical and engineering function library is thin next to a dedicated scientific calculator.
  • Ambiguous multi-clause sentences. add 15% then subtract 10% of the original requires knowing which base "the original" refers to. The parser has no referent tracking.

The failure mode itself is worth calling out as a design choice. Numi returns no result rather than guessing. A parser that guessed would produce a plausible-looking number for a line it misread, and a wrong number that looks right is worse than a blank. The cost is that a near-miss phrasing gives you nothing to debug from, and you're left rewording by trial until something lands.

Why it isn't a language model

An obvious 2026 question: why not just hand the line to an LLM? Three reasons hold up.

Determinism. A grammar returns the same answer for the same input every time. That's non-negotiable for a calculator. Speed. Local parsing completes before your next keystroke, while a network round trip to a model does not. Privacy. Nothing you type leaves the machine for parsing purposes, which matters when the numbers are salary figures, client rates, or medical dosages.

The tradeoff is exactly what you'd expect. A model would handle "roughly what's a fifth of my rent" gracefully. The grammar won't touch it. That's a narrower tool making a deliberate bet that correctness and speed beat flexibility for this specific job. Whether that bet suits you depends on whether you type numbers or type questions.

Practical rules that fix most problems

  1. Use digits, not words. Write 15%, not "fifteen percent."
  2. Name variables with three or more characters that aren't unit words.
  3. Add parentheses whenever a line mixes worded and symbolic operators.
  4. Spell out ambiguous unit abbreviations. min over m, sec over s.
  5. Split long lines. Two short lines with a variable between them parse more reliably than one clause-heavy sentence, and they're easier to audit later.

Applying those five rules eliminated nearly every parsing problem I ran into across a week of daily use. The remaining failures were all cases where the feature genuinely doesn't exist rather than cases where phrasing was the issue, and a calculator notepad app can't parse its way into a capability it wasn't built with.

Frequently asked questions

Does Numi use AI to understand what you type?

No. Numi app runs a deterministic grammar-based parser, not a language model. The same input always produces the same output, parsing happens locally in milliseconds, and no text is sent to a server for interpretation. Only currency rate lookups touch the network, and those fetch numbers rather than sending your input anywhere.

Why does Numi sometimes read a word as a unit instead of a variable?

Numi checks its unit dictionary before treating an unrecognized word as a variable name. Short words that double as unit abbreviations, such as in, s, m, and h, resolve to units first. Naming a variable something longer and unambiguous avoids the collision entirely.

How does Numi decide operator precedence in a worded line?

After tokenizing, Numi mac builds an expression tree using standard mathematical precedence: parentheses, then exponents, then multiplication and division, then addition and subtraction. Worded operators map onto the same tree. When a phrasing is genuinely ambiguous, explicit parentheses are the only reliable fix.

What happens when Numi cannot parse a line?

The line returns no result rather than a wrong one, and the text stays editable so you can adjust the phrasing. Numi does not guess at a plausible interpretation, which is the safer behavior for a calculator but does mean some near-miss phrasings produce nothing at all.

Can Numi parse a question typed as a full sentence?

Partially. Numi tolerates filler words around a recognizable expression, so a short lead-in usually parses. It's not a chatbot, though, and a fully conversational question with no clear numeric expression inside it won't resolve. Keeping numbers and operators adjacent gives the most reliable result.

פתוח 24 שעות ביממה

שתפו את המקום עם חברים:

אטרקציות נוספות שיכולות לעניין:

חברים בקבוצות שלנו?

הצטרפו לסיורים שלנו!

ותכירו את העיר מהעניים של המקומיים