Skip to content

Proposal: dialect spellings for the expression language - #156

Closed
hadley wants to merge 1 commit into
mainfrom
expression-dialects
Closed

Proposal: dialect spellings for the expression language#156
hadley wants to merge 1 commit into
mainfrom
expression-dialects

Conversation

@hadley

@hadley hadley commented Jul 31, 2026

Copy link
Copy Markdown
Member

What this is

A design proposal (not spec, not implementation): site/expression-dialects.md, following the semantic-models.md pattern of a design doc in site/ outside the navbar. It proposes letting expressions be written in R, pandas, polars, or Python spelling as well as SQL — one language, one AST, one semantics; the dialects are alternative spellings that parse to identical nodes and may be mixed freely.

Highlights

  • Up-front "What changes for SQL" section: the only breaking change is None/NA becoming reserved words; everything else gives meaning to syntax that is an error today. A table covers where SQL instincts will be wrong ("…" is a string not an identifier, || is OR not concat, % is floored not truncated, &/| are logical).
  • Operator aliases: ==, !/~, &/&&, |/||, %in%, all at the canonical operator's precedence (R agrees almost exactly; pandas/polars divergences are called out).
  • Two modulos: MOD(x, y) keeps its truncated (SQL/C) semantics unchanged; %/%% arrive as a new floored operation (Python/R semantics). The one place dialects add an operation rather than a spelling.
  • Method calls as uniform sugar: x.f(a)f(x, a) for every function, so x.trim().length() <= 10 works; parens required, inert .str accessor accepted, . in numbers only between digits.
  • Function aliases (nchar, len_chars, tolower, trimws, ceiling, is_null, is_in, between, ifelse, lubridate-style weeks(2), …), chained comparisons (lo <= x <= hi, single-direction only), None/NA null spellings, double-quoted strings, and IN list forms […]/c(…).
  • SQL lowering sketch: violations query (WHERE (expr) IS FALSE) and CHECK emission, with a node-by-node DuckDB/Postgres table — NULLIF guards to preserve totality, explicit casts for temporal literals, COLUMNS(...) expanded at translation time.
  • Diagnostics: no new S-codes, but targeted hints for near-misses (|| on strings, pl.col('x'), is.na(x), mixed chains).

Open questions (in the doc)

  1. Should NA really be reserved case-insensitively (na is a plausible column name)?
  2. Alias breadth — happy to cut or extend.
  3. Keep the inert .str qualifier, or hint it away?
  4. A future canonicalizing fmt.

Conceptually builds on #155 (backtick-quoted names): backticks quoting identifiers is what frees "…" to be a string literal, and is the escape hatch for columns named na. No textual dependency — this PR is a single new doc based on main.

Per AGENTS.md this is phase 1: nothing is implemented, and the spec text itself is untouched pending sign-off on this wording.

🤖 Generated with Claude Code

@hadley

hadley commented Jul 31, 2026

Copy link
Copy Markdown
Member Author

Moved to #157 for discussion — a proposal is better debated as an issue than a doc PR.

@hadley hadley closed this Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant