{"action":"created","issue":{"url":"https://api.github.com/repos/ValeevGroup/tiledarray/issues/64","labels_url":"https://api.github.com/repos/ValeevGroup/tiledarray/issues/64/labels{/name}","comments_url":"https://api.github.com/repos/ValeevGroup/tiledarray/issues/64/comments","events_url":"https://api.github.com/repos/ValeevGroup/tiledarray/issues/64/events","html_url":"https://github.com/ValeevGroup/tiledarray/pull/64","id":124275022,"number":64,"title":"mock-up of \"forced result type\" approach","user":{"login":"evaleev","id":2192487,"avatar_url":"https://avatars.githubusercontent.com/u/2192487?v=3","gravatar_id":"","url":"https://api.github.com/users/evaleev","html_url":"https://github.com/evaleev","followers_url":"https://api.github.com/users/evaleev/followers","following_url":"https://api.github.com/users/evaleev/following{/other_user}","gists_url":"https://api.github.com/users/evaleev/gists{/gist_id}","starred_url":"https://api.github.com/users/evaleev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/evaleev/subscriptions","organizations_url":"https://api.github.com/users/evaleev/orgs","repos_url":"https://api.github.com/users/evaleev/repos","events_url":"https://api.github.com/users/evaleev/events{/privacy}","received_events_url":"https://api.github.com/users/evaleev/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"justusc","id":5115941,"avatar_url":"https://avatars.githubusercontent.com/u/5115941?v=3","gravatar_id":"","url":"https://api.github.com/users/justusc","html_url":"https://github.com/justusc","followers_url":"https://api.github.com/users/justusc/followers","following_url":"https://api.github.com/users/justusc/following{/other_user}","gists_url":"https://api.github.com/users/justusc/gists{/gist_id}","starred_url":"https://api.github.com/users/justusc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/justusc/subscriptions","organizations_url":"https://api.github.com/users/justusc/orgs","repos_url":"https://api.github.com/users/justusc/repos","events_url":"https://api.github.com/users/justusc/events{/privacy}","received_events_url":"https://api.github.com/users/justusc/received_events","type":"User","site_admin":false},"milestone":null,"comments":17,"created_at":"2015-12-29T22:06:37Z","updated_at":"2016-01-01T14:59:26Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/ValeevGroup/tiledarray/pulls/64","html_url":"https://github.com/ValeevGroup/tiledarray/pull/64","diff_url":"https://github.com/ValeevGroup/tiledarray/pull/64.diff","patch_url":"https://github.com/ValeevGroup/tiledarray/pull/64.patch"},"body":"only MINIMALLY tested for D = A + B, where add(A,B) produces C != D\r\n\r\nsummary: result type gets forced down the expression *engine* tree at runtime (expression tree itself is immutable) ... see a version of `Expr<>::eval_to` that forces result type onto the subexpression engine by creating a new result-type-dependent engine. This can then be used to call result-dependent version of add; in experimental::Add (see add.h) I just do a cast from freestanding add() versions that produces wrong result types. The user will have to provide a `BinaryBrait<Result,Arg1,Arg2>` with appropriate add() implementations.\r\n\r\n@justusc what do you think? Such approach should be relatively easy to implement throughout. I also envision something along the lines of \r\n\r\n`D(\"1,2,3\") = result_tile_cast<my_tile_type>(A(\"1,2,3\") + B(\"1,3,2\")) + C(\"3,2,1\")`\r\n\r\nP.S. This is not meant for merging into mixed-expressions, just wanted a convenient place for discussion."},"comment":{"url":"https://api.github.com/repos/ValeevGroup/tiledarray/issues/comments/168312185","html_url":"https://github.com/ValeevGroup/tiledarray/pull/64#issuecomment-168312185","issue_url":"https://api.github.com/repos/ValeevGroup/tiledarray/issues/64","id":168312185,"user":{"login":"evaleev","id":2192487,"avatar_url":"https://avatars.githubusercontent.com/u/2192487?v=3","gravatar_id":"","url":"https://api.github.com/users/evaleev","html_url":"https://github.com/evaleev","followers_url":"https://api.github.com/users/evaleev/followers","following_url":"https://api.github.com/users/evaleev/following{/other_user}","gists_url":"https://api.github.com/users/evaleev/gists{/gist_id}","starred_url":"https://api.github.com/users/evaleev/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/evaleev/subscriptions","organizations_url":"https://api.github.com/users/evaleev/orgs","repos_url":"https://api.github.com/users/evaleev/repos","events_url":"https://api.github.com/users/evaleev/events{/privacy}","received_events_url":"https://api.github.com/users/evaleev/received_events","type":"User","site_admin":false},"created_at":"2016-01-01T14:59:26Z","updated_at":"2016-01-01T14:59:26Z","body":"I like the trait solution. It can accept freestanding functions and yet achieve what we want. I *think* for simple work the freestanding approach works well so we should support it.\r\n\r\nTo make sure: your `Add` class != the existing `Add` class? I would prefer to avoid an extra class. So far we'd have `Add1` specifying how to add, specialized by user, `Add2` using `Add1` to implement all the extra logic (zero tensors, etc.) that user does not usually need to specialize. How about moving most of functionality of `Add2` into `AddBase`, and `Add` (CRTP-derived from `AddBase`) provide the all addition operations (base, +perm, +scal, +perm+scal).\r\n\r\nI would also consider leveraging the much common functionality between `AddBase`, `SubtBase`, etc. to introduce `BinaryOpBase`. Not sure whether it's possible to write a single class for all unary/binary ops ... perhaps the logic of writing single BinaryOp(zero,arg) is too much to ask ... it's arg for addition, -arg for subtraction, and zero for multiplication. Perhaps by having e.g. `Add` tell `BinaryOpBase` that it implements an addition operation on a ring (hence it's commutative and the result of 0+x and x+0 is well defined) this could be used to provide a correct default implementation.\r\n\r\nOr perhaps there is a smaller subset of functionality that can be shared between `AddBase`, `SubtBase`, and `MultBase` ..."}}