You can also set! the extra constructor

#lang racket

(struct foo [a b c]
  #:extra-constructor-name -foo
  #:transparent)

(define ((foo* make-foo) a b)
  (make-foo a b (+ a b)))

(set! -foo (foo* -foo))

(foo 1 2) ; -> (foo 1 2 3)
(match (foo 1 2)
  [(foo _ _ c) c]) ; -> 3

However I usually just provide a custom make-X function as the only 
constructor. If you're hiding initialization details through the 
constructor it seems a bit 
odd to not hide these details in the match expander. So if you really want 
full encapsulation you should write the match expander as well. But in 
practice
that's usually overkill.

On Friday, March 9, 2018 at 10:24:00 PM UTC-5, Jon Zeppieri wrote:
>
>
>
> On Fri, Mar 9, 2018 at 9:35 PM, Kevin Forchione <lys...@gmail.com 
> <javascript:>> wrote:
>
>> Is it possible to initialize a struct field based on values from 
>> previously defined fields? Something equivalent to let* where
>>
>>         >(struct foo (A B C))
>>         >(foo 1 2) would produce (foo 1 2 3) for example?
>>
>>
>> As far as I know, the only way to do this is to write your own function 
> that calls the struct constructor. You can do this in a module, and only 
> export your constructor, instead of the default struct constructor.
>
> If you want the constructor and the match expander to use the same 
> identifier, then you need to do a bit more work.  For example:
>
> ```
> #lang racket/base
>
> (require racket/match
>          (for-syntax racket/base
>                      syntax/transformer))
>
> (struct foo* (A B C))
>
> (define (foo a b)
>   (foo* a b (+ a b)))
>
> (define-match-expander $foo
>   (syntax-rules ()
>     [(foo a b c) (foo* a b c)])
>   (make-variable-like-transformer #'foo))
>
> (provide (rename-out [$foo foo]
>                      [foo*-A foo-A]
>                      [foo*-B foo-B]
>                      [foo*-C foo-C])))
> ```
>
> Of course, even here, an instance will print as #<foo*>. You can implement 
> gen:custom-write to fix that.
>
> There might be a better way to do this, but this is what I've used in the 
> past.
>
> - Jon
>
>
>
>
>

-- 
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