>>I take that as being somewhat tongue-in-cheek. ATS is a very theoretical
language, after all.

I know that this sounds very ironic but interesting stuff often does sound
ironic :)

My view of programming language research is changing gradually but surely.
I now strongly feel
that the most important programming support is to facilitate the need to
alter/adapt the behaviour
of a written program without actually requiring direct changes to be made
to the program. And the
template system of ATS can be seen as an attempt to provide programming
support of this sort.


On Wed, Mar 8, 2017 at 4:47 PM, August Alm <august...@gmail.com> wrote:

> See in.
>
> Den onsdag 8 mars 2017 kl. 17:51:36 UTC+1 skrev gmhwxi:
>>
>> Tangential to the topic of monads: Do you know if someone has thought
>>> about the relations between ATS and "enriched effect calculus" (as
>>> described in http://homepages.inf.ed.ac.uk/als/Research/Sources/eec.pdf)
>>> or "linear state monads" (as mentioned in https://arxiv.org/pdf/1403.147
>>> 7.pdf)? There is a clear analogy. Implementing a concept such as a
>>> linear state monad in ATS would be nice, I think. Monadic programming on an
>>> Arduino, anyone? =) It would certainly be a unique selling point.
>>>
>>
>> I can't really follow these monad papers. Too much for me :)
>> Given your background, maybe you could give this a try?
>>
>> I'm tempted but I feel like I have to understand ATS:s function tags
> ("cloref" and the like, the flavours of function) better first, and
> generally get a more solid footing. I don't want to write something "cool",
> I want it to be useful, too.
>
>
>> Over the years, I have gradually grown more and more cynic about
>> "theoretic" research
>> in the area of programming languages. I feel that the most urgent issue
>> in programming is
>> to find effective approaches to reducing programming complexity.
>>
>> I take that as being somewhat tongue-in-cheek. ATS is a very theoretical
> language, after all. To clarify, I think Haskell suffers greatly from
> having too little focus on efficiency (among many of its users, not among
> the guys working on the compiler). I heard about ATS about the same time as
> I heard about Idris (the dependent type thing) and decided to pursue ATS
> precisely because of its air of efficiency and "real-world-readiness". I do
> still love my Haskell though, mainly because it is so easy to be productive
> with it. Scala has a very good no-bs culture and good library hygiene, but
> I'm not too fond of OOP so...
>
>
>> For instance, in your csv parser, there are a lot of if-then-else's.
>> Maybe you took them from
>> some Haskel code. The point is that if-then-else's make programming hard
>> to write and harder
>> to read/follow. I propose the following style:
>>
>> I first tried to write it using only pattern matching but failed to get
> it passed the typechecker. Maybe I will have another go at it.
>
>
>> 1) Implementing a csv parser without worrying about quotes (DQUOT). Call
>> this version 1.
>> 2) Using templates to improve version 1 without directly modifying
>> version 1. Another way
>>     to put it: you still have version 1 available after doing the
>> improvement.
>>
>> If I was uncertain about the algorithm then such an incremental
> development style would surely be preferable, but since the code is a port
> of a tried and tested Haskell library I'm
> not very motivated to scrap and start over. But for my next project(s) I
> will try to heed your words.
>
> I know that this may sound a bit vague but that is my point. Being vague
>> makes people
>> think more and more deeply :)
>>
>> Cheers!
>>
>>
>> On Tuesday, March 7, 2017 at 4:52:58 PM UTC-5, August Alm wrote:
>>>
>>> I'm glad too! I wrote my first "Hello World" program (in Haskell) less
>>> than four months ago, before that I was completely illiterate about
>>> programming--writing a linear, lazy CSV-parser in ATS has definitely been
>>> my most challenging venture so far. I mean this in a good way. ATS is
>>> quickly becoming my favorite language. It is daunting at times, sure, but
>>> its unique combination of low-level abilities and functional abstractions
>>> makes me feel like the Star Trek idiom "To boldly go where no one has gone
>>> before", heh. The ATS sky is so vast I've almost forgot about monads. And
>>> YES!, I do suggest trying ATS to every programmer I meet.
>>>
>>> Tangential to the topic of monads: Do you know if someone has thought
>>> about the relations between ATS and "enriched effect calculus" (as
>>> described in http://homepages.inf.ed.ac.uk/als/Research/Sources/eec.pdf)
>>> or "linear state monads" (as mentioned in https://arxiv.org/pdf/1403.147
>>> 7.pdf)? There is a clear analogy. Implementing a concept such as a
>>> linear state monad in ATS would be nice, I think. Monadic programming on an
>>> Arduino, anyone? =) It would certainly be a unique selling point.
>>>
>>> I do not understand what you're aiming at with your suggestion to maje
>>> CSVState a datavtype or absvtype. Could you elaborate? I have seen abstract
>>> types used as a way to make otherwise allowed operation illegal (there is
>>> an example in your book, I think, of how to construct a record type where
>>> some fields are mutable and some are not), but not for the sake of
>>> overloading symbols.
>>>
>>> I will rewrite the code so that DELIM and QNLIN are passed as templates.
>>> I also intend to add some further functionality, like functions for
>>> filtering out errors, for printing and for collecting the output in tabular
>>> form with rows and columns rather than as a single row. When I'm satisfied
>>> I will make an npm-package out of it.
>>>
>>> Best wishes,
>>> August
>>>
>>> Den tisdag 7 mars 2017 kl. 02:21:00 UTC+1 skrev gmhwxi:
>>>>
>>>> Really glad that you got it to work!
>>>>
>>>> I suggest that you make a npm-package for the parser and then
>>>> publish the package. In this way, other ats-lang users can benefit
>>>> from your work easily.
>>>>
>>>> You could try to introduce some abstract types into your code. For
>>>> instance, I would suggest that you make CSVstate a datavtype (linear
>>>> datatype)
>>>> (a datatype is often referred to as being semi-abstract). Then you can
>>>> introduce overloaded symbols for functions processing CSVstate, making
>>>> your code
>>>> more accessible.
>>>>
>>>> Also, the following interface:
>>>>
>>>> extern fun
>>>> lex_csv(QNLIN: bool, DELIM: char, cs: llstring): CSVEntries
>>>>
>>>> can and probably should be changed into
>>>>
>>>> extern
>>>> fun{}
>>>> lex_csv(cs: listing): CSVEntries
>>>>
>>>> The parameters QNLIN and DELIM can be passed via templates:
>>>>
>>>> extern
>>>> fun{} lex_csv$QNLIN(): char
>>>> extern
>>>> fun{} lex_csv$DELIM(): char
>>>>
>>>> implement{} lex_csv$QNLIN() = false
>>>> implement{} lex_csv$DELIM() = ',' // default value
>>>>
>>>> Writing function templates (instead of functions) enables you to move
>>>> your code around very conveniently. You can even move template code
>>>> into the body of another function.
>>>>
>>>> That's all for now. Hope you will like ATS and tell/teach it to your
>>>> friends.
>>>>
>>>> Cheers!
>>>>
>>>> On Monday, March 6, 2017 at 4:06:11 PM UTC-5, August Alm wrote:
>>>>>
>>>>> The code now seems to work as inteded!
>>>>>
>>>>> https://github.com/August-Alm/ats_csv_lexer
>>>>>
>>>>> Thank you for all the help. I still don't fully grokk why the function
>>>>> needs to consume each of its arguments--will have to meditate more on
>>>>> that--but at least I know how to write code like this from now on.
>>>>>
>>>>> Den måndag 6 mars 2017 kl. 17:43:36 UTC+1 skrev gmhwxi:
>>>>>>
>>>>>> Yes, CSVstate needs to be changed as well.
>>>>>>
>>>>>> However, your code needs very little change. This is like a
>>>>>> a 5 minute job to me. I would be happy to give it a try if you say so.
>>>>>> But I thought that you might want to get the thrill of fixing the
>>>>>> code :)
>>>>>>
>>>>>> On Monday, March 6, 2017 at 11:30:27 AM UTC-5, August Alm wrote:
>>>>>>>
>>>>>>> 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>
>>>>>>>> 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/EXAM
>>>>>>>>>> PLE/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/grou
>>>>>>>>>>>>>>>>>>>>>>> p/ats-lang-users.
>>>>>>>>>>>>>>>>>>>>>>> To view this discussion on the web visit
>>>>>>>>>>>>>>>>>>>>>>> https://groups.google.com/d/ms
>>>>>>>>>>>>>>>>>>>>>>> gid/ats-lang-users/69535c5c-ea
>>>>>>>>>>>>>>>>>>>>>>> c3-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/grou
>>>>>>>>>>>>>>>>>>>>> p/ats-lang-users.
>>>>>>>>>>>>>>>>>>>>> To view this discussion on the web visit
>>>>>>>>>>>>>>>>>>>>> https://groups.google.com/d/ms
>>>>>>>>>>>>>>>>>>>>> gid/ats-lang-users/e608c7bb-42
>>>>>>>>>>>>>>>>>>>>> ce-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/grou
>>>>>>>>>>>>>>>>>> p/ats-lang-users.
>>>>>>>>>>>>>>>>>> To view this discussion on the web visit
>>>>>>>>>>>>>>>>>> https://groups.google.com/d/ms
>>>>>>>>>>>>>>>>>> gid/ats-lang-users/34dfad01-9b
>>>>>>>>>>>>>>>>>> d4-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/grou
>>>>>>>>>>>>>>>> p/ats-lang-users.
>>>>>>>>>>>>>>>> To view this discussion on the web visit
>>>>>>>>>>>>>>>> https://groups.google.com/d/ms
>>>>>>>>>>>>>>>> gid/ats-lang-users/c2f9d2b7-61
>>>>>>>>>>>>>>>> f5-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/grou
>>>>>>>>>>> p/ats-lang-users.
>>>>>>>>>>> To view this discussion on the web visit
>>>>>>>>>>> https://groups.google.com/d/msgid/ats-lang-users/d78409e2-af
>>>>>>>>>>> f1-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.
>>>>>>>>> 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/716c8c61-d5
>>>>>>>>> 35-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/f19d1d97-1aa7-40a2-83e3-d779c3f674b8%
> 40googlegroups.com
> <https://groups.google.com/d/msgid/ats-lang-users/f19d1d97-1aa7-40a2-83e3-d779c3f674b8%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/CAPPSPLqJWLvBR4-ahP9YUxjULNd%3DkLGQ5v009RaHUwvaOy6O%2Bw%40mail.gmail.com.

Reply via email to