From: Zach Beane
Subject: Portability gotchas
Date: 
Message-ID: <m33b4zo73f.fsf@unnamed.xach.com>
I've run into a few situations where I discovered rather late that I
was relying on unportable behavior. Here they are:

  - Arrays aren't required to be predictably initialized. On many
    Lisps, (make-array 5 :element-type '(unsigned-byte 8)) will give
    you a vector of five zeros, but it's not required, and LispWorks
    initializes arrays with (apparent) garbage. Moral: provide
    :initial-element or :initial-contents.

  - The default package :use list, when none is specified in
    defpackage, is implementation-dependent. Most Lisps include the
    COMMON-LISP package, but some include more than just that, and
    some include nothing (SBCL). Moral: provide a package :use list in
    defpackage.

  - Modifying objects used as hash table keys will produce undefined
    behavior for further hash table operations. I found this out when
    I wrote a word-chain program that produced tables of adjacent
    words by moving a wildcard across a string, e.g. "_ood" "f_od"
    "fo_d" "foo_", but it turns using such a mutated string as a hash
    table key is not required to work (and it didn't work in Allegro
    CL). Moral: don't do that.

All these situations are pretty clearly specified by the standard, but
since they worked a particular way in a few different Lisps, I didn't
bother looking up the specified behavior until I ran into a Lisp that
acted differently.

Have you run into portability issues like this? Do you have any morals
to share?

Zach

From: Tayssir John Gabbour
Subject: Re: Portability gotchas
Date: 
Message-ID: <1172080404.046186.160420@j27g2000cwj.googlegroups.com>
On Feb 21, 4:36 pm, Zach Beane <····@xach.com> wrote:
> I've run into a few situations where I discovered rather late that I
> was relying on unportable behavior. Here they are:
> [...]
>
> All these situations are pretty clearly specified by the standard, but
> since they worked a particular way in a few different Lisps, I didn't
> bother looking up the specified behavior until I ran into a Lisp that
> acted differently.

Well...

   - Modifying literals. (You know, quoted lists, literal strings,
     etc.) Offered me many minutes (hours?) of big fun.

   - In Loop, putting FOR clauses after body clauses like WHILE.
     The following picture illustrates my temptation to use Iterate,
     in such moments: <http://dali.urvas.lt/forviewing/pic27.jpg>

     And the terrible thing is that Loop's supposed to be
     "intuitive." I think people loosen their morals enough to not
     check Loop's syntax rigorously in this case.

   - Not using eval-when around function definitions used in
     expanding macros within the same file. Works fine when
     interpreting...

   - This isn't implementation-specific behavior... But often, people
     use symbols-as-linguistic-words pretty loosely because they
     didn't want to learn how packages work. When people agree it's
     time to bring some ethics into the codebase, all sorts of
     assumptions suddenly break about how symbols print and compare.


> Have you run into portability issues like this? Do you have any morals
> to share?

I should have morals to share, shouldn't I? ("Oh, of course I've
written lint-like tools. They signal errors when I even /think/ about
making such mistakes.")

I have a warning though. You know how many programmers simply let
thousands of wildly urgent compiler warning messages scroll by? As if
they were just a pleasant thing to stare at while letting the mind
rest a bit?

Some program in Lisp.


Tayssir
--
http://wiki.alu.org/Lisp_Gotchas
From: Zach Beane
Subject: Re: Portability gotchas
Date: 
Message-ID: <m3wt2bmlwh.fsf@unnamed.xach.com>
"Tayssir John Gabbour" <············@googlemail.com> writes:

>    - Not using eval-when around function definitions used in
>      expanding macros within the same file. Works fine when
>      interpreting...

Ah yes, that reminds me of another recent one:

  (defconstant +foo+ 1)

  (case bar
    (#.+foo+ ...))

This will compile in some Lisps, but doesn't necessarily, and clisp in
particular will not accept it.

Zach
From: Tim Bradshaw
Subject: Re: Portability gotchas
Date: 
Message-ID: <1172138813.654628.158400@l53g2000cwa.googlegroups.com>
On Feb 21, 5:53 pm, "Tayssir John Gabbour"
<············@googlemail.com> wrote:

>
> I have a warning though. You know how many programmers simply let
> thousands of wildly urgent compiler warning messages scroll by? As if
> they were just a pleasant thing to stare at while letting the mind
> rest a bit?

When I rule the world this problem will go away.  There will be a lot
of surplus soap though.

--tim
From: John Thingstad
Subject: Re: Portability gotchas
Date: 
Message-ID: <op.tn31qcgkpqzri1@pandora.upc.no>
On Wed, 21 Feb 2007 16:36:52 +0100, Zach Beane <····@xach.com> wrote:

>
> Have you run into portability issues like this? Do you have any morals
> to share?
>
> Zach

Sure. Using make-pathname under Windows. What is a device?
ACL and Corman seem to think C: is a device.
In LispWorks it is nil..

-- 
Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
From: Tim Bradshaw
Subject: Re: Portability gotchas
Date: 
Message-ID: <1172138863.228068.165970@s48g2000cws.googlegroups.com>
On Feb 21, 6:02 pm, "John Thingstad" <··············@chello.no> wrote:

> Sure. Using make-pathname under Windows. What is a device?
> ACL and Corman seem to think C: is a device.
> In LispWorks it is nil..

Always, *always* start from a parsed namestring, on any OS.
From: Barry Margolin
Subject: Re: Portability gotchas
Date: 
Message-ID: <barmar-009C74.21051821022007@comcast.dca.giganews.com>
In article <··············@unnamed.xach.com>,
 Zach Beane <····@xach.com> wrote:

> I've run into a few situations where I discovered rather late that I
> was relying on unportable behavior. Here they are:
> 
>   - Arrays aren't required to be predictably initialized. On many
>     Lisps, (make-array 5 :element-type '(unsigned-byte 8)) will give
>     you a vector of five zeros, but it's not required, and LispWorks
>     initializes arrays with (apparent) garbage. Moral: provide
>     :initial-element or :initial-contents.

I've rarely had much need to access array elements before I filled them 
in.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***
From: Vassil Nikolov
Subject: Re: Portability gotchas
Date: 
Message-ID: <yy8vabz6d7yk.fsf@eskimo.com>
On Wed, 21 Feb 2007 21:05:18 -0500, Barry Margolin <······@alum.mit.edu> said:
| ...
| I've rarely had much need to access array elements before I filled them 
| in.

  Being one of those lucky few who do not program in the looking-glass
  world...

  ---Vassil.


-- 
Our programs do not have bugs; it is just that the users' expectations
differ from the way they are implemented.
From: Zach Beane
Subject: Re: Portability gotchas
Date: 
Message-ID: <m3hctem6p3.fsf@unnamed.xach.com>
Barry Margolin <······@alum.mit.edu> writes:

> In article <··············@unnamed.xach.com>,
>  Zach Beane <····@xach.com> wrote:
> 
> > I've run into a few situations where I discovered rather late that I
> > was relying on unportable behavior. Here they are:
> > 
> >   - Arrays aren't required to be predictably initialized. On many
> >     Lisps, (make-array 5 :element-type '(unsigned-byte 8)) will give
> >     you a vector of five zeros, but it's not required, and LispWorks
> >     initializes arrays with (apparent) garbage. Moral: provide
> >     :initial-element or :initial-contents.
> 
> I've rarely had much need to access array elements before I filled them 
> in.

I took the 0s for granted and treated them as a value meaning
"uninitialized".

Zach
From: Vassil Nikolov
Subject: Re: Portability gotchas
Date: 
Message-ID: <yy8vbqjmd810.fsf@eskimo.com>
On 21 Feb 2007 10:36:52 -0500, Zach Beane <····@xach.com> said:
| ...
|   - Modifying objects used as hash table keys will produce undefined
|     behavior for further hash table operations. I found this out when

  Strictly speaking, this is not a portability gotcha, nor an issue
  specific to Lisp...  (Incidentally, "what is a hash table?" is an
  excellent, and extremely effective, interview question.)

| ...
| Do you have any morals to share?

  This isn't mine, of course, but it does apply to programming, too:

    `Be what you would seem to be'---or, if you'd like it put more
    simply---`Never imagine yourself not to be otherwise than what it
    might appear to others that what you were or might have been was not
    otherwise than what you had been would have appeared to them to be
    otherwise.'  (_Alice in Wonderland_, Chapter IX)

 (couldn't resist...).

 ---Vassil.

-- 
Our programs do not have bugs; it is just that the users' expectations
differ from the way they are implemented.
From: ············@gmail.com
Subject: Re: Portability gotchas
Date: 
Message-ID: <1172161212.363728.188970@a75g2000cwd.googlegroups.com>
On Feb 21, 7:36 am, Zach Beane <····@xach.com> wrote:
> Have you run into portability issues like this? Do you have any morals
> to share?

Something I've encountered is the boxed-vs-unboxed arrays issue (which
I think has been discussed extensively in an earlier thread).  If you
give an :ELEMENT-TYPE argument to MAKE-ARRAY, Lisp has the _option_ to
unbox the array objects, but is not _required_ to.  This is a big deal
if you want to pass, say, an array of doubles to an external routine
written in C or Fortran; when these languages ask for an array of
doubles, they mean a chunk of memory containing doubles and nothing
but doubles, stored contiguously.  If the Lisp boxes the array
elements, then you have to copy in and copy out.  There isn't a
portable way to query a Lisp to see if it boxes arrays, but if the
implementation offers some kind of "vector-pointer" function or its
FFI supports putting a Lisp array in place of a C array, then it
probably doesn't box.  This can be annoying for complex numbers
though, as many Lisps box complex numbers.

mfh
From: Zach Beane
Subject: Re: Portability gotchas
Date: 
Message-ID: <m3lkiqma8r.fsf@unnamed.xach.com>
·············@gmail.com" <············@gmail.com> writes:

> On Feb 21, 7:36 am, Zach Beane <····@xach.com> wrote:
> > Have you run into portability issues like this? Do you have any morals
> > to share?
> 
> Something I've encountered is the boxed-vs-unboxed arrays issue (which
> I think has been discussed extensively in an earlier thread).  If you
> give an :ELEMENT-TYPE argument to MAKE-ARRAY, Lisp has the _option_ to
> unbox the array objects, but is not _required_ to.  This is a big deal
> if you want to pass, say, an array of doubles to an external routine
> written in C or Fortran; when these languages ask for an array of
> doubles, they mean a chunk of memory containing doubles and nothing
> but doubles, stored contiguously.  If the Lisp boxes the array
> elements, then you have to copy in and copy out.  There isn't a
> portable way to query a Lisp to see if it boxes arrays, 
[snip]

Isn't that what UPGRADED-ARRAY-ELEMENT-TYPE is for?

Zach
From: Vassil Nikolov
Subject: Re: Portability gotchas
Date: 
Message-ID: <yy8vk5y9y2lg.fsf@eskimo.com>
On 22 Feb 2007 11:24:04 -0500, Zach Beane <····@xach.com> said:

| ·············@gmail.com" <············@gmail.com> writes:
|| ...
|| There isn't a
|| portable way to query a Lisp to see if it boxes arrays, 
| [snip]

| Isn't that what UPGRADED-ARRAY-ELEMENT-TYPE is for?

  No.  By definition, you cannot tell at the Lisp level whether an
  object is boxed or unboxed.  (You could only if you penetrated into
  the level underneath.)  Fixnums are probably the canonical example
  (of course, (< MOST-POSITIVE-FIXNUM (EXPT 2 (1- MACHINE-WORD-SIZE)))
  is strong circumstantial evidence that they are unboxed (ignoring
  the fact that you cannot tell the machine word size at the Lisp level,
  either)).

  UPGRADED-ARRAY-ELEMENT-TYPE only tells you what type the
  implementation actually gives you, in Lisp terms.  For example,
  (SIGNED-BYTE 63) might get upgraded to (SIGNED-BYTE 64) and still you
  don't know if it is boxed or not.

  ---Vassil.

-- 
Our programs do not have bugs; it is just that the users' expectations
differ from the way they are implemented.
From: ············@gmail.com
Subject: Re: Portability gotchas
Date: 
Message-ID: <1173215386.421138.186200@c51g2000cwc.googlegroups.com>
On Feb 22, 7:28 pm, Vassil Nikolov <···············@pobox.com> wrote:
>   UPGRADED-ARRAY-ELEMENT-TYPE only tells you what type the
>   implementation actually gives you, in Lisp terms.  For example,
>   (SIGNED-BYTE 63) might get upgraded to (SIGNED-BYTE 64) and still you
>   don't know if it is boxed or not.

That's right.  It's a PITA with complex numbers; C(99) and Fortran of
course don't box their complex floating-point numbers (and even if
they did, there's no guarantee that the box format would be the
same!), and so it's basic trial and error or "ask the developer" if
you want to find out if you can call e.g. the complex BLAS without
copyin/copyout.

The trouble with IEEE 754 is that it was meant for static languages
without the dynamic debugging environment that CL and others provide.
In a really complicated and highly optimized floating-point code, it
may not even be useful to get dynamic debugging info, since your code
may have been auto-generated (think ATLAS or FFTW) and so you
shouldn't even try to debug the code -- rather you should debug the
code _generator_.  That's one reason why IEEE 754 non-signaling NaN's
exist -- sometimes it's more useful to let the computation blow
through to the end and then try to debug by interpreting the results.

mfh
From: Robert Dodier
Subject: Re: Portability gotchas
Date: 
Message-ID: <1172167960.379848.207880@k78g2000cwa.googlegroups.com>
On Feb 21, 8:36 am, Zach Beane <····@xach.com> wrote:

> Have you run into portability issues like this?

(1) Stuff having to do with files or i/o.

(2) The CL spec can be interpreted (Clisp, Allegro) as ruling out
IEEE 754 floating point special values. Some implementations
(CMUCL, SBCL) allow them anyway.

(3) GCL seems to have a noticeably greater lack of conformance to
ANSI CL than other implementations.

(4) The divide between Windows and *nix is nontrivial.

FWIW
Robert Dodier
From: Pascal Bourguignon
Subject: Re: Portability gotchas
Date: 
Message-ID: <87tzx0f6u1.fsf@voyager.informatimago.com>
Zach Beane <····@xach.com> writes:
> Have you run into portability issues like this? Do you have any morals
> to share?

You've got a whole range of portability issue when mixing #+ or #-
with themselves, or with ## and #=.

'(#+a #+b x y z)

'(#+#1=a #1#)

Most implementations try to give the same results, but there are exceptions.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
        Un chat errant
se soulage
        dans le jardin d'hiver
                                        Shiki