Hi folks,
Hope everyone's having a relaxing start to the holiday season. I've written
a package dealing with generic relations and types, just announcing it here
in case anyone finds it useful.

https://docs.racket-lang.org/relation/index.html

The package provides generic versions of order relations like < and =, and
algebraic operators like +, so that they work on any type that exhibits a
structure appropriate for the operation. I think of this as a complement to
something like data/collection, which when used together make the
experience of writing Racket type-agnostic for the most common cases. Here
are some examples:

> (< 1 2 3)

#t
> (< "apple" "banana" "cherry")

#t
> (= "apple" "APPLE")

#f
> (= #:key string-upcase "apple" "APPLE")

#t
> (.. "hi" " " "there")

"hi there"
> (+ #(1 2 3) #(1 2 3) #(1 2 3))

'#(3 6 9)
> (->list (stream 1 2 3))

'(1 2 3)
> (= #:key (.. even? ->number) "12" "20")

#t
> (min #:key length "apple" "pear" "strawberry")

"pear"

The #:key argument is worth noting as it allows you to provide a definition
of equivalence, i.e. supporting arbitrary equivalence classes on the input
type. This inclusion was inspired by a recent discussion on this list
(cc @George
Neuner <gneun...@comcast.net> ). I also included the /= relation for good
measure :)

Performance wise I haven't really looked into optimizing it since it mostly
dispatches to built-in interfaces, but from profiling at an arm's length
using this package <https://docs.racket-lang.org/profile/index.html> just
to give an idea, it looks like the interfaces range about 1-4x slower than
built-in type-specific relations.

Some next steps or pipe dreams could be:
- supporting "ring" style distributive operators like the usual * for
generalized multiplication.
- looking into multi-dispatch, like what @Alexis talks about here
<https://lexi-lambda.github.io/blog/2016/02/18/simple-safe-multimethods-in-racket/>,
to make the implementation cleaner. This is probably a necessary
prerequisite to...
- ... adding more algebraic datatypes as templates for generic interfaces
(like the monoid or "composition-like" and group or "addition-like"
interfaces already present)
- ... which could be useful in supporting linear algebra types and
operations like the matrix operations in the math package
<https://docs.racket-lang.org/math/matrices.html>
- more explicit treatment of order structures like lattices, supremums,
infimums in the order relations so that you could do something like (sup
<args>) and it would return a result using a standard supremum-finding
algorithm across any types for which an order relation has been defined,
for example (sup canid felid) ; => carnivora

This is my first Racket package, so feedback of any kind would be much
appreciated. Thanks!

-Sid

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CACQBWFmL4eBayQraWDuwYmhsK%2BGYvvajAF6gQBTPegguxMCQFA%40mail.gmail.com.

Reply via email to