I will take a look later. Based on your description, the issue seems to be caused by not providing certain template arguments explicitly:
Say, foo is a template. Please use foo<...>(...) instead of foo(...) Compared to Haskell, type inference in ATS is quite limited :) On Mon, Mar 13, 2017 at 4:51 PM, August Alm <august...@gmail.com> wrote: > So... I added some "second stage" parsing functionality, to get the en > result in tabular form rahter than as a single [stream_vt], and to check > for global errors such as unequal number of columns in the rows, and now I > am back to segfaulting! =( However, this time it does not seem to be a > stack issue because I run into the segmentation fault already at the > compilation stage. > > I code in Vim and have it set up so that typing ":make" will run "patsopt > -tc -d %", i.e., typechecking only. When I do everything seems fine--no > complaints. I have used this utility for some time now and it has always > worked like a charm. Wierdly though, if I issue "$ patsopt -tc -d > csv_lexer.dats" in the console instead I get a segfault. The same happens > for every other compilation command: I've tried compiling just using type > checking, just to c, or etc. Always segfault. Compiling with the "-verbose" > flag prints > > exec(patsopt --output csv_lexer_dats.c --dynamic csv_lexer.dats) > Segmentation fault > exec(patsopt --output csv_lexer_dats.c --dynamic csv_lexer.dats) = 35584 > > which does not tell me anything. > > My code can be found at https://github.com/August-Alm/ats_csv_lexer Note > that I have moved some function implementations into a hats-file. Might > this be a cause of trouble? Any tips at all on how to debug this are most > appreciated. I don't know where to even begin as gdb seems useless as long > as I can't even generate the C-code. > > Best wishes, > August > > Den onsdag 8 mars 2017 kl. 23:44:10 UTC+1 skrev gmhwxi: >> >> >>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 <augu...@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.1477.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.1477.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/grou >>>>>>>>>>> p/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-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/ms >>> gid/ats-lang-users/f19d1d97-1aa7-40a2-83e3-d779c3f674b8%40go >>> oglegroups.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/d38dfda3-e1f5-4633-a6ae-ef6274e95fb3% > 40googlegroups.com > <https://groups.google.com/d/msgid/ats-lang-users/d38dfda3-e1f5-4633-a6ae-ef6274e95fb3%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/CAPPSPLrYVmUgZKoD9YXrCBpF7e5y8fL-ZXDKD3E4ZkJp3V2vqA%40mail.gmail.com.