Clines, dexes, merges, and fuses

A “cline” is based on a total ordering on values in its domain, or in other words a binary relation that is reflexive, transitive, and antisymmetric. Its antisymmetry is as fine-grained as possible: If any two values in a cline’s domain are related by that cline in both directions, there will be no Cene code at all that can distinguish the two values.

However, a cline does not merely expose this total ordering. Within the cline’s domain, there may be equivalence classes of values for which every two nonequal values will not have their relative order exposed to Cene code. When Cene code uses call-cline to compare two values by a cline, it can get several results:

  • (nil): The values are not both in the domain.

  • (yep (yep (nil))): The first value candidly precedes the second.

  • (yep <encapsulated value>): The first value secretly precedes the second.

  • (yep (nil)): The first value is equal to the second.

  • (yep <encapsulated value>): The first value secretly follows the second.

  • (yep (nope (nil))): The first value candidly follows the second.

The “secretly precedes” and “secretly follows” cases are indistinguishable to Cene code.

A “dex” is like a cline, but it never results in the “candidly precedes” and “candidly follows” cases. Thus, a dex is useful as a kind of equality test.

A “merge” is a binary operation that is commutative, associative, and idempotent for values in its domain.

A “fuse” is a binary operation that is commutative and associative for values in its domain.

dex-cline

Call with (ignored)

Todo

Document this.

This can distinguish between values that might not have been distinguishable any other way. For instance, it can distinguish between (cline-default (cline-give-up) a) and a.

cline-by-dex

Call with dex

Todo

Document this.

cline-give-up

Call with (ignored)

Todo

Document this.

cline-default

Call with cline-for-trying-first cline-for-trying-second

Given two clines, returns a cline over the union of their domains. The resulting cline’s ascending order consists of the first cline’s ascending order in its domain, followed by the second cline’s ascending order outside the first cline’s domain.

cline-by-own-method

Call with dexable-get-method

Given a dexable function, returns a cline that works by invoking that function with each value to get (yep <cline>) or (nil), verifying that the two <cline> values are the same, and then proceeding to invoke that value.

cline-fix

Call with dexable-unwrap

Given a dexable function, returns a cline that works by passing itself to the function and then invoking the resulting cline.

call-cline

Call with cline a b

Todo

Document this.

in-cline

Call with cline x

Todo

Document this.

dexable

Construct with dex val

A value tagged with a dex that applies to it.

dex-dex

Call with (ignored)

Todo

Document this.

This can distinguish between values that might not have been distinguishable any other way. For instance, it can distinguish between (dex-by-cline (cline-by-dex a)) and a.

dex-by-cline

Call with cline

Todo

Document this.

name-of

Call with dexable

Todo

Document this.

dex-name

Call with (ignored)

Returns a dex that applies to any name. Names are encapsulated values that are good for nothing but comparing using this dex. They are usually obtained by calling procure-name on a namespace.

dex-merge

Call with (ignored)

Todo

Document this.

This can distinguish between values that might not have been distinguishable any other way. For instance, it can distinguish between (merge-default a b) and (merge-default b a).

merge-by-dex

Call with dex

Todo

Document this.

This only processes the dex operation once, calling it with the two values being merged. It doesn’t sanity-check that the dex is reflexive for either argument.

merge-default

Call with merge-for-trying-first merge-for-trying-second

Todo

Document this.

merge-by-own-method

Call with dexable-get-method

Given a dexable function, returns a merge that works by invoking that function with each value to get (yep <merge>) or (nil), verifying that the two <merge> values are the same, invoking that value, and invoking the function on the result again to make sure it yields the same <merge>. That final check makes sure this operation is associative.

merge-fix

Call with dexable-unwrap

Given a dexable function, returns a merge that works by passing itself to the function and then invoking the resulting merge.

call-merge

Call with merge a b

Todo

Document this.

dex-fuse

Call with (ignored)

Todo

Document this.

This can distinguish between values that might not have been distinguishable any other way. For instance, it can distinguish between (fuse-default a b) and (fuse-default b a).

fuse-by-merge

Call with merge

Todo

Document this.

fuse-default

Call with fuse-for-trying-first fuse-for-trying-second

Todo

Document this.

fuse-by-own-method

Call with dexable-get-method

Given a dexable function, returns a fuse that works by invoking that function with each value to get (yep <fuse>) or (nil), verifying that the two <fuse> values are the same, invoking that value, and invoking the function on the result again to make sure it yields the same <fuse>. That final check makes sure this operation is associative.

fuse-fix

Call with dexable-unwrap

Given a dexable function, returns a fuse that works by passing itself to the function and then invoking the resulting fuse.

call-fuse

Call with fuse a b

Todo

Document this.