Factor

Implementation of programming language Factor

Main implementation of the language, developed and maintained by language author Slava Pestov.

Examples:

Hello, World!:

Example for versions Factor 0.94

The first line imports io dictionary (print word). The second line pushes the message string on the stack and then calls print which prints the top element of the stack.

USE: io 

"Hello, World!" print

Factorial:

Example for versions Factor 0.94

The first line lists the necessary dictionaries: formatting (printf), kernel (dup), math (arithmetical operators) and sequences (iota).

Next the definition of factorial word follows which replaces an integer n with its factorial on the top of the stack. To do this, it constructs an array of numbers from 0 to n — 1 (word iota) and folds it with 1 using quotation [ 1 + * ] (increment and multiply) and combinator reduce.

The main program constructs a list of numbers from 0 to 16 (iota again) and for each of them (combinator each) applies the quotation which calculates the factorial and outputs the result in required format.

Standard dictionary math.combinatorics contains word factorial defined exactly like this.

USING: formatting kernel math sequences ;
IN: factorial-example

: factorial ( n -- n! )
    iota 1 [ 1 + * ] reduce ;

17 iota
[ dup factorial "%d! = %d\n" printf ] each

Fibonacci numbers:

Example for versions Factor 0.94

This example shows recursive calculation of Fibonacci numbers.

Word fib calculates the n-th number: if the argument is not greater than 1, it stays on the stack as the return value, otherwise it is replaced with a sum of previous numbers. Word bi is a short-hand version of cleave combinator and allows to apply two quotations (in this case calls of fib for smaller arguments) to the same element of the stack (n).

USING: formatting kernel math sequences ;
IN: fibonacci-example

: fib ( n -- fib(n) )
    dup
    1 >
    [ [ 1 - fib ] [ 2 - fib ] bi + ]
    when ;

16 iota [ 1 + fib "%d, " printf ] each 
"...\n" printf

Factorial:

Example for versions Factor 0.94

This example uses a purely recursive approach to factorial calculation. Word factorial replaces n with n! on the stack with a side effect: it prints all values of factorial from 0 to n. After if combinator is applied, the stack holds values of n and n!. Words swap and over replace them with n!, n and n!; two latter values are used for printing, and the first one stays on the stack as a return value.

In the main part of the program we need to add drop to remove 16! from the stack, so that the effect of the program on the stack is ( -- ).

USING: formatting kernel math ;
IN: factorial-example

: factorial ( n -- n! )
    dup
    0 =
    [ 1 ]
    [ dup dup 1 - factorial * ]
    if
    swap over "%d! = %d\n" printf ;

16 factorial
drop

Quadratic equation:

Example for versions Factor 0.94

Word quadratic-equation takes coefficients of the equation as input and prints the solution while returning nothing. Note that this word is declared using token :: instead of : used in most cases; this means that within it lexically scoped variables can be used, in this case parameters a, b and c as well as local variables d, x0 and sd bound by :> operator. Such variables can be loaded on the stack using their names. Words and operators which process lexically scoped variables are available in dictionary locals.

Factor provides a built-in data type for complex numbers; whenever the discriminant is negative, its square root will be of type complex. In this case complex roots are printed using words real-part and imaginary-part which extract corresponding parts of a number.

readln reads a string from input stream (till the end of line), and string>number (from math.parser dictionary) converts a string to a floating-point number.

USING: formatting io kernel locals math math.functions math.parser ;
IN: quadratic-example

:: quadratic-equation ( a b c -- )
    a 0 =
    [ "Not a quadratic equation." printf ]
    [ b sq a c * 4 * - :> d 
      b neg a 2 * / :> x0
      d sqrt a 2 * / :> sd
      d 0 =
      [ x0 "x = %f\n" printf ]
      [ d 0 >
        [ x0 sd + x0 sd - "x1 = %f\nx2 = %f\n" printf ]
        [ x0 sd + [ real-part ] [ imaginary-part ] bi "x1 = (%f, %f)\n" printf
          x0 sd - [ real-part ] [ imaginary-part ] bi "x2 = (%f, %f)\n" printf ]
        if
      ]
      if
    ]
    if ;

readln string>number
readln string>number
readln string>number
quadratic-equation

CamelCase:

Example for versions Factor 0.94

This example uses regular expressions. Word re-split (from regexp) splits a string into an array of strings separated by matches to the given regular expression. After this map combinator applies word >title (from unicode.case) to each element of the resulting array, converting them to title case. Finally, join (from sequences) concatenates the strings into one using “” as a separator.

USING: kernel io regexp sequences unicode.case ;

readln R/ [^a-zA-Z]+/ re-split
[ >title ] map
"" join print

Factorial:

Example for versions Factor 0.94

This example uses a built-in word factorial defined in dictionary math.combinatorics.

USING: formatting kernel math.combinatorics sequences ;

17 iota [ dup factorial "%d! = %d\n" printf ] each