Why Singapore English (Singlish) Confuses AI Grammar Checkers
9 min read · updated August 11, 2026
You paste a message into a model with “fix the grammar” and get back something nobody in Singapore would write. Every discourse particle is gone, every aspect marker has been reinterpreted as a tense error, and the meaning has quietly shifted. The checker is not broken. It was given a target and you did not choose it.
What comes back
The concrete artefact, so you can recognise it. Input:
Eh, you got go the meeting or not? I already send the deck to Marcus liao, but he never reply. Later boss angry then how? Can just call him lah, don't need to wait.
Output from a checker with no variety declared:
Did you attend the meeting? I have already sent the deck to Marcus, but he has not replied. What if the manager becomes upset? You could simply call him; there is no need to wait.
Twelve changes, and at least two are not corrections. never reply in Singapore English is a negated past — it means “did not reply” on this occasion, not “has never replied” and not “has not replied yet”. And Later boss angry is a warning about a consequence, not a hypothetical question. The rewrite is fluent, standard, and says something different from the original. That is the part that makes this a bug rather than a style preference.
What is actually being flagged
Singapore English is one of the most thoroughly described contact varieties in the literature, and each of the constructions the checker removed has a name and a function. Knowing them is what lets you write an allowlist instead of giving up.
feature example function copula deletion He very tall. "is" is not required zero article I go library. article optional null subject Cannot lah. subject recoverable topic prominence This book I already read. topic fronted existential "got" Got people waiting. there-is / have "got" question You got go anot? past interrogative perfective "already" I eat already. completed aspect "never" as past neg He never come. did not come adversative "kena" He kena scolded. adversative passive nominaliser "one" He very stingy one. assertion / emphasis A-not-A question You want or not? polar question bare "can" answer Can. / Cannot. full sentence answer reduplication walk walk, small small attenuation / iteration
The discourse particles are a separate closed class and they carry meaning that has no single-word English equivalent, which is why deleting them is a semantic edit rather than a tidy-up:
- lah — marks mood and solidarity; softens or asserts depending on contour.
- leh — softens, appeals, marks a tentative suggestion.
- lor — resignation, or obviousness of an outcome.
- meh — scepticism; turns a statement into an incredulous question.
- hor — seeks agreement or confirmation.
- mah — presents something as an obvious justification.
Replacing Can just call him lah with “You could simply call him” loses the solidarity marking entirely. Replacing Really meh? with “Is that so?” loses the scepticism. The lexical layer — chope, makan, paiseh, bojio, sian, atas, shiok, blur — gets the same treatment, and several of those are borrowings from Malay and Hokkien with no compact English equivalent either.
Why the checker does this
Three causes stack, and only one of them is about the model being multilingual.
First, the instruction is under-specified. “Fix the grammar” names an operation but not a target grammar. The model has to pick one, and it picks the register that dominates its instruction-tuning data for the word “grammar”: edited standard English, usually American. Every difference from that target then looks like an error, because by the target it is one.
Second, there is no locale to fall back on. Rule-based checkers ship a set of English variants — en-US, en-GB, en-AU, en-CA, en-NZ, en-ZA — and Singapore is not among them in the common tools at the time of writing, so even a system that respects locales has nothing to select. Singapore Standard English follows British spelling, so en-GB is the nearest, and it still says nothing about any feature in the table above.
Third, correction is a rewriting task, not a diffing task. Asked to “fix”, the model regenerates the sentence rather than editing it, so unrelated changes ride along: the register goes up, the vocabulary formalises, and the meaning drifts. That happens in every language; the variety mismatch just makes it visible.
The fix
Three changes, in order of how much they buy you. The first alone fixes most cases.
- Declare the variety and the scope. Say what is being corrected and, explicitly, what must be preserved. The preserve clause is doing the real work.
- Ask for a diff with reasons, not a rewrite. Return each change as a triple of original span, replacement and reason. Then you can filter or reject changes rather than accepting a paragraph wholesale, and the reasons make the checker’s assumptions visible.
- Give a short allowlist. Naming the particles and the aspect markers is far more effective than the abstract instruction, for the same reason a glossary beats an adjective everywhere else in this cluster.
{
"role": "system",
"content": [
"You are proofreading Colloquial Singapore English (Singlish).",
"This variety is not an error. Correct ONLY: typos, wrong word",
"forms that are also wrong in Singlish, and punctuation.",
"PRESERVE exactly, and never flag:",
" discourse particles (lah, leh, lor, meh, hor, mah, sia, ah)",
" perfective 'already' and 'liao'",
" 'never' used as a simple past negative",
" existential and interrogative 'got'",
" adversative 'kena'",
" A-not-A questions ('or not', 'anot')",
" copula and article omission, null subjects, topic fronting",
" borrowings: chope, makan, paiseh, bojio, sian, atas, shiok",
"Use British spelling.",
"Return JSON: an array of edits, each with the fields",
"original, replacement and reason. Return an empty array if",
"nothing needs changing. Do not rewrite the passage."
].join("\n")
}An empty array is a valid and common answer, and asking for it explicitly matters: a model handed text and asked to improve it will find something to improve unless told that no change is an acceptable outcome.
When you do want it corrected
There are real cases for converting to Singapore Standard English — a formal report, a regulatory filing, external correspondence. Treat that as translation between registers rather than as correction, and say so, because the two produce different output.
- Ask for a rewrite, not a fix. “Rewrite this in Singapore Standard English, preserving the meaning including the speaker’s attitude” sets the target explicitly and keeps the pragmatics in scope. The particle meanings then get rendered as words instead of dropped.
- Keep both versions. If the original came from a customer, the standardised version is your working copy and the original is the record. Do not overwrite user text with a normalisation.
- Watch the same failure in classification. A sentiment or intent model trained on standard English reads
sianandkenaas unknown and often lands on neutral. The general case is in what code-switching means in NLP and handling code-switched prompts, since Singlish text is frequently code-switched with Malay, Hokkien and Mandarin within a single sentence.