Library Name:  (visualscheme data linq)


Language INtegrated Query (“LINQ”) is a popular feature of languages on the Common Language Runtime (“CLR”), intended to generalize querying of arbitrary collections with syntax familiar to SQL developers. On languages that do not feature Lisp’s homoiconic syntax, LINQ needs to be implemented by the compiler vendors, and developers must wait for bug fixes and new versions to extend LINQ functionality. But languages in the Lisp tradition, such as Scheme and IronScheme, were designed to allow developers to add their own novel syntax to the language itself.


The (visualscheme data linq) library wraps the (ironscheme linq) library and adds an additional (define-enumerable …) form to convert .NET IEnumerable instances into Scheme-compatible iterators.


Scheme iterators defined in (ironscheme linq) have nothing to do with LINQ as implemented in C# or VB.NET, except for behaving according to the C# specification for LINQ. It is 100% Scheme and not dependent at all on any specific CLR implementation of LINQ. 


For this reason, we found it necessary to create an adapter from .NET to Scheme iterators defined in (ironscheme linq) that understands the core IEnumerable and IEnumerator interfaces, on which LINQ implementations in C# and VB.NET also rely. This is exactly what the (define-enumerable …) form does.



Form Name:  define-enumerable


Signature

(define-enumerable <enumerable-name> 

   <enumerable-instance-function> [as <typecast-type>])

Exported From

(visualscheme data linq)

Type of Form

Syntax extension (macro)

Description

(define-enumerable …) creates a standard Scheme iterator for a .NET collection that implements IEnumerableIEnumerable implementations have a GetEnumerator() function that returns an IEnumerator instance suitable for that collection, allowing an iterator to be advanced, the current element in an iterator to be obtained, and for the entire iterator to be reset.


Formal Parameters


Parameter

Description

<enumerable-name>

The name given to the resulting form, representing a .NET iterator generator.

<enumerable-instance-function>

The lambda or case-lambda expression used to create a fresh instance of the enumerable collection for which the iterator is being created.

<typecast-type>

The specific type to cast the IEnumerable instance to, when necessary for correct iterator semantics.


Examples


(define-enumerable reader/records
   ;; The simplest enumerable function is one that 

   ;; merely returns an object implementing IEnumerable
   (lambda (reader) reader) as DbDataReader)


(define-enumerable graph/triples
  (case-lambda
   [()
    (clr-prop-get Graph Triples (current-graph))]

   [(graph)
    (begin
      (if (or (null? graph)
              (not (graph? graph)))
          (error "graph must be a non-null instance of Graph.")
          (if (not (eq? graph (current-graph)))
              (current-graph graph)))
      (clr-prop-get Graph Triples graph))]) as TreeIndexedTripleCollection)


Remarks

In the simplest case, the (define-enumerable …) macro takes a simple lambda form that returns the parameter it was passed, which must be a CLR type implementing IEnumerable. The GetEnumerator() function is invoked on it immediately to obtain the IEnumerator instance wrapped by the macro in a canonical Scheme iterator. 


A more complicated example is when some global state, usually during development in a REPL, such as a tracked “current'' instance of something, obviates the need for passing the expression a specific enumerable instance; in this case a (case-lambda ..) expression can deal with invocation of the enumerable with zero parameters. In the second example above, the (visualscheme data rdf core) library provides a concept of the “current” graph, important to minimize typing REPL contexts, and so invoking the enumerable value without any parameters will essentially use (current-graph) as the enumerable instance in the second case clause. In other words, developers can provide a specific graph instance from which to obtain the enumerator, or, absent that, it will simply use the (current-graph) instance.


Like the .NET IEnumerator interface, which IEnumerable collections return via GetEnumerator(), Scheme iterators also are defined by three functions—a function to advance the iterator, a function to get the current item in the collection being iterated, and a function to reset the iterator. That made the implementation of the adapter somewhat simpler. This last function—reset—is a bit problematic, however, when dealing with .NET objects implementing the IEnumerator interface, because as a matter of experience they are notoriously non-regular, as what exactly “resetting” an iterator means was sadly left unspecified in the interface at the time Microsoft defined it. 


One may occasionally encounter an IEnumerator instance that does what is expected, but only trial and error will reveal if the object “behaves.” The approach taken by (define-enumerable …) therefore is just to start all over with a fresh instance of the enumerable that generates the enumerator, when possible. Whether this is possible or not, depends once again how the implementer interpreted the interface requirements. Some do give you a fresh enumerator, and some return an already-existing one. 


It is often helpful to specify a specific class type to cast the enumerator generated by the enumerable to, rather than rely on the generic IEnumerator interface to pick the “right” dispatch method, so this is an option using the optional “as <typecast-type>” clause.

The value returned by invocation of the enumerable form is ready now to be used in LINQ expressions.


(foreach t in (graph/triples (current-graph))
   (display t)
   (newline))

LINQ expressions can be quite complex but essentially they allow you to filter and possibly combine multiple iterators to obtain or construct a meaningful subset (or superset) of data from all available data in the collection (or collections being combined). Note in the example above, we are calling the (current-graph) parameter and passing that into (graph/triples …), but we could have left it out, as the case-lambda expression used to define the enumerable would use (current-graph) by default, in the absence of a specific instance being passed into it.


The big advantage of using LINQ expressions is that they make explicit what might be hidden or implicit in “object oriented” wrappers of database entities. The famed “impedance mismatch” problem of object-relational mappers is bypassed altogether when using iterators with the declarative syntax of LINQ. While conversion to/from forms that are convenient for use in the programming language are inevitable, they need not be obscured by layers of object hierarchies that make what is going on less apparent, for the sake of creating the illusion that database entities are domain objects. They aren’t, so anything creating the illusion that they are is just overhead.



Form Name:  iterator?


Signature

(iterator? <object>)

Exported From

(visualscheme data linq)

Type of Form

Function

Description

Returns #t if the <object> passed in is an iterator; otherwise it returns #f.


Formal Parameters


Parameter

Description

<object>

A Scheme value that may or may not be an instance of an iterator.


Examples


(iterator? (graph/triples))
=> #t
(iterator? '(1 2 3))
=> #f


Remarks

Used as a guard to ensure that some passed-in object is an iterator before trying to use it in a LINQ expression.



Form Name:  make-iterator


Signature

(make-iterator <move-next-function> <get-current-function> <reset-function>)

Exported From

(visualscheme data linq)

Type of Form

Function (constructor of iterators)

Description

Creates a new iterator suitable for use in LINQ expressions.




Formal Parameters


Parameter

Description

<move-next-function>

A function or lambda expression that performs the “move next” operation on the iterator.

<get-current-function>

A function or lambda expression that performs the “get current” operation on the iterator.

<reset-function>

A function or lambda expression that performs the “reset” operation on the iterator.


Examples

The (define-enumerable …) macro uses (make-iterator …) to implement the adapter to .NET IEnumerable collections:


(define-syntax define-enumerable
  (lambda (x)
    (syntax-case x (as)

      ((_ enum-name enum-fn)
       #'(define-enumerable enum-name enum-fn as IEnumerable))

      ((_ enum-name enum-fn as enum-type)
       #'(define enum-name
           (case-lambda
            [()
             (let ((iter (enum-fn)))
               (make-iterator
                (lambda ()
                  (unless iter
                    (set! iter
                          (clr-call enum-type GetEnumerator (enum-fn))))
                  (clr-call IEnumerator MoveNext iter))
                (lambda ()
                  (clr-prop-get IEnumerator Current iter))
                (lambda ()
                  (set! iter
                        (clr-call enum-type
                                  GetEnumerator (enum-fn))))))]
            [(obj)
             (let ((iter (enum-fn obj)))
               (make-iterator
                (lambda ()
                  (unless iter
                    (set! iter
                          (clr-call enum-type GetEnumerator (enum-fn obj))))
                  (clr-call IEnumerator MoveNext iter))
                (lambda ()
                  (clr-prop-get IEnumerator Current iter))
                (lambda ()
                  (set! iter
                        (clr-call enum-type
                                  GetEnumerator (enum-fn obj))))))]))))))


Remarks

(make-iterator …) is a constructor created by the definition of the iterator record type in (ironscheme linq):


  (define-record-type iterator 
    (opaque #t
    (fields move-next 
            current 
            reset))  



Form Name:  get-iterator


Signature

(get-iterator <object>)

Exported From

(visualscheme data linq)

Type of Form

Function

Description

If the <object> passed has an iterator defined, then an iterator for that kind of object is returned. Supported iterator types are: grouping, lists, vectors, strings and hashtables. If the object passed in is already an iterator, it is simply returned. Otherwise, an assertion violation is raised.


Formal Parameters


Parameter

Description

<object>

A Scheme value that may or may not have an iterator defined for it.


Examples


(get-iterator '(1 2 3)) 

;; => #<clr-type record.ed4e466f-5a59-40d8-b1d4-5d2eaca4c628.iterator>


Remarks

(get-iterator …) is unaware of types for which you may have created an iterator. To overcome this, you can do something like this:


(define my-get-iterator
  (lambda (obj)
    (cond
      [(clr-is DbDataReader obj) (reader/records obj)]
      [(clr-is Graph obj) (graph/all-triples obj)]
      [else (get-iterator obj)])))


Note that our example uses the iterator adapters returned from our (define-enumerable …) form but you can create your own iterators. The key point is, if there is an iterator for a type not otherwise specified by (get-iterator …) you simply need to wrap calling (get-iterator) in the else clause of your custom get-iterator implementation.



Form Name:  trace-iterator


Signature

(trace-iterator <name> <iterator>)

Exported From

(visualscheme data linq)

Type of Form

Function 

Description

Wraps the passed-in iterator instance in a new iterator that displays state information about the current element when it is requested.


Formal Parameters


Parameter

Description

<name>

A string to be displayed to indicate meaningful information when displaying the current element.

<iterator>

The iterator to wrap with the returned trace-iterator.


Examples


> (define chatty-list (trace-iterator "chatty-list" (get-iterator '(1 2 3 4))))
> (foreach item in chatty-list
.    (display item)
.    (newline))
chatty-list -> 1
1
chatty-list -> 2
2
chatty-list -> 3
3
chatty-list -> 4
4
>



Remarks

Wrapping an existing iterator in a trace-iterator is possibly useful for debugging, but definitely not for production use. Professional logging techniques are recommended for production systems.



Form Name:  iterator->list


Signature

(iterator->list <iterator>)

Exported From

(visualscheme data linq)

Type of Form

Function

Description

Converts an iterator to a proper list.


Formal Parameters


Parameter

Description

<iterator>

The iterator to be converted into a proper list.


Examples


> (define it (get-iterator '(1 2 3 4)))
> it
#<clr-type record.ed4e466f-5a59-40d8-b1d4-5d2eaca4c628.iterator>
> (iterator->list it)
(1 2 3 4)
>


Remarks


Useful when returning a value from a function that uses LINQ to filter a collection. Most Scheme consumers will want a list or a vector of the results.



Form Name:  iterator->vector


Signature

(iterator->vector <iterator>)

Exported From

(visualscheme data linq)

Type of Form

Function

Description

Converts an iterator to a vector.


Formal Parameters


Parameter

Description

<iterator>

The iterator to be converted into a vector.


Examples


> (define it (get-iterator '(1 2 3 4)))
> it
#<clr-type record.ed4e466f-5a59-40d8-b1d4-5d2eaca4c628.iterator>
> (iterator->vector it)
#(1 2 3 4)
>


Remarks


Useful when returning a value from a function that uses LINQ to filter a collection. Most Scheme consumers will want a list or a vector of the results.



Form Name:  iterator->string


Signature

(iterator->string <char-iterator>)

Exported From

(visualscheme data linq)

Type of Form

Function

Description

Given an iterator of chars, returns a string.


Formal Parameters


Parameter

Description

<chariterator>

The iterator of chars to be converted into a string.


Examples


> (define chars (get-iterator '(#\f #\o #\o)))
> chars
#<clr-type record.ed4e466f-5a59-40d8-b1d4-5d2eaca4c628.iterator>
> (iterator->string chars)
"foo"
>


Remarks

Useful when converting results of queries on character iterators.



Form Name:  iterator->hashtable


Signature

(iterator->hashtable <iterator> [<selector-function>])

Exported From

(visualscheme data linq)

Type of Form

Function

Description

Given a hashtable iterator, returns a copy of the underlying hashtable.


Formal Parameters


Parameter

Description

<iterator>

The hashtable iterator from which we wish to extract a copy of the underlying hashtable.

<selector-function>

[Optional] A function to obtain the key/value pair when iterating the entries in a hashtable. If not provided a simple default selector is used.


Examples


> (import (visualscheme data linq))
> (compile)
> (define ht (make-hashtable string-hash string=?))
> (hashtable-set! ht "Fee" 1)
> (hashtable-set! ht "Fi" 2)
> (hashtable-set! ht "Fo" 3)
> (hashtable-set! ht "Fum" 4)
> (define hti (get-iterator ht))
> (define (hashtable-entry->tuple entry)
.   (values (car entry) (cdr entry)))
> (define ht-copy (iterator->hashtable hti hashtable-entry->tuple))
> (hashtable-ref ht-copy "Fum" 0)
4
>


Remarks

Obtaining a copy of the underlying data structure when that structure is a hashtable requires a way to iterate each key value pair and add them to a new hashtable copy. The example (hashtable-entry->tuple) function to select the key-value pair values does exactly this. Indeed, this is the default implementation we provide, so ordinarily you won’t need to provide this optional <selector> parameter unless, based on the data you stored in the original keys, you need more exotic processing of the key-value pair, for example: you want the new hashtable to be something other than an exact copy.



Form Name:  iterator-move-next


Signature

(iterator-move-next <iterator>)

Exported From

(visualscheme data linq)

Type of Form

Function

Description

Given an iterator, it attempts to move to the “next” item in the underlying data structure, if one exists.


Formal Parameters


Parameter

Description

<iterator>

The iterator whose next item we seek to move to.


Examples


> (iterator-reset hti)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fee" . 1)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fo" . 3)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fi" . 2)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fum" . 4)
> (iterator-move-next hti)
#f
>


Remarks


The iterator-* functions tend to be used together. The (iterator-move-next <iterator>) function will advance to the “next” item, and return #t if successful, #f if there are no more items left to iterate.



Form Name:  iterator-current


Signature

(iterator-current <iterator>)

Exported From

(visualscheme data linq)

Type of Form

function

Description

Returns the current item in the underlying data structure being iterated, if any.

Formal Parameters


Parameter

Description

<iterator>

The iterator whose next item we seek to move to.


Examples


> (iterator-reset hti)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fee" . 1)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fo" . 3)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fi" . 2)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fum" . 4)
> (iterator-move-next hti)
#f
>


Remarks

The iterator-* functions tend to be used together. (iterator-current <iterator>) will return the current value after the most recent call to (iterator-move-next <iterator>).



Form Name:  iterator-reset


Signature

(iterator-reset <iterator>)

Exported From

(visualscheme data linq)

Type of Form

Procedure with a side effect

Description

If successful, it repositions the iterator at the beginning of the underlying data structure. Note, not all iterator types support this function in the same way, especially if the underlying iterator is a .NET collection.


Formal Parameters


Parameter

Description

<iterator>

The iterator we seek to reset or otherwise position at the beginning of the underlying data structure. 


Examples


> (iterator-reset hti)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fee" . 1)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fo" . 3)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fi" . 2)
> (iterator-move-next hti)
#t
> (iterator-current hti)
("Fum" . 4)
> (iterator-move-next hti)
#f
>


Remarks


The iterator-* functions tend to be used together. (iterator-reset <iterator>) restores the iterator to the initial position so the underlying collection can be iterated again. It doesn’t work as expected for all iterator types, especially those based on .NET collections, which are notoriously inconsistent in their interpretation of/support for resetting iterators.



Form Name:  select


Signature

(select <x> <selector>)

Exported From

(visualscheme data linq)

Type of Form

Function and keyword

Description

You are unlikely (not to say discouraged) to use this function directly. It’s part of the domain-specific language we call “LINQ” and is intended for internal use in syntax extensions that comprise the iterator framework.


Remarks

Use select as a keyword in LINQ queries but not directly.



Form Name:  select-many


Signature

(select-many <x> <selector>)

Exported From

(visualscheme data linq)

Type of Form

Function and keyword

Description

You are unlikely (not to say discouraged) to use this function directly. It’s part of the domain-specific language we call “LINQ” and is intended for internal use in syntax extensions that comprise the iterator framework.


Remarks

Use select-many as a keyword in LINQ queries but not directly



Form Name:  where


Signature

(where <x> <proc>)

Exported From

(visualscheme data linq)

Type of Form

Function and keyword

Description

You are unlikely (not to say discouraged) to use this function directly. It’s part of the domain-specific language we call “LINQ” and is intended for internal use in syntax extensions that comprise the iterator framework.

Remarks

Use where as a keyword in LINQ queries but not directly.



Form Name:  reverse-iterator


Signature

(reverse-iterator <iterator>)

Exported From

(visualscheme data linq)

Type of Form

function

Description

Obtains a copy of the underlying data structure of the provided <iterator>, reverses its order, and then wraps it in a new iterator.



Formal Parameters


Parameter

Description

<iterator>

The iterator or iterable collection, the order of which you wish to reverse.


Examples


> (define lst '(1 2 3 4))
> (define lst-iter (get-iterator lst))
> (define reverse-lst-iter (reverse-iterator lst-iter))
> (foreach i in reverse-lst-iter
.   (display i)
.   (newline))
4
3
2
1
>


Remarks


If you have access to the original collection, you can of course call the appropriate flavor of (reverse! …) on it, and then call (get-iterator …) on the result of that; but if you have the iterator for the list, (reverse-iterator …) will save you a couple extra steps.



Form Name:  single


Signature

(single <iterator>)

Exported From

(visualscheme data linq)

Type of Form

Function

Description

If the <iterator> contains exactly one element, returns that element; otherwise throws an assertion violation.



Formal Parameters


Parameter

Description

<iterator>

The iterator on or iterable collection which the predicate is being invoked.



Examples


> (single '(1))
1
> (single '())
Unhandled exception during evaluation:
&assertion
&who: single
&message: "contains no elements"
&irritants: (#<clr-type record.9b26080c-35ae-48e7-8667-5540ece81d23.iterator>)

> (single '(1 2 3 4))
Unhandled exception during evaluation:
&assertion
&who: single
&message: "contains more than one element"
&irritants: (#<clr-type record.9b26080c-35ae-48e7-8667-5540ece81d23.iterator>)

>


Remarks

This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.



Form Name:  single/default


Signature

(single/default <iterator> <default-value>)

Exported From

(visualscheme data linq)

Type of Form

Function

Description

Similar to (single <iterator>) except returns the default value if the iterator is empty. Otherwise, it throws an assertion violation.


Formal Parameters


Parameter

Description

<iterator>

The iterator or iterable collection on which the predicate is being invoked.


Examples


> (single/default '() 0)
0
> (single/default '(10)
1
> (single/default '(1 2 3 40)
Unhandled exception during evaluation:
&assertion
&who: single/default
&message: "contains more than one element"
&irritants: (#<clr-type record.9b26080c-35ae-48e7-8667-5540ece81d23.iterator>)

>


Remarks

This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.



Form Name:  first


Signature

(first <iterator>)

Exported From

(visualscheme data linq)

Type of Form

function

Description

Returns the first element of the passed-in iterator. Throws assertion violation if iterator is empty.


Formal Parameters


Parameter

Description

<iterator>

The iterator or iterable collection whose first element you seek.


Examples


> (first '(1 2 3 4))
1
> (first '())
Unhandled exception during evaluation:
&assertion
&who: first
&message: "contains no elements"
&irritants: (#<clr-type record.9b26080c-35ae-48e7-8667-5540ece81d23.iterator>)

>


Remarks

This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.



Form Name:  first/default


Signature

(first/default <iterator> <default-value>)

Exported From

(visualscheme data linq)

Type of Form

function

Description

Returns the first value of the passed-in <iterator>, or the desired <default-value> when it’s empty.


Formal Parameters


Parameter

Description

<iterator>

The iterator or iterable collection whose first value you seek.

<default-value>

The default value to return if the iterator is empty.


Examples


> (first/default '(1 2 3 40)
1
> (first/default '() 0)
0
>


Remarks

This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.



Form Name:  last


Signature

(last <iterator>)

Exported From

(visualscheme data linq)

Type of Form

function

Description

Returns the last element of the passed in <iterator>. Throws an assertion violation if the iterator is empty.


Formal Parameters


Parameter

Description

<iterator>

The iterator or iterable collection whose last element you seek.


Examples


> (last '(1 2 3 4))
4
> (last '())
Unhandled exception during evaluation:
&assertion
&who: last
&message: "contains no elements"
&irritants: (())

>


Remarks

This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.



Form Name:  last/default


Signature

(last/default <iterator> <default-value>)

Exported From

(visualscheme data linq)

Type of Form

function

Description

Similar to (last …) except returns the provided default value if the iterator is empty.

Formal Parameters


Parameter

Description

<iterator>

The iterator or iterable collection whose last element you seek.

<default-value>

The default value to return if the iterator is empty.


Examples


> (last/default '(1 2 3 40)
4
> (last/default '() 0)
0
>


Remarks

This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.



Form Name:  element-at


Signature

(element-at <iterator> <index>)

Exported From

(visualscheme data linq)

Type of Form

function

Description

Returns the element from the iterator or iterable collection provided, or an error if the index is out of range.


Formal Parameters


Parameter

Description

<iterator>

The iterator or iterable collection whose value at <index> n is desired.

<index>

The base-0 index at which position the desired element is found.


Examples


> (element-at '(1 2 3 42)
3
> (element-at '() 2)
Unhandled exception during evaluation:
&assertion
&who: element-at
&message: "index out of range"
&irritants: (() 2)



Remarks

This is another function used internally in LINQ but which may be useful. For examples of practical LINQ usage, see Practical LINQ Examples.



Form Name:  foreach


Signature

(foreach <var> in <iterator> body …)

Exported From

(visualscheme data linq)

Type of Form

Syntax extension

Description

Similar to foreach semantics in C#. This syntax extension allows you to step eagerly element by element through an iterator or iterable collection and perform some action on the “current” element.


Formal Parameters


Parameter

Description

<var>

The name to give to the current element of the <iterator> to be used in the <body> of the expression.

<iterator>

The iterator (or iterable collection) through which one intends to operate on each element one at a time, eagerly. Note, this can be an iterator result from complex linq query expressions. Note also that when working with an iterable collection, an iterator will be created behind the scenes. 

body

The block representing the expression to evaluate with each step through the iterator/iterable collection.


Examples


> (define ht (make-hashtable string-hash string=?))
> (hashtable-set! ht "Foo" "bar")
> (hashtable-set! ht "Baz" "qux")
> (foreach entry in ht
.   (display (string-append (car entry) " => " (cdr entry)))
.   (newline))
Foo => bar
Baz => qux
> (foreach i in '(1 2 3 4)
.   (display i)
.   (newline))
1
2
3
4
>


Remarks

Similar to the built-in (for-each <fn> <list>) except it works with any iterable collection as supported in (visualscheme data linq). Compare:



> (for-each (lambda (entry)
.             (display entry)
.             (newline))
.           '(1 2 3 4))
1
2
3
4
> (for-each (lambda (entry)
.             (display (string-append (car entry) " => " (cdr entry)))
.             (newline))
.           ht)
Unhandled exception during evaluation:
&assertion
&who: "car"
&message: "not a pair"
&irritants: (#<hashtable>)

>


Not only is (foreach …) syntax nicer and more flexible, it is also more broadly applicable. (for-each …) requires a lambda expression, and only accepts a list for input.



Additional Available (visualscheme data linq) Functions


The following list of functions are used internally in LINQ but you may find them useful. Each of these are exported from the (visualscheme data linq) library and are provided here for reference. For examples of practical LINQ usage, see Practical LINQ Examples.



Form Name

Signature

Description

element-at/default

(element-at/default <iterator> <index> <default-value>)

Gets the element at a specified index. Returns default when index is out of bounds.

count

(count iter)

Returns the number of elements in the iterator.

range

(range end)

Returns an iterator of numbers starting with 0, incrementing 1, up to, but excluding 'end'.

aggregate

(aggregate iter init proc)

Also known as fold-left. Procedure takes 2 args (accumulator and element) and returns a single value.

concat

(concat iter1 iter2)

Return an iterator for the concatenation of both iterators.

any?

(any? iter pred)

Also known as exists.

all?

(all? iter pred)

Also known as for-all.

empty

(empty)

Returns an empty iterator (singleton).

empty?

(empty? iter)

Tests if an iterator is empty (contains no elements).

repeat

(repeat obj count)

Returns an iterator that contains one repeated value, for count number of times.

average

(average iter)

Gets the average of an iterable of numbers.

maximum

(maximum iter)

Returns the maximum element of an iterator. Must be a number.

minimum

(minimum iter)

Returns the minimum element of an iterator. Must be a number.

sum

(sum iter)

Gets the sum of an iterable of numbers.

take

(take count iter)

Returns an iterator that takes the count number of elements of an iterator. Returns an empty iterator if the count is smaller than the count of the iterator.

skip

(skip count iter)

Returns an iterator that skips the count number of elements of an iterator. Returns an empty iterator if the count is smaller than the count of the iterator.

iterator=?

(iterator=? iter1 iter2)

Determines whether two iterators are equal by comparing the elements.

distinct

(distinct iter)

Returns an iterator of distinct elements of iter.

union

(union iter1 iter2)

Returns an iterator that contains the elements from both iterators, excluding duplicates.

except

(except iter1 iter2)

Returns an iterator that contains the set difference of the elements of two iterators.

intersect

(intersect iter1 iter2)

Returns an iterator that contains the elements that form the set intersection of two iterators.

grouping?

(grouping? obj)

Returns an iterator that contains the elements that form the set intersection of two iterators.

from

-

Tests whether an object is a grouping.





The following terms are registered trademarks of the Microsoft group of companies and are used in accordance with Microsoft’s Trade and Brand Guidelines: Microsoft, Microsoft 365, Microsoft Office, Microsoft Excel, Microsoft Edge, Microsoft Edge WebView2, Microsoft Windows, Excel, Office 365




Copyright © 2022.  Apex Data Solutions, LLC. All Rights Reserved.