266: The expr syntax

by José Bollo

Status

This SRFI is currently in draft status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to srfi-266@nospamsrfi.schemers.org. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.

Abstract

The syntax expr allows one to write arithmetic expressions using a syntax near to mathematical notation, potentially improving the readability of Scheme programs.

Issues

Rationale

Scheme programmers expressing arithmetic expression see all over their code the gap between what they learnt at school for expressing arithmetic formulae and what is written in Scheme.

Here is an example of Scheme for computing the root of a quadratic.

	(let ((rdelta (sqrt (- (* b b) (* 4 a c)))))
           (values (/ (- rdelta b) 2 a)
                   (/ (+ rdelta b) -2 a)))

Even experienced Scheme programmers may have trouble validating such a simple expression. What about complex expressions written by someone else? As an example, here is a challenging quiz. Can you guess what k represents? (The answer appears later in the text.)

   (define k (- (quotient (+ (abs (- (* dark 20) (* total 10))) total -1) total) 1))

This SRFI describes the syntax expr that fills the gap between Scheme and mathematics, at least for arithmetic. Using this syntax, the above examples can be written as below:

   (let ((rdelta (sqrt (expr b * b - 4 * a * c))))
           (values (expr (- b + rdelta) / (2 * a))
                   (expr (- b - rdelta) / (2 * a))))

The syntax expr is inspired by the eponymous UNIX tool expr. The expression at its right is expressed using almost standard formulae. Using it, the definition of k becomes:

   ; Compute the smallest integer k >= 0 such that (45-5k)% <= dark/total <= (55+5k)%
   (define k (expr ((((abs dark)) * 20 - total * 10) + total - 1) : total - 1))

Writing arithmetic expressions is common when programming. Writing logic expressions and comparison expressions is also quite common. For this reason, the syntax expr comes with flavours allowing these expressions, too. Thus it is possible to write:

   (if (expr a < 0 and (k or b + c <> 9)))
      ...
instead of:
   (if (and (< a 0) (or k (not (= (+ b c) 9))))
      ...

SUBJECT TO DISCUSSION Neither bitwise operations nor fixnum operation are present in this first draft because these features are not part of R7RS-small. Also, it has to be noted that C-like operators cannot be used because the vertical bar | is used for other purposes in Scheme.

Moreover, mathematical formulae can deal with objects that are not numbers but vectors, matrices, monoid elements, ... For this reason, this SRFI includes definition of operators specifically for these purposes.

SRFI 105, Curly-infix-expressions, already introduced the ability to write expressions in a more usual way. The current SRFI differs for the the following reasons:

Specification

This SRFI exports only one syntax item: expr. According to SRFI 261, this syntactic item can be imported using:

   (import (srfi srfi-266))

The syntactic item expr is followed by an infix expression whose elements E are separated by space (except if enclosed in braces):

   (expr E ...)
The expression E ... must satisfy the grammar below:


   (EXPR
     (COND                       -> $1))
   (COND
     (OR "if" OR "else" OR       -> ("if" $3 $1 $5))
     (OR                         -> $1))
   (OR
     (AND (+ "or" AND)           -> ("or" $1 . $2))
     (AND                        -> $1))
   (AND
     (IMPLIES (+ "and" IMPLIES)  -> ("and" $1 . $2))
     (IMPLIES                    -> $1))
   (IMPLIES
     (EQV "implies" EQV          -> ("or" ("not" $1) $3))
     (EQV                        -> $1))
   (EQV
     (NOT "not" "eqv" NOT        -> ("not" ("eqv?" $1 $4)))
     (NOT "eqv" NOT              -> ("eqv?" $1 $3))
     (NOT                        -> $1))
   (NOT
     ("not" NOT                  -> ("not" $2))
     (COMP                       -> $1))
   (COMP
     (SUM (+ "<"  SUM)           -> ("<" $1 . $2))
     (SUM (+ "<=" SUM)           -> ("<=" $1 . $2))
     (SUM (+ ">"  SUM)           -> (">" $1 . $2))
     (SUM (+ ">=" SUM)           -> (">=" $1 . $2))
     (SUM "="  SUM               -> ("=" $1 $3))
     (SUM "<>" SUM               -> ("not" ("=" $1 $3)))
     (SUM                        -> $1))
   (SUM
     (DIFF (+ "+" DIFF)          -> ("+" $1 . $2))
     (DIFF                       -> $1))
   (DIFF
     (FACTOR (+ "-" FACTOR)      -> ("-" $1 . $2))
     (FACTOR                     -> $1))
   (FACTOR
     ("-" FACTOR                 -> ("-" $2))
     ("+" FACTOR                 -> $2)
     (MUL                        -> $1))
   (MUL
     (DIV (+ "*" DIV)            -> ("*" $1 . $2))
     (DIV                        -> $1))
   (DIV
     (QUOT (+ "/" QUOT)          -> ("/" $1 . $2))
     (QUOT                       -> $1))
   (QUOT
     (QUOT ":" REM               -> ("quotient" $1 $3))
     (REM                        -> $1))
   (REM
     (REM "%" EXP                -> ("remainder" $1 $3))
     (EXP                        -> $1))
   (EXP
     (TERM "^" TERM (+ "^" TERM) -> ("expt" $1 ("*" $3 . $4)))
     (TERM "^" TERM              -> ("expt" $1 $3))
     (TERM                       -> $1))
   (EXPT
     ("-" EXPT                   -> (- $2))
     ("+" EXPT                   -> $2)
     (TERM "^" EXPT              -> ("*" $1 $3))
     (TERM                       -> $1))
   (TERM
     (ITEM "@" ITEM              -> ("vector-ref" $1 $3))
     (ITEM "@." ITEM             -> ("list-ref" $1 $3))
     (ITEM "@@" ITEM             -> ("bytevector-u8-ref" $1 $3))
     (ITEM                       -> $1))
   (ITEM
     (((x ...))                  -> (x ...))
     ((x ...)                    -> ("expr" x ...))
     (x                          -> x))

SUBJECT TO DISCUSSION The grammar above is subject to change according to the discussion. It is not currently explained in any way. The explanation could be done later if needed and if that kind of formalism is of interest. At the moment, it is expected that readers can understand such grammar or at least guess how it works. For example, it may be better to just supply an array of the operation with their priority and some rules around these priorities. But at the moment, reasoning based on a grammar has advantages.

It is an error to provide an expression E ... that is not in the production of the grammar above.

Application of the syntax expr should transform the expression to an optimal Scheme expression so that using expr has no runtime cost.

For example:

   (expr a + b + c < d < x - y - z)

Must be translated to:

   (< (+ a b c) d (- x y z))

Implementation

Implementation of syntactic item expr can be made in many ways: using standard Scheme macros, using implementation specific macros, or, using internals of implementation.

The sample implementation given here uses the above grammar to produce R7RS-Small macros.

Source for the sample implementation.

Acknowledgements

Many thanks to writers of the UNIX tool expr.

© 2026 José Bollo.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


Editor: Arthur A. Gleckler