Table of Contents for Programming Languages: a survey

Regular expressions

not Turing-complete

and their more powerful cousins, PCRE without embedded code, also not Turing-complete


(note: can be Turing complete)

see Chapter ? in Part ? Formal for the Chomsky hierarchy, which unifies sub-turing grammars and regular expressions and Turing-complete languages into a hierachy.



Selectors are predicates that match certain nodes in an HTML DOM.

adding :pred, where 'pred' is one of the defined primitive predicates (called 'pseudo-classes') to the end of a selector imposes a condition. You can add multiple :s; this is a boolean AND of those predicates.

Some pseudo-classes are quite expressive; consider :nth-child(3n + 1), which takes an arithmetical expression arguments, and :last-child.

You can combine multiple selectors with commas in between them; this is a boolean OR of those selectors.

There are a few selector 'combinators', such as +, which is a binary infix operator which takes two selectors as input and says 'match something that matches my right argument if it is immediately preceded by something that matches my left argument'.


The following example, from , assumes we have a 3-column grid; if the last row has only one item, it make that item fill the row; if the last column has two items, it makes them each fill half the row.

li:nth-child(3n + 1):last-child {
   float: none;
   width: auto;

li:nth-child(3n + 1):nth-last-child(2), 
li:nth-child(3n + 1):nth-last-child(2) + li {
   width: 50%;


"CSS, a language for specifying visual appearance on the web, is … so complex that it has never been implemented correctly; yet, successive versions specify even more complexity. At the same time, it is so underpowered that many elementary graphic designs are impossible or prohibitively difficult, and context-sensitivity (or anything computational) must be addressed externally. Most CSS lore is dedicated to describing the tangles of brittle hacks needed to circumvent incompatibilities or approximate a desired appearance." -- Bret Victor

"I’ve recently been looking at various client-side development technologies, in particular Elm. As a functional programming language, Elm isn’t terribly exciting, but something I enjoy about the language is that it provides a sane combinator library for describing layout, as opposed to the pile of hacks that is HTML+CSS and explicit DOM manipulation in Javascript. Elm’s author has stated that this is not a bug, it’s a feature. Elm provides the escape hatch if you need it, but it is entirely possible to use pure Elm for layout without giving a thought to the DOM.

Update: Elm now has a rather nice story for integrating with (and building new abstractions atop!) HTML/CSS. See the elm-html library.

As a result of this bold stance, there’s been some inevitable discussions on the Elm mailing list about how to use CSS in conjunction with Elm layout and graphics. But a separate stylesheet language is generally unnecessary when using a real language for describing layout, as you can use the normal means of abstraction and combination provided by the language to factor out whatever layout or styling decisions one wishes to be able to modify in a centralized place. CSS, you’ll recall, was yet another dubious web technology that sprung up to solve a short-term need, in the void of HTML having no means of abstraction. As it became more widely used, CSS accumulated lots of features, features which might have been regular libraries if CSS or HTML had any means of abstraction or combination. Seeing a pattern here? Means of abstraction and means of combination are important, and first-order hacks are no substitute for supporting these capabilities properly. ... It’s true that in using a language like Elm for layout, one loses the ability to cut and paste random CSS found on Stack Overflow in cargo-cult fashion without understanding what it does. I consider this limitation a feature. Layout code can and should be managed using the regular tools that programmers have developed for managing complexity and factoring out duplication. " -- Paul Chiusano

Best practices