Skip to content

Instantly share code, notes, and snippets.

@countvajhula
Created February 4, 2022 00:38
Show Gist options
  • Save countvajhula/7b4d56049121c9fc2f59b55e187cce2b to your computer and use it in GitHub Desktop.
Save countvajhula/7b4d56049121c9fc2f59b55e187cce2b to your computer and use it in GitHub Desktop.
Rhombus Meeting: Interface to elementary relations such as equality

0. Motivation

We all want Rhombus to succeed

Not a juggernaut but a flagship

Syntax is one aspect to experiment with and improve

Coherence is another

1. Theoretical stuff

Functions express any notion of equality

That’s why we intuitively reach for functions to tailor equality

“it makes no difference to me”

“if it’s all the same to you, …”

Examples:

(= #:key floor num1 num2)

(= #:key string-upcase name1 name2)

Function is a very basic relation – one of the most foundational

Therefore, “higher level” relations inherit the same considerations

Order relations are such higher level relations

this is why we do things like (sort #:key first ‘(3 “Apple”) ‘(1 “Banana”) ‘(2 “Cherry”))

This means that the #:key argument is inherited by order relations < and > as well as the composite relations ≥ and ≤

We can compare any objects using the equality relation

We’d like to also compare any objects using order relations

e.g. (< “apricot” “banana”) ;=> #t e.g. (< #:key length “apricot” “banana”) ;=> #f

… since numbers aren’t special - they are just convenient

2. Practical stuff

Proposal:

Choose any elementary “sufficiently fine” notion of equality (e.g. `egal`)

Support a `key` optional argument

(that’s it)

Proposal 2:

Make < and > generic

Support an optional `key` argument

Consequences:

All interfaces dealing in equality and order relations expose the optional `key` argument

member

remove

hash / make-hash

sort

max

min

everything

Benefits

Small, consistent interface presented everywhere

(== #:key string-upcase a b …) vs (apply == (map string-upcase (list a b …)))
standard convention: key, rather than (key, eq-proc, absence)
e.g. sort (key) and assoc (eq-proc) present two different interfaces

Minimize the size of the language

e.g. eliminate string-ci=? stringci<? etc. and all type-specific order and equality relations

Eliminate hasheq hasheqv memq remq …

while avoiding constant mapping to e.g. string-upcase
fully encapsulates the definition of equality behind the interface

Syntax

Rhombus could support some creative syntax here, e.g.

“a” =.(string-upcase) “b” “a” =/string-upcase “b”

Extras

(sort > ‘(“a” “bcd” “ef” “ghij”)) (sort > #:key length ‘(“a” “bcd” “ef” “ghij”))

Meeting Notes

A standard convention

a standard convention can be widely followed

“big” convention: support key function as well as comparator

a small convention would be preferable

but this big convention would be trivially performant

Rebellion already follows the key convention in many cases, and also uses a comparator in other cases [which cases?]

Syntax for Rhombus’s binary =

Jack: the existing proposals (above) don’t look great

TBD

Syntax vs semantics

The syntax may vary across #langs

The present discussions are mainly about semantics that may be leveraged by any #lang

Nonlinear order with non-numeric data could be surprising

E.g. a < b, a > b, and a = b could all be false!

Users would need to be aware of this possibility for custom data

For most common cases (e.g. numbers, strings) the ordering is linear

Defining vs using these relations

At definition site they would be binary (define (less-than-proc a b) …), to define equality or order for each type. E.g. lexicographic ordering for strings would be defined using a binary function somewhere

At use site it would be the unary key function

Performance

If done as a macro, the key argument could be rewritten to a binary comparator

Static optimizations:

unary functions like string-upcase could “store” binary comparators like string-equal?, string-ci<? etc. that can be used instead of performing the unary mapping

Next steps

Organize the proposal into its various components

generic order relations

key convention for APIs

choice of egal, etc.

misc

e.g. relationship to builtin generic comparison
API design
details about single equality function
removing eq? equal? string-equal? etc.
generic order relations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment