Hi, here now a small code example to make clear what I was taking about when I mentioned class-functions. A log10 function is declared as an example. The fclass (-> function) class basically installs some default printing and has some convenience ctors. I know there are some issues about the macros (fixed archiving defaults, naming, ...), some print stuff is missing in fclass, and there is no special code for log10 (series, ...) yet, but the main concept should become clear. Eval: - compatibility is severly broken (but maybe we should break it anyhow: why not rename tgamma to Gamma, beta to Beta, lgamma to logGamma?) + logic like if (is_a<function>(e)) { std::string name = ex_to<function>(e).get_name(); if (name == "H") { ... can be replaced by more efficient code + hierarchies like polylog->nielsen_polylog->multiple_polylog possible + function.pl is no longer needed + eval/evalf slightly faster (?) + non-ex arguments for ctors (and eval, ...) possible + extra methods/logic/data can be included in the function class (projects like nestedsums, xloops suffer from not being able to do this at the moment) + more OOP like (disputable, but we will never hear the often raised question 'why didn't you just define the functions as classes?' again + better (OOP-like) handling of look-up tables (as static data or maybe the function might become a singleton) - no nice separation of cln and GiNaC code possible + print-Methods can also be changed at runtime for functions - archiving slightly slower because of longer reg_info list Regards, Jens #include <iostream> #include <fstream> #include <stdexcept> #include <ginac/ginac.h> using namespace std; using namespace GiNaC; namespace GiNaC { /** Primary macro for inclusion in the declaration of each registered class. */ #define NEW_GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(classname, supername) \ public: \ typedef supername inherited; \ private: \ static GiNaC::registered_class_info reg_info; \ public: \ static GiNaC::registered_class_info &get_class_info_static() { return reg_info; } \ virtual const GiNaC::registered_class_info &get_class_info() const { return classname::get_class_info_static(); } \ virtual GiNaC::registered_class_info &get_class_info() { return classname::get_class_info_static(); } \ virtual const char *class_name() const { return classname::get_class_info_static().options.get_name(); } \ \ classname(const GiNaC::archive_node &n, GiNaC::lst &sym_lst) : inherited(n, sym_lst) {} ; \ static GiNaC::ex unarchive(const GiNaC::archive_node &n, GiNaC::lst &sym_lst) \ { return (new classname(n, sym_lst))->setflag(status_flags::dynallocated); }; \ class visitor { \ public: \ virtual void visit(const classname &) = 0; \ virtual ~visitor() {}; \ }; \ private: /** Macro for inclusion in the declaration of each registered class. * It declares some functions that are common to all classes derived * from 'basic' as well as all required stuff for the GiNaC class * registry (mainly needed for archiving). */ #define NEW_GINAC_DECLARE_REGISTERED_CLASS(classname, supername) \ NEW_GINAC_DECLARE_REGISTERED_CLASS_NO_CTORS(classname, supername) \ public: \ classname() { tinfo_key = TINFO_##classname; } \ virtual classname * duplicate() const { return new classname(*this); } \ \ virtual void accept(GiNaC::visitor & v) const \ { \ if (visitor *p = dynamic_cast<visitor *>(&v)) \ p->visit(*this); \ else \ inherited::accept(v); \ } \ private: //////////////////////////////////////////////////////////////////////////////// const unsigned TINFO_fclass = 0x47231232U; class fclass : public exprseq { NEW_GINAC_DECLARE_REGISTERED_CLASS(fclass, exprseq) public: fclass(unsigned ti, const ex& x1) : inherited(x1) { tinfo_key = ti; } fclass(unsigned ti, const ex& x1, const ex& x2) : inherited(x1,x2) { tinfo_key = ti; } fclass(unsigned ti, const ex& x1, const ex& x2, const ex& x3) : inherited(x1,x2,x3) { tinfo_key = ti; } protected: void fclass::do_print(const print_context &c, unsigned level) const { c.s << class_name(); inherited::do_print(c,level); } }; GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(fclass, exprseq, print_func<print_context>(&fclass::do_print)) //////////////////////////////////////////////////////////////////////////////// const unsigned TINFO_log10 = 0x47321232U; class log10 : public fclass { NEW_GINAC_DECLARE_REGISTERED_CLASS(log10, fclass) public: log10(const ex& x) : inherited(TINFO_log10, x) {} log10(const ex& x, const ex& y) : inherited(TINFO_log10, x, y) {} }; GINAC_IMPLEMENT_REGISTERED_CLASS(log10, fclass) //////////////////////////////////////////////////////////////////////////////// } main() { try { symbol x("x"); ex d = x; ex r1 = log10(d) * log10(x) + x; cout << r1 << endl; cout << tree << r1 << endl; cout << dflt << log10(lst(x,x),lst(x)) << endl; } catch (const exception& e) { cout << e.what() << endl; } return 0; }