> On Dec 6, 2017, at 10:45 PM, David Storrs <david.sto...@gmail.com> wrote:
> 
> I have a struct that looks like this (simplified for concision):
> 
> (struct db-chunk (scratchdir-path chunkdir-path) #:mutable)
> 
> I'd like to ensure that:
> 
> 1) At least one of the fields must be set at creation
> 2) Both fields will accept only a path-string? value
> 3) Both fields will return string? when accessed, as that makes it
> easier to insert into the DB when the time comes.
> 
> I can put a #:guard parameter on db-chunk that will check #1 and #2
> and (if necessary) transform the input into a string in order to
> satisfy #3, but that only works at initialization.  From there I would
> need to redefine the mutator:
> 
> (struct db-chunk (scratchdir-path chunkdir-path) #:mutable)
> 
> (let ([old-mut set-db-chunk-scratchdir-path!])
>  (set! set-db-chunk-scratchdir-path!
>      (lambda (chnk val)
>        (old-mut chnk (if (path? val) (path->string val) val))))))
> 
> Alternatively, I could define my struct and then make a bunch of
> custom manipulation functions, but then (a) I've got these unguarded
> functions floating around and (b) I've given up a major advantage of
> structs, which is their concision.
> 

Consider the introduction of a syntax transformer that refines struct 
according to your needs. The sketch below is a bit brittle but if you 
need to strengthen it, I am sure our virtual macrologists can help. 

— Matthias




#lang racket

;; ---------------------------------------------------------------
;; in some module/file:

#;
(provide
 ;; SYNTAX    (struct/ccc Id [Id ...] MINUS Id ...)
 ;; SEMANTICS (struct/ccc a [b ...] MINUS c ...) is like
 ;;  (struct a [b ...]) but hides the struct-defined functions
 ;;  c ...
 struct/ccc)

(define-syntax (struct/ccc stx)
  (syntax-case stx (MINUS PLUS)
    [(struct/ccc s [a ...] (MINUS x ...) (PLUS [f ex] ...))
     ;; ==>
     (let ((my-require (datum->syntax stx '(require 'server))))
       #`(begin
           (module server #,(datum->syntax stx 'racket)
             (provide 
              (except-out (struct-out s) x ...))
             (struct s [a ...])
             (set! f ex) ...)
           #,my-require))]))

;; ---------------------------------------------------------------
;; require the module here

(struct/ccc s [a b c]
            (MINUS s-a)
            (PLUS [s-b (let ((old s-b)) (λ (x) (define b (old x)) (* 2 b)))]))
(define s0 (s 1 2 3))
(s-b s0)

-- 
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to