Page 1 of 1

(newbie) Listiness

PostPosted: Sat Oct 25, 2014 6:40 am
by mark5009
Hi. Newbie here. I am trying to understand what is happening here.

My expectation is that bar should contain (() 1 2 3 4 5) (which is what
I am after, but it doesn't. Can someone fill me in on where my thinking
is a little broken? I want to construct a list of the individual items of
foo in bar.

Thanks .. mark.

Code: Select all
> (set 'foo '(1 2 3 4 5))
(1 2 3 4 5)
> (set 'bar (cons))
()
> (dolist (it foo) (println it))
1
2
3
4
5
5
> (dolist (it foo) (list bar it))
(() 5)

Re: (newbie) Listiness

PostPosted: Sat Oct 25, 2014 12:15 pm
by bairui
Hi, Mark,

The dolist iterates the list one element at a time. Because you're not printing in that loop, the interpreter is silently throwing away each internal result. Finally the result of the whole loop (its final evaluation) is shown by the interpreter, which is (() 5), as you would expect.

For your stated goal of (() 1 2 3 4 5) you could merely do (cons bar foo)

-- bairui

Re: (newbie) Listiness

PostPosted: Sun Oct 26, 2014 1:57 am
by mark5009
Thanks for your reply, bairui. My problem is I am not being very clear.

Here is the real issue. Say I have a file I want to read:

Code: Select all
# stuff to ignore
123:avc
234:vvc
# more to ignore and the following blank line as well

# and there is the last stuff
999:xxc


I want to end up with something like:

Code: Select all
> (set 'foo-file "/tmp/foo.tmp")
> (set 'contents (slurp-in-file foo-file)

> contents
((123 "avc")(243 "vvc")(999 "xxc"))


Basically your typical read-in-a-file scenario for sysadmin work.
I am just not sure of the syntax involved in going through the file
a line at a time, throwing away the crud, then parsing the line.
I know newlisp can do it because I can make each part do its thing.
It is just the putting it all together that I am having a problem with.

TIA, mark.

Re: (newbie) Listiness

PostPosted: Sun Oct 26, 2014 3:53 am
by saulgoode
I'm sure there are Newlispers here who will be able to provide a much better solution (probably with just a single function), but nonetheless perhaps some of the following might spawn some ideas for you.

-----------------
> (set 'in-string (read-file "tmp/foo.tmp"))
"# stuff to ignore\n123:avc\n234:vvc\n# more to ignore and the following blank line as well\n\n# and there is the last stuff\n999:xxc\n"

> (set 'all-lines (parse in-string "\n"))
("# stuff to ignore" "123:avc" "234:vvc" "# more to ignore and the following blank line as well"
"" "# and there is the last stuff" "999:xxc" "")

> (set 'non-empty-lines (clean = all-lines)) ; monadic = compares to empty string
("# stuff to ignore" "123:avc" "234:vvc" "# more to ignore and the following blank line as well"
"# and there is the last stuff" "999:xxc")

> (define (comment? s) (starts-with s "#"))
> (set 'lines (clean comment? non-empty-lines))
("123:avc" "234:vvc" "999:xxc")

> (define (split-at-colons s) (parse s ":"))
> (set 'contents (map split-at-colons lines))
(("123" "avc") ("234" "vvc") ("999" "xxc"))

Re: (newbie) Listiness

PostPosted: Sun Oct 26, 2014 5:48 am
by ralph.ronnquist
Well, I'd follow saulgoode's approach, but exercise the PCRE engine more, as in:
Code: Select all
(define (slurp-in-file file)
  (map (fn (line)
        (and (regex "([0-9]*):(.*)" line 0) (list (int $1) $2)))
      (clean empty? (parse (read-file file) "\\s*(#[^\n]*)?\n" 0))))

Thus, an initial chunking that consumes end-of-of line comments as well as trailing spaces of lines, providing a mix of data lines and empty lines as separate strings, and then, after cleaning out the empty lines, a secondary parts extraction for each line making the first parts into integers.

Note that bad data lines turn up as nil data elements, without a direct trace-back to the source, but maybe the "and" clasue changed to an "if" clause could deal with that.

Re: (newbie) Listiness

PostPosted: Sun Oct 26, 2014 11:09 pm
by mark5009
Thanks, guys! That is most helpful.

.. mark.

Re: (newbie) Listiness

PostPosted: Mon Oct 27, 2014 10:23 pm
by tomtoo
This way also seems to work...
Code: Select all
(set 'a (parse (read-file "foo.tmp") "\n"))
(dolist (item a)
   (unless (or (starts-with item "\#")(empty? item))
      (push item box -1)))
(dolist (item box)
   (set 'z (parse item ":"))
   (push (cons (int (first z))(last z)) bag -1))