Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!mips!spool.mu.edu!munnari.oz.au!goanna!ok From: ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) Newsgroups: comp.lang.prolog Subject: Re: converting ascii character lists to functors Message-ID: <5384@goanna.cs.rmit.oz.au> Date: 24 Apr 91 07:16:50 GMT References: Distribution: comp Organization: Comp Sci, RMIT, Melbourne, Australia Lines: 138 In article , eiverson@nmsu.edu (Eric Iverson) writes: > The following is a letter I just wrote to Quintus: > To: teksup@quintus.com > Subject: converting ascii character lists to functors > --text follows this line-- > > I called today about converting ascii character lists into functors > which could be unified with other functors. I need to do this because > I need to use a character based read function for my file I/O. Here's > what I came up with: > > functor_chars(Functor,Chars):- > atom_chars(Char1,Chars), > tell('functor_chars'), > format('~w.~n',Char1), > see('functor_chars'), > read(Functor), > close('functor_chars'), > unix(system('rm functor_chars')). I'm sorry, but you haven't made it clear what you want this thing to do. The code is rather strange. If you have a list of character codes that you want to write to a file, that's precisely what the format code "~s" is for. So you should have done something like :- use_module(library(files), [ remove_file/1 ]). functor_chars(Functor, Chars) :- SratchFileName = functor_chars, open(StratchFileName, write, OutputStream), format(OutputStream, "~s .~n", [Chars]), close(OutputStream), open(StratchFileName, read, InputStream), read(InputStream, Term), close(InputStream), remove_file(StratchFileName), Functor = Term. And *now* I see what you want to do. Why in the name of sanity are you abusing the word "functor" (which means a pair consisting of a function symbol and an arity, e.g. fred/2) when you mean "term"? What you have here is not something that interconverts functors and character lists, but a one-way conversion from character lists to terms. The operation should thus be called chars_to_term(+Chars, -Term) and if you look in the library you will find that it already exists. There are lots of useful things in the library, and you are expected to look there _first_. library(charsio) exports the following operations: chars_to_stream(Chars, Stream) Chars must be a ground list of character codes. A new input stream is created whose contents are the Chars, and Stream is bound to the new stream. This should probably be renamed to open_string_stream/2 or something like that. with_input_from_chars(Goal, Chars) Opens an input stream whose contents are given by the list of Chars, makes that the current input stream, and executes once(Goal). When the Goal has finished, it restores the original input stream, and closes the character input stream it created. Then it succeeds or fails the same way that once(Goal) succeeded or failed. with_input_from_chars(Goal, Stream, Chars) Opens an input stream whose contents are given by the list of Chars and binds Stream to the new stream. It then calls once(Goal), then closes Stream before succeeding or failing just as once(Goal) did. with_output_to_chars(Goal, Chars) Creates a new output stream, makes that the current output stream, and executes once(Goal). The idea is that when Goal writes to current output the characters are held internally. When Goal has finished, the characters written by Goal are gathered up as a list of Chars, and the command succeeds or fails just as once(Goal) did. Thus with_output_to_chars/2 can fail if Goal fails or if you guessed wrong about Chars, but in either case the stream is closed. with_output_to_chars(Goal, Stream, Chars) Creates a new output stream and binds Stream to that new stream, then executes once(Goal). Goal having finished, the characters written to Stream are gathered up, Stream is closed, and the character list unified with Chars. The command fails if Goal fails. chars_to_term(Chars, Term) is almost the same as with_input_from_chars(read(Term), Chars) except that it takes care of adding a clause terminator " . " if necessary. For example, chars_to_term("fred", Term) ==> Term = fred chars_to_term("f(r,e(d))", Term) ==> Term = f(r,e(d)) chars_to_term("f(X,g(X))", Term) ==> Term = f(_23,g(_23)) term_to_chars(Term, Chars) is essentially the same as with_output_to_chars(write_canonical(Term), Chars) If that's not the conversion you want (and you can rely on no other conversion to give you something you can read back) then just do with_output_to_chars(print(Term), Chars) or whatever takes your fancy. It can be quite convenient to do with_output_to_chars(format(Format,ArgList), Chars) I _think_ library(charsio) was provided in release 1.6; it has been around for quite a while. The streams it manipulates are the same kind of thing as Lisp "string streams", and do not involve external files. The characters you write using with_output_to_chars/[2,3] or term_to_chars/2 are held in memory, so don't expect to write millions of them. But *PLEASE*, if you mean "term", _say_ "term" if you mean (function symbol/arity) pair, say "functor", and _only_ then if you mean function symbol, say "function symbol". DON'T say "functor" when you mean "term", it only confuses people. -- Bad things happen periodically, and they're going to happen to somebody. Why not you? -- John Allen Paulos.