Many functions accept a lot of optional "boolean" keyword arguments. These arguments are known as flags. As an example:
(define (string-trim s #:left? [left? #f] #:right? [#:right? #f])
(list s left? right?))
has two flags: #:left? and #:right?.
The function then can be called with:
(string-trim " 1 2 3 " #:left? #t #:right? #t)
Flaggable #%app allows users to instead write:
(string-trim " 1 2 3 " #:left? #:right?)
That is, a keyword argument that doesn't have a "value" will default the value to #t. Explicit "value" is still supported.
This does come at a cost: all keyword arguments must be specified after positional arguments to avoid ambiguity. Without this restriction, it's hard to tell whether:
(f #:a 1)
is meant to be itself or:
(f 1 #:a #t)
Macro
#lang racket
(require syntax/parse/define
(only-in racket [#%app racket:#%app]))
(begin-for-syntax
(define-splicing-syntax-class arg/keyword
#:attributes (k v)
;; first case: something like #:a 1
(pattern {~seq k:keyword v:expr})
;; second case: something like #:a.
(pattern {~seq k:keyword}
#:with v #'#t)))
(define-syntax-parse-rule (#%app f arg/no-keyword:expr ... arg/keyword:arg/keyword ...)
(racket:#%app f arg/no-keyword ... {~@ arg/keyword.k arg/keyword.v} ...))
Many functions accept a lot of optional "boolean" keyword arguments. These arguments are known as flags. As an example:
has two flags:
#:left?
and#:right?
.The function then can be called with:
Flaggable
#%app
allows users to instead write:That is, a keyword argument that doesn't have a "value" will default the value to
#t
. Explicit "value" is still supported.This does come at a cost: all keyword arguments must be specified after positional arguments to avoid ambiguity. Without this restriction, it's hard to tell whether:
is meant to be itself or:
Macro
Note: inspired by https://www.reddit.com/r/Racket/comments/oytknk/keyword_arguments_without_values/h7w67dd/, though I had thought of doing it before, too.
Example usage:
Before code
Licence
MIT / CC-BY 4.0