For version 0.7.0.
To top.  Up: ..Shapes


Nested namespaces

Core bindings
array cons fcons graph lexiographicSort list newArray nil nil? range sort span unlist walk

Summary of extensions
..Shapes..Data / seq-support

It is not entirely clear at the moment how this namespace should be organized. Currently, there is not too much in here, but the plan is to equip Shapes with a type system and object-oriented features in the future, and then it may be more natural to use types rather than namespaces for organization. So, take this as a notice of subject to change, and read on!
Sections:    Sequences    Arrays    Graphs    Miscellaneous


The empty list.
Type of elements in result.
car::§A cdr::[§Seq §A] [§Seq §A]
Similar to cons, but forces both arguments and always producing a [§Seq §A].
This function is typically called using it's infix syntax, ../syntax.html.
The internal representation of the result is more efficient than what is generally obtained with cons, even if the results are equal in type.
See also:cons
<> §Seq
Constructs a list of the arguments.
The value created when called with no arguments is recognized by nil?, and should be used as a null marker for §Seq.
See also:unlist array
::§Object §Boolean
Dynamic references:none
True if the argument is the empty §Seq.
::§Seq §Structure
Converts a list to a structure, being the inverse of list in the sense that
\ lst → ( list [] <>[unlist lst] )
is the identity for §Seq values, and
\ struct → [unlist ( list [] <>struct )]
is the identify for §Structure values without named parts.
Note how this function may be used to define a Scheme-like apply function:
apply: \ fun args → ( fun [] <>[unlist args] )
See also:list
Type of values to be sorted.
keys::[§Seq [§Array §Integerml]] values:void::( [§Seq §V] §Void ) [§Seq §V]
Lexiographic sorting of values according to the corresponding keys. If values is not provided, keys is used instead.
The lexiographic order puts smaller values before larger ones, and if one array is a prefix of another, the prefix goes before. The sorting is stable, that is, values associated with equal keys will follow the same order in the result as given in values.
By sorting based on arrays associated with values, rather than using a comparison function to compare the values directly, sorting will be much more efficient compared to sort.
It is an error if values is present but does not have the same number of elements as keys.
Lexiographic sorting
Lexiographic sorting. First sorting integer arrays in lexiographic order. Then sorting some string values by using the integer arrays as keys for sorting. Finally deriving new integer arrays from the string values in order to achieve alphabetical sorting.

Source: show/hide visit

stdout: show/hide
See also:sort
keys::[§Seq [§Array §Float]] values:void::( [§Seq §V] §Void ) [§Seq §V]
Similar to the previous case, but for keys being arrays of §Float values.
Type of values to be sorted.
values::[§Seq §V] precedes?::( ::§V ::§V  §Boolean ) [§Seq §V]
Sort values in increasing order according to a comparison function. The comparison function precedes? shall be a strict precedence test.
The sorting is stable, that is, values that compare equal (neither precedes the other) will follow the same order in the result as given in values.
The generality of using a comparison function comes at a performance penalty compared to the key-based sorting of lexiographicSort. Hence, it is recommended to use lexiographicSort for performance-critical tasks. Use sort when performance is not critical or deriving keys for lexiographic sorting is difficult or contreived.
Part of the performance penalty lies in the bookkeeping in terms of setting up all the continuations for a full blown continuation passing style algorithm. However, a worse problem may actually be that the Shapes compiler currenty does no garbage collection of function environments. This means that any program that does lots of functions calls has a problem, and sorting large amounts of data using a callback function clearly falls into this category.
To clarify how the precedes? test is applied, the following will sort the numbers in increasing order:
[sort [list '5 '4 '6 '3 '2 '7 '1 '9 '8] (<)]
See also:lexiographicSort


<> §Array
Constructs a vector of the arguments.
See also:unlist
This is a hot value.


Type of node values.
Type of edge values.
nodes:nil::[§Seq ( [§NodeData §N] §GraphKey )] edges:nil::[§Seq [§EdgeData §E]] directed:false::§Boolean undirected:false::§Boolean loops:false::§Boolean parallel:false::§Boolean partitions:void::( [§Seq §GraphKey] §Void ) ( [§Graph §N §E] (> directed?::§(not undirected) undirected?::§(not directed) mixed?::§(directed and undirected) loops?::§(loops) parallel?::§(parallel) <) )
Dynamic references:none
Functional construction of a graph.
The §Boolean arguments define the graph domain, and it is an error if edges contains edges that are inconsistent with the graph domain.
If partitions is present, each node must belong to one of the given partitions, and the graph will become a partitioned graph. If partitions is void, the graph will not be considered partitioned and nodes are not allowed to specify a partition.
Each node and edge in a graph can be identified by an index. For nodes, the indices correspond to the positions in nodes (starting from zero). For edges, however, the indices must not be assumed to have any particular relation to the order in edges.
The rather unwieldy type of this function states that if the §Boolean arguments can be evaluated at compile time, then the graph domain is encoded in the type of the result. If the §Boolean arguments are not evaluated at compile time, the type of the result is just [§Graph §N §E] with no information about the domain.
Type of node values.
Type of edge values.
edges::[§Seq [§Edge §N §E]] start:void::( [§Node §N §E] §Void ) end:void::( [§Node §N §E] §Void ) [§Walk §N §E]
Dynamic references:none
Construction of a walk in a graph.
In all but two special situations it is enough just to specify the edges, and the rest will be derived from the edges. The first exceptions is empty paths, when there are no edges to derive at which node the walk starts and ends. The second exception is walks consisting of a single undirected non-loop edge, where one cannot know which of the two nodes is the start and which is the end. However, when writing code that has to work for any length of the walk, there is clearly a need to specify either start or end. Providing both start and end adds redundancy that might help detecting errors.
Note that the arguments are not §NodeData and §EdgeData values, but nodes and edges of an existing graph. It is an error if not all nodes and edges belong to the same graph.
It is an error if start is not incident to the first edge, if end is not incident to the last edge, or if it is not possible to trace the sequence of edges. If there are no edges, start and end must coincide.


Type of car field in result.
Type of cdr field in result.
car::§A cdr::§D [§ConsPair §A §D]
Constructs a cons pair. The arguments are not forced, which allows infinite data structures to be defined.
Explicit forcing of the arguments (see ../syntax.html) may improve performance when there is no point to have evaluation delayed. Also consider using fcons instead of cons.
Note that if §D is [§Seq §A], then the result will also be a [§Seq §A]. However, having the type [§Seq §A] is not the same as being as efficiently represented internally as if constructed with fcons.
See also:fcons
begin::§Integer end::§Integer step::§Integer count::§Integer §Seq
Constructs a range of §Integer values. One of the arguments must be omitted, and it is forbidden to provide begin, end, and count at the same time. It is allowed to omit both step and count, in which case step defaults to (a positive) 1.
See the §Float case for the semantics of the various argument combinations, and notes on efficiency.
begin::§Float end::§Float step::§Float count::§Integer §Seq
Constructs a range of §Float values. One of the arguments must be omitted. It is allowed to omit both step and count, in which case step defaults to (a positive) 1.
If step is provided, it determines the step length. If count is provided, it determines the number of elements in the constructed range, which will begin at begin if begin is provided, and end at end if end is provided (note that achieving this using step may be inconvenient or even difficult due to problems with numeric precision). If neither step nor count is provided, step defaults to 1.
When both begin and end are provided, the range starts at begin, and ends at a value with is not past end. This is not like in c++, where end refers to a point in a range which itself is past the end of the range.
Note on efficiency: The result is constructed in constant time and space, and is particularly efficient for left folds. Semantically, it is as if the whole range was stored element by element in a long list, but the kernel just stores the first element, the step, and the total number of elements. During a left fold, at two values in the range are stored in memory at the same time. A right fold, on the other hand, will require all elements to be constructed before they can be destructed again. Hence, when possible, right folds should be avoided in favor of left folds over a range constructed with elements in the reverse order.
begin::§Length end::§Length step::§Length count::§Integer §Seq
Constructs a range of §Length values. One of the arguments must be omitted, and it is forbidden to omit both step and count.
See the §Float case for the semantics of the various argument combinations, and notes on efficiency.
Range construction

Source: show/hide visit

stdout: show/hide
begin end step count §Span
Calling span is like calling range, except that the arguments may use the special last-expr expression to refer to the last position in a container. Since the container will generally not be known at the time of the call, the arguments are not evaluated immediately, but stored as thunks inside §Span value.
Since a span should be used to select ranges of valid container positions, there are more defaults available when calling span compared to range. For instance, a span including all but the first two positions in a container can be constructed as
[span begin:'2]
and a span including all but the last two positions as
[span end:%last-'2]
Note that a §Span value is not automatically expanded to §Seq whenever a §Seq is expected, so it is up to the methods of the container types to accept §Span values and expand them.
See also:range §String
Get Shapes at Fast, secure and Free Open Source software downloads