Dallycot

A linked open code engine

View project on GitHub

Linked Open Code Library

The definitions in this library provide the basic operations expected in a linked open code engine. Many of these are used to implement syntactic constructs in Dallycot.

Functions

all-true

(*x: Expressions) → Boolean

Accepts any number of arguments and returns a true value if all expressions evaluate to true. Returns false otherwise.

Examples

expression1 and expression2 and expression3

Dallycot uses the all-true function to implement the and operator.

Implementation

This is implemented natively.

Without short-circuiting, this is equivalent to the following:

all-true(*x) :> (
  tester := y-combinator(
    (self, x) :> (
      x?  : (
              x'  : self(self, x...)
              ( ) : false
            )
      ( ) : true
    )
  );

  tester(x)
)

any-true

(*x: Expressions) → Boolean

Accepts any number of arguments and returns a true value if any expressions evaluate to true. Returns false otherwise.

Examples

expression1 or expression2 or expression3

Dallycot uses the any-true function to implement the or operator.

Implementation

This is implemented natively.

Without short-circuiting, this is equivalent to the following:

any-true(*x) :> ~all-true({ ~# } @ x)

filter

Implementation

filter := y-combinator(
  (self, selector, stream) :> (
    (?stream) : (
      (selector(stream')) : [ stream', self(self, selector, stream...) ]
      (                 ) : self(self, selector, stream...)
    )
    (       ) : [ ]
  )
)

foldl

(x: T1, f: Lambda/2, s: [T2]) :> [T1]

Implementation

foldl(initial, function, stream) :> (
  folder := y-combinator(
    (self, pad, function, stream) :> (
      (?stream) : (
        next := function(pad, stream');
        [ next, self(self, next, function, stream...) ]
      )
      ( ) : [ ]
    )
  );

  (
    (?stream) : folder(initial, function, stream)
    (       ) : [ initial ]
  )
)

foldl1

(f: Lambda/2, s: [T]) :> [T]

Implementation

foldl1(function, stream) :> (
  (?stream) : foldl(stream', function, stream...)
  (       ) : [ ]
)

map

Implementation

map := y-combinator(
  (self, mapper, stream) :> (
    (?stream) : [ mapper(stream'), self(self, mapper, stream...) ]
    (       ) : [ ]
  )
)

range

(a: Numeric, b: Numeric) :> [Numeric]

Returns a stream of numbers starting at the first and increasing or decreasing to the second.

Examples

1..5 = range(1, 5) = [ 1, 2, 3, 4, 5 ]
5..1 = range(5, 1) = [ 5, 4, 3, 2, 1 ]

Implementation

range := y-combinator(
  (self, m, n) :> (
    (m > n) : [ m, self(self, m - 1, n) ]
    (m = n) : [ m ]
    (m < n) : [ m, self(self, m + 1, n) ]
    (     ) : [ ]
  )
)

upfrom

(x: Numeric) :> [Numeric]

Produces an unbounded stream of increasing integers starting with the given value.

Examples

10.. = upfrom(10) = [ 10, 11, 12, 13, ... ]
-5.. = upfrom(-5) = [ -5, -4, -3, -2, -1, 0, 1, ...]

Implementation

upfrom := y-combinator( (self, n) :> [ n, self(self, n + 1) ] )

y-combinator

(f: Lambda/n) → Lambda/(n-1)

The Y-combinator is a fixed-point combinator that produces a new function encapsulating the given function’s self-reference. This function can be used with streams to implement recursion.

Examples

See the implementation of many of the functions in this library.

Implementation

y-combinator(function) :> function(function, ___)