{"action":"created","issue":{"url":"https://api.github.com/repos/imagej/imagej-ops/issues/320","labels_url":"https://api.github.com/repos/imagej/imagej-ops/issues/320/labels{/name}","comments_url":"https://api.github.com/repos/imagej/imagej-ops/issues/320/comments","events_url":"https://api.github.com/repos/imagej/imagej-ops/issues/320/events","html_url":"https://github.com/imagej/imagej-ops/issues/320","id":126550042,"number":320,"title":"Lacking way to obtain \"hidden\" ops without matching their class explicitly","user":{"login":"LeonYang5114","id":9411485,"avatar_url":"https://avatars.githubusercontent.com/u/9411485?v=3","gravatar_id":"","url":"https://api.github.com/users/LeonYang5114","html_url":"https://github.com/LeonYang5114","followers_url":"https://api.github.com/users/LeonYang5114/followers","following_url":"https://api.github.com/users/LeonYang5114/following{/other_user}","gists_url":"https://api.github.com/users/LeonYang5114/gists{/gist_id}","starred_url":"https://api.github.com/users/LeonYang5114/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/LeonYang5114/subscriptions","organizations_url":"https://api.github.com/users/LeonYang5114/orgs","repos_url":"https://api.github.com/users/LeonYang5114/repos","events_url":"https://api.github.com/users/LeonYang5114/events{/privacy}","received_events_url":"https://api.github.com/users/LeonYang5114/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2016-01-14T00:39:29Z","updated_at":"2016-01-21T22:37:50Z","closed_at":null,"body":"======== Problem Description ========\r\nHidden ops: ops that have conflicting signatures with other ops of higher priority. For example:\r\n```Java\r\n@Plugin(type = Ops.Image.Test.class, priority = HIGH_PRIORITY + 10)\r\npublic class OpA extends AbstractUnaryComputerOp<Img<Type>, Img<Type>> implements Ops.Image.Test {...}\r\n@Plugin(type = Ops.Image.Test.class, priority = HIGH_PRIORITY)\r\npublic class OpB extends AbstractUnaryComputerOp<IterableInterval<Type>, IterableInterval<Type>> implements Ops.Image.Test {...}\r\n```\r\nSuppose the additional parameters of `OpA` and `OpB` are of the same types. Then `OpB` is hidden by `OpA`. The calls `Computers.unary(ops(), Ops.Image.Test.class, out, in, otherArgs)` will never return instance of `OpB`.\r\n\r\nRight now, if we really want to use `OpB`, we would either call\r\n- `ops().image().test((IterableInterval<Type>) out, (IterableInterval<Type>) in, otherArgs)` or\r\n- `Computers.unary(ops(), OpB.class, out, in, otherArgs)`\r\n\r\n(notice that `Computers.unary(ops(), Ops.Image.Test.class, out, in, otherArgs)` will cause an infinite loop since it will match `OpA` repeatedly)\r\n\r\nIt is very likely that `OpA` is an op that does some extra stuff than `OpB`, so that `OpA` will call `opBInstance.compute1(...)` in its own `compute1`. Since the first way above does not return an instance of `OpB`, we can only use the second one.\r\n\r\nIf a user creates a `OpBCustomized` with same signature as `OpB` and `priority = 5`, we would expect that any matching to `OpB` should be directed to `OpBCustomized`. However, since the second way mentioned above matches with an explicit class name, `OpA` will still use `OpB` to do the work.\r\n\r\n======== Propose Solution ========\r\nHave some way to tell the matcher the exclusive upper bound of priority we want. In this case, we could pass `HIGH_PRIORITY + 10` to `ops()` so that `Computers.unary(ops(), Ops.Image.Test.class, out, in, otherArgs)` will match `OpBCustomized`."},"comment":{"url":"https://api.github.com/repos/imagej/imagej-ops/issues/comments/173737975","html_url":"https://github.com/imagej/imagej-ops/issues/320#issuecomment-173737975","issue_url":"https://api.github.com/repos/imagej/imagej-ops/issues/320","id":173737975,"user":{"login":"ctrueden","id":556626,"avatar_url":"https://avatars.githubusercontent.com/u/556626?v=3","gravatar_id":"","url":"https://api.github.com/users/ctrueden","html_url":"https://github.com/ctrueden","followers_url":"https://api.github.com/users/ctrueden/followers","following_url":"https://api.github.com/users/ctrueden/following{/other_user}","gists_url":"https://api.github.com/users/ctrueden/gists{/gist_id}","starred_url":"https://api.github.com/users/ctrueden/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ctrueden/subscriptions","organizations_url":"https://api.github.com/users/ctrueden/orgs","repos_url":"https://api.github.com/users/ctrueden/repos","events_url":"https://api.github.com/users/ctrueden/events{/privacy}","received_events_url":"https://api.github.com/users/ctrueden/received_events","type":"User","site_admin":false},"created_at":"2016-01-21T22:37:50Z","updated_at":"2016-01-21T22:37:50Z","body":"I believe that adding priority filtering to the matcher would make the design too complicated.\r\n\r\nIf an op needs a computer of the same type that it itself is, this danger of infinite recursion exists. But I think such loops can be avoided with intelligent use of interfaces. I.e.: `OpA` should request an `image.test` op of a _different_ interface than it itself is. Would that work?"}}