{"action":"created","issue":{"url":"https://api.github.com/repos/odlgroup/odl/issues/319","repository_url":"https://api.github.com/repos/odlgroup/odl","labels_url":"https://api.github.com/repos/odlgroup/odl/issues/319/labels{/name}","comments_url":"https://api.github.com/repos/odlgroup/odl/issues/319/comments","events_url":"https://api.github.com/repos/odlgroup/odl/issues/319/events","html_url":"https://github.com/odlgroup/odl/issues/319","id":142609224,"number":319,"title":"Make LinearSpace methods more permissive?","user":{"login":"kohr-h","id":5030250,"avatar_url":"https://avatars.githubusercontent.com/u/5030250?v=3","gravatar_id":"","url":"https://api.github.com/users/kohr-h","html_url":"https://github.com/kohr-h","followers_url":"https://api.github.com/users/kohr-h/followers","following_url":"https://api.github.com/users/kohr-h/following{/other_user}","gists_url":"https://api.github.com/users/kohr-h/gists{/gist_id}","starred_url":"https://api.github.com/users/kohr-h/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kohr-h/subscriptions","organizations_url":"https://api.github.com/users/kohr-h/orgs","repos_url":"https://api.github.com/users/kohr-h/repos","events_url":"https://api.github.com/users/kohr-h/events{/privacy}","received_events_url":"https://api.github.com/users/kohr-h/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/odlgroup/odl/labels/odl%20core","name":"odl core","color":"5319e7"},{"url":"https://api.github.com/repos/odlgroup/odl/labels/question","name":"question","color":"cc317c"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2016-03-22T10:37:06Z","updated_at":"2016-03-22T10:45:24Z","closed_at":null,"body":"We have very strict rules currently when it comes to `LinearSpaceVector` methods, like arithmetic, inner product etc. For example, the following is an error:\r\n\r\n```python\r\n>>> odl.Rn(2).one() + (2, 2)\r\nTraceback (most recent call last):\r\n...\r\nTypeError: unsupported operand type(s) for +: 'FnVector' and 'tuple'\r\n```\r\n\r\nAt the same time, this is okay:\r\n\r\n```python\r\n>>> odl.Rn(2).one() + 2\r\nRn(2).element([3.0, 3.0])\r\n```\r\n\r\nI think we should consider a change of paradigm here, from \"forbid all except\" to \"allow all except\". Concretely, this would mean that we test for `other in space` first. Then we check if `isinstance(other, self.space.element_type)` and raise an exception if `True` (don't allow foreign space elements). We go on with `other in space.field` and if both were `False`, we use `self.element(other)`. If it fails, we return `NotImplemented`. For example\r\n\r\n```python\r\nclass LinearSpaceVector(...):\r\n    ...\r\n    def __add__(self, other):\r\n        \"\"\"Return ``self + other``.\"\"\"\r\n        # Instead of using __iadd__ we duplicate code here for performance\r\n        if other in self.space:\r\n            tmp = self.space.element()\r\n            return self.space.lincomb(1, self, 1, other, out=tmp)\r\n        # --- Start added code ---\r\n        elif isinstance(other, self.space.element_type):\r\n            raise TypeError('other is of the same type, but not an element of {}'.\r\n                            ''.format(self.space))\r\n        # --- Stop added code ---\r\n        elif other in self.space.field:\r\n            one = getattr(self.space, 'one', None)\r\n            if one is None:\r\n                return NotImplemented\r\n            else:\r\n                # other --> other * space.one()\r\n                tmp = one()\r\n                self.space.lincomb(other, tmp, out=tmp)\r\n                return self.space.lincomb(1, self, 1, tmp, out=tmp)\r\n        else:\r\n            # --- Start modified code ---\r\n            try:\r\n                other = self.space.element(other)\r\n            except (TypeError, ValueError):\r\n                return NotImplemented\r\n            else:\r\n                return self.__add__(other)\r\n            # --- Stop modified code ---\r\n```\r\n\r\nA side effect of this would be that we get rid of the notorious \r\n\r\n    TypeError: unsupported operand type(s) for +: 'DiscreteLpVector' and 'DiscreteLpVector'\r\n\r\nerror message which makes no sense at all."},"comment":{"url":"https://api.github.com/repos/odlgroup/odl/issues/comments/199747970","html_url":"https://github.com/odlgroup/odl/issues/319#issuecomment-199747970","issue_url":"https://api.github.com/repos/odlgroup/odl/issues/319","id":199747970,"user":{"login":"adler-j","id":2202312,"avatar_url":"https://avatars.githubusercontent.com/u/2202312?v=3","gravatar_id":"","url":"https://api.github.com/users/adler-j","html_url":"https://github.com/adler-j","followers_url":"https://api.github.com/users/adler-j/followers","following_url":"https://api.github.com/users/adler-j/following{/other_user}","gists_url":"https://api.github.com/users/adler-j/gists{/gist_id}","starred_url":"https://api.github.com/users/adler-j/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/adler-j/subscriptions","organizations_url":"https://api.github.com/users/adler-j/orgs","repos_url":"https://api.github.com/users/adler-j/repos","events_url":"https://api.github.com/users/adler-j/events{/privacy}","received_events_url":"https://api.github.com/users/adler-j/received_events","type":"User","site_admin":false},"created_at":"2016-03-22T10:45:24Z","updated_at":"2016-03-22T10:45:24Z","body":"Will read more on this, see also #272."}}