passing a constructor to a package

12 views
Skip to first unread message

Ralf Hemmecke

unread,
Jul 2, 2025, 7:24:40 PMJul 2
to fricas-devel
Hello,

Since I have two packages PA and PB with the same parameters and exports
that behave slightly differently, I would like to be able to pass them
to another constructor C to use them internally there. So I want the
respective packages be build/instantiated inside C (and maybe with
different parameters.

To simplify it a bit I came up with the following construction (attachment).

================
)abbrev domain RHSUP RHSparseUnivariatePolynomial
RHSparseUnivariatePolynomial(R : Ring): UnivariatePolynomialCategory(R)
== SparseUnivariatePolynomial(R) add
coerce(p : %) : OutputForm ==
h := p pretend SparseUnivariatePolynomial(R)
outputForm(h, "t"::Symbol::OutputForm)

)abbrev package RHX RHx
RHx(R: Ring, POL: R -> UnivariatePolynomialCategory R): with
var: () -> OutputForm
== add
mon ==> monomial $ POL(R)
var(): OutputForm == mon(1$R,1$NonNegativeInteger) :: OutputForm
================

Compilation of RHSUP is no problem, but RHx does not work:

initializing NRLIB RHX for RHx
compiling into NRLIB RHX
processing macro definition mon ==> Sel(POL R,monomial)
compiling exported var : () -> OutputForm
Internal Error
Error while instantiating type POLR

Well, maybe that is no surprise, because I haven't yet seen a
construction like

POL: R -> UnivariatePolynomialCategory R

in an argument. But what would be the way to go? Or does FriCAS simply
not allow that and I must think of something else?

Ralf
foo.spad

Waldek Hebisch

unread,
Jul 2, 2025, 9:16:02 PMJul 2
to 'Ralf Hemmecke' via FriCAS - computer algebra system
On Thu, Jul 03, 2025 at 01:24:35AM +0200, 'Ralf Hemmecke' via FriCAS - computer algebra system wrote:
> Hello,
>
> Since I have two packages PA and PB with the same parameters and exports
> that behave slightly differently, I would like to be able to pass them to
> another constructor C to use them internally there. So I want the respective
> packages be build/instantiated inside C (and maybe with different
> parameters.
>
> To simplify it a bit I came up with the following construction (attachment).
>
> ================
> )abbrev package RHX RHx
> RHx(R: Ring, POL: R -> UnivariatePolynomialCategory R): with
> var: () -> OutputForm
> == add
> mon ==> monomial $ POL(R)
> var(): OutputForm == mon(1$R,1$NonNegativeInteger) :: OutputForm
> ================

You are exploring land of bugs. The following compiles

)abbrev package RHX RHx
RHx(R: Ring, POL: R -> UnivariatePolynomialCategory R): with
var: () -> OutputForm
== add
fT := POL(R)
mon ==> monomial$fT
var(): OutputForm == mon(1$R, 1$NonNegativeInteger)::OutputForm

but generated code is wrong.

In general, your code here is quite different than current algebra
code. That is normally caller would evaluate POL(R) nad RHx would
use its value.

Also, do I guess correctly that you want to pass
RHSparseUnivariatePolynomial as an argument to RHx? Currently
constructors and functions defined inside constructors use
different call convention. In Spad we can write functions
producing types and functions taking types as arguments, and
normally one should expect POL to be such a function.

--
Waldek Hebisch

Ralf Hemmecke

unread,
Jul 3, 2025, 1:46:26 AMJul 3
to fricas...@googlegroups.com
On 7/3/25 03:15, Waldek Hebisch wrote:
> You are exploring land of bugs.

As usual. ;-)

I don't even know whether such a construction is specified to work even
in Aldor.

The following compiles
>
> )abbrev package RHX RHx
> RHx(R: Ring, POL: R -> UnivariatePolynomialCategory R): with
> var: () -> OutputForm
> == add
> fT := POL(R)
> mon ==> monomial$fT
> var(): OutputForm == mon(1$R, 1$NonNegativeInteger)::OutputForm
>
> but generated code is wrong.
>
> In general, your code here is quite different than current algebra
> code. That is normally caller would evaluate POL(R) nad RHx would
> use its value.

Hmmm... but that seems to tell my that I would have to make a part of
the respective (RHx) package explicit to the caller.

Actually, I oversimplified. What I really want inside RHx is calling
functions from POL(Matrix R), i.e., I should have given

RHx(R: Ring, POL: (X:Ring) -> UnivariatePolynomialCategory X): with

as the initial line of definition. In my current setup the respective
POL constructor would even have a second parameter that depends on X.
I wanted to hide the (respective) "Matrix" constructur from the caller
as implementation detail.

> Also, do I guess correctly that you want to pass
> RHSparseUnivariatePolynomial as an argument to RHx?

Yes, that is exactly my wish, but good to know that it doesn't work.
I somehow wanted to avoid doubling the code for RHx, by factoring out
this POL constructor

Thank you for your quick reply.

Ralf

Waldek Hebisch

unread,
Jul 3, 2025, 11:44:19 AMJul 3
to 'Ralf Hemmecke' via FriCAS - computer algebra system
On Thu, Jul 03, 2025 at 07:46:22AM +0200, 'Ralf Hemmecke' via FriCAS - computer algebra system wrote:
> On 7/3/25 03:15, Waldek Hebisch wrote:
> > You are exploring land of bugs.
>
> As usual. ;-)
>
> I don't even know whether such a construction is specified to work even in
> Aldor.

I would say that from general point of view code looks OK.
It is just question what in implemented in the respective compiler.

> The following compiles
> >
> > )abbrev package RHX RHx
> > RHx(R: Ring, POL: R -> UnivariatePolynomialCategory R): with
> > var: () -> OutputForm
> > == add
> > fT := POL(R)
> > mon ==> monomial$fT
> > var(): OutputForm == mon(1$R, 1$NonNegativeInteger)::OutputForm
> >
> > but generated code is wrong.
> >
> > In general, your code here is quite different than current algebra
> > code. That is normally caller would evaluate POL(R) nad RHx would
> > use its value.
>
> Hmmm... but that seems to tell my that I would have to make a part of the
> respective (RHx) package explicit to the caller.
>
> Actually, I oversimplified. What I really want inside RHx is calling
> functions from POL(Matrix R), i.e., I should have given
>
> RHx(R: Ring, POL: (X:Ring) -> UnivariatePolynomialCategory X): with
>
> as the initial line of definition. In my current setup the respective POL
> constructor would even have a second parameter that depends on X.
> I wanted to hide the (respective) "Matrix" constructur from the caller as
> implementation detail.

You need to specify them somewhere. Old Spad way it to pass all
such thing down trough intermediate constructors. Some things
may be hidden by using categores: category specifies what needs
to be visible to users of a package, package may have more arguments
or more specific arguments. You may look at amodgcd.spad.
ModularAlgebraicGcdOperations specifies things in terms of abstrat
types and users of packages of this category only see abstrat
things, but unneeded specifics are hidden. Only package gets
full details.

Also, there is question of efficiency. Your 'var' is probably
rather uncritical, but in amodgcd.spad I wanted as efficient code
as possible. Giving specific types to packages (and in fact
"hardcoding" some details inside packages) lead to efficient
code inside. With code as you wrote there is ususaly expensive
call to package/domain that is specified only at runtime. My
modification above which compiles moved place where POL(R) is
fully specified to place that is run only once (that is at
package instationation time). Theoretically Spad compiler could
automatically do such transformantions, but I do not think
that this is done now.

There is related issue. To get better efficiency Spad compiler
normally caches types, that is types is instantiated once and
reused after that. But if type depends on runtime values, then
it must be dully recomputed. Spad functions may produce different
value on each call, even if arguments are the same, so your
use disallows caching. My modification explicitely caches type
value.

One extra remark: I do not know how to implement such calls
efficiently. This means that usually I would prefer different
construct. This limits my motivation to implement them
(which currently seem to require substantial work).

--
Waldek Hebisch

Grégory Vanuxem

unread,
Jul 3, 2025, 2:14:44 PMJul 3
to fricas...@googlegroups.com
Hello,

I am pretty sure I am wrong but why not something like:

)abbrev domain RHSUP RHSparseUnivariatePolynomial
RHSparseUnivariatePolynomial(R) : Exports == Implementation where
R : Ring
Exports ==> UnivariatePolynomialCategory(R) with
foo : () -> String
Implementation ==> SparseUnivariatePolynomial(R) add
foo() == "foo"
coerce(p : %) : OutputForm ==
h := p pretend SparseUnivariatePolynomial(R)
outputForm(h, "t"::Symbol::OutputForm)

)abbrev domain RH2SUP RH2SparseUnivariatePolynomial
RH2SparseUnivariatePolynomial(R) : Exports == Implementation where
R : Ring
Exports ==> UnivariatePolynomialCategory(R) with
foo : () -> String
bar : () -> String
Implementation ==> SparseUnivariatePolynomial(R) add
foo() == "foo"
bar() == "bar"
coerce(p : %) : OutputForm ==
h := p pretend SparseUnivariatePolynomial(R)
outputForm(h, "t"::Symbol::OutputForm)

)abbrev package RHX RHx
RHx(R: Ring, POL : UnivariatePolynomialCategory(R)): with
var: () -> OutputForm
if POL has foo : () -> String then
foo : () -> String
if POL has bar : () -> String then
bar : () -> String
bar2 : () -> String
== add
mon ==> monomial$POL
if POL has foo : () -> String then
foo() == foo()$POL
if POL has bar : () -> String then
bar() == bar()$POL
bar2() == bar()$POL
var(): OutputForm == mon(1$R,1$NonNegativeInteger) :: OutputForm

?

- Greg
PS: I will respond to your question later in another thread about SUP,
SingletonAsOrderedSet etc when I can, sorry.
> --
> 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...@googlegroups.com.
> To view this discussion visit https://groups.google.com/d/msgid/fricas-devel/aGalT4ix9bI3JAKm%40fricas.org.

Grégory Vanuxem

unread,
Jul 5, 2025, 3:50:27 PMJul 5
to fricas...@googlegroups.com
---------- Forwarded message ---------
De : Grégory Vanuxem <g.va...@gmail.com>
Date: sam. 5 juil. 2025 à 21:49
Subject: Re: [fricas-devel] passing a constructor to a package
To: Ralf Hemmecke <ra...@hemmecke.org>


Makes sense.

May I be wrong in thinking of a new domain that present a signature.
May be that is doable. I wonder. Like a *package2* thing like.

I always avoid this.

- Greg

Le ven. 4 juil. 2025 à 21:12, Ralf Hemmecke <ra...@hemmecke.org> a écrit :
>
> Hi Greg,
>
> indeed, your suggestion does not help.
>
> Note that in my actual real implementation I would not need POL(R) but
> something like POL(X(R)) where the X is specified by the RHx package.
> My original wish was to hide the X since that would only be an auxiliary
> constructor.
>
> Ralf
>
Reply all
Reply to author
Forward
0 new messages