<div dir="ltr"><div>Hi Eric,<br><br>I like it!<br><br></div>One thing though: instead of adding a guard which forbids use of the constructor,<br>what about simply hiding the constructor , like this:<div class="im"><br><br>
(define-syntax-rule (define-type t (variant vfield ...) ...)<br>
  (begin<br></div>    (struct t () #:transparent #:constructor-name ?dummy)<div class=""><div id=":33" class="" tabindex="0"><img class="" src="https://mail.google.com/mail/u/0/images/cleardot.gif"></div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">2013/6/10 Eric Tanter <span dir="ltr">&lt;<a href="mailto:etanter@dcc.uchile.cl" target="_blank">etanter@dcc.uchile.cl</a>&gt;</span><br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">

Hi,<br>
<br>
Sorry if this has been discussed before.<br>
<br>
One of the things I often miss while programming in Racket, is variant types. In Shriram&#39;s PLAI, there is a `define-type&#39; form:<br>
<br>
   (define-type Expr<br>
     [num (n number?)]<br>
     ...)<br>
<br>
<br>
This is very helpful, with two caveats:<br>
<br>
1- it requires contracts on fields -- while this is a feature, it also departs from simple structs in Racket.<br>
<br>
2- its syntax for variants corresponds to the `type-case&#39; matching form, eg:<br>
<br>
   (type-case Expr e<br>
     [num (n) ...]<br>
     ...)<br>
<br>
Note the `[num (n) ...]&#39;, while the constructor is `(num n)&#39;.<br>
<br>
After reading the nice thread on writing style, I came up with a very simple `define-type&#39; form that has the advantage of addressing both issues above:<br>
<br>
(define-type expr<br>
 (num n)<br>
 (add l r)<br>
 (sub l r))<br>
<br>
1- no contracts, just like standard structs<br>
<br>
2- the syntax of a variant declaration, eg. `(num n)&#39; directly corresponds to the constructor syntax, which is used in `match&#39;:<br>
<br>
(define (interp expr)<br>
  (match expr<br>
    [(num n) n]<br>
    ...))<br>
<br>
A first version of the macro, included at the end of this mail, makes all structs transparent by default (this could be changed of course):<br>
<br>
&gt; (num 10)<br>
(num 10)<br>
&gt; (expr? (num 10))<br>
#t<br>
<br>
and avoids the instantiation of the abstract type:<br>
<br>
&gt; (expr)<br>
. . cannot construct value of type expr: use one of the variants (num add sub)<br>
<br>
I would actually love to have this facility in Racket, but I suspect that the fact that it is not there already (even though these variant types are common in other FP languages) is due to some &quot;good reason&quot; to not include it.<br>


If so, I&#39;d like to understand why.<br>
<br>
And if there is interest and it is indeed possible to include it in Racket, I&#39;d be happy to contribute it (after some polishing, of course).<br>
<br>
Thanks,<br>
<br>
-- Éric<br>
<br>
(define-syntax-rule (define-type t (variant vfield ...) ...)<br>
  (begin<br>
    (struct t ()<br>
            #:transparent<br>
            #:guard<br>
            (λ (const)<br>
              (if (eq? const &#39;t)<br>
                  (error (format &quot;cannot construct value of type ~a: use one of the variants ~a&quot;<br>
                                 &#39;t (list &#39;variant ...)))<br>
                  (values))))<br>
    (struct variant t (vfield ...) #:transparent) ...))<br>
____________________<br>
  Racket Users list:<br>
  <a href="http://lists.racket-lang.org/users" target="_blank">http://lists.racket-lang.org/users</a><br>
</blockquote></div><br></div></div>