Language

Sets data types

These data types are defined in /pliant/language/type/set/ source directory.

Lists

A list is an ordered set, with the following properties:

   •   

The order is defined at inserting items time (through inserting at head, or at tail, or before an existing element, or after an existing element)

   •   

Traveling is local, you can get the first or last one, then repeatedly the next or previous one.
On the other hand, you cannot access the 10th element at once.

In the following sample 'xxx' can be any type, and 'p' is a pointer to one of the elements in the list:

var List:Int l
var xxx e
var Pointer:xxx p
var Int i

Inserting and removing elements:

+= e # same as append
-= p # same as remove
p :> l append e # returned element is the new one
p :> l insert_before p e # if addressof:p=null then will be append at end of the list
p :> l insert_after p e # if addressof:p=null then will be inserted as the first element
p :> l remove p # returns a pointer to the next element

Traveling:

p :> l first
if exists:p
  console "list is not empty" eol
p :> l next p
p :> l last
p :> l previous p
i := l size # this is not efficient since the all list will be traveled

Higher level traveling:

each p l # Using 'each' will implicitly define 'p' local variable
  ...

is equivalent to:

var Pointer:xxx p :> l first
while exists:p
   ...
   p :> l next p

Arrays

An array is a set, with the following properties:

   •   

If the array has 'n' elements, each of them is assigned an index ranging from 0 to n-1

   •   

Direct access to any element is provided.

var Array:xxx a
var xxx e
var Int i
var Pointer:xxx p

Reading or changing the array size:

console a:size eol
a size := i
+= e # same as { a size += 1 ; a a:size-1 := e }

Accessing an element:

:> a i

Dictionaries

A dictionary is a an unordered set, with the following properties:

   •   

Each element is associated with a key at inserting time

   •   

All elements in the array can be traveled, unordered

   •   

The subset of all elements associated with a given key can be traveled efficiently, unordered

The last properties means that several elements can be associated with the same key.

var (Dictionary xxx yyy) d
var xxx k
var yyy e
var Pointer:yyy p
var Int i
var CBool c

High level methods:

p :> d k # returns a pointer to the first element associated with key 'k'. If it does not exist, it will be created/inserted automatically
p :> d k e # same, but if the element is to be created/inserted, then it will be associated with default value 'e'
undefine k # removes any value associated with key 'k'

The high level method:

p :> d k e

is equivalent to the low level sequence:

p :> d first k
if not exists:p
  p :> d insert k e

Inserting or removing elements:

p :> d insert k e
p :> d remove p # on return, 'p' will point the next element in the dictionary
d -= p # same as 'd remove p'

Traveling all elements:

p :> d first
if exists:p
  console "dictionary is not empty" eol
p :> d next p

Traveling the subset of elements associated with a given key:

p :> d first k
p :> d first k e # 'e' is a default value. If no element is associated with key 'k', then p will be set to map 'e'
p :> d next k p

Other informations:

k := d key p # retrieve the key associated with the current element
c := d exists k # same as 'exist:(d first k)'
i := d size # number of elements in the dictionary. This is efficient as opposed to lists.
resize i # set the hash table size. Don't use unless you know what you do since hash table size adjusting is automatic. FIXME: should be 'd hashsize := i'
# FIXME: 'd hashsize' should be added

Higher level traveling:

each p d # Using 'each' will implicitly define 'p' local variable
  ...

is equivalent to:

var Pointer:yyy p :> d first
while exists:p
   ...
   p :> d next p

It is also possible to scan elements in reversed order:

each p d reversed
  ...

Indices

An index is basically the same as a dictionary, but traveling is ordered according to the key associated with each element.

var (Index xxx yyy) d
var xxx k
var yyy e
var Pointer:yyy p
var Int i
var CBool c

Inserting or removing elements:

p :> d insert k e
p :> d remove p
d -= p # same as 'd remove p'

Traveling all elements:

p :> d first
p :> d next p
p :> d last
p :> d previous p

Traveling the subset of elements associated with a key interval:

p :> d from k # returns the first element associated to greater or equal to 'k' key
p :> d to k # returns the first element associated to a greater than 'k' key

Traveling the subset of elements associated with a given key value:

p :> d first k
p :> d first k e # 'e' is a default value. If no element is associated with key 'k', then 'p' will be set to map 'e'
p :> d next k p

p :> d k # same as 'd first k', but program will stop if there is no element associated with key 'k'

Other informations:

k := d key p # retrieve the key associated with the current element
c := d exists k # same as exist:(d first k)
i := d size # number of elements in the index.

'each' can be used on an index.

Pliant defines a second set of non generic sets data types that are defined only because needed to bootstrap Pliant compiler engine. Here they are:

Built in list

Data type 'List' is basically the same as 'List:Arrow'.
Also please notice that when traveling, you must not use 'exists:p' as the continue condition but rather 'p<>null'

var List l
var Address a
var Pointer:Arrow p

p :> l append a # a must be the address of a Pliant object, returned element is the new one
p :> l insert_before p a # if p=null then will be append at end of the list
p :> l insert_after p a # if p=null then will be inserted as the first element
p :> l remove p # returns a pointer to the next element

p :> l first
if p<>null # you must not use exists:p here
  console "list is not empty" eol
p :> l next p
p :> l last
p :> l previous p

Built in array

Data type 'Array' is basically the same as 'Array:Arrow'.

var Array a
var Int i
var Pointer:Arrow p
var Int i

i := a size
a size := i

p :> a i

Built in dictionaries

Data type 'Dictionary' is basically the same as '(Dictionary Str Arrow)'.
Also please notice that when traveling, you must not use 'exists:p' as the continue condition but rather 'p<>null'

var Dictionary d
var Str k
var Address a
var Pointer:Arrow p

Inserting or removing elements:

insert k true a
remove k a

When inserting, 'a' must be the address of a true Pliant object.
If the boolean is true, then the element will be inserted at the head of the subset of elements associated with the key. Otherwise it will be inserted at tail.
When removing, if 'a' is null so that all elements associated with key 'k' will be removed. If 'a' is not null, only elements associated with key k, and only this one will be removed.

Traveling the subset of elements associated with a given key:

p :> d first k
if p<>null
  console "dictionary contains an element associated with key " k eol
p :> d next k p

Other informations:

count # number of elements in the dictionary # FIXME: should be 'd size'
i := d hashsize # size of the hash table.
hashsize := i # set the hash table size. Don't use unless you know what you do since hash table size adjusting is automatic.
freeze # prevent the hash table size to be automatically adjusted when elements are inserted

Built in relations

A relation is a kind of hash associating two elements to a third one.
There are two things that makes it different from a dictionary:

   •   

the two elements are defined by their address, not their content.

   •   

the two elements are associated to a single third one, trying to associate to another one will just overwrite the first association.

var Relation r
var Address a1 a2 a
var Int i

Configuring:

flags := 1+2+4
console r:flags eol

When setting flags:
1 means that the the first element ('a1' in the following samples) will point to a true Pliant object, so that it's references count will be adjusted.
2 means that the the second element ('a2' in the following samples) will point to a true Pliant object, so that it's references count will be adjusted.
4 means that the third element ('a' in the following samples) will point to a true Pliant object, so that it's references count will be adjusted.
The default value for 'flags' is 1+2+4

Inserting or removing elements:

define a1 a2 a

There is a single operation since removing an association is performed through calling 'define' with 'a=null'

Testing:

a := r query a1 a2

Other informations:

count # number of elements in the dictionary # FIXME: should be 'r size'
i := r hashsize # size of the hash table.
hashsize := i # set the hash table size. Don't use unless you know what you do since hash table size adjusting is automatic.