Examples Here are some examples in lang5 with explanations: No TabsThrowing diceGenerating a list of primesMultiplying a matrix with a vectorMandelbrot setCantor Set : throw_dice # Define new word # Make a vector [6 6 6 ... 6] 6 over reshape # Throw dice 100 times, # retain integer part and # make sure result is # between 1 and 6: ? int 1 + # Sum over all results and # divide by the number of # values: '+ reduce swap / ; 100 throw_dice . The lang5 program shown on the left simulates a dice which is thrown 100 times. The results are then used to calculate the arithmetic mean. Using the array language features of lang5 this task can be readily solved without using a loop construction. The main idea is to create a vector containing 100 elements with a value of 6 each. This is done by applying the reshape function to the scalar 6 and the number of runs which should be performed. This yields a vector 6 6 6 .. 6. This vector is then used as argument for the dice operator ? which pulls this vector from the TOS and pushes a result vector containing 100 pseudo random values between 0 and 6 (exclusively). In the following the int operator is applied to this vector returning a vector with integer elements between 0 and 5. Adding 1 shifts these elements one up. To add all vector elements together, the operator + is pushed onto the stack and then the reduce operator is called. This operator applies an operator found at the TOS to the elements of a vector found below the TOS element in a way that this operator is written between all elements of this vector. The result is a scalar representing the sum of all vector elements which is then divided by the number of elements found in the vector yielding the desired arithmetic mean. The code example shown on the right generates a list of primes between 2 and 100 - this program is just a rewrite of a wellknown APL example. The idea is to create two vectors of the form 2 3 4 .. 100 and create an outer product yielding a matrix which contains all non primes in the interval (and more - this is far from being efficient but it is very elegant). This matrix is then used in conjunction with another vector of the first form to generate a selection vector containing values 0 and 1 depending on the result of the set operation in. This control vector is the used to select all primes from yet another copy of the first vector. : prime_list 1 - iota 2 + dup dup dup '* outer swap in not select ; 100 prime_list . # Overload * for matrix-vector-multiplication. : *(m,v) : inner+(*) '+ reduce ; # Calculate the inner sum of a vector: swap strip shape rot strip swap reshape * 'inner+ apply 'v dress ; [[1 2 3][4 5 6][7 8 9]](m) [10 11 12](v) * . In contrast to APL the built in multiplication operator does not naturally extend to multiplying matrices with vectors but this is not a problem at all since 5 allows one to "dress" data structures (mark them as being something special like complex numbers, matrices, quaternions etc.) and to overload operators, even built-ins, to behave differently on dressed data structures. In the example above, the built-in operator '* is overloaded as a binary operator which expects a matrix and a vector (denoted by the dress codes m and v respectively). This user defined word contains yet another user defined word, 'inner+, which is a unary operator working on any data. In a first step this overloaded multiplication operator strips its arguments from their dresses and applies the built-in multiplication operator after performing a reshape to form the necessary partial products. After that, 'inner+ is applied in a row-wise fashion to build the inner sums yielding the final product of the matrix-vector-multiplication. The last step consists of marking the resultant one dimensional array as a vector again by dressing it with 'v. This last example shows the calculation of a Mandelbrot set (a detailed description of this program can be found in the introduction.pdf which is delivered with the lang5-interpreter). The most noteworthy fact about this example is that it does not need any explicit loop at all. Everything, from the creation of a matrix of complex numbers, to the iteration algorithm applied to these numbers and the final print out, makes extensive use of the array capabilities of lang5 and the fact that its operators (built-ins as well as user defined ones) extend to nested data structures in a natural way. : d2c(*,*) 2 compress 'c dress ; # Make a complex number. : iterate(c) [0 0](c) "dup * over +" steps reshape execute ; : print_line(*) "#*+-. " "" split swap subscript "" join . "\n" . ; 75 iota 45 - 20 / # x coordinates 29 iota 14 - 10 / # y cordinates 'd2c outer # Make complex matrix. 10 'steps set # How many iterations? iterate abs int 5 min 'print_line apply # Compute & print Running this program yields the following output: # * ** ##* *##### +*####*- * *###############*#*#* #*################### * *#####################-* -##*###*..*####################### *################################# *################################### +*#*#*#***####################################* *################################### *################################# -##*###*..*####################### * *#####################-* #*################### *###############*#*#* +*####*- * *##### ##* * ** # A detailed discription of this program is given in the following video-clip (German only, sorry): Flash player not available. : cantor : iterate : r(*) " " over 3 compress "" join ; "" split r "" join ; 'iterate swap reshape '- swap execute ; 4 cantor . "\n" . This small example program generates a cantor set (cf. Wikipedia) by applying the well known rule of starting with a single character "-" and then applying the following substitution rule repeatedly: Take a character "c" and replace it by the three character string "c c". The substitution is done in the unary word "r(*)" which is a inner word of the word "iterate" which is itself an inner word of the word "cantor". "iterate" splits a string found on TOS into single characters and applies "r(*)" onto these characters (this is done automatically due to the fact that "r(*)" is a unary word and split returns a one dimensional array). The outmost word "cantor" creates an array of "iterate"-calls which are then executed and applied repeatedly to their respective output. Running this program yields the following output: - - - - - - - - - - - - - - - -