On Sat, Nov 04, 2023 at 11:40:52PM +0100, Grégory Vanuxem wrote:
> Hello,
> 
> I looked a little at the different implementations of qnew and found
> some what I think are issues. qnew, which should mean, I think, quick
> new, is usually used to construct uninitialized arrays, but is rarely
> exposed, presumably because it should only be used by Spad developers
> and not FriCAS users.
> 
>  An issue comes from TwoDimensionalArrayCategory (exposed) that
> declares it. Matrix, TwoDimensionalArray and other domains use it (via
> MatrixCategory for example). But if a user uses it, and the array is
> displayed using OutputForm coercion let's see what happens:
> 
> Clozure CL:
> =============
> (1) -> qnew(4,4)$Matrix(Float)
> 
> Fatal error in "FRICASsys" : Fault during read of memory address #x5
> =============
> and returns to the system shell.
> Segmentation fault so.
> 
> SBCL:
> =============
> (2) -> qnew(4,4)$Matrix(Float)
> 
>    >> System error:
>    The value
>   0
> is not of type
>   CONS
> ===============
> 
> What happens is that from what I have seen the elements of the
> uninitialized array are integers (0) and OutputForm expects a Float
> which is implemented in Lisp with a cons. Same thing happens with
> POLY(INT) for example. I agree that the qnew function should only be
> used if you know what you're doing and you know, if necessary, the
> internal representation of an uninitialized array but having a Lisp
> error instead of a system error is somewhat disappointing. Moreover,
> if Clozure CL was used to build your FriCAS version, a segfault is
> signalled and FriCAS crashes (see Murphy's law).
> 
> I put it here before filling an issue because I think "fixing" this
> requires some thoughts. Personally I have no opinion on this, doing
> nothing, documenting this, do not expose qnew, conditional export (I
> only see INT and SINT), modifying qnew-s, but it will no longer be a
> "quick" constructor, modifying OutputForm, etc.

Well, in general array produced by 'qnew' is uninitialized and
can contain anything.  Due to internal working of Lisp almost
surely such array will be filled with valid Lisp objects.
But one can not count on those object being 0, it could be Lisp
NIL or something else (AFAIK Poplog will use NIL-s).

_Any_ attempt to read elements of uninitialized array may lead
to troubles.  So it is not only printing, but in general it is
unsafe to pass uninitialized array to a routine, unless one
_knows_ that the routine will initialize the array.

Currenly exposure is for constructors, if constructor is exposed
all its operations are exposed.  And 'qnew' must be exported for
use in packages.

'qnew' is for speed, so IMO at code level we could check if it
actually gives speedup and replace it by 'new' in cases where
is does not matter.  Actually, for general integer vectors qnew
gives no speedup and we do not have it.  But AFAICS it gives
speedup exactly in cases where inproper uses is dangerous.
So really not much to do at code level.

We could add the followowing to description of 'qnew':

Use only when you know what you are doing.

Possibly we could add a FAQ entry with some explanation.

> BTW, Waldek, in your implementation of (unexposed) DoubleFloatVector,
> DoubleFloatMatrix and their Complex counterparts, you use, contrary to
> usual uses in FriCAS, for arrays at least, Integer as qnew arguments.
> Wouldn't it be preferable to use NonNegativeInteger instead? You had
> something in mind while doing this maybe.  Again, the following code is
> a nonsense but errare humanum est, even when typing:
> 
> Clozure CL:
> ================
> (1) -> qnew(-4)$DoubleFloatVector
> Fatal error in "FRICASsys" : Cannot allocate a (SIMPLE-ARRAY
> DOUBLE-FLOAT (*)) with -4 elements.
> Objects of type (SIMPLE-ARRAY DOUBLE-FLOAT (*)) can can have at most
> 72057594037927935 elements in this implementation.
> ================
> FriCAS crashes and it is a return to the system shell.
> 
> SBCL:
> ================
> (9) -> qnew(-3)$DoubleFloatVector
> 
>    >> System error:
>    The value
>   -3
> is not of type
>   (MOD 4611686018427387901)
> ================

Again, 'qnew' is for cases when the user knows what she/he is
doing.

I have doubts about general usefulness of NonNegativeInteger.  Namely,
arithmetic is likely to produce Integer and then one needs coercion
to get NonNegativeInteger.  To avoid extra code one probably would
use qcoerce and then we are back where we started: there is no
checking.  And with Integer code is simpler.

-- 
                              Waldek Hebisch

-- 
You received this message because you are subscribed to the Google Groups 
"FriCAS - computer algebra system" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to fricas-devel+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/ZUbjqtISXAtYeCMk%40fricas.org.

Reply via email to