Pffff... tough stuff. And great thanks for sharing your problems with us.

In fact, what you experience is probably for all the biggest frustration
that lets people turn their back to FriCAS.

So let me give a word of clarification. The main difference of FriCAS in
contrast to other CAS(es) is types. When you program in SPAD (the
programming language of FriCAS) you will certainly appreciate types.
However, this is not how an ordinary person starts to learn FriCAS. You
get in contact with it throught the FriCAS session prompt. When you hit
ENTER, the expression is analysed by the FriCAS interpreter.

Now, clearly, there are natural ambiguities. When you write

[[a, b],[c,d]]

it can mean quite a lot of things in FriCAS. So the interpreter must
decide what to do with your expression. It resolves it by preferring
List instead of anything else. So this gives List(List(X))) where the
interpreter must decide about what X to chose by the nature of your
objects. But already

[[1,2],[3,4]]

is rather difficult. Did you mean List(List(Integer)) or perhaps
List(List(NonNegativeInteger)) or List(List(PositiveInteger))?

That doesn't solve your problem, but it shows how difficult it is for
the interpreter to find a good heuristics.

Coming to your line (3). For the SPAD compiler the

  @SquareMatrix(2, Float)

actually means: "If there is a function "construct" with different
result types, then choose the function that has SquareMatrix(2, Float)
as a result type."

Note that "[x]" is actually syntactic sugar for the function call
"construct(x)".

In your case, I cannot see a function "construct" in SquareMatrix
http://fricas.github.io/api/SquareMatrix . So the hint that you have
given it practically worthless to the FriCAS interpreter.

Now why does

  ::SquareMatrix(2, Float)

work? The "::" operator (or rather "x::Y" for the FriCAS compiler means
the following. coerce(x)@Y, i.e,, find a function with name "coerce" in
the current scope that has Y as a result type.

For the FriCAS interpreter, however, it is not only "coerce", but also
"convert" and "retract". OK, that still would not resolve the case of
turning List(List(Float)) into SquareMatrix(2, Float). I also don't know
how the interpreter exactly behaves, but I guess, it tries even harder
when "coerce", "convert", and "retract" do not resolve the problem.
Applying the functions "matrix" and "vector" are probably so common that
the interpreter also tries those. But understand, all that is just
heuristics and it might happen that the interpreter finds a way to
interpret your expression, but it is not the way you wanted. All is
possible. The safest way to deal with it is to always assign types to
your expressions and also otherwise be explicit, i.e. write the "matrix"
function in front of a list of lists if you want the result be a matrix.

Yes, that all is not so self explaining as it should be. In particular,
most people do not from the start understand the precise meaning of @, $
and ::. Unfortunately, the FriCAS interpreter also does not do much to
help people to understand/teach the difference.

Maybe I should take you example and add it to the FAQs.
So thank you for sharing your session and your question.

Ralf



On 10/30/20 10:31 AM, Neven Sajko wrote:
> Hello,
> 
> I've stumbled on a seeming inconsistency while using Fricas and I'm
> writing to the mailing list in hopes of getting more understanding of
> the issue, or just reporting a bug if the issue is a bug.
> 
> Consider the following Fricas session:
> 
> (1) -> x : DirectProduct(2, Float) := (2,3)
> 
>    (1)  [2.0, 3.0]
>                                                  Type: DirectProduct(2,Float)
> (2) -> [[(x.j)^i for j in 1..2] for i in 0..1]
> 
>    (2)  [[1.0, 1.0], [2.0, 3.0]]
>                                                       Type: List(List(Float))
> (3) -> [[(x.j)^i for j in 1..2] for i in 0..1]@SquareMatrix(2, Float)
> 
>    Cannot convert the value from type List(Float) to Float .
> 
> (3) -> [[1.0, 1.0], [2.0, 3.0]]@SquareMatrix(2, Float)
> 
>         +1.0  1.0+
>    (3)  |        |
>         +2.0  3.0+
>                                                   Type: SquareMatrix(2,Float)
> (4) -> [[(x.j)^i for j in 1..2] for i in 0..1]::SquareMatrix(2, Float)
> 
>         +1.0  1.0+
>    (4)  |        |
>         +2.0  3.0+
>                                                   Type: SquareMatrix(2,Float)
> (5) -> v : SquareMatrix(2, Float) := [[(x.j)^i for j in 1..2] for i in 0..1]
> 
>    Cannot convert the value from type List(Float) to Float .
> 
> (5) -> v : SquareMatrix(2, Float) :=
>                             matrix [[(x.j)^i for j in 1..2] for i in 0..1]
> 
>         +1.0  1.0+
>    (5)  |        |
>         +2.0  3.0+
>                                                   Type: SquareMatrix(2,Float)
> 
> Why is it that the list collection can't be automatically converted to
> a matrix, if an equivalent list of lists (written directly) can?
> 
> Why does using the matrix function help, even though it's not
> necessary when using a list of lists directly?
> 
> Thank you,
> Neven Sajko
> 

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/fricas-devel/737a2a79-7018-47f6-c29b-89cbe55a0885%40hemmecke.org.

Reply via email to