On Mon, Mar 03, 2025 at 05:06:31PM +0000, Martin Baker wrote:
> I am finding my working code is producing a lot of compiler warnings.
> The code is working OK so should I take any notice of these warnings?
> 
> I have distilled the most common ones to the test cases below:
> 
> test1 says "x has no value". I've got a hazy memory that there is some
> issue with a function returning a value that may not be valid outside
> the scope of the function. Is it something like that? Although the code
> does run as I would expect so should I make some change just to
> eliminate the warning?

This warning looks like a bug in the Spad compiler.  Namely
it looks that 'if' is loosing information that 'x' has initial
value.  I will try to fix this, but in the mean time you can
safely ignore this one.

> Why does test3 produce an warning and not test2?
> I have commented out test3 because the "The variable % is defined but
> never used." warning masks out the "x has no value" warning.

I am not sure what you mean saying "masks out".  The "The variable
% is defined but never used." warning comes from Lisp compiler (sbcl).
This warning is true, but useless one: '%' is an extra (hidden)
parameter added to Spad functions and is passed by each Spad function
call.  It is necessary, because when doing call we do not know
if the function will use it.

Actually this warning indicates good thing: in 'test3' all operations
are inlined, so it is much more efficient than 'test2' (also, 'test2'
has quadratic complexity while 'test3' has linear complexity).

When 'test3' is uncommented I see the "x has no value" warning.
Simply, it is earlier: all diagnostics from Spad compiler come
before diagonstics from Lisp compiler.  One needs to scroll back
a bit to see this diagnostics.

Concerning code style, the first two functions can be written
in shorter and more efficient way:

   test1a(im : List NNI) : List NNI ==
       concat([4, 5, 6], [p for p in im | p = 3])

   test2a(a : List NNI) : List NNI == map(a1 +-> a1 + 1, a)

   test2b(a : List NNI) : List NNI == [a1 + 1 for a1 in a]

Note: adding things element by element to the end of a list
is inherently slow, as each 'concat' needs to copy first part
of the list.  'test1a' contains only single call to 'concat',
so it makes at most one copy of the initial list.

'map' in 'test2a' makes a single pass over the list, so
typically is faster then 'test2'.  'test2b' is doing all
work by inline code, so should be faster than both 'test2a'
and 'test2'.

'test3' adds elements to start of the list, this is typical
pattern when we need somewhat more complex processing and
efficiency.  However, I would advise against using 'concat'
here and using 'cons' instead.  That is:

   test3a(c : List NNI) : List NNI ==
        d : List NNI := []
        for c1 in c repeat
            d := cons(c1 + 1, d)
        d

The reason is that 'concat' is overloaded and in case of
list of lists we may get wrong resolution of overload
doing something like 'concat([], d)'.  While this is
rather special case, it is easier to remeber to use 'cons'
to add elements to the start of the list, than to watch
out for special cases.  In particular, normally one can
modify Spad code without troubles, but when using 'concat'
plugging in known value of variable may lead to different
overload resolution and consequently to trouble.  So
using 'cons' is much safer.

-- 
                              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 visit 
https://groups.google.com/d/msgid/fricas-devel/Z8ZtLIJ6zrOfk0sg%40fricas.org.

Reply via email to