why Fricas allows Float as argument to function defined to accept Integer?

27 views
Skip to first unread message

Nasser M. Abbasi

unread,
Dec 25, 2023, 12:48:07 AM12/25/23
to FriCAS - computer algebra system
I am learning little Fricas. But confused about this


(21) -> g2(x: Integer): Integer == x^2              
   Function declaration g2 : Integer -> Integer has been added to
      workspace.

Is the above function supposed to accept only Integer type as input and return Integer? Then why does this call work:

22) -> g2(7.0)                      
   Compiling function g2 with type Integer -> Integer
   (22)  49
                                                        Type: PositiveInteger

It seems to have casted 7.0 to 7? And should not the type returned be Integer and not PositiveInteger?

23) -> typeOf(7.0)
   (23)  Float

Fricas does however catch the error when passing string:

24) -> g2("hello")                  
   Conversion failed in the compiled user function g2 . 
   Cannot convert the value from type String to Integer .

Compare to Maple
-------------------------------------------------
g2:=proc(x::integer)::integer;
      x^2;
end proc;

g2(7.0);
Error, invalid input: g2 expects its 1st argument, x, to be of type integer, but received 7.0
-----------------------------------------------

And that is what I was expecting, given that Fricas is very strongly typed.

Did I do something wrong or do I need to turn some setting on or something?

Fricas 1.3.9

Thanks
--Nasser




Waldek Hebisch

unread,
Dec 25, 2023, 7:10:52 AM12/25/23
to 'Nasser M. Abbasi' via FriCAS - computer algebra system
FriCAS has notion of "coercion", "retraction" and "convertion". There
is a difference between them, but basically FriCAS "knows" that some
functions can be used to change types. In particular, FriCAS has
'retract' function that can change Float to Integer: it will work only
when Float happens to have integer value, otherwise will fail. In
interactive use, when types do not match FriCAS automatically tries
to inserts convertion functions to ensure type agreement. In effect,
FriCAS treats your 'g(7.0)' as 'g(retract(7.0))'. In similar spirit,
FriCAS tries to show result in narrowest possible type, that is why it
prints 'PositiveInteger'.

Note: On command line FriCAS tries very hard to change types so
that expression can be evaluated. In user defined functions
FriCAS is doing less work, but still inserts convertion like
above. In Spad language FriCAS is insterting only small number
of "obvious" coercions.

This may look not very consistent, but simply having to insert
coercions and convertions everywhere is too inconvenient for
most users, so convenience wins. In Spad you are programming
and for readability supposed to be more explicit. Function
definitions in "interpreter" are an intermediate thing.

Concering user settings: this can not be changed by normal
settings.

--
Waldek Hebisch

Waldek Hebisch

unread,
Dec 25, 2023, 12:01:34 PM12/25/23
to fricas...@googlegroups.com
A few more remaks. In your previous example:

concat([1, 2, 3], ["e", "f", "g"])

FriCAS was too shy to invent List(Any). OTOH in

(5) -> [1, 2, 3, "e", "f", "g"]

(5) [1, 2, 3, "e", "f", "g"]
Type: List(Any)

it introduced List(Any).

in

concat([1, 2, 3]::List(Any), ["e", "f", "g"])

FriCAS saw List(Any) as type of first argument and decided to
coerce second argument to match.

in

concat([1, 2, 3], ["e", "f", "g"])$List(Any)

FriCAS saw that it needs arguments of type List(Any) and coerced
both arguments to match.

--
Waldek Hebisch
Reply all
Reply to author
Forward
0 new messages