How to use the datavtype for tagged union?

46 views
Skip to first unread message

Kiwamu Okabe

unread,
Apr 4, 2021, 1:20:23 AM4/4/21
to ats-lang-users
Dear all,

I'm trying the datavtype for tagged union as following:

```ats
#include "share/atspre_define.hats"
#include "share/atspre_staload.hats"

#define AF_INET 2 /* internetwork: UDP, TCP, etc. */
#define AF_INET6 28 /* IPv6 */

typedef sockaddr_in = @{
sin_port = int,
sin_addr = int,
sin_zero = int
}

typedef sockaddr_in6 = @{
sin6_port = int,
sin6_flowinfo = int,
sin6_addr = int,
sin6_scope_id = int
}

datavtype sockaddr (sa_family: int) =
| Af_inet (AF_INET) of sockaddr_in
| Af_inet6 (AF_INET6) of sockaddr_in6

vtypedef wg_endpoint = [i:int] @{
e_remote = sockaddr(i)
}

fun wg_input
{l1,l2:addr}{i:int}
(pfe: !wg_endpoint@l1, pfso: !sockaddr(i)@l2 | e: ptr l1, so: ptr l2):
void = let
val so = scase i of
| AF_INET => so
| AF_INET6 => so
| _ => null
val () = !e.e_remote := so
in
()
end

implement main0 () = {
var e: wg_endpoint
var so: sockaddr(AF_INET6)
prval pre = view@e
prval prso = view@so
// val () = wg_input(pre, prso | e, so)
prval () = view@e := pre
prval () = view@so := prso
}
```

But above code causes following error:

```
$ patscc -o a.out main.dats -DATS_MEMALLOC_LIBC
.../main.dats: 680(line=33, offs=9) -- 687(line=33, offs=16):
error(parsing): the keyword [in] is needed.
.../main.dats: 644(line=31, offs=8) -- 647(line=31, offs=11):
error(parsing): the syntactic entity [d0exp] is needed.
.../main.dats: 533(line=28, offs=1) -- 536(line=28, offs=4):
error(parsing): the token is discarded.
.../main.dats: 768(line=37, offs=3) -- 770(line=37, offs=5):
error(parsing): the token is discarded.
```

I miss-use `scase`? How to fix above error?

Best regards,
--
Kiwamu Okabe at METASEPI DESIGN

Kiwamu Okabe

unread,
Apr 4, 2021, 1:33:06 AM4/4/21
to ats-lang-users
I think I miss-undertood datavtype.
In this case, it doesn't need to depend to int.

Following is a more simple version:

```ats
#include "share/atspre_define.hats"
#include "share/atspre_staload.hats"

typedef sockaddr_in = @{
sin_port = int,
sin_addr = int,
sin_zero = int
}

typedef sockaddr_in6 = @{
sin6_port = int,
sin6_flowinfo = int,
sin6_addr = int,
sin6_scope_id = int
}

datavtype sockaddr =
| Af_inet of sockaddr_in
| Af_inet6 of sockaddr_in6

vtypedef wg_endpoint = @{
e_remote = sockaddr
}

fun wg_input
{l1,l2:addr}
(pfe: !wg_endpoint@l1, pfso: !sockaddr@l2 | e: ptr l1, so: ptr l2):
void = let
val () = !e.e_remote := so
in
()
end

implement main0 () = {
var e: wg_endpoint
var so: sockaddr
prval pre = view@e
prval prso = view@so
// val () = wg_input(pre, prso | e, so)
prval () = view@e := pre
prval () = view@so := prso
}
```

But above causes the other errors:

```
$ patscc -o a.out main.dats -DATS_MEMALLOC_LIBC
/home/kiwamu/src/practice-ats/tagged_union/main.dats: 511(line=29,
offs=14) -- 528(line=29, offs=31): error(3): a linear component of the
following type is abandoned: [S2Ecst(sockaddr)].
/home/kiwamu/src/practice-ats/tagged_union/main.dats: 538(line=31,
offs=5) -- 540(line=31, offs=7): error(3): the linear dynamic variable
[pfe$4738(-1)] is preserved but with an incompatible typ
e.
/home/kiwamu/src/practice-ats/tagged_union/main.dats: 538(line=31,
offs=5) -- 540(line=31, offs=7): error(3): mismatch of static terms
(tyleq):
The actual term is: S2Eapp(S2Ecst(ptr_addr_type); S2Evar(l2(8481)))
The needed term is: S2Ecst(sockaddr)
/home/kiwamu/src/practice-ats/tagged_union/main.dats: 538(line=31,
offs=5) -- 540(line=31, offs=7): error(3): mismatch of static terms
(tyleq):
The actual term is: S2Etyrec(flt0; npf=-1;
e_remote=S2Eapp(S2Ecst(ptr_addr_type); S2Evar(l2(8481))))
The needed term is: S2Etyrec(flt0; npf=-1; e_remote=S2Ecst(sockaddr))
/home/kiwamu/src/practice-ats/tagged_union/main.dats: 538(line=31,
offs=5) -- 540(line=31, offs=7): error(3): mismatch of static terms
(tyleq):
The actual term is: S2Eat(S2Etyrec(flt0; npf=-1;
e_remote=S2Eapp(S2Ecst(ptr_addr_type); S2Evar(l2(8481))));
S2Evar(l1(8480)))
The needed term is: S2Eat(S2Etyrec(flt0; npf=-1;
e_remote=S2Ecst(sockaddr)); S2Evar(l1(8480)))
```

Something is wrong?

Hongwei Xi

unread,
Apr 5, 2021, 6:06:13 AM4/5/21
to ats-lan...@googlegroups.com

>>val () = !e.e_remote := so

The original linear content in !e.e_remote is discarded, resulting in a leak. Also, 'so' is
a pointer (instead of a sockaddr).



--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ats-lang-users/CAEvX6dmgZGvdUkVG93ajPVscqD44A8t2P4_ucemqPkR%2BA52mCQ%40mail.gmail.com.

Kiwamu Okabe

unread,
Apr 5, 2021, 10:51:05 PM4/5/21
to ats-lang-users
Dear Hongwei,

On Mon, Apr 5, 2021 at 7:06 PM Hongwei Xi <gmh...@gmail.com> wrote:
> >>val () = !e.e_remote := so
>
> The original linear content in !e.e_remote is discarded, resulting in a leak. Also, 'so' is
> a pointer (instead of a sockaddr).

It's fixed with `!so` and following patch:

```patch
--- a/tagged_union/main.dats
+++ b/tagged_union/main.dats
@@ -14,7 +14,7 @@ typedef sockaddr_in6 = @{
sin6_scope_id = int
}

-datavtype sockaddr =
+datatype sockaddr =
| Af_inet of sockaddr_in
| Af_inet6 of sockaddr_in6

```

Thanks,

Kiwamu Okabe

unread,
Apr 5, 2021, 11:39:45 PM4/5/21
to ats-lang-users
But second calling `wg_input` causes error:

```ats
#include "share/atspre_define.hats"
#include "share/atspre_staload.hats"

typedef sockaddr_in = @{
sin_port = int,
sin_addr = int,
sin_zero = int
}

typedef sockaddr_in6 = @{
sin6_port = int,
sin6_flowinfo = int,
sin6_addr = int,
sin6_scope_id = int
}

datatype sockaddr =
| Af_inet of sockaddr_in
| Af_inet6 of sockaddr_in6

vtypedef wg_endpoint = @{
e_remote = sockaddr
}

fun wg_input
{l1,l2:addr}
(pfe: !wg_endpoint? @ l1 >> wg_endpoint @ l1, pfso: !sockaddr@l2 | e:
ptr l1, so: ptr l2):
void = let
val () = !e.e_remote := !so
in
()
end

implement main0 () = {
var e: wg_endpoint
var so: sockaddr = Af_inet @{
sin_port = 1,
sin_addr = 2,
sin_zero = 3
}
var so6: sockaddr = Af_inet6 @{
sin6_port = 1,
sin6_flowinfo = 2,
sin6_addr = 3,
sin6_scope_id = 4
}

prval pre = view@e
prval prso = view@so
val () = wg_input(pre, prso | addr@e, addr@so)
prval () = view@e := pre
prval () = view@so := prso

prval pre = view@e
prval prso6 = view@so6
val () = wg_input(pre, prso6 | addr@e, addr@so6)
prval () = view@e := pre
prval () = view@so6 := prso6
}
```

```
$ patscc -o a.out main.dats -DATS_MEMALLOC_LIBC
/home/kiwamu/src/practice-ats/tagged_union/main.dats: 1042(line=56,
offs=21) -- 1045(line=56, offs=24): error(3): the dynamic expression
cannot be assigned the type [S2Eat(S2Etyrec(flt0; npf=-1;
e_remote=S2Etop(knd=0; S2Ecst(sockaddr))), S2EVar(5246))].
/home/kiwamu/src/practice-ats/tagged_union/main.dats: 1042(line=56,
offs=21) -- 1045(line=56, offs=24): error(3): mismatch of static terms
(tyleq):
The actual term is: S2Ecst(sockaddr)
The needed term is: S2Ecst(ptr_type)
/home/kiwamu/src/practice-ats/tagged_union/main.dats: 1042(line=56,
offs=21) -- 1045(line=56, offs=24): error(3): mismatch of static terms
(tyleq):
The actual term is: S2Etyrec(flt0; npf=-1; e_remote=S2Ecst(sockaddr))
The needed term is: S2Etyrec(flt0; npf=-1; e_remote=S2Etop(knd=0;
S2Ecst(sockaddr)))
/home/kiwamu/src/practice-ats/tagged_union/main.dats: 1042(line=56,
offs=21) -- 1045(line=56, offs=24): error(3): mismatch of static terms
(tyleq):
The actual term is: S2Eat(S2Etyrec(flt0; npf=-1;
e_remote=S2Ecst(sockaddr)); S2Evar(e(8482)))
The needed term is: S2Eat(S2Etyrec(flt0; npf=-1;
e_remote=S2Etop(knd=0; S2Ecst(sockaddr)));
S2EVar(5246->S2Evar(e(8482))))
```

Following patch does fix the error:

```diff
--- a/tagged_union/main.dats
+++ b/tagged_union/main.dats
@@ -51,6 +51,7 @@ implement main0 () = {
prval () = view@e := pre
prval () = view@so := prso

+ var e: wg_endpoint
prval pre = view@e
prval prso6 = view@so6
val () = wg_input(pre, prso6 | addr@e, addr@so6)
```

How to re-use initialized argument on `wg_input` function?

Hongwei Xi

unread,
Apr 6, 2021, 2:00:40 AM4/6/21
to ats-lan...@googlegroups.com

It seems that you need to unintialize 'e' explicitly:

extern
praxi
uninitize
{a:t0ype}
(x: &INV(a) >> a?): void


implement main0 () = {
  var e: wg_endpoint
  var so: sockaddr = Af_inet @{
    sin_port = 1,
    sin_addr = 2,
    sin_zero = 3
  }
  var so6: sockaddr = Af_inet6 @{
    sin6_port = 1,
    sin6_flowinfo = 2,
    sin6_addr = 3,
    sin6_scope_id = 4
  }
//                                                                                                                                                                                              
  prval pre = view@e
  prval prso = view@so
  val () = wg_input(pre, prso | addr@e, addr@so)
  prval () = view@e := pre
  prval () = view@so := prso
//                                                                                                                                                                                              
  prval () = uninitize(e)
//                                                                                                                                                                                              
  prval pre = view@e
  prval prso6 = view@so6
  val () = wg_input(pre, prso6 | addr@e, addr@so6)
  prval () = view@e := pre
  prval () = view@so6 := prso6
}
--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.

Kiwamu Okabe

unread,
Apr 6, 2021, 2:08:28 AM4/6/21
to ats-lang-users
Dear Hongwei,

On Tue, Apr 6, 2021 at 3:00 PM Hongwei Xi <gmh...@gmail.com> wrote:
> It seems that you need to unintialize 'e' explicitly:
> --snip--
> prval () = uninitize(e)

Umm... We should take care to change uninitize it?
The wg_input would like to take both:

A. uninitized `e`
B. initialized `e`

I feel the uninitize function is not safe...

Best regards,
--
Kiwamu Okabe at METASEPI DESIGN

Hongwei Xi

unread,
Apr 6, 2021, 2:32:44 AM4/6/21
to ats-lan...@googlegroups.com
>>I feel the uninitize function is not safe...

Such a function is always safe as initialized data can always
be treated as uninitialized.

--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.

Kiwamu Okabe

unread,
Apr 6, 2021, 3:44:46 AM4/6/21
to ats-lang-users
Dear Hongwei,

On Tue, Apr 6, 2021 at 3:32 PM Hongwei Xi <gmh...@gmail.com> wrote:
> >>I feel the uninitize function is not safe...
>
> Such a function is always safe as initialized data can always
> be treated as uninitialized.

I understood.
If so, could you include the `uninitize` praxi on ATS3 prelude library?

I think this idiom is common for all of ATS programmer.

Hongwei Xi

unread,
Apr 7, 2021, 1:23:36 AM4/7/21
to ats-lan...@googlegroups.com
Okay. I put some 'topize' functions in basic_dyn.dats.
Changes have been uploaded.

--
You received this message because you are subscribed to the Google Groups "ats-lang-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-user...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages