A sequence is a list (possibly infinite) which is accessed sequentially with the words:

  1. HEAD ( seq -- * )
    puts the first item from the sequence on the stack, and
  2. TAIL ( seq -- seq )
    puts the tail of the sequence (i.e., without the head) on stack.

There are many ways to create a sequence and they may be displayed using the word 
.LIST ( seq --  )
(of course, an infinite list gives a never-ending listing!)

For example, a sequence can be built "by hand". The word
puts an empty list on the stack. The word
CONS ( seq * -- seq )
adds a head to a sequence and requires two arguments; the first argument is the target sequence and the second argument (*) is the new head to be added:
		nil 0 cons 1 cons 2 cons .list
		2 1 0
A sequence of numbers can also be built using the word
... ( a b -- seq )
(be extra careful as this sequence is infinite by default!). It requires 2 arguments and the elements inside the sequence follow the arithmetic progression defined by them:
		1 2 ... .list
		1 2 3 4 5 6 (keeps on going!)
Or, a sequence can be built using both methods:
		1 3 ... "hello" cons .list
		hello 1 3 5 7 9 11 (keeps on going!)
Note that the previous sequence is mixed - it contains both numbers and a textual head. The word
accesses the head/first item on the list:
		1 2 ... head .
		1 ok
		nil 0 cons 1 cons 2 cons head .
		2 ok
The word
accesses the remainder of the list without its head:
		1 2 ... 10 take tail .list
		2 3 4 5 6 7 8 9 10
		nil 0 cons 1 cons 2 cons tail .list
		1 0
Now you can see clearly what the difference is between using
and using
to build sequences in terms of the head and tails.

The following words can also help you with sequences:

Truncating a Sequence

Many times, you may want to create a finite list but not "by hand". There are a couple of ways to do this.

The word 
TAKE ( seq n -- seq )
takes only the first N elements from a sequence:
		0 5 ... 10 take .list
		0 5 10 15 20 25 30 35 40 45
Alternatively, you can also use word
TAKE-WHILE ( seq xt -- seq )
uses an XT to determine if it should accept further elements from the input list. It truncates the list as soon as the XT returns
		: 100< 100 < ; 
		0 10 ... ' 100< take-while .list
		0 10 20 30 40 50 60 70 80 90

Lazy Nature of Infinite Sequences

In Smojo, all infinite sequences are lazy, which means it does not place every elements immediately onto the stack or anywhere in the program. 
	Instead, an object describing the infinite sequence is placed onto the stack. 
	Only when words such as 
needs to take the sequence as an argument, will the sequence be constructed, one element at a time.

Many sequence-related words like 
are also lazy. These words will not perform their tasks until they are forced to (e.g. by

This property of the laziness of infinite sequences and related words can make Smojo highly efficient when processing or transferring an extremely long data sequence or even an infinite sequence (e.g. data continuously collected by a sensor). Also, with laziness it is possible to represent an indefinite amount of data. Typically, we want to process only some, not all of this data.
	You should try using the word 
instead of
to print a sequence or the output of
to see what is actually on the stack.


Question 1

Write a word
.. ( s e -- seq )
which takes 2 numbers, start (s) and end (e) and produces a sequence of numbers from start to end, with skip of 1. For example:
		20 25 .. .list
		20 21 22 23 24 25 ok
What if start > end (i.e. a descending list)? Try to come up with 2 solutions; one that uses
and the other using
. Be reminded that
requires using an XT.

Question 2

Improve both your solutions to Question 1 so that your word
can take 3 numbers, start end and skip. For example:
		20 30 2 .. .list
		20 22 24 26 28 30 ok
What happens if the end value is not on the arithmetic progression?

Next: Hashes