Giter Site home page Giter Site logo

mathematicaclasslessobjects's People

Contributors

jkuczm avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

mathematicaclasslessobjects's Issues

usage question 1: setting methods (functions) in constructors

Hi.

First: Thanks 10^3 for creating and sharing this. It is a Godsend.

Second: Please forgive me if this is the wrong venue for communicating questions to you. I don't have enough reputation points on Stack Exchange yet to post a comment on your excellent answer there, and I'm new to GitHub so I'm unfamiliar with the conventions.

Third: I'm trying to use this package in a Mathematica project, and I'm having trouble figuring out how to accomplish a couple of less basic things. The first is simple to describe: Is it possible to define a "constructor" that takes methods (set-delayed rules) as well as properties (set-immediately rules)? I tried the obvious, simply passing a function in as one of the constructor parameters and then setting the object rule to it, but no luck:

ancestor@construct[obj_Symbol, v0$_, r0$_, f$_Function] := (
  DeclareObject[obj, $self];
  obj@r0 = r0$;
  obj@v0 = v0$;
  obj@f := f$;
  obj )

I've tried with := and = in that code, and I've tried various methods of defining the function that I pass to the constructor: delayed or not, as a normal f[x_] rule or a pure function, etc.

ClearAll[child];
ff = (#^2) &;
ancestor@construct[child, 20, 0, ff];

In all cases, I'm getting the following error message:

Object::objectMember: The call child@0 didn't match any of defined member patterns in child nor in its ancestors: {ancestor,Object}.

I can, of course, bypass the constructor and simply define the method for the child directly, with setDelayed, but it would be helpful (and ultimately easier for users of my project) if I could handle it in the constructor. Is this possible? Am I being dumb or blind?

BTW, I'm moderately but not expertly skilled with Mathematica, but I'm not yet conversant with the subtleties of HoldAll and when/how to use it.

Thanks,
:Ian

usage question 2: integrating a child object method once, not every time, to get a new function that can be called

Hi again. Here's a second question. It is considerably more subtle and specialized, but perhaps you might find it interesting.

Each of the child objects I'm subclassing from a superclass object has a function we'll call a[t_]. The specific function differs for each child, but I've got superclass methods that use it (via your excellent $self syntax) to generate a set of graphs. Specifically, these superclass methods graph the function, its integral, and its second integral (acceleration, velocity, and position -- this is a physics application).

The way they work is that I've defined superclass methods thusly:

ancestor@v[t_] := $self@v0 + Integrate[$self@a[tt], {tt, 0, t}, Assumptions -> t \[Element] Reals];
ancestor@r[t_] := $self@r0 + Integrate[$self@v[tt], {tt, 0, t}, Assumptions -> t \[Element] Reals];

I then use Plot[$self@v[t]] or Plot[$self@r[t]] in the superclass methods that generate the plots. This all works just fine, EXCEPT that it's hideously slow, especially for the plot of the second integral r[t]. I've wrestled with this before, when not using objects or subclassing or anything, and what I decided is that the Integrate[...] functions were being called many many times during plotting, for every single plot point (and perhaps the first integral was being called many times during each execution of the second integral). Well, of course! It is defined as set-delayed, after all.

That is really unnecessary, since the a[t] function does not change once defined, and the indefinite integral only needs to be calculated once. Before using your OOP package, I simply replaced SetDelayed with Set in my definitions of the v[t] and a[t] functions, and all speed problems disappeared.

Unfortunately, I can't figure out how to do the same thing within this OOP/inheritance context. If I replace SetDelayed with Set in the superclass definitions of ancestor@v[t_] and ancestor@r[t_], I get nasty cross-contamination between different child objects; it looks like the rule is being executed once per argument, regardless of which $self is involved. Somehow, the rule needs to execute once for each child object, and it needs to execute once for a generic variable argument to create a new function that gets stored, rather than once per numerical argument value.

I have come up with a workaround for my particular case: putting the plotting functions inside a Module and setting (not delayed) a temporary function equal to that original superclass set-delayed that worked fine but was slow, like this:

ancestor@vGraph[tF_] := Module[{vFunc},
  vFunc[t_] = $self@v[t];
  Plot[vFunc[t], {t, 0, tF},]]

That's not ideal, since in principle the integrated functions v[t] and r[t] should only be calculated once per child object (assuming the child's a[t] doesn't change once set), rather than once per call to the graphing method. It does, however, make my code work adequately.

I'm wondering whether you had any thoughts on this, because they might go a long way towards improving my understanding of your OOP system and how to navigate per-child vs. once-per-superclass issues.

(BTW, if you'd like me to re-post this as a question on Stack Exchange, please say so. I put it here because it seems very specific to your answer to a prior question, and to this package, and I don't yet have the reputation to post a comment.)

Thanks,
:Ian

Handling of protected objects

When object obj is protected, WithOrdinaryObjectSet doesn't remove it's special up values.
Attempt of setting obj@member results in infinite recursion instead of Set::write warning.

Wrap up value changing code in WithOrdinaryObjectSet with Unprotect ... Protect.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.