From: Barry Fishman on
pjb(a)informatimago.com (Pascal J. Bourguignon) writes:

> Barry Fishman <barry_fishman(a)acm.org> writes:
>
>> pjb(a)informatimago.com (Pascal J. Bourguignon) writes:
>>> All right, but to make it a portable program, you would have to do this:
>>>
>>> (when (ignore-errors (read-from-string "#\\tab"))
>>> (push :has-tab *features*))
>>>
>>> (let ((fspec #+has-tab (format nil "~~{~~s~c~~}" #\tab)
>>> #-has-tab "~11S "))
>>> (with-open-file (stream "c:/tabout.txt" :direction :output)
>>> (format stream fspec (list 1 2 3 4 5))))
>>
>> Do portable programs accept file names in the form "c:/tabout.txt"?
>
> This is irrelevant. You may substitute *my-file-pathname* instead.

I was just trying to understand what you mean by "portable program". It
seems to be a program which follows the Common Lisp standard, without
requiring any of its non-mandated features. This is as good as any
definition of "portable program" (in this news group).

There is of course the issue of meeting the OP's requirements.

One could say that a portable program could not produce a tab delimited
file which the user requires, and common lisp should not be used. Or
one could argue that use of tabs is a bad design and the perceived
requirements should be reevaluated. Or that the tab which is a part
UTF, and every other character set the OP is likely to use during the
rest of his lifetime, and is probably in every Common Lisp to which the
OP has access.

I only bring this up because when I first started programming in Common
Lisp I found many thing that seemed to missing from the language. I'm
not talking about sockets or threads which are technically not a part of
such mainstream languages as C, but the ability to deal with basic Posix
file system in consistent ways. Yes, it could deal with obscure file
systems, but not in ways which are well defined in the language. This
causes problems when trying to both be portable and establish
predictable behavior between Common Lisp systems, even on the same
platform.

On the other hand, with time, I found the Common Lisp gave me what I
needed, if not always what I originally thought I needed, and I always
feel I am missing important features which are basic to Common Lisp,
when I use other languages.

One of the most powerful is to deal with implementation differences with
portable (and readable) code, and without any external code
prepossessing, as you did in your example. But with this power, it
masks an important issue.

The issue comes down to requirements. If one really requires tab
delimited files your example code does not work, since an output
of "(1 2 3 4 5) ", is not in any way the same as
"1<tab>2<tab>3<tab>4<tab>5<tab>".

While there are very good reasons to avoid using tab delimited files,
producing invalid output from "portable" code, I believe, is worse than
producing errors on a Common Lisp system the user is very unlikely to
ever see.

--
Barry Fishman