Spoken symbol reference for code dictation
VoiceGem recognizes 78 spoken symbol phrases producing 40 symbols, 7 casing phrases producing 5 identifier styles, and 5 whitespace phrases producing 3 outputs. Most symbols carry more than one alias, so the phrase you would guess is usually the phrase that works: "open paren", "open parenthesis" and "left paren" all produce an opening parenthesis.
Given a symbol you need to dictate, produce the phrases that make it, in under 5 seconds.
48 of 48 outputs shown. 90 spoken phrases in total.
| Output | Say any of | Spacing | Example |
|---|---|---|---|
| ( | open paren, open parenthesis, left paren | No space either side | “print open paren value close paren”print(value) |
| ) | close paren, close parenthesis, right paren | No space before | “sum open paren a comma b close paren”sum(a, b) |
| [ | open bracket, left bracket | No space either side | “items open bracket zero close bracket”items[zero] |
| ] | close bracket, right bracket | No space before | “rows open bracket index close bracket”rows[index] |
| { | open brace, left brace, open curly | Space on both sides | “if ready open brace”if ready { |
| } | close brace, right brace, close curly | Space on both sides | “close brace else open brace”} else { |
| < | open angle, less than | Space on both sides | “while i less than length”while i < length |
| > | close angle, greater than | Space on both sides | “if count greater than zero”if count > zero |
| . | dot, period, full stop | No space either side | “user dot name”user.name |
| , | comma | No space before | “first comma second comma third”first, second, third |
| ; | semicolon | No space before | “return value semicolon”return value; |
| : | colon | No space before | “name colon string”name: string |
| :: | double colon, scope | No space either side | “std double colon vector”std::vector |
| = | equals, equal, assign | Space on both sides | “camel case retry count equals zero”retryCount = zero |
| == | double equals, equal equals | Space on both sides | “if status double equals ready”if status == ready |
| === | triple equals | Space on both sides | “if value triple equals null”if value === null |
| != | not equals, bang equals | Space on both sides | “while node not equals null”while node != null |
| => | arrow, fat arrow | Space on both sides | “open paren x close paren fat arrow x plus one”(x) => x + one |
| -> | thin arrow, dash arrow | Space on both sides | “func total thin arrow int”func total -> int |
| + | plus | Space on both sides | “total plus one”total + one |
| - | minus, dash | Space on both sides | “length minus one”length - one |
| * | star, asterisk, times | Space on both sides | “width times height”width * height |
| / | slash, forward slash, divide | Space on both sides | “total divide count”total / count |
| \ | backslash | No space either side | “backslash n”\n |
| % | percent, modulo | Space on both sides | “index modulo length”index % length |
| & | ampersand | Space on both sides | “flags ampersand mask”flags & mask |
| && | double ampersand, logical and | Space on both sides | “if ready logical and open”if ready && open |
| | | pipe, vertical bar | Space on both sides | “string pipe null”string | null |
| || | double pipe, logical or | Space on both sides | “value logical or fallback”value || fallback |
| ! | bang, exclamation, exclamation point | No space either side | “bang ready”!ready |
| ? | question mark | No space before | “name question mark colon string”name?: string |
| @ | at sign, at symbol | No space after | “at sign State private var count”@State private var count |
| # | hash, pound, hashtag | No space after | “hash include”#include |
| $ | dollar, dollar sign | No space after | “dollar sign count”$count |
| ^ | caret | Space on both sides | “base caret exponent”base ^ exponent |
| ~ | tilde | Space on both sides | “tilde mask”~ mask |
| ` | backtick | No space either side | “backtick hello backtick”`hello` |
| " | double quote, quote | No space either side | “double quote ready double quote”"ready" |
| ' | single quote, apostrophe | No space either side | “single quote a single quote”'a' |
| _ | underscore | No space either side | “underscore internal”_internal |
| Style | Say any of | Example |
|---|---|---|
| camelCase | camel case | “camel case max retry count”maxRetryCount |
| PascalCase | pascal case | “pascal case max retry count”MaxRetryCount |
| snake_case | snake case | “snake case max retry count”max_retry_count |
| kebab-case | kebab case | “kebab case max retry count”max-retry-count |
| CONSTANT_CASE | constant case, screaming snake case, scream case | “constant case max retry count”MAX_RETRY_COUNT |
| Output | Say any of | Example |
|---|---|---|
| Line break | new line, newline | “close brace new line const next”}
const next |
| Blank line | new paragraph | “done new paragraph next”done
next |
| Tab | tab, indent | “tab return value” return value |
userProfile =[]
Keep the sheet where you dictate.
Reading the table once is the whole learning curve — most people settle on about fifteen phrases and stop consulting it. Download it, put it beside your editor for a week, then try the converter on a line from your own codebase.
Run a line of your own through the converterVoiceGem has no mailing list and runs no drip sequence. An address left here is stored on voicegem.app for one purpose — sending you a single message when the code-dictation accuracy benchmark publishes — and is deleted after that send. The lawful basis is your consent, given by submitting this form; the field is optional and nothing is pre-selected. Leaving it blank costs you nothing on this page, because everything above is already yours. See the privacy policy.
This tool runs entirely in your browser. The table is compiled into the page and the search box filters it locally, so nothing you type is sent anywhere, stored, or logged. The one exception is the email box under the result: an address left there is sent to VoiceGem, and nothing else on this page is.
How to read the spoken symbol table
Each row of the table above is one output and every spoken phrase that produces it. VoiceGem matches phrases longest-first — three words, then two, then one — so "double equals" wins over "equals" and you never have to think about the order you say things in.
The spacing column is the part most people skip and then need. Every symbol carries two flags: whether it attaches to the token on its left, and whether it attaches to the token on its right. An opening parenthesis attaches on both sides, which produces print(value). A comma attaches left only, which produces a, b. An equals sign attaches on neither side, which produces a = b. Those flags are why dictated code comes out looking like code instead of like a word list with punctuation sprinkled through it.
Aliases exist because people say the same symbol different ways under pressure. There are 78 phrases for 40 symbols, which averages just under two ways to ask for each one. You do not need to learn all of them — pick whichever alias you would say naturally and the table will already have it.
How to dictate symbols without a phrase table
Dictating punctuation into an editor with no phrase table means one of three things. Built-in macOS dictation understands a handful of punctuation words — "period", "comma", "open parenthesis" — and writes the rest out as English. Text expansion snippets cover more symbols but cannot handle casing or spacing. A language model asked to format the transcript covers everything and gives a different answer on different runs.
The manual approach that actually works for a few people is a keyboard-only compromise: dictate the words, type the punctuation. It is genuinely fine for short lines. It falls apart on a function signature, where the symbols outnumber the words and your hands never leave the keyboard anyway.
VoiceGem publishes the whole table for a reason that is partly self-interested and partly not. A phrase table only works if you can see it. A tool that hides its command list behind a settings screen makes you discover it by trial and error, and most people quit before they finish discovering.
Where the phrase table produces something you have to fix
Three rows in the table above give output that a developer will want to edit, and pretending otherwise would be the kind of demo that works only on the demo sentence. An exclamation point attaches on both sides, so "bang ready" gives !ready — correct for a negation, wrong if you wanted a space. An ampersand attaches on neither side, so "flags ampersand mask" gives flags & mask — correct for a bitwise operator, wrong for a C address-of. A tilde behaves the same way.
The reason is that the flags are fixed per symbol and a symbol's correct spacing depends on the language and the position. VoiceGem chose one setting per symbol rather than guessing from context, because a fixed rule can be learned and a guess cannot. Dictating the first draft and fixing three characters is still faster than typing the line.
The whitespace commands have a related sharp edge worth knowing before you rely on them. "new line" inserts a line break but not indentation, and "tab" inserts a literal tab character. An editor that auto-indents will do its own thing with both, so the result depends on your editor settings rather than on the table.
Why the table is published in full
The complete mapping is the answer to the most common objection to code dictation, which is that it means memorizing a hundred commands. It does not: there are 48 outputs, most people use about fifteen of them, and the aliases mean the phrase you would guess is usually the phrase that works.
VoiceGem publishes it here rather than only inside the app because a reader deciding whether code dictation is worth trying needs to see the surface area before installing anything. The table is also the thing to argue with — if a symbol you need is missing, that is a concrete, checkable gap rather than a vague impression, and the source is public under GPL-3.0, a derivative of VoiceInk by Prakash Joshi Pax.
- Download the sheet as plain text for a printed card, or as CSV to diff against a future version.
- Every example in the table is generated by running the converter on the phrase next to it, so an example cannot be out of date.
- The Mac app adds a personal dictionary and word-replacement rules on top of this table, for project vocabulary the table has no opinion about.
Related: the casing converter, the speech-to-code converter, or what changes for the filler word remover.
Common questions
90 in total: 78 symbol phrases, 7 casing phrases, and 5 whitespace phrases. They produce 48 distinct outputs, because most symbols have more than one way to ask for them.
No. Most people use around fifteen phrases day to day — parentheses, brackets, braces, dot, comma, semicolon, equals, and a casing command or two. The rest are there when you need them.
The words pass through unchanged. An unrecognized word is treated as ordinary text, which is what lets you dictate English prose into a code comment without it turning into symbols.
Not to this table — it is fixed, which is what makes the behavior predictable. VoiceGem on macOS 14.4 or later adds a separate personal dictionary and word-replacement layer for project-specific vocabulary.
The longest one. Matching runs at three words, then two, then one, so "double equals" is matched before "equals" and "screaming snake case" before "snake case".