User:Dcoetzee/Wikicode

From Wikipedia, the free encyclopedia


About 8 months ago now, I got the idea of creating a standard pseudocode for use across Wikipedia. As you can see from the talk pages, this idea was not welcomed by others, who variously thought:

  • Wikicode looks just like (random language), why not just use that?
  • We shouldn't invent our own pseudocode, we should use real languages only, because they can be run.
  • People should all be able to make up their own pseudocode however they like.
  • Wikicode is too detailed; pseudocode should only contain prose descriptions, not symbols.

I don't really agree with any of these points, and argued vociferously against them, but ultimately the community has the last say. I'll keep using something like it in my own editing, and I've archived the introduction and specification here for reference purposes, but as of now Wikicode is no longer proposed; only use it if you want to, and do not use the {{wikicode}} template at all.


Wikicode is a proposed standard for describing algorithms and other small code samples across Wikipedia in a way that is easy to read and edit. This page contains a concise tutorial and reference for the pseudocode. You may also wish to see its complete specification and discussion about it.

The point of the Wikicode proposal is to offer a generally applicable pseudocode so that articles trying to accomplish the same thing (describing algorithms) can have a similar appearance. However, this does not mean real source code should not be used, and if changing the pseudocode in some way is helpful in a particular article, feel free to do so. Wikicode does not restrict, only suggests. If you want to help add or convert pseudocode in existing articles to use wikicode, please see User:Dcoetzee/Wikicode/Pages needing conversion.

Introduction and motivation[edit]

Wikicode is a proposed standard way of writing pseudocode across Wikipedia. While Wikipedia certainly has plentiful examples of code in real programming languages, like C, Python, Java, and even ARM assembly language, in many cases the syntax and irrelevant details of such a language can get in the way of the main goal of clear exposition. A variety of pseudocodes have been used in various publications, but we had a unique goal that they don't: being Wikipedia, we also wanted our pseudocode to be as easy to edit as it is to read. Wikicode is a standard collaboratively developed by a number of computer science experts at Wikipedia to help address these goals, but if you feel dissatisfied about any aspect of it, we urge you to voice your complaints.

Basics[edit]

Wikicode is, primarily, an imperative language in the procedural programming paradigm. Functions are declared with the emboldened function keyword, and can call themselves and one another in a manner similar to that in C or Java. For example:

function isEven(int x) {
    if x = 0
        return true
    else if x < 0
        return isOdd(x+1)
    else return isOdd(x-1)
}
  
function isOdd(int x)
    if x = 0 then return false
    if x < 0 then return isEven(x+1)
    return isEven(x-1)

If any particular article requires you to make up functionality or change syntax, you're free to do so. However, anything you add should be explained in the text. Links are also allowed in wikicode, and braces are optional almost everywhere (indentation can be used instead).

Very importantly, right before the first conspicuous use of Wikicode on a page should be a link to this page, via the template {{wikicode}}. This allows readers to come here to learn about what the code means if they're confused.

Syntax[edit]

The HTML <pre> tag is not used; instead, each line is indented by at least two spaces, taking advantage of Wikipedia's automatic table formatting. Wikicode in the middle of text should use the <code></code> HTML tags. All keywords are typed in bold type, and comments and types are placed in italics. In some browsers, you may have to set your fixed-width or monospace font to a font like Courier to see bold correctly.

Variable declarations are optional in Wikicode, and performed with the var keyword, as in this example:

 var int a := 2, b, c, d := 5   // Lots of declarations

The optional type is int; a, b, c, and d are the names of new variables, with a initially set to 2 and d initially set to 5. The message at the end is a comment, and serves to describe, summarize, or explain. It is preceded by ''//, an italic marker followed by two slashes. Comments placed on their own lines also use this syntax:

 // This is a comment on its own line

Statements are simply listed one per line with no separator. A statement continuing over several lines should be indicated with additional indentation:

 x := 5
 y := z +
      w

For consistency, all multiword names begin with lowercase letters and use mixed-case, not underscores. For example, theEndOfTheWorld, rather than the_end_of_the_world or TheEndOfTheWorld.

Basic types[edit]

The types used in Wikicode are very unrealistic, but easy to understand and work with:

  • boolean: a boolean value, either true or false
  • int: an arbitrary-precision integer of either sign
  • real: an arbitrary real number
  • character: an arbitrary character
  • string: a string, or list, of characters; these can be written like "Hello"

Note that types can be omitted wherever they are either unnecessary, unknown, or unimportant; they are a device for increasing clarity.

Operators[edit]

The := operator is used for assignment. A number of other operators are also currently available, and you can always make up new operators as long as you explain it in the text:

Op Typed Description
^ ^ Exponentiate numeric values
×,÷ &times;,&divide; Multiply/divide numeric values
+,- +,- Add/subtract numeric values
=,<,>,≤,≥,≠ =,&lt;,>,&le;,&ge;,&ne; Comparison
in '''in''' Collection membership
not '''not''' Logical not
and,or '''and''','''or''' Logical and, or
additional operators as needed

Control flow constructs[edit]

All the familiar imperative control flow constructs are available, including:

  • if-else: a conditional used to perform one action if a condition is true or, optionally, another if it is false
  • while: used to repeat a sequence of actions as long as a condition holds
  • until: used to repeat a sequence of actions until a condition holds
  • do-while: repeats a loop at least once and then as long as a condition holds
  • for-from-to: repeats a sequence of actions for each integer in an integer range
  • for each-in: repeats a sequence of actions for each object in a container

With all control flow constructs, braces are optional but generally recommended if it includes many statements. Here's an example:

 if 1=0
     print "World is ending"
 else while 0=0 {
     print "This loop will never end. I guess I'll count:"
     for i from 1 to 10
         print i
     // This works too
     for each i in list(1,2,3,4,5,6,7,8,9,10)
         print i
 }

Composite types[edit]

There are also a number of composite types that can be built up from primitive types. They are only referred to by reference, and a reference can also have the value null. Don't worry about allocation or deallocation; it just happens. The composite types are:

  • record: Creates a new, possibly recursive, record type (struct or aggregate type). For example:
 record employee {
     string name
     int age
     employee supervisor
 }

Fields are accessed with dot (e.name), as in C or Java.

  • tagged union: Creates a tagged union, called a datatype in ML. Used to express a value that may be one of several, possibly recursive alternatives:
 tagged union tree {
     Leaf:
     Node:  tree left, tree right
 }

The only useful thing you can do with a tagged union is access one of its fields or match on its tag using the cases keyword:

 cases t {
    Leaf: // it's a leaf
          (do stuff)
    Node: // it's a node
          (do stuff with t.left and t.right)
 }

Lists and arrays[edit]

You can also have lists or arrays of objects, such as list(1, 2, 3) or array("Joe", "Harry"). Note that arrays are 1-based. Here are some examples of list and array use:

 var x := emptyList
 insert 2 at end of x
 insert 3 at end of x
 y := getFront(x)
 z := x[2]
 append list(y,z) to end of x   // Just made up this one
 for each i in x
     print i
 var int[1..j,1..k] a   // A j-by-k array of integers
 var int[,] b           // A two-dimensional array of integers
 a[2,3] := a[3,4] + 1
 for i from 1 to 10
     b[1,i] := i+1

Sets[edit]

Sets are used to store an unordered sequence of values, such as set(2,3,1). Here's an example:

 var s := emptySet
 insert(s, 5)
 insert(s, 2)
 insert(s, 7)
 remove(s, 5)
 print size(s)  // prints 2
 if 7 in s
     print "7 is in the set!"
 var y := extractElement(s)    // gets and removes an arbitrary element
 for each x in s
     print x + " is in the set!"

Maps[edit]

Maps are associative arrays, useful for looking up values based on keys. For example, you could create a map mapping a person's name to their age:

 m["John"] := 26
 var name := "Sara"
 m[name] := 19
 var sarasAge := m["Sara"]

A key which has not been assigned maps to unassigned, and you can retrieve the set of keys and the set of values with keys(m) and values(m).

See also[edit]