-
-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Example does not run as advised: probably need to get rid of weak typing in ismethod
#1
Comments
Quick fix to problem supporting custom classes. • Now the a call to foo with a "Person" argument does not fail. • Note that "dispatch on number of inputs" API has changed, imho it is not necessary to allow passing just a number for that, you could just pass ["any"] for one input, ["any","any"] for two and so forth… TODO: extend the implementation to allow multiple output arguments
@bellomia Did #3 fix this issue? |
Yes as far as I'm concerned you can close it :) |
Great! Thanks for confirming. I have to release a new version on the Matlab repository lists |
Do you mean the MathWorks File Exchange? I could not find a corresponding entry therein. Anyway I'm planning on trying a deep refactor to enable the "second" great pillar of Julia's approach to code reuse via multiple dispatch: I'm referring to the famous talk by Karpinski, in particular to the slide The current implementation does not allow the user of a library which provides generic functions built through dispatch.m to add his own specialized methods, for that he has no access to the body of such wrappers. Don't get me wrong, it is already great for organizing runtime polymorphism in a self-contained Matlab project (much much better than the usual duck typing), but misses imo a great opportunity at enabling ergonomic code reuse. So what I thought is to encapsulate dispatch() inside a suitable class so that a library would export an object instead of a generic function, as a wrapper of all the methods. Don't worry, I do not mean going full (nor even half) OOP style. Something like: >> % init the interface object,
>> % there are no methods at first
>> % (but there would be a one-shot constructor eventually, nevermind for now)
>> f = interface
f =
interface with properties:
method_list: {}
>> % Add a specialized implementation,
>> % by providing a lambda function
>> % (or a handle of course) and the type signature...
>> f = f.add_method(@(x,y)(x+y),["numeric","numeric"])
f =
interface with properties:
method_list: {@(x,y)(x+y) ["numeric" "numeric"]}
>> h = f.activate % emit a function handle to allow calling the generic as in your implementation
h =
function_handle with value:
@(varargin)dispatch(self,varargin{:})
>> h(3,3) % test... and works!
ans =
6
>>
>> % NOW, imagine this is what the library exports
>> % to the user, not just h(), but also the object f
>> % what we want now is to allow extending f, and
>> % eventually h(), of course....
>>
>> % So let's add another method
>> f = f.add_method(@sin,"numeric")
f =
interface with properties:
method_list: {@(x,y)(x+y) ["numeric" "numeric"] @sin ["numeric"]}
>> h(pi/2) % If I don't "reload" it is not accessed by the handle (but this could make sense I guess...)
Error using interface/dispatch (line 59)
no method found
Error in interface>@(varargin)dispatch(self,varargin{:}) (line 34)
handle = @(varargin) dispatch(self,varargin{:});
>> h = f.activate % So let's activate again the interface
h =
function_handle with value:
@(varargin)dispatch(self,varargin{:})
>> h(pi/2)
ans =
1
>> % hell yeah, successfully added another method,
>> % /dynamically/, which is the crucial requirement. As you can see the class has just the role of allowing dynamic method extension (which happens automatically in Julia), and I believe should be All this is already implemented in my fork (in a seminal, rusty, stage for now), you can take a look and try it here. Please note that for now all the syntax is tentative and most probably I would change something, but the UI idea is already all there I think. Tell me if you could be interested in such a huge modification (I understand if not, as it would drastically change the API). In that case we should move this discussion to a new issue and I could provide a targeting PR in a few days. Otherwise I would continuing exploring the idea on my own fork. |
Though it works if I remove the dispatch to the "Person" class in the
methodTable
. I believe this happens because of the effective weak-typed use ofnumOrType
inismethod
.On a side note I think you probably could enable multiple outputs by just making use of
varargout
and collecting from the specialized implementation everything as[varargout{1:nargout}]
. This was the initial patch I was targeting, but the fundamental design issue (in my view) with collision between dispatch on number of (numeric-only) and on non-numeric types has made me desist. Nevertheless I find the idea of building an "julia-like" ergonomic interface for multiple dispatch viaisa
quite interesting, I might return on this when I have time: matlab has all the needed functionality for that, just a painful API. Thanks for the idea :)The text was updated successfully, but these errors were encountered: