Hello,
I would like to define new type in my package but I don't know how. What should I change in followng code to make it work? Thank you.
Karel Srot
restart:
march('create', ".", 3);
MyModule := module() option package;
export p, `type/FS`;
`type/FS`:=proc(t); # define new type
if t=`a` then
RETURN(true);
else
RETURN(false);
end if;
end:
p:=proc(S::FS) local coeff, t;
print(1);
end proc:
end module;
savelibname := ".":
savelib('MyModule');
restart:
libname:=libname, `.`:
with(MyModule);
type(a, FS);
TypeTools[AddType]
Does this work for you?
MyModule := module() option package;
export p, FS;
TypeTools[AddType](FS,proc(t) if t=`a` then true else false end if; end proc);
p:=proc(S::MyModule:-FS) local coeff, t;
print(1);
end proc:
end module:
with(MyModule);
type(a, FS);
p(a);
p(z);
Dave Linder
Mathematical Software, Maplesoft
ModuleLoad with Type Assignment
I don't believe that will do the trick, that is, it will fail when the module is loaded from a repository because the type wasn't defined. The trick is to add the type in a procedure that is executed when module is loaded. By default, a local/export named ModuleLoad is executed when the module is loaded.
MyModule := module() option package; export p, FS; local ModuleLoad; ModuleLoad := proc() TypeTools[AddType](FS, identical('a')); end proc; p := proc(S::MyModule:-FS) local coeff, t; print(1); end proc; ModuleLoad(); # necessary if module is not saved/loaded. end module:Note that in the above I used
identical('a')rather than the more cumbersome original procedure as the type definition.Thanks Joe, yet again
Thank you Joe, for pointing out the correction with respect to loading from an archive, which was in the submitter's original post. It's odd that I forgot that, since I've recently been using the method in ModuleLoad myself. :)
Dave Linder
Mathematical Software, Maplesoft
Thank you, it is working. I
Thank you, it is working. I would also like to define how this type should be printed.
Suppose that FS type is defined as follows:
TypeTools[AddType](FS, t->evalb(op(0,t)=`a`));
then
type(a(1), FS); is true
And I would like to print this type in a different way
`print/a`:=proc(t) [`a`,op(1,t)]: end proc:
so
> a(1); returns [a, 1]
Can you tell me how to add this procedure into the package?
Thank you.
Karel
Make global and use ModuleLoad
Use the same approach, assign the procedure `print/a` in ModuleLoad. There is, alas, no equivalent PrintTools package. Instead of making `print/a` an export you need to declare it as a global. Here is a snippet
MyModule := module() local ModuleLoad; export FS; option package; ModuleLoad := proc() global `print/a`; `print/a` := proc(t) ['a', op(1,t)] end proc; TypeTools[AddType]('FS', specfunc(anything,a)); end proc: ModuleLoad(); end module:Note that I used forward quotes, not backquotes, around a. The backquotes are never required. The forward quotes are useful to prevent a global assignment to a from spoiling the effect. Note the change to your type definition. Also, note that there is a probable flaw in your assignment to `print/a`, which I have not corrected. Try
a().Thank you for your
Thank you for your help.
Karel
Pet peeve
Assuming the above does indeed work, I really dislike seeing
when simply
does the same.
And once you get there, then you see that this type is in fact
identical('`a`'), which is much faster than any user-defined type.Thank you for the comment.
Thank you for the comment. But the test is just a simplified example, actually I don't want to define such kind of type. :-) I just want to know how to export type from the package.
evalb and conditionals (tri-state logic)
As Jacques knows (and was careful to distinguish), but others may not realize, the result of
is not always identical to
For example,
evalb(I<4*I); FAIL if I<4*I then true else false end if; falseEven worse than that
evalb can sometimes return 'unevaluated', where the if statement in the same situation would throw an error.
Informally one can say that if the question was meaningful, then evalb and if will agree. Only when you are dealing with expressions that are dubiously meaningful like comparing complexes with < (where the tri-valued logic of evalb works differently than an if's two-valued interpretation), or when asking even less meaningful questions, like having a free variable in a boolean query (where evalb will return unevaluated and if will give an error).
One could argue that Maple is very creative with the diversity of its GIGO behaviour!
PS: Thanks for the clarification, I think MaplePrimes readers will appreciate it.
How to define new type - again
In this forum topic you told me how to define my own type in a package and how to redefine the style my new type should be printed. But Now I found that this approach is correct when running on Maple10 but not on Maple8 (and maybe on other Maple versions). It works until I try to load the package from the file. How to do this in Maple8?
Thank you.
Karel Srot
This is a piece of code I use:
restart:
currentdir(`e:/Devel/Maple/MyLibs/`);
march('create', ".", 4);
MyModule := module()
local ModuleLoad;
export PAIR;
option package;
ModuleLoad := proc()
global `print/PAIR`;
`print/PAIR` := proc(a,b) [a, b] end proc;
TypeTools[AddType]('PAIR', x->evalb(op(0,x)=`PAIR`));
end proc:
ModuleLoad();
end module:
savelibname := ".":
savelib('MyModule');
with(MyModule);
type(`PAIR`(1,2), PAIR);
`PAIR`(1,2);
lprint(`PAIR`(1,2));
restart;
libname:=`e:/Devel/Maple/MyLibs/`, libname:
with(MyModule);
type(`PAIR`(1,2), PAIR);
TypeTools didn't exist back then...
I suspect that TypeTools was not added until Maple 9. To work around that, use the older method of creating a type: assign a `type/NameOfType` procedure, similar to what you did for the print function. That method still works, its drawback is that it pollutes the global name space.
MyModule := module() local ModuleLoad; export PAIR; option package; ModuleLoad := proc() global `print/PAIR`, `type/PAIR`; `print/PAIR` := proc(a,b) [a, b] end proc; `type/PAIR` := x->evalb(op(0,x)=PAIR); end proc: ModuleLoad(); end module:Note, by the way, that backquotes are not needed around PAIR. They are only required to enter a name that has none alphanumeric characters.
When assigning globals in a ModuleLoad, it is good practice to unassign them in a ModuleUnload. That is, add the following assignment (with a local declaration) to your module