Thanks for your answer.

After some retries, I had realized, that the rule of keeping
var-representation type at the exit of function requires me to define most
basic type, so instead of my first try:
```
fn
  test1(): $BS.BytestringNSH0 = bs1 where {
  var bs = $BS.pack "hello world"
  var bs1 = $BS.take( i2sz 11, bs)
  val () = $BS.decref_bs( bs, bs1) // consume bs and decref for bs1
}
```
which fails, because bs type at definition is Bytestring(11, 0, 11, 0, 0,
false, l) and should be the same at exit, so I came up to:
```
fn
  test1(): $BS.BytestringNSH0 = bs1 where {
  var bs: $BS.Bytestring0
  val () = bs := $BS.pack "hello world"
  var bs1: $BS.Bytestring0
  val () = bs1 := $BS.take( i2sz 11, bs)
  val () = $BS.decref_bs( bs, bs1) // consume bs and decref for bs1
}
```
which compiles, as both bs and bs1 has types defined as 'Bytestring0?',
which is easier to keep at exit, especially, as ```test1():
$BS.BytestringNSH0 = *bs1* where {``` turns type of bs1 from Bytestring0
into Bytestring0? automatuically.
So my initial issue with var-representation constraint had been solved and
I will stick with style

Thanks!

вс, 4 окт. 2020 г. в 05:10, Hongwei Xi <gmh...@gmail.com>:

> By the way, if 'i' is call-by-value, then it cannot be updated. If it
> needs to be updated,
> then it cannot be call-by-value.
>
>
> On Sun, Oct 4, 2020 at 1:01 AM Hongwei Xi <gmh...@gmail.com> wrote:
>
>> The following line caused the issue:
>>
>> val () = i := build( () | (len, offset, cap, i2sz 0, refcnt + i2sz 1,
>> dynamic, p)) // restore i
>>
>> It should be changed to
>>
>> prval () = i := build( () | (len, offset, cap, i2sz 0, refcnt + i2sz 1,
>> dynamic, p)) // restore i
>>
>> Only a linear proof call-by-value argument can be a left-value. So 'i' is
>> treated as a proof,
>> and its erasure is of the type 'void'.
>>
>>
>> On Sat, Oct 3, 2020 at 11:32 PM Dambaev Alexander <ice.redm...@gmail.com>
>> wrote:
>>
>>> Hi,
>>>
>>> I have a viewtype, defined like this:
>>> ```
>>> absvt0ype
>>>   Bytestring_vtype
>>>   ( len:int (* size in bytes, which occupied by data *)
>>>   , offset: int (* the offset from base pointer at which data of length
>>> len starts *)
>>>   , cap: int (* capacity of the buffer *)
>>>   , ucap: int (* how much unused bytes of buffer available after this
>>> bytestring *)
>>>   , refcnt:int (* how many other bytestrings refer to this bytestring *)
>>>   , dynamically_allocated: bool (* if false, then base pointer is
>>> statically allocated *)
>>>   , base: addr (* base pointer *)
>>>   ) =
>>>   ( void
>>>   | ( size_t (* len *)
>>>     , size_t (* offset *)
>>>     , size_t (* capacity *)
>>>     , size_t (* available capacity *)
>>>     , size_t (* refcnt *)
>>>     , bool (* is dynamically allocated *)
>>>     , ptr
>>>     )
>>>   )
>>>
>>> (* bytestring, which backend memory is not shared with other bytestrings
>>> *)
>>> vtypedef
>>>   BytestringNSH0 =
>>>   [len: nat][offset,cap,ucap:nat][dynamically_allocated:bool][l:agz]
>>>   Bytestring_vtype( len, offset, cap, ucap, 0, dynamically_allocated,l)
>>>
>>> ```
>>>
>>> In many functions, I would like to modify argument's type and value in
>>> order to modify reference count, the simplified example of usage is:
>>> ```
>>> fn
>>>   test1(): $BS.BytestringNSH0 = bs1 where {
>>>   val bs = $BS.pack "hello world"
>>>   val bs1 = $BS.incref_bs bs
>>>   // do some stuff like val bs2 = $BS.take( i2sz 2, bs1)...
>>>   val () = $BS.decref_bs( bs, bs1) // consume bs and decref for bs1
>>> }
>>> ```
>>> where incref_bs and decref_bs defined like this:
>>> ```
>>> fn
>>>   decref_bs
>>>   {c_len, c_offset, cap, c_ucap: nat}{dynamic:bool}{l:addr}
>>>   {p_len, p_offset, p_ucap, p_refcnt: nat | *p_refcnt > 0*}
>>>   ( consume: Bytestring_vtype( c_len, c_offset, cap, c_ucap, *1*,
>>> dynamic, l) // consume bytestring with refcounter = 1
>>>   , preserve: !Bytestring_vtype( p_len, p_offset, cap, p_ucap,
>>> *p_refcnt*, dynamic, l) >> Bytestring_vtype( p_len, p_offset, cap,
>>> p_ucap, *p_refcnt - 1*, dynamic, l) // and decrease refcounter for one,
>>> that should be preserved
>>>   ):<!wrt>
>>>   void
>>> fn
>>>   incref_bs
>>>   {len, offset, cap, ucap, refcnt: nat}{dynamic:bool}{l:addr}
>>>   ( i: !Bytestring_vtype( len, offset, cap, ucap, *refcnt*, dynamic, l)
>>> >> Bytestring_vtype( len, offset, cap, 0, *refcnt + 1*, dynamic, l) //
>>> increase reference counter on original bytestring
>>>   ):<!wrt>
>>>   Bytestring_vtype( len, offset, cap, ucap, *1*, dynamic, l) // produce
>>> the same string with refcount == 1
>>> ```
>>> and the implementation of incref_bs is (decref_bs is similar to it):
>>> ```
>>> implement incref_bs( i) = res where {
>>>   extern castfn
>>>     explode
>>>     { len, offset, cap, ucap, refcnt:nat}{dynamic:bool}{l:addr}
>>>     ( i: Bytestring_vtype( len, offset, cap, ucap, refcnt, dynamic, l)
>>>     ):<> ( size_t(len), size_t(offset), size_t(cap), size_t(ucap),
>>> size_t(refcnt), bool(dynamic) ptr(l))
>>>   extern castfn
>>>     build
>>>     { len, offset, cap, ucap, refcnt:nat}{dynamic:bool}{l:addr}
>>>     ( void
>>>     | ( size_t(len), size_t(offset), size_t(cap), size_t(ucap),
>>> size_t(refcnt), bool(dynamic), ptr(l) )
>>>     ):<> Bytestring_vtype( len, offset, cap, ucap, refcnt, dynamic, l)
>>>   val (len, offset, cap, ucap, refcnt, dynamic, p) = explode(i) //
>>> consume i
>>>   val res = build( () | (len, offset, cap, ucap, i2sz 1, dynamic, p))
>>>   val () = i := build( () | (len, offset, cap, i2sz 0, refcnt + i2sz 1,
>>> dynamic, p)) // restore i
>>> }
>>> ```
>>> this implementation typechecks, but C's generated code can't be compiled
>>> with error:
>>> ```
>>>
>>> /nix/store/cqynqsas6nwk3gbn8m2pi9lx4m0shr0y-ats2-0.3.13/lib/ats2-postiats-0.3.13/ccomp/runtime/pats_ccomp_instrset.h:339:39:*
>>> error: invalid use of void expression*
>>>  #define ATSINSstore(pmv1, pmv2) (pmv1 = pmv2)
>>>                                        ^
>>> bytestring_flat_dats.c:5417:1: note: in expansion of macro ‘ATSINSstore’
>>>  ATSINSstore(ATSderef(arg0, atsvoid_t0ype), ATSPMVcastfn(build,
>>> postiats_tyrec_0, tmp311)) ;
>>> ```
>>> and the generated code for incref_bs is:
>>> ```
>>> /*
>>> local:
>>> global: incref_bs$80$0(level=0)
>>> local:
>>> global:
>>> */
>>> ATSextern()
>>> postiats_tyrec_0
>>> bytestring__incref_bs(*atsrefarg0_type*(postiats_tyrec_0) arg0)
>>> {
>>> /* tmpvardeclst(beg) */
>>> ATStmpdec(tmpret301, postiats_tyrec_0) ;
>>> ATStmpdec(tmp302, atstkind_t0ype(atstype_size)) ;
>>> ATStmpdec(tmp303, atstkind_t0ype(atstype_size)) ;
>>> ATStmpdec(tmp304, atstkind_t0ype(atstype_size)) ;
>>> ATStmpdec(tmp305, atstkind_t0ype(atstype_size)) ;
>>> ATStmpdec(tmp306, atstkind_t0ype(atstype_size)) ;
>>> ATStmpdec(tmp307, atstkind_t0ype(atstype_bool)) ;
>>> ATStmpdec(tmp308, atstkind_type(atstype_ptrk)) ;
>>> ATStmpdec(tmp309, postiats_tyrec_0) ;
>>> ATStmpdec(tmp310, atstkind_t0ype(atstype_size)) ;
>>> ATStmpdec(tmp311, postiats_tyrec_0) ;
>>> ATStmpdec(tmp312, atstkind_t0ype(atstype_size)) ;
>>> ATStmpdec(tmp313, atstkind_t0ype(atstype_size)) ;
>>> ATStmpdec(tmp314, atstkind_t0ype(atstype_size)) ;
>>> /* tmpvardeclst(end) */
>>> ATSfunbody_beg()
>>> ATSINSflab(__patsflab_incref_bs):
>>> ATSINSmove(tmp302, ATSSELfltrec(ATSPMVcastfn(explode, postiats_tyrec_0,
>>> arg0), postiats_tyrec_0, atslab__0)) ;
>>> ATSINSmove(tmp303, ATSSELfltrec(ATSPMVcastfn(explode, postiats_tyrec_0,
>>> arg0), postiats_tyrec_0, atslab__1)) ;
>>> ATSINSmove(tmp304, ATSSELfltrec(ATSPMVcastfn(explode, postiats_tyrec_0,
>>> arg0), postiats_tyrec_0, atslab__2)) ;
>>> ATSINSmove(tmp305, ATSSELfltrec(ATSPMVcastfn(explode, postiats_tyrec_0,
>>> arg0), postiats_tyrec_0, atslab__3)) ;
>>> ATSINSmove(tmp306, ATSSELfltrec(ATSPMVcastfn(explode, postiats_tyrec_0,
>>> arg0), postiats_tyrec_0, atslab__4)) ;
>>> ATSINSmove(tmp307, ATSSELfltrec(ATSPMVcastfn(explode, postiats_tyrec_0,
>>> arg0), postiats_tyrec_0, atslab__5)) ;
>>> ATSINSmove(tmp308, ATSSELfltrec(ATSPMVcastfn(explode, postiats_tyrec_0,
>>> arg0), postiats_tyrec_0, atslab__6)) ;
>>> ATSINSmove(tmp310, atspre_g1int2uint_int_size(ATSPMVi0nt(1))) ;
>>> ATSINSmove_fltrec_beg()
>>> ATSINSstore_fltrec_ofs(tmp309, postiats_tyrec_0, atslab__0, tmp302) ;
>>> ATSINSstore_fltrec_ofs(tmp309, postiats_tyrec_0, atslab__1, tmp303) ;
>>> ATSINSstore_fltrec_ofs(tmp309, postiats_tyrec_0, atslab__2, tmp304) ;
>>> ATSINSstore_fltrec_ofs(tmp309, postiats_tyrec_0, atslab__3, tmp305) ;
>>> ATSINSstore_fltrec_ofs(tmp309, postiats_tyrec_0, atslab__4, tmp310) ;
>>> ATSINSstore_fltrec_ofs(tmp309, postiats_tyrec_0, atslab__5, tmp307) ;
>>> ATSINSstore_fltrec_ofs(tmp309, postiats_tyrec_0, atslab__6, tmp308) ;
>>> ATSINSmove_fltrec_end()
>>> ATSINSmove(tmp312, atspre_g1int2uint_int_size(ATSPMVi0nt(0))) ;
>>>
>>> ATSINSmove(tmp314, atspre_g1int2uint_int_size(ATSPMVi0nt(1))) ;
>>>
>>> ATSINSmove(tmp313, atspre_g1uint_add_size(tmp306, tmp314)) ;
>>>
>>> ATSINSmove_fltrec_beg()
>>> ATSINSstore_fltrec_ofs(tmp311, postiats_tyrec_0, atslab__0, tmp302) ;
>>> ATSINSstore_fltrec_ofs(tmp311, postiats_tyrec_0, atslab__1, tmp303) ;
>>> ATSINSstore_fltrec_ofs(tmp311, postiats_tyrec_0, atslab__2, tmp304) ;
>>> ATSINSstore_fltrec_ofs(tmp311, postiats_tyrec_0, atslab__3, tmp312) ;
>>> ATSINSstore_fltrec_ofs(tmp311, postiats_tyrec_0, atslab__4, tmp313) ;
>>> ATSINSstore_fltrec_ofs(tmp311, postiats_tyrec_0, atslab__5, tmp307) ;
>>> ATSINSstore_fltrec_ofs(tmp311, postiats_tyrec_0, atslab__6, tmp308) ;
>>> ATSINSmove_fltrec_end()
>>> *ATSINSstore(ATSderef(arg0, atsvoid_t0ype), ATSPMVcastfn(build,
>>> postiats_tyrec_0, tmp311)) ;*
>>> ```
>>> So, althought, 'build' has the same return type as arg0, I assume, that
>>> compiler generates type 'void' for arg0 because it had been consumed during
>>> call to 'explode'.
>>>
>>> So the question is: is there a way to overcome this issue?
>>>
>>> There are alternative ways exist:
>>> 1. 'explode' should not consume, but preserve it's argument. In this
>>> case, type checker will complain, that ```val () = i := build( () | (len,
>>> offset, cap, i2sz 0, refcnt + i2sz 1, dynamic, p)) // restore i``` will
>>> loose linear component of the original value of i
>>> 2. use variables for arguments of incref_bs and decref_bs, like this:
>>> ```
>>> fn
>>>   incref_bs
>>>   {len, offset, cap, ucap, refcnt: nat}{dynamic:bool}{l:addr}
>>>   ( i: *&*Bytestring_vtype( len, offset, cap, ucap, *refcnt*, dynamic,
>>> l) >> Bytestring_vtype( len, offset, cap, 0, *refcnt + 1*, dynamic, l)
>>> // increase reference counter on original bytestring
>>>   ):<!wrt>
>>>   Bytestring_vtype( len, offset, cap, ucap, *1*, dynamic, l) // produce
>>> the same string with refcount == 1
>>> ```
>>> but in this case, test1() won't compile. because of the requirement to
>>> restore type of var, passed to incref_bs
>>> 1. consume arguments of incref_bs and decref_bs and return tuples, like
>>> this
>>> ```
>>> fn
>>>   incref_bs
>>>   {len, offset, cap, ucap, refcnt: nat}{dynamic:bool}{l:addr}
>>>   ( i: Bytestring_vtype( len, offset, cap, ucap, *refcnt*, dynamic, l)
>>>   ):<!wrt>
>>>   ( Bytestring_vtype( len, offset, cap, 0, *refcnt + 1*, dynamic, l) //
>>> increase reference counter on original bytestring
>>>   , Bytestring_vtype( len, offset, cap, ucap, *1*, dynamic, l) //
>>> produce the same string with refcount == 1
>>>   )
>>> ```
>>> but this is much verbose and require tracking of resource names manually
>>> in order to not to mess things up.
>>>
>>> --
>>> 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-users+unsubscr...@googlegroups.com.
>>> To view this discussion on the web visit
>>> https://groups.google.com/d/msgid/ats-lang-users/CAHjn2Ky2gr53BoRhEO50XXX9DQTw2Evees%3DmtQMS%2BosghcDNdw%40mail.gmail.com
>>> <https://groups.google.com/d/msgid/ats-lang-users/CAHjn2Ky2gr53BoRhEO50XXX9DQTw2Evees%3DmtQMS%2BosghcDNdw%40mail.gmail.com?utm_medium=email&utm_source=footer>
>>> .
>>>
>> --
> 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-users+unsubscr...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/ats-lang-users/CAPPSPLrOdLXoB2DGa0xdui47Mto13iowECK%2BKem2UjjjwGuv8A%40mail.gmail.com
> <https://groups.google.com/d/msgid/ats-lang-users/CAPPSPLrOdLXoB2DGa0xdui47Mto13iowECK%2BKem2UjjjwGuv8A%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>

-- 
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-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ats-lang-users/CAHjn2KwmgGoOuHZai5K80_nNzPwV2_xjfoqLvChD-yR3hue7fQ%40mail.gmail.com.

Reply via email to