If I write implement extfree<CSVErrors> = ...
then I get it passed the typechecking level of compilation, but when trying to generate C-code I instead get an error saying [extfree] has not been implemented: "csv_lexer_dats.c:93504:45: error: ‘extfree’ undeclared (first use in this function)" Den tisdag 14 mars 2017 kl. 00:57:18 UTC+1 skrev August Alm: > > Yes, as you guessed I am having problems with covariance. Some I have > solved but this one leaves me very puzzled: > > I'll copy the code here in the order that it appears in my file. First (in > "csv_lib.hats", which is #include:d at the very beginning) I have a template > > extern fun {a: vt0ype} extfree(x: a): void > > which is used to free variables in some of the functions using the > [Either] constructor. Then I have: > > vtypedef CSVErrors = List0_vt(CSVError) > > where CSVError is a non-linear datatype. If I after that definition write > > implement {CSVErrors} extfree(errs) = list_vt_free(errs), > > then I get a compiler error telling me that [CSVErrors] can't be assigned > the type of linear lists. If I try to go explicit and write > > implement{CSVErrors} extfree(errs) = let > val errs: List0_vt(CSVError) = errs > in case errs of > | ~list_vt_nil() => () > | ~list_vt_cons(er, ers1) => extfree<CSVErrors>(ers1) > end > > then I get roughly the same error, saying: > > The actual term is: S2Evar(CSVErrors(8927)) > The needed term is: S2Eapp(S2Ecst(list_vt0ype_int_vtype); > S2Ecst(CSVError), S2EVar(5476)) > > How can I help the compiler infer that CSVErrors is indeed a > listvt0ype_int_vtype of CSVError? > > Den måndag 13 mars 2017 kl. 23:42:03 UTC+1 skrev gmhwxi: >> >> Once INV annotation is done properly, template annotation can be pretty >> much removed. >> >> >> On Mon, Mar 13, 2017 at 6:39 PM, August Alm <augu...@gmail.com> wrote: >> >>> Thanks for the hint! I added template arguments wherever I could and now >>> I got some error messages that actually say something. However, I do find >>> it a bit disconcerting that the compiler would segfault rather than tell me >>> I need to annotate templates. >>> >>> Den måndag 13 mars 2017 kl. 22:02:57 UTC+1 skrev gmhwxi: >>>> >>>> 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 <augu...@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/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 >>>>>>>>>>>>>>>>>>>>>>>>>>>>> <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-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/5b1f1046-0664-447d-8ffc-bdcbb81981eb%40googlegroups.com.