2025-03-26

syntax styles

keywords and identifiers

there seem to be two extremes of design styles, reflecting a dichotomy between expressive complexity and functional minimalism. this dichotomy may correspond to deeper psychological or cultural tendencies. it manifests not only in programming languages, but also in written language, particularly in typography.

enrichment-oriented

this style favors special characters, combinations of special characters, and abbreviations. examples include: apl, mathematical notation, haskell, perl.

such systems seek expressive power through layered meanings, much like mathematical notation or apl, which rely on compact symbols. they feature a dense symbolic vocabulary and require a tediously acquired, shared understanding of esoteric symbols. these systems often use ornate and highly contextualized forms.

simplification-oriented

this style prioritizes words from natural language, and alphanumeric characters. examples include: coffeescript, scheme, ruby.

these systems employ minimalist, uniform notation, or attempt to approximate spoken language. they seek accessibility and clarity, aiming to reduce the cognitive load on users. this approach often favors streamlined and universal formats.

nesting

keyword

example (vbscript)

if 3 = x then
  msgbox "test"
end if

for each a in list: msgbox a: next

benefit: quick to type

bracket

example (c)

if (3 == x) {
  printf("test");
}

for (int i=1; i

example (scheme)

(if (= 3 x)
  (display "test"))

(for-each display mylist)

indent

example (coffeescript)

if 3 is x
  console.log "test"

list.forEach (a) -> console.log a

benefit: code written by different authors looks more uniform, as there are fewer structural elements, such as spaces or brackets, that can be freely positioned.

operator placement style

prefix

+ 1 2 3 4

infix

1 + 2 + 3 + 4

suffix

1 2 3 4 +

whitespace, indent, and infix notation

draft coffeescript and wisp highlight interesting differences in how whitespace, indentation, and additional structural characters can be used differently.

commas

in the examples below, a coffeescript-style syntax uses commas in infix notation to show argument continuation on the same line. in coffeescript, a newline can replace the comma.

wisp

single-line function call

f a b c

continued argument list

f a b
  . c d
  . e f

-> "(f a b c d e f)"

nested multiline function calls

f a
  f2 b c
  f3 d e

-> "(f a (f2 b c) (f3 d e))"

coffeescript

the space between identifiers marks application position

f a, b, c

in array and object literals, newline can replace comma. there, the comma can be used solely as a single-line separator.

a = [
  b, c
  d, e
]

-> "a = [b, c, d, e]"

argument list continuation does not have the information from the assignment operator or the literal brackets, and needs at least an initial comma

f a, b,
  c, d
  e, f

-> "f(a, b, c, d, e, f)"

f a,
  f2 b, c
  f3 d, e

-> "f(a, f2(b, c), f3(d, e))"

f a,
  f2 b, f3(
    c, d
  )
  (e - f)

-> "f(a, f2(b, f3(c, d)), e - f)"

associations

a similar situation as with commas arises with associations.

wisp/scheme handle associations with sub-lists and the syntax of "let", the colon is merely used to open a second nesting on the same line.

let
  : x a
    y b
    z c
  display x

-> (let ((x a) (y b) (z c)) (display x))

coffeescript uses the colon as a marker for each association

let
  x: a
  y: b
  z: c,
  display x