GolfScript Tutorial

basics

There are four types, integers, arrays, strings, and blocks. Strings are really just arrays of integers with a different output behavior. Blocks are basically strings except they typically represent code that is to be evaluated. Integers are arbitrary precision and arrays can be indexed from the back using negative numbers.

A GolfScript program can be thought of as a list of items. Items are pushed onto the stack, unless it is a variable and it's type happens to be a block, these can be thought of as operators, and they are executed instead.
1 1+
Has 3 items, "1", "1", "+". The ones push the number 1 onto the stack. The + is a built-in block defined to take the top two stack items, add them together, and push the result on the stack. There is nothing special about +, you could define it yourself:
{-1* -}:+;
-1 does not mean subtract then push a 1, it is treated as the same token "-1", it just pushes a negative one onto the stack, * pops two values, multiplies them and pushes the result. Finally the - does what you would expect. This code is placed in { }, creating a block of code, which is pushed onto the stack then assigned to + using the assignment (:) operator. Finally this block is removed from the stack using ;

For integers our new + operator will behave exactly like the original built-in one. However the old + also worked with arrays, strings, and even blocks. It would simply concatenate its two arguments together if they are not integers.
[1 2 3][4 5]+ -> [1 2 3 4 5]
{.}{*}+:square -> {. *}
The second example shows how to build a function "square" which squares a number, by concatenating two blocks, one which duplicates the top stack, and the other which multiplies.

coercion

[50]'23'+ -> "223" #50 is the ascii value of "2"
The operators + - ^ & | all use type coercion if their argument types do not match. You can think of the types as having a priority, the coercion will convert both arguments to the type with the highest priority. The order from smallest to largest in priority is: integer, array, string, block.

Here are all the different coercion behaviors.
 1[2]+ -> [1 2]
 1'2'+ -> "12"
 1{2}+ -> {1 2}
 [50]'3'+ -> "23"
 [50 'a']{3}+ -> {50 a 3}
 'asdf'{1234}+ -> {asdf 1234}
In all of these examples the arguments that gets converted is the first one, but the order does not actually matter. The only one of these which may seem strange is array being coerced to string, the other possibly desired behavior is to convert each element into a string. This can be accomplished as following:
 [50 51 52]' '* -> "50 51 52"
 [50 51 52]` -> "[50 51 52]"
In the first example * is used, but here it means join, this behavior is determined by the types. The second examples uses ` which is like ruby's .inspect method. It creates a string which displays the object in the same format as it could be written. It is what is used to show what the results are after -> in examples. It may also be of great use in debugging. If you get a result that is unclear, use ]` to grab elements in the stack then display it in a way that is unambiguous.

input and output

There is no explicit input command in GolfScript, instead when your script is executed, all input from stdin is read first and placed as a string onto the stack. To run a program you should do something like:
echo my input | ruby golfscript.rb my_script.gs
You don't have to pipe input in, but if you don't, it will not prompt for input, instead it will assume there is no input. There are explicit ways to output, but they are not really needed. When your script reaches the end. The contents of the stack are printed automatically.

control flow

Control flow is done by calling blocks like all other operations, the only difference is that these ops typically use blocks as their arguments. Built-ins include while, until, do, if, map (denoted using %), each (denoted using /), and fold (denoted using *). These will be demonstrated by showing different ways of implementing the factorial function. To see how a specific operator works, click on it as with any example code. Note, for any operator that deals with conditions, 0 [] "" {} are treated as false, everything else is true.
{ #method 1
	.
	{. 1- factorial*} {;1} if
}:factorial;
{ #method 2
	:x;
	0:i;
	1
	{i x<} {i 1+:i *} while
}:factorial;
{1+,1>{*}*}:factorial; 5 factorial -> 120 #method 3


pitfalls

Whitespace is not special, it actually behaves the same as any other undefined variable, which is nothing. You can set a space to some value and use it like any other variable. This has the potential to cause hard to track down errors if you accidently set it without knowing. For instance this code does not behave as you'd expect:
"darren": name;1 1+ -> 1 "darren1"darren
This is why you should always golf your code :)