From: Pascal J. Bourguignon on
Barry Fishman <barry_fishman(a)acm.org> writes:

> 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.

Sure. It is well know to long time cll readers, that #\TAB and
characters vs. codes are just my pet peeve. I may surprise newcomers.

Considering that #\TAB is semi-standard, that is, when there is a
control code that means Tabulate in the character set provided by the
implementation, it MUST be #\TAB, therefore you can also assume it is
and accept to have a program that will break on implementations where
the character set is EBCDIC. Even on EBCDIC systems, they should
nowaday use Unicode!

So, sorry, I was just "joking".

--
__Pascal Bourguignon__
http://www.informatimago.com