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 <[email protected]>
>>>>>>> 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 <[email protected]>
>>>>>>>>> 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 <[email protected]
>>>>>>>>>>>>>> > 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 <
>>>>>>>>>>>>>>>> [email protected]> 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
>>>>>>>>>>>>>>>>>>>>>> [email protected].
>>>>>>>>>>>>>>>>>>>>>> To post to this group, send email to
>>>>>>>>>>>>>>>>>>>>>> [email protected].
>>>>>>>>>>>>>>>>>>>>>> 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
>>>>>>>>>>>>>>>>>>>> [email protected].
>>>>>>>>>>>>>>>>>>>> To post to this group, send email to
>>>>>>>>>>>>>>>>>>>> [email protected].
>>>>>>>>>>>>>>>>>>>> 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
>>>>>>>>>>>>>>>>> [email protected].
>>>>>>>>>>>>>>>>> To post to this group, send email to
>>>>>>>>>>>>>>>>> [email protected].
>>>>>>>>>>>>>>>>> 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 [email protected].
>>>>>>>>>>>>>>> To post to this group, send email to
>>>>>>>>>>>>>>> [email protected].
>>>>>>>>>>>>>>> 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 [email protected].
>>>>>>>>>> To post to this group, send email to [email protected].
>>>>>>>>>> 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 [email protected].
>>>>>>>> To post to this group, send email to [email protected].
>>>>>>>> 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 [email protected].
To post to this group, send email to [email protected].
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.