Project

General

Profile

Actions

List in Scol

Lists are very common in Scol.
A list can be extended dynamically. Its use memory can increase and, in a long list, the accessing an element can take a "long" time.

A list is always a tuple with two element : the first element and the next of the list. This next is itself composed of the first element of this next and the next of the next ...


first element next
            first element next
                        first element next
                                    first element next
                                                nil

The last element is always nil : this is the end of our list.

Example : 0 1 2 3 4 5 6 7

0 next
    1 next
        2 next
            3 next
                4 next
                    5 next
                        6 next
                            7 nil

So, we get in Scol :

[0 next] with next is [1 next_2] with next_2 is [2 next_3] .... until [7 nil]

So, we get really in Scol :

[0 [1 [2 [3 [4 [5 [6 [7 nil]]]]]]]]

We can write the same exact list with this other manner :

0::1::2::3::4::5::6::7::nil

This is faster but the structure disappears.

hd <list> returns the first element (head)
tl <list> returns the next (tail)

What is the type of a list ?

Generally, the type of a list is [u0 r1], u0 for any type, simple or complex, r1 for the first level of recursivity. The second level, r2, exists, rarest. r3 ... rn are theoretical.

Example :

[I r1] : a list of integers
[[S F] r1] : a list of tuple, each tuple has two element, a string (F) and a float (F)
[[[[S I I] r1] I S] r1] : a list of tuples, each tuple has three elements : another list, an integer, a string.
[[S r1] r1] : a list of list of strings. We will meet often this when we parse a text : each line is a list of words, the text is a list of lines.

How get the Nth element ?

By a Scol function (standard api) :

nth_list <list> <position>


set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
set n = nth_list list 5;    // is 54

By writing a recursive function.

We find again the structure of a list :

fun getNelement (list, n)=
    if list == nil then
        nil    // the list is smaller then n
    else
        let list -> [first next] in
        if n == 0 then
            first
        else
            getNelement next n-1;;    // we continue with the next of the current list

fun main ()=
    _showconsole;
    set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    _fooId getNelement list 5;    // 54 is displayed
    0;;

Note : the list is unchanged before and after the threatment by getNelement !

How get the size of a list ?

By a Scol function (standard api) :

sizelist <list>

set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
set size = sizelist list;    // is 8

By writing a recursive function.

We find again the structure of a list :

fun getSizeList (list, n)=
    if list == nil then
        n    // we are at the end of the list (= nil)
    else
        getSizeList    tl list n+1;; // we continue with the next of the current list

fun main ()=
    _showconsole;
    set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    _fooId getSizeList list 0;    // 8 is displayed
    0;;

How set the Nth element ?

By writing a recursive function. We find again the structure of a list :

fun setNelement (list, position, value)=
    if list == nil then
        nil    // the list is smaller then n
    else
        if position == 0 then
            [value tl list] // or value :: (tl list), it is the same thing
        else
            [hd list setNelement tl list position-1 value];; // we continue with the next of the current list

fun main ()=
    _showconsole;
    set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    set list = setNelement list 5 100;    // [0 [10 [21 [32 [43 [100 [65 [76 nil]]]]]]]]
    0;;

How to get a sub list from a position ?

By writing a recursive function. We find again the structure of a list :

fun getSubList (list, position)=
    if list == nil then
        nil    // the list is smaller then n
    else
        if position == 0 then
            list
        else
            getSubList tl list position-1;; // we continue with the next of the current list

fun main ()=
    _showconsole;
    set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    set list = getSubList list 5;    // [54 [65 [76 nil]]]
    0;;

How to find the position of an element ?

By writing a recursive function. We find again the structure of a list :

fun findAnInteger (list, intToFind, position)= // all types except a string (S)
    if list == nil then
        nil    // not found
    else
        if intToFind == hd list then
            position
        else
            findAnInteger tl list intToFind position+1;; // we continue with the next of the current list

fun findAString (list, strToFind, position)= // type string (S) only
    if list == nil then
        nil    // not found
    else
        if (!strcmp strToFind hd list )then
            position
        else
            findAString tl list strToFind position+1;; // we continue with the next of the current list

fun main ()=
    _showconsole;
    set list = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    _fooId findAnInteger list 54 0;    // 5
    0;;

How compare two lists ?

By writing a recursive function. We find again the structure of a list :

fun cmpLists (listA, listB)=
    if ((listA == nil) && (listB == nil)) then // lists are ended, we return 1 (true)
        1
    else if (hd listA) == (hd listB) then    // First elements are equals, we continue with the next
        cmpLists tl listA tl listB
    else    // first elements ae differents, we stop and returns 0 (false)
        0;;

fun main ()=
    _showconsole;
    set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    set listB = [0 [10 [21 [32 [43 [54 [65 nil]]]]]]];
    _fooId cmpLists listA listB;    // 0, not equal
    0;;

To try it, copy this code :

- In tutorials/list.pkg :

typeof listA = [I r1];;
typeof listB = [I r1];;

fun getNelement (list, n)=
    if list == nil then
        nil    // the list is smaller then n
    else
        let list -> [first next] in
        if n == 0 then
            first
        else
            getNelement next n-1;;    // we continue with the next of the current list

fun mainGetNelement ()=
    _showconsole;
    set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    _fooId getNelement listA 5;    // 54 is displayed
    0;;

fun getSizeList (list, n)=
    if list == nil then
        n    // we are at the end of the list (= nil)
    else
        getSizeList    tl list n+1;; // we continue with the next of the current list

fun mainSizeList ()=
    _showconsole;
    set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    _fooId getSizeList listA 0;    // 8 is displayed
    0;;

fun setNelement (list, position, value)=
    if list == nil then
        nil    // the list is smaller then n
    else
        if position == 0 then
            [value tl list] // or value :: (tl list), it is the same thing
        else
            [hd list setNelement tl list position-1 value];; // we continue with the next of the current list

fun mainSetNelement ()=
    _showconsole;
    set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    set listA = setNelement listA 5 100;    // [0 [10 [21 [32 [43 [100 [65 [76 nil]]]]]]]]
    _fooIdList listA;
    0;;

fun getSubList (list, position)=
    if list == nil then
        nil    // the list is smaller then n
    else
        if position == 0 then
            list
        else
            getSubList tl list position-1;; // we continue with the next of the current list

fun mainSubList ()=
    _showconsole;
    set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    set listA = getSubList listA 5;    // [54 [65 [76 nil]]]
    _fooIdList listA;
    0;;

fun findAnInteger (list, intToFind, position)= // all types except a string (S)
    if list == nil then
        nil    // not found
    else
        if intToFind == hd list then
            position
        else
            findAnInteger tl list intToFind position+1;; // we continue with the next of the current list

fun findAString (list, strToFind, position)= // type string (S) only
    if list == nil then
        nil    // not found
    else
        if (!strcmp strToFind hd list )then
            position
        else
            findAString tl list strToFind position+1;; // we continue with the next of the current list

fun mainFind ()=
    _showconsole;
    set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    _fooId findAnInteger listA 54 0;    // 5
    0;;

fun cmpLists (listA, listB)=
    if ((listA == nil) && (listB == nil)) then // lists are ended, we return 1 (true)
        1
    else if (hd listA) == (hd listB) then    // First elements are equals, we continue with the next
        cmpLists tl listA tl listB
    else    // first elements ae differents, we stop and returns 0 (false)
        0;;

fun mainCmp ()=
    _showconsole;
    set listA = [0 [10 [21 [32 [43 [54 [65 [76 nil]]]]]]]];
    set listB = [0 [10 [21 [32 [43 [54 [65 nil]]]]]]];
    _fooId cmpLists listA listB;
    0;;

- In tutorials/list.scol :

_load "tutorials/list.pkg" 
mainGetNelement
mainSizeList
mainSetNelement
mainSubList
mainFind
mainCmp

Note :
In files "locked/lib/stdlib.pkg" et "locked/lib/_mlistlib.pkg", functions about lists are already coded. For use them, add the line _load "locked/lib/stdlib.pkg" and(or) the line _load "locked/lib/_mlistlib.pkg" in your launcher.

Other functions about list are availables in the Syspack library.

License : CC-BY-SA-2.0
Tutorial by iri
Updated by /

Updated by iri over 11 years ago · 2 revisions