Idiomdrottning’s homepage

Matchable’s custom destructing

Easily the two features I use the most in Matchable (which I mostly use through my match generics) are ? and =, the custom predicate and the custom accessor respectively.

I’ve found that the ?-> combinator is a great match for = when you conditionally want to coerce a data type into another type.

Another comfy use for = is with a custom destructurer that you can then further destructure with matchable. You can just keep on nesting = procs deep in there at every layer.

Here’s a simple example.

This is from the SVG path lib from earlier today. The context is a procure named distance that takes two attribute alists, like ((coords (x n) (y n))), and calculates the Pythagorean diagonal distance between them.

Here is the custom destructurer, which in turn uses alist-ref in its own destructuring parameter list to grab ((x n) (y n)) and then returns a list of those just two numbers.

(define (get-coords (= (c alist-ref 'coords) atts))
  (list (car (alist-ref 'x atts))
	(car (alist-ref 'y atts))))

And here’s how that destructurer is used in practice, twice, in order to bind the values in those lists directly.

(define (distance (= get-coords (x1 y1)) (= get-coords (x2 y2)))
  (hypothenuse (- x1 x2) (- y1 y2)))

Using = first and then furthering destructuring the value with another pattern might not have been intended (since it was created primarily for record access) but it’s so flexible and it, along with ?, is an easy way for end users to extend Matchable.