In Racket you have the opportunity to create and use your structure type like this
(define-struct example (a b))
(define var (make-example 1 2))
(example? var)
(example-a var)
I'm trying to implement something like this in scheme using macros but I have a problem with the creation of procedures with combined names like (make-example 1 2)
where instead of example can be absolutely anything.
Is there a way to define procedures with such names or some other way to solve this problem?
There is no need for looking at other languages for features that already exists. It only has a different name: records!
It's defined in SRFI-9 Defining record types and the latest R7RS included backward compatibility to this so it's all good to choose this even in R5RS. Many R5RS implementations has them included. R6RS has a different implementation of records that is not compatible and should be avoided at this time.
#!r6rs
;; You want to use SRFI-9 rather than the d\included define-record-type
(import (except (rnrs) define-record-type)
(srfi :9))
(define-record-type :example
(make-example a b)
example?
(a example-a set-example-a!)
(b example-b set-example-b!))
(define var (make-example 1 2))
(example? var) ; ==> #t
(example-a var) ; ==> 1
Then the best way is to try figuring this out by yourself. To make a macro that makes concatenated identifiers you cannot use define-syntax
since it cannot do that. Doing it without cheating too much will give you a better understanding of macros. In R6RS syntax-case
was in the included libraries and you could make an identifier with datum->syntax
:
#!r6rs
(import (rnrs)
(rnrs syntax-case))
(define-syntax make-predicate
(lambda (stx)
(define (s->p sym)
(string->symbol (string-append (symbol->string sym) "?")))
(syntax-case stx ()
[(_ name)
(with-syntax
([predicate (datum->syntax #'name (s->p (syntax->datum #'name)))])
#'(define (predicate v)
(and (pair? v)
(eq? (car v) 'name))))])))
(make-predicate circle)
predicate? ; ==> #<procedure-predicate?>
(predicate? '(predicate x)) ; ==> #t
If you are after doing this is #lang racket
rather than standard Scheme I think syntax-case
exists and is compatible with this. Also I would suggest you read Greg Hendershott's fear of macros for more racket specific features.
Well. If you look the the SRFI-9 spec it supplies implementation and even look at #lang racket
implementation of struct at github or simply right click on the symbol in your DrRacket and choose "Open defining file" to open the source just like any other file. There are no secrets to this but it might be slightly more complicated than you bargained for.
NB: Note that define-struct
is no longer the preferred form in #lang racket
, but is provided just for backwards compatibility. struct
is preferred.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With