
Is the grammar of patterns used by syntax-parse
based on a particular formalism? It looks like <https://en.wikipedia.org/wiki/Boolean_grammar|boolean grammars>, but I don’t know if that’s just coincidence.

I have yet to encounter a use case for mutable strings that justifies their existence

finally got around to making a utility for chaining together multiple comparators

Is this comparator-chain
similar to chain=?
? https://srfi.schemers.org/srfi-67/srfi-67.html#node_idx_90

No, that chain=?
is doing something totally unrelated

comparator-chain
combines multiple comparators into a single comparator

I’ve been reimplementing most of this recently, if only I had known!

Thanks for this then!

hmm, maybe I’ll add a reducer version of this

(transduce (list ...)
#:into (into-sorted? comparator #:descending? #true #:strict? #true))

@soegaard2 The main difference IIUC with <https://github.com/Metaxal/bazaar/blob/master/order.rkt|my version> is that I use a partial order, i.e. the possible values of a comparison are <
, =
, >
, #f
where the latter means uncomparable

what sort of stuff do you find yourself using partial orders for?

Got it. I see that we chose a slightly different approach using refine-compare
. I have forgotten most of this SRFI. The rationale at the time:

It would have been natural to include something equivalent to comparator-chain
though.

I kind of like the idea of using #f to represent uncomparable.

@notjack for compound objects

whatcha mean?

say (random example) you can compare the social-rank
of animal
s in the same family
, but it’s meaningless if they are from different family
s

Then you can create a social-order<=>
comparator

It’s also useful for numbers. You can define a number comparator based on the existing <
and compare with incomparable +nan.0
for free, since (< x nan.0)
is #f
for every number x


interesting, I’ve done that social-rank
thing a few times but I made the comparator throw when given values from different families, since in my case that shouldn’t happen in normal code (like you shouldn’t be trying to make a sorted set of animals unless they’re all from the same family)

and yet in Racket you can do (sort '(0 2 +nan.0 3) <)
:wink:

yeah I’d want that to throw

since if it happens something has gone drastically wrong somewhere

Indeed, but that exception should the duty of sort, not of the comparator.

I’m also using sets of canonical elements, where I want to keep only the <?-most elements. That is, i remove each element A for which there is in this set another element B s.t. B < A. Here I don’t want to throw an exception if A and B are not comparable.

in bazaar
this is named make-chain<=>
https://github.com/Metaxal/bazaar/blob/master/order.rkt#L192 It takes as arguments ‘pairs’ of [comparator, extractor] and produces a new comparator.

Interestingly the box-compare
example in srfi/67 is a partial order :slightly_smiling_face:

The srfi site has got some new features! https://srfi.schemers.org/?keywords=comparison

re comparator-chain
and refine-compare
, bazaar/order has a make-chain<=>
function to keep things curried and a chain-comparisons
macro to keep things fast. Naming is hard :smile:

I’ve run into uses of several kinds of comparator, which makes it pretty hard to name things sometimes. One of the more exotic ones I’ve had in mind has results of the form “Well I can at least tell you these two are <=
, but I’m not sure if they’re >=
or not.” (This is the kind of result contract-stronger?
can give.)

Not sure I follow. If they are both <=
and >=
, I suppose this entails that they are =
, right? If so, how is that different from a normal <=
? If not, then… uh… I’m at a loss

contract-stronger?
tells you either that they’re known to be <=
or that they’re not known to be <=
; it never tells you they’re known to be not <=
(in other words, known to be either >
or incomparable)

Question about #%app
:
If we override #%app
, it looks like keyword argument calls will always take the slow path. Is this intentional?
E.g., consider:
#lang racket/base
(require (rename-in racket/base [#%app racket:#%app]))
(define-syntax-rule (#%app . xs) (racket:#%app . xs))
(define (function-name #:a a) 1)
(function-name #:a 2)

If we comment define-syntax-rule
, then the expanded code will contain:
(if (#%app
variable-reference-constant?
(#%variable-reference function-name3))
(#%app function-name temp4)
(slow-path ...))

But with define-syntax-rule
, the if
expression is replaced with just (slow-path ...)

Also, curious why we need to test for variable-reference-constant?
at runtime. Isn’t it possible to decide which branch to take at compile-time?

Ah, a better example is:
#lang racket/base
(define (function-name #:a a) 1)
(define-syntax-rule (test . xs)
(#%app function-name . xs))
(test #:a 2)

Implicit #%app
(comment #%app
out) allows us to use the fast path

but explicit #%app
forces us to use the slow path