Hrrm, I had:

fun
parse_entry
( st: !CSVState >> _
, at: (int, int)
, acc: !$SBF.stringbuf
, cs: llstring
) : stream_vt(CSVEntry)

I gather I have to change not just [!$SBF.stringbuf] but also [!CSVState >> 
_], right? What about if I did

fun
parse_entry_con
( st: !CSVState >> _
, at: (int, int)
, acc: !$SBF.stringbuf
, cs: llstring
) : stream_vt_con(CSVEntry)

and then put 

parse_entry(...) = 
$ldelay
( parse_entry_con(...)
, ( free(st)
  ; free(acc)
  ; free(cs)
  )
)

--would that work? Would it be idiomatic and efficient?

Thanks, again,
August

Den måndag 6 mars 2017 kl. 14:30:05 UTC+1 skrev gmhwxi:
>
> I forgot to tell you something essential in using stream_vt.
> The following interface for 'test' cannot work:
>
> fun test (acc: !$SBF.stringbuf, cs: llstring): stream_vt(DT) =
>
> What you need is
>
> fun test (acc: $SBF.stringbuf, cs: llstring): stream_vt(DT) =
>
> The 'acc' stringbuf needs to be consumed by 'test'. The implementation
> of 'test' looks like this:
>
> $ldelay
> (
> <code for stream construction>
> ,
> (freeing(acc); freeing(cs)) // this part is executed when the stream is 
> freed
> )
>
> On Mon, Mar 6, 2017 at 8:19 AM, August Alm <augu...@gmail.com 
> <javascript:>> wrote:
>
>> The points you mention are part of the reason I chose to wrote the csv 
>> lexer the way I did. It follows one of the fastests Haskell csv parsers, 
>> and I was curious to see how using linear types could optimize performance.
>>
>> Regarding your suggestion on how to make better use of $ldelay in my 
>> code: I'm stuck on a compiler error that I can't make sense of. The 
>> following pseudo-minimal example throws the same kind of errors:
>>          
>>          #include "share/atspre_define.hats"
>>          #include "share/atspre_staload.hats"
>>          staload UN = "prelude/SATS/unsafe.sats"
>>          staload SBF = "libats/SATS/stringbuf.sats"
>>          staload _(*SBF*) = "libats/DATS/stringbuf.dats"
>>          
>>          datatype DT = D_T of @{ alpha = char }
>>          vtypedef llstring = stream_vt(char)
>>          
>>          fun
>>          test (acc: !$SBF.stringbuf, cs: llstring): stream_vt(DT) =
>>          $ldelay
>>          ( case !cs of
>>            | ~stream_vt_nil() =>
>>              if $SBF.stringbuf_get_size(acc) = i2sz(0) then 
>> stream_vt_nil()
>>              else stream_vt_cons(D_T(@{alpha = 'a'}), 
>> stream_vt_make_nil())
>>            | ~stream_vt_cons(c, cs1) =>
>>              let val crec = D_T(@{alpha = c})
>>              in stream_vt_cons(crec, test(acc, cs1))
>>              end
>>          , ~cs
>>          )
>>
>> The compiler can not infer the type I want (which is [stream_vt_con(DT)] 
>> for the [stream_vt_nil()] following the first [then] in the function body. 
>> The error message says
>>
>> the dynamic expression cannot be assigned the type [S2EVar(5492)].
>> [...] mismatch of sorts in unification:
>> The sort of variable is: S2RTbas(S2RTBASimp(1; t@ype))
>> The sort of solution is: S2RTbas(S2RTBASimp(2; viewtype))
>> [...] mismatch of static terms (tyleq):
>> The actual term is: S2Eapp(S2Ecst(stream_vt_con); S2EVar(5495))
>> The needed term is: S2EVar(5492)
>>
>> (There are further errors of the same form.) Is the culprit that 
>> [stream_vt] of a nonlinear datatype requires some special care? The version 
>> with [stream_vt_make_nil()] instead of explicit [$ldelay] works so the 
>> error ought to be subtle.
>>
>> Best wishes,
>> August
>>
>> Den söndag 5 mars 2017 kl. 23:58:35 UTC+1 skrev gmhwxi:
>>>
>>> Yes, you definitely got it :)
>>>
>>> Stream_vt is very memory-frugal.
>>>
>>> Haskell relies on deforestation (complex complier optimization)
>>> to reduce memory usage of lazy evaluation. In ATS, deforestation is
>>> not supported. Instead, the programmer needs to recycle memory 
>>> explicitly.
>>>
>>> Compared to Haskell, corresponding code using stream_vt in ATS can be
>>> much more efficient both time-wise and memory-wise.
>>>
>>> For instance, the following example (for computing Mersenne primes) can
>>> run for days without run-time GC:
>>>
>>>
>>> https://github.com/githwxi/ATS-Postiats/blob/master/doc/EXAMPLE/RosettaCode/Lucas-Lehmer_test2.dats
>>>
>>> It convincingly attests to the power of linear streams.
>>>
>>> Cheers!
>>>
>>>
>>> On Sun, Mar 5, 2017 at 5:34 PM, August Alm <augu...@gmail.com> wrote:
>>>
>>>> Thanks for the tip! I think I understand. I treated $ldelay much as a 
>>>> data constructor, so that all streams are equally lazy, whereas there are 
>>>> in fact many ways to sequence into thunks. Let me give an example to 
>>>> anchor 
>>>> the discussion. Both the following implementations of a map-template for 
>>>> linear streams typecheck:
>>>>
>>>>          fun {a, b: t0ype}
>>>>          map_make_cons 
>>>>          ( xs: stream_vt(a)
>>>>          , f: a -> b
>>>>          ) : stream_vt(b) =
>>>>          case !xs of
>>>>          | ~stream_vt_nil() => stream_vt_make_nil()
>>>>          | ~stream_vt_cons(x, xs1) =>
>>>>            stream_vt_make_cons(f(x), map_make_cons(xs1, f))
>>>>          
>>>>          fun {a, b: t0ype}
>>>>          map_ldelay
>>>>          ( xs: stream_vt(a)
>>>>          , f: a -> b
>>>>          ) : stream_vt(b) =
>>>>          $ldelay
>>>>          ( case !xs of
>>>>            | ~stream_vt_nil() => stream_vt_nil()
>>>>            | ~stream_vt_cons(x, xs1) =>
>>>>              stream_vt_cons(f(x), map_ldelay(xs1, f))
>>>>          , ~xs
>>>>          )
>>>>
>>>> The second is maximally lazy. The first, [map_make_cons] is less lazy 
>>>> because checking the case-conditions is not delayed. My code was like the 
>>>> first example, only much more was going on inside the case expressions. Is 
>>>> that a correct assessment?
>>>>
>>>>
>>>> Den söndag 5 mars 2017 kl. 04:07:42 UTC+1 skrev gmhwxi:
>>>>>
>>>>> BTW, it seems you don't need to do much to fix the issue.
>>>>>
>>>>> Basically, you just do
>>>>>
>>>>> 1) Put the body of parse_entry into $ldelay(...)
>>>>> 2) Change stream_vt_make_cons into stream_vt_cons
>>>>>
>>>>> There may be a few other things but they should all be
>>>>> very minor.
>>>>>
>>>>> On Saturday, March 4, 2017 at 9:47:07 PM UTC-5, gmhwxi wrote:
>>>>>>
>>>>>> I took a glance at your code.
>>>>>>
>>>>>> I noticed a very common mistake involving the use of
>>>>>> stream (or stream_vt). Basically, the way stream is used
>>>>>> in your code is like the way list is used. This causes the
>>>>>> stack issue you encountered.
>>>>>>
>>>>>> Say that you have a function that returns a stream. In nearly
>>>>>> all cases, the correct way to implement such a function should
>>>>>> use the following style:
>>>>>>
>>>>>> fun foo(...): stream_vt(...) = $ldelay
>>>>>> (
>>>>>> ...
>>>>>> )
>>>>>>
>>>>>> The idea is that 'foo' should return in O(1) time. The body of $ldelay
>>>>>> is only evaluated with the first element of the returned stream is 
>>>>>> neede.
>>>>>> Sometimes, this is call full laziness. Without full laziness, a 
>>>>>> stream may
>>>>>> behave like a list, defeating the very purpose of using a stream.
>>>>>>
>>>>>> On Saturday, March 4, 2017 at 7:27:03 PM UTC-5, August Alm wrote:
>>>>>>>
>>>>>>> I've spent  few hours trying to figure out how to make proper use of 
>>>>>>> npm and gave up--for now. If the project turns into something more 
>>>>>>> serious 
>>>>>>> (i.e., useful to others) then I will have another go at it. For now my 
>>>>>>> naive attempts at making effective use of linear streams can be 
>>>>>>> witnessed 
>>>>>>> at GitHub: https://github.com/August-Alm/ats_csv_lexer Any and all 
>>>>>>> comments on how to improve are appreciated.
>>>>>>>
>>>>>>> Best wishes, August.
>>>>>>>
>>>>>>> Den fredag 3 mars 2017 kl. 23:57:54 UTC+1 skrev gmhwxi:
>>>>>>>>
>>>>>>>> One possibility is to build a npm package and then publish it.
>>>>>>>>
>>>>>>>> If you go to https://www.npmjs.com/ and seach for 'atscntrb'. You 
>>>>>>>> can find
>>>>>>>> plenty packages. You may need to install npm first.
>>>>>>>>
>>>>>>>> If you do build a npm package, I suggest that you choose a name 
>>>>>>>> space for
>>>>>>>> yourself. E.g., atscntrb-a?a-..., where ? is the first letter of 
>>>>>>>> your middle name.
>>>>>>>>
>>>>>>>> On Fri, Mar 3, 2017 at 5:48 PM, August Alm <augu...@gmail.com> 
>>>>>>>> wrote:
>>>>>>>>
>>>>>>>>> How would I best share larger code portions? I have no concerns 
>>>>>>>>> about my making my mistakes public, heh.
>>>>>>>>>
>>>>>>>>> I believe everything is lazy as-is (all data is 
>>>>>>>>> [stream_vt("sometype")]). And I've tried to write tail-recursive 
>>>>>>>>> functional 
>>>>>>>>> code. The algorithm is based on two mutually recursing functions, 
>>>>>>>>> "fun ... 
>>>>>>>>> and ..", similar to how you did things in your csv-parser (thanks for 
>>>>>>>>> pointing out that piece of code). However, I cannot set them up with 
>>>>>>>>> "fn* 
>>>>>>>>> .. and .." to enforce a local jump because they call each other in a 
>>>>>>>>> too 
>>>>>>>>> intertwined way. Might that be it?
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Den fredag 3 mars 2017 kl. 23:32:15 UTC+1 skrev gmhwxi:
>>>>>>>>>>
>>>>>>>>>> You are welcome!
>>>>>>>>>>
>>>>>>>>>> Since I have not seen your code, I could only guess :)
>>>>>>>>>>
>>>>>>>>>> Usually, what you described can be fixed by using tail-recursion, 
>>>>>>>>>> or
>>>>>>>>>> by using lazy-evaluation. The former approach is straightforward. 
>>>>>>>>>> You
>>>>>>>>>> just need to identify the function or functions that cause the 
>>>>>>>>>> deep stack
>>>>>>>>>> usage. Then try to rewrite using tail-recursion.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On Fri, Mar 3, 2017 at 5:25 PM, August Alm <augu...@gmail.com> 
>>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> Hi!
>>>>>>>>>>> I had indeed made a logical error that caused any stream with 
>>>>>>>>>>> "carriage return" followed by "newline" to recurse indefinitely. 
>>>>>>>>>>> Thank you 
>>>>>>>>>>> for your patience and pedagogical instincts, Professor! There is 
>>>>>>>>>>> still some 
>>>>>>>>>>> issue though, one that I believe is more subtle. I fixed the 
>>>>>>>>>>> logical error 
>>>>>>>>>>> and my algorithm now handles all the test cases you suggested. 
>>>>>>>>>>> However, 
>>>>>>>>>>> when fed an actual CSV-file with a thousand rows and about 300 
>>>>>>>>>>> columns it 
>>>>>>>>>>> still segfaults--unless I manually increase the stack space on my 
>>>>>>>>>>> computer! 
>>>>>>>>>>> I don't know exactly where the critical limit is, but increasing it 
>>>>>>>>>>> from 
>>>>>>>>>>> 8192 kbytes to 65536 certainly did the trick. The whole file parsed 
>>>>>>>>>>> without 
>>>>>>>>>>> problem, and rather quickly at that. It seems my algorithm makes 
>>>>>>>>>>> too much 
>>>>>>>>>>> use of stack allocation and that I may have to rethink some of my 
>>>>>>>>>>> (would-be) optimization choices.
>>>>>>>>>>> Best wishes,
>>>>>>>>>>> August
>>>>>>>>>>>
>>>>>>>>>>> Den fredag 3 mars 2017 kl. 15:22:00 UTC+1 skrev gmhwxi:
>>>>>>>>>>>>
>>>>>>>>>>>> Now you may do the following tests:
>>>>>>>>>>>>
>>>>>>>>>>>> Try:
>>>>>>>>>>>>
>>>>>>>>>>>> val ins = streamize_string_char("a;b") // should work
>>>>>>>>>>>>
>>>>>>>>>>>> Try:
>>>>>>>>>>>>
>>>>>>>>>>>> val ins = streamize_string_char("a;b\n") // may not work
>>>>>>>>>>>>
>>>>>>>>>>>> Try:
>>>>>>>>>>>>
>>>>>>>>>>>> val ins = streamize_string_char("a;b\015\012") // should cause 
>>>>>>>>>>>> crash
>>>>>>>>>>>>
>>>>>>>>>>>> On Thursday, March 2, 2017 at 9:21:21 PM UTC-5, gmhwxi wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>> When tried, I saw the following 5 chars (ascii) in small.csv:
>>>>>>>>>>>>>
>>>>>>>>>>>>> 97
>>>>>>>>>>>>> 59
>>>>>>>>>>>>> 98
>>>>>>>>>>>>> 13
>>>>>>>>>>>>> 10
>>>>>>>>>>>>>
>>>>>>>>>>>>> My testing code:
>>>>>>>>>>>>>
>>>>>>>>>>>>> #include"share/atspre_staload.hats"
>>>>>>>>>>>>> #include"share/HATS/atspre_staload_libats_ML.hats"
>>>>>>>>>>>>>
>>>>>>>>>>>>> implement main0 () = {
>>>>>>>>>>>>>   val inp = fileref_open_exn("small.csv", file_mode_r)
>>>>>>>>>>>>>   val ins = streamize_fileref_char(inp)
>>>>>>>>>>>>>   val ins = stream2list_vt(ins)
>>>>>>>>>>>>>   val ins = g0ofg1(list_vt2t(ins))97
>>>>>>>>>>>>>   val ( ) = println! ("length(ins) = ", length(ins))
>>>>>>>>>>>>>   val ( ) = (ins).foreach()(lam c => println!(char2int0(c)))
>>>>>>>>>>>>> (*
>>>>>>>>>>>>>   val lexed = lex_csv(true, ';', ins)
>>>>>>>>>>>>> *)
>>>>>>>>>>>>>   val () = fileref_close(inp)
>>>>>>>>>>>>> (*
>>>>>>>>>>>>>   val h = (lexed.head())
>>>>>>>>>>>>>   val- CSV_Field(r) = h
>>>>>>>>>>>>>   val a = r.csvFieldContent
>>>>>>>>>>>>>   val () = println!(a)
>>>>>>>>>>>>> *)
>>>>>>>>>>>>> }
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Thu, Mar 2, 2017 at 9:13 PM, August Alm <...> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Just "a;b", or? (Attached.)
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Den fredag 3 mars 2017 kl. 03:03:08 UTC+1 skrev gmhwxi:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I suspect that the file you used contains other characters.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> What is in "small.csv"?
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> On Thu, Mar 2, 2017 at 8:52 PM, August Alm <...> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The file compiles (I've tried a few compiler options) and 
>>>>>>>>>>>>>>>> "gdb run" yields
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     Program received signal SIGSEGV, Segmentation fault.
>>>>>>>>>>>>>>>>     0x00007ffff783eea5 in _int_malloc (av=0x7ffff7b6a620 
>>>>>>>>>>>>>>>> <main_arena>, bytes=16) at malloc.c:3790
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The frames 0-3 involve allocation functions that are not 
>>>>>>>>>>>>>>>> particular to my file. Frame 4 says:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>     #4  __patsfun_28__28__14 (arg0=<optimized out>, 
>>>>>>>>>>>>>>>> env1=0x605540, env0=10 '\n') at csv_lexer_dats.c:9023
>>>>>>>>>>>>>>>>     9023    ATSINSmove_con1_new(tmpret63__14, 
>>>>>>>>>>>>>>>> postiats_tysum_7) ;
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> My not-so-educated guess is that this refers to making a 
>>>>>>>>>>>>>>>> cons-cell of a stream.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> But: How can my function do just fine when manually fed 
>>>>>>>>>>>>>>>>  
>>>>>>>>>>>>>>>>     cons('a', cons( ';', sing('b'))): stream_vt(char), 
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> but segfault when I use [streamize_fileref_char] to 
>>>>>>>>>>>>>>>> construct the very same stream from the string "a;b" in a 
>>>>>>>>>>>>>>>> file? Where is 
>>>>>>>>>>>>>>>> the room for an infinite recursion in that?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Thank you,
>>>>>>>>>>>>>>>> August
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Den torsdag 2 mars 2017 kl. 23:04:35 UTC+1 skrev August Alm:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Hi!
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I'm in over my head and tried writing a CSV-parser using 
>>>>>>>>>>>>>>>>> linear lazy streams. My code thus far is 600 lines and almost 
>>>>>>>>>>>>>>>>> to my own 
>>>>>>>>>>>>>>>>> surprise I get it to compile! However, there is something 
>>>>>>>>>>>>>>>>> fishy because I 
>>>>>>>>>>>>>>>>> get a segfault when applying my program to an actual 
>>>>>>>>>>>>>>>>> CSV-file. I've been 
>>>>>>>>>>>>>>>>> trying to debug using gdb but the fault eludes me. Since I 
>>>>>>>>>>>>>>>>> don't expect 
>>>>>>>>>>>>>>>>> anyone to mull through 600 lines of code, I am hoping these 
>>>>>>>>>>>>>>>>> code snippets 
>>>>>>>>>>>>>>>>> are enough for one of you guys to give me some advice.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> This code executes just fine:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>         implement main0 () = {
>>>>>>>>>>>>>>>>>            
>>>>>>>>>>>>>>>>>            val test = stream_vt_make_cons(
>>>>>>>>>>>>>>>>>                             'a', stream_vt_make_cons(
>>>>>>>>>>>>>>>>>                                     ';', 
>>>>>>>>>>>>>>>>> stream_vt_make_sing('b')))          (* the stream ('a', ';', 
>>>>>>>>>>>>>>>>> 'b') *)
>>>>>>>>>>>>>>>>>            val lexed = lex_csv(true, ';', test)
>>>>>>>>>>>>>>>>>            val h = (lexed.head())
>>>>>>>>>>>>>>>>>            val- CSV_Field(r) = h
>>>>>>>>>>>>>>>>>            val a = r.csvFieldContent
>>>>>>>>>>>>>>>>>            val () = println!(a)
>>>>>>>>>>>>>>>>>          
>>>>>>>>>>>>>>>>>          }
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Here [lex_csv] is my 600-line alogrithm. It reads a 
>>>>>>>>>>>>>>>>> [stream_vt(char)] and gives back a [stream_vt(CSVEntry)], 
>>>>>>>>>>>>>>>>> where [CSVEntry] 
>>>>>>>>>>>>>>>>> is a record type, one of whose fields is [CSVFieldContent]. 
>>>>>>>>>>>>>>>>> When executing 
>>>>>>>>>>>>>>>>> the program I get "a" printed to the console.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> This code results in a segfault:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>         implement main0 () = {
>>>>>>>>>>>>>>>>>         
>>>>>>>>>>>>>>>>>            val inp = fileref_open_exn("small.csv", 
>>>>>>>>>>>>>>>>> file_mode_r)
>>>>>>>>>>>>>>>>>            val ins = streamize_fileref_char(inp)
>>>>>>>>>>>>>>>>>            val lexed = lex_csv(true, ';', ins)
>>>>>>>>>>>>>>>>>            val () = fileref_close(inp)
>>>>>>>>>>>>>>>>>            val h = (lexed.head())
>>>>>>>>>>>>>>>>>            val- CSV_Field(r) = h
>>>>>>>>>>>>>>>>>            val a = r.csvFieldContent
>>>>>>>>>>>>>>>>>            val () = println!(a)
>>>>>>>>>>>>>>>>>          
>>>>>>>>>>>>>>>>>          }
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> The file "small.csv" only contains the string "a;b". Hence 
>>>>>>>>>>>>>>>>> I would expect this code to give the result as the previous 
>>>>>>>>>>>>>>>>> one! But, it 
>>>>>>>>>>>>>>>>> doesn't just return something else, it segfaults.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> gdb indicates there is a malloc problem having to do with 
>>>>>>>>>>>>>>>>> "GC_clear_stack_inner", in case that's helpful. (I'm a 
>>>>>>>>>>>>>>>>> mathematician who 
>>>>>>>>>>>>>>>>> recently left academia after postdoc and decided to teach 
>>>>>>>>>>>>>>>>> myself 
>>>>>>>>>>>>>>>>> programming to become more useful outside of academia; hence 
>>>>>>>>>>>>>>>>> I understand 
>>>>>>>>>>>>>>>>> type systems and the like--the mathy stuff--a lot better than 
>>>>>>>>>>>>>>>>> I understand 
>>>>>>>>>>>>>>>>> memory allocation and other stuff that most programmers are 
>>>>>>>>>>>>>>>>> supposed to be 
>>>>>>>>>>>>>>>>> confident with.)
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> What could be the problem here?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Best wishes,
>>>>>>>>>>>>>>>>> August
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> -- 
>>>>>>>>>>>>>>>> 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 post to this group, send email to 
>>>>>>>>>>>>>>>> ats-lan...@googlegroups.com.
>>>>>>>>>>>>>>>> Visit this group at 
>>>>>>>>>>>>>>>> https://groups.google.com/group/ats-lang-users.
>>>>>>>>>>>>>>>> To view this discussion on the web visit 
>>>>>>>>>>>>>>>> https://groups.google.com/d/msgid/ats-lang-users/69535c5c-eac3-472c-bb39-062ad4708a72%40googlegroups.com
>>>>>>>>>>>>>>>>  
>>>>>>>>>>>>>>>> <https://groups.google.com/d/msgid/ats-lang-users/69535c5c-eac3-472c-bb39-062ad4708a72%40googlegroups.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-user...@googlegroups.com.
>>>>>>>>>>>>>> To post to this group, send email to 
>>>>>>>>>>>>>> ats-lan...@googlegroups.com.
>>>>>>>>>>>>>> Visit this group at 
>>>>>>>>>>>>>> https://groups.google.com/group/ats-lang-users.
>>>>>>>>>>>>>> To view this discussion on the web visit 
>>>>>>>>>>>>>> https://groups.google.com/d/msgid/ats-lang-users/e608c7bb-42ce-457b-a606-9fe3525f801d%40googlegroups.com
>>>>>>>>>>>>>>  
>>>>>>>>>>>>>> <https://groups.google.com/d/msgid/ats-lang-users/e608c7bb-42ce-457b-a606-9fe3525f801d%40googlegroups.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-user...@googlegroups.com.
>>>>>>>>>>> To post to this group, send email to ats-lan...@googlegroups.com
>>>>>>>>>>> .
>>>>>>>>>>> Visit this group at 
>>>>>>>>>>> https://groups.google.com/group/ats-lang-users.
>>>>>>>>>>> To view this discussion on the web visit 
>>>>>>>>>>> https://groups.google.com/d/msgid/ats-lang-users/34dfad01-9bd4-464f-9ccd-6dfae8207f4c%40googlegroups.com
>>>>>>>>>>>  
>>>>>>>>>>> <https://groups.google.com/d/msgid/ats-lang-users/34dfad01-9bd4-464f-9ccd-6dfae8207f4c%40googlegroups.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-user...@googlegroups.com.
>>>>>>>>> To post to this group, send email to ats-lan...@googlegroups.com.
>>>>>>>>> Visit this group at https://groups.google.com/group/ats-lang-users
>>>>>>>>> .
>>>>>>>>> To view this discussion on the web visit 
>>>>>>>>> https://groups.google.com/d/msgid/ats-lang-users/c2f9d2b7-61f5-4142-b8b2-930147ee589d%40googlegroups.com
>>>>>>>>>  
>>>>>>>>> <https://groups.google.com/d/msgid/ats-lang-users/c2f9d2b7-61f5-4142-b8b2-930147ee589d%40googlegroups.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-user...@googlegroups.com.
>>>> To post to this group, send email to ats-lan...@googlegroups.com.
>>>> Visit this group at https://groups.google.com/group/ats-lang-users.
>>>> To view this discussion on the web visit 
>>>> https://groups.google.com/d/msgid/ats-lang-users/d78409e2-aff1-4b96-98f3-eb3a5d20ff95%40googlegroups.com
>>>>  
>>>> <https://groups.google.com/d/msgid/ats-lang-users/d78409e2-aff1-4b96-98f3-eb3a5d20ff95%40googlegroups.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-user...@googlegroups.com <javascript:>.
>> To post to this group, send email to ats-lan...@googlegroups.com 
>> <javascript:>.
>> Visit this group at https://groups.google.com/group/ats-lang-users.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/ats-lang-users/716c8c61-d535-412d-8584-d4030d20801d%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/ats-lang-users/716c8c61-d535-412d-8584-d4030d20801d%40googlegroups.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 post to this group, send email to ats-lang-users@googlegroups.com.
Visit this group at https://groups.google.com/group/ats-lang-users.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/ats-lang-users/14bf0cb9-38ff-44cb-b832-da73efc58a50%40googlegroups.com.

Reply via email to