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.

Reply via email to