Range Over Iterators in Scilab

Starting with version 1.23, the language has added support for iterators, which lets us range over pretty much anything!

Let’s look at the List type from the previous example again. In that example we had an AllElements method that returned a slice of all elements in the list. With iterators, we can do it better - as shown below.

Here is the code translated to Scilab:

clear

// Define list structure
function lst = List()
    lst.head = [];
    lst.tail = [];
endfunction

// Define element structure
function el = element(val)
    el.next = [];
    el.val = val;
endfunction

// Function to push an element into the list
function lst = Push(lst, val)
    if isempty(lst.tail) then
        lst.head = element(val);
        lst.tail = lst.head;
    else
        lst.tail.next = element(val);
        lst.tail = lst.tail.next;
    end
endfunction

// Function returning all elements as an iterator
function seq = All(lst)
    seq = function (yield)
        e = lst.head;
        while ~isempty(e)
            if ~yield(e.val) then
                return
            end
            e = e.next;
        end
    end;
endfunction

// Function generating Fibonacci numbers as an iterator
function seq = genFib()
    seq = function (yield)
        a = 1;
        b = 1;
        while %t
            if ~yield(a) then
                return
            end
            temp = a;
            a = b;
            b = temp + b;
        end
    end;
endfunction

// Main function to test the list and Fibonacci iterator
function main()
    lst = List();
    lst = Push(lst, 10);
    lst = Push(lst, 13);
    lst = Push(lst, 23);

    // Iterating over list elements
    All(lst)(function (e)
        disp(e);
        return %t;
    end);

    // Collecting all elements into an array (for display purposes)
    all = [];
    All(lst)(function (e)
        all = [all e];
        return %t;
    end);
    mprintf("all: [%s]\n", string(all));

    // Iterator over Fibonacci numbers
    genFib()(function (n)
        if n >= 10 then
            return %f;
        end
        disp(n);
        return %t;
    end);
endfunction

// Run the main function
main()

Explanation:

  • We create a List structure and an element structure for linked list implementation.
  • The Push function allows us to add elements to the list.
  • The All function returns an iterator (inside Scilab’s function) that uses a nested function to yield values.
  • The genFib function demonstrates creating a Fibonacci sequence generator that uses iteration.
  • The main function demonstrates using these capabilities, iterating over list elements and generating Fibonacci numbers.

The output of running this script in Scilab would resemble:

10
13
23
all: [10 13 23]
1
1
2
3
5
8