login  home  contents  what's new  discussion  bug reports help  links  subscribe  changes  refresh  edit

Generic Functions in FriCAS

This acutally works better than I expected.

fricas
U:=Union(Integer,Float) (1)
Type: Type
fricas
plus(f:U->U,g:U->U):U->U ==
(x:U):U +-> if x case Integer then
(f(x)::Integer+g(x)::Integer)::U
else
(f(x)::Float+g(x)::Float)::U
Function declaration plus : ((Union(Integer,Float) -> Union(Integer,
Float)), (Union(Integer,Float) -> Union(Integer,Float))) -> (
Union(Integer,Float) -> Union(Integer,Float)) has been added to
workspace.
Type: Void
fricas
double(n) == n + n
Type: Void
fricas
h:=plus(double,double)
fricas
Compiling function double with type Union(Integer,Float) -> Union(
Integer,Float)
fricas
Compiling function plus with type ((Union(Integer,Float) -> Union(
Integer,Float)), (Union(Integer,Float) -> Union(Integer,Float)))
-> (Union(Integer,Float) -> Union(Integer,Float)) (2)
Type: (Union(Integer,Float) -> Union(Integer,Float))
fricas
h(4) (3)
Type: Union(Integer,...)
fricas
h(3.5) (4)
Type: Union(Float,...)

Ref.

---------- Forwarded message ----------:

 From: jiazhaoconga <jiazhaoconga@gmail.com>
Date: 23 April 2014 09:16
Subject: [fricas-devel] High order (generic) functions

I have some problems when I try to have high order generic functions in Fricas:

For example, 'plus' is a high order generic functions that takes two functions
(f,g) and returns an (anonymous) function (with parameter x) that returns the
sum of f(x) and g(x) :

1. Do it in REPL:
plus (f,g) == x+->f(x)+g(x)

Test it:
double n == n + n
h := plus(double,double)
h 4

but get:

FriCAS will attempt to step through and interpret the code.

Anonymous user functions created with +-> that are processed in
interpret-code mode must have result target information
available. This information is not present so FriCAS cannot
proceed any further. This may be remedied by declaring the
function.

)abbrev package PLSPKG PlusPackage

PlusPackage(A:SetCategory, B:AbelianSemiGroup) : Exports == Impl where
Exports == with
plus2 : ((A->B),(A->B))->(A->B)
plus2(f,g) == x+->f(x)+g(x)

)abbrev package TEST1 TestPlusPackage

TestPlusPackage(A:AbelianSemiGroup) : Exports == Impl where
Exports == with
double2 : A->A
double2 x == x+x

and in REPL:
)compile plus
h == plus2(double2,double2)
h 4

but get:

There are 1 exposed and 0 unexposed library operations named plus2
having 2 argument(s) but none was determined to be applicable.

What/Where is going wrong?


---------- Forwarded message ----------:

 From: Waldek Hebisch <hebisch@math.uni.wroc.pl>
Date: 23 April 2014 13:51
Subject: Re: [fricas-devel] High order (generic) functions

>
> > Hmmm... Acutally I really wouldn't expect this to work in the
> > interpreter given what I know about it's design, but it seems OK in
> > when using the compiler:
> >
> > (3) -> h := plus2(double2,double2)$PLSPKG(FLOAT,FLOAT) > > > > (3) theMap(PLSPKG;plus2;3M;1!0,655) > > Type: (Float -> Float) > > (4) -> h 3.5 > > > > (4) 14.0 > > Type: Float > > (5) -> > jiazhaoconga wrote: > Yeah, but I don't want to specify the '$PLSPKG(FLOAT,FLOAT)' by hand, I want
> Fricas to do type inference for me, to be exact, I want 'h :=
> plus2(double2,double2)'
> to act like as if the following Spad code have been added into the system:
>
> AnonymousPackage(A:AbelianSemiGroup) : Exports == Impl where
>   Exports == with
>     h : A->A
>     h x == double2 x+ double2 x
>
> So that I can do 'h := plus2(double2,double2);h 4; h 3.5' without
> specify any type.

h := plus2(double2,double2);h 4; h 3.5

in current FriCAS has typing problem: assignment produces value of
definite type.  So the only way to satify this is to have
some type which can be both applied to integer argumements and
to float arguments.  This is doable, but different from what
you think.  Basically you need some "universal" type U.  Then
you need to define

elt : (U, U) -> U
elt : (U, U, U) -> U

and so on up to some maximal arity.  Additinally you need
coercions from concrete types (like integer) to the universal
type.

The way to do this is to have type schemes with free parameters
(equivalently have "forall" types).  Interpreter currently
supports limited form of type schemes called "modes".  But
a mode can have only one free parameter and modes can not
be used in some contexts, which unfortunately excludes
use of modes in higher order functions.  This is not
fundamental restriction, but requires better typechecker
than what we have now.

Concerning use of generic functions defined in Spad
files: in Spad you need to specify types in terms of
parameters.  Interpreter sometimes can infer parameters,
but in general you need to give them explicitely.

--
Waldek Hebisch


 Subject:   Be Bold !! ( 15 subscribers )