I see. Yes, being able to write st.tableRow(2)
instead of st.2->tableRow := 2 would make the code a little cleaner, I guess, What would really reduce syntacic noise in my code though would be a slick way of writing what currently I have as st.2->tableRow := st.2->tableRow + 1 Continuing your suggestion, I can write something like extern fun {} CSVState_update_tableRow ( st: !CSVState, up: int -> int ) : void implement {} CSVState_update_tableRow(st, up) = let val @CSVState(s) = st in s.tableRow := up(s.tableRow); fold@(st) end fun {} plus(n: int): (int -> int) = lam(i) => n + i overload .tableRow with CSVState_update_tableRow After this I can write st.tableRow(plus(1)) Is there a way to use overloading that would let me write that instead as st.tableRow(+1) ? I tried "overload + with plus" but get the error "operator fixity cannot be resolved" when used. Den onsdag 8 mars 2017 kl. 02:03:33 UTC+1 skrev gmhwxi: > > I was referring to some kind of code of the following style: > > typedef > CSVState_rec = > @{ > tableRow = int, > tableCol = int, > textRow = int, > textCol = int > } > > datavtype > CSVState = CSVState of CSVState_rec > > extern > fun{} > CSVState_get_tableRow(!CSVState): int > extern > fun{} > CSVState_set_tableRow(!CSVState, int): void > overload .tableRow with CSVState_get_tableRow > overload .tableRow with CSVState_set_tableRow > > implement > {} > CSVState_get_tableRow > (state) = let > // > val+CSVState(x0) = state in x0.tableRow > // > end // end of [CSVState_get_tableRow] > implement > {} > CSVState_set_tableRow > (state, i0) = let > // > val+@CSVState(x0) = state in x0.tableRow := i0; fold@(state) > // > end // end of [CSVState_set_tableRow] > typedef > CSVState_rec = > @{ > tableRow = int, > tableCol = int, > textRow = int, > textCol = int > } > > datavtype > CSVState = CSVState of CSVState_rec > > extern > fun{} > CSVState_get_tableRow(!CSVState): int > extern > fun{} > CSVState_set_tableRow(!CSVState, int): void > overload .tableRow with CSVState_get_tableRow > overload .tableRow with CSVState_set_tableRow > > implement > {} > CSVState_get_tableRow > (state) = let > // > val+CSVState(x0) = state in x0.tableRow > // > end // end of [CSVState_get_tableRow] > implement > {} > CSVState_set_tableRow > (state, i0) = let > // > val+@CSVState(x0) = state in x0.tableRow := i0; fold@(state) > // > end // end of [CSVState_set_tableRow] > > 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/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. >>>>>>>> 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-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/d11e9572-1725-414e-b22f-a305a49540b2%40googlegroups.com.