{"action":"created","issue":{"url":"https://api.github.com/repos/daokoder/dao/issues/434","labels_url":"https://api.github.com/repos/daokoder/dao/issues/434/labels{/name}","comments_url":"https://api.github.com/repos/daokoder/dao/issues/434/comments","events_url":"https://api.github.com/repos/daokoder/dao/issues/434/events","html_url":"https://github.com/daokoder/dao/issues/434","id":94779704,"number":434,"title":"Discussion: simplifying the OOP","user":{"login":"Night-walker","id":5074460,"avatar_url":"https://avatars.githubusercontent.com/u/5074460?v=3","gravatar_id":"","url":"https://api.github.com/users/Night-walker","html_url":"https://github.com/Night-walker","followers_url":"https://api.github.com/users/Night-walker/followers","following_url":"https://api.github.com/users/Night-walker/following{/other_user}","gists_url":"https://api.github.com/users/Night-walker/gists{/gist_id}","starred_url":"https://api.github.com/users/Night-walker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Night-walker/subscriptions","organizations_url":"https://api.github.com/users/Night-walker/orgs","repos_url":"https://api.github.com/users/Night-walker/repos","events_url":"https://api.github.com/users/Night-walker/events{/privacy}","received_events_url":"https://api.github.com/users/Night-walker/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":5,"created_at":"2015-07-13T18:18:55Z","updated_at":"2015-07-14T10:38:58Z","closed_at":null,"body":"One thing attractive in Go and Rust are their simplicity when it comes to OOP. Even Rust, being a rather tricky language to deal with, bases its OOP on several simple concepts. Sometimes that leads to a more verbose, boilerplate code, but the gain in maintainability is worth attention.\r\n\r\nThe ability to easily read, understand and change *existing* code, in my opinion, is usually more important then being able to concoct some working piece of code with minimal efforts (aka write-only programming). Simplicity and transparency play crucial role here, and that is what classic OOP often lacks.\r\n\r\nHence I open this abstract issue to discuss ways of making Dao OOP simpler. It won't come without sacrifices, but we should better decide what is really important and what is just a fancy toy or a legacy cruft. Looking at Go, you can clearly ascertain that it is not the abundance of features which makes the language successful.\r\n\r\nHere are few simplest ideas with short synopses.\r\n\r\n1) Throw async classes overboard (#393). There is a dedicated issue in which the arguments are presented, so I don't stop here.\r\n\r\n2) Always use explicit `self` to refer to class members.\r\n`+` clear and readable (mostly), prevents name collisions\r\n`-` happens to be verbose\r\n\r\n3) Get rid of static variables (at least do not expose them to the users).\r\n`+` no loss of functionality since they can always be substituted by global variables and namespace usage\r\n`-` tricky wrapping of C++ classes with public static variable members (albeit highly unlikely)\r\n\r\n4) Switch to explicit `self` parameter in class methods.\r\n`+` syntax consistency with wrapped types, no need for static and invar methods syntax sugar\r\n`-` somewhat cumbersome\r\n\r\n5) Remove in-class interface methods in favor of separate interfaces.\r\n`+` clarity and predictability of class behavior\r\n`-` boilerplate code to emulate abstract classes:\r\n```ruby\r\n# currently\r\nclass Abstract {\r\n    interface routine virtual(){}\r\n    routine invokeVirtual(){\r\n        virtual()\r\n    }\r\n}\r\n\r\nclass Derived: Abstract {\r\n    interface routine virtual(){...}\r\n}\r\n\r\n# after the change\r\ninterface HasVirtual {\r\n    routine virtual()\r\n}\r\n\r\nclass Abstract {\r\n    var slot: HasVirtual\r\n    routine Abstract(slot: HasVirtual){\r\n        self.slot = slot\r\n    }\r\n    routine invokeVirtual(){\r\n        slot.virtual()\r\n    }\r\n}\r\n\r\nclass Derived: Abstract {\r\n    routine Derived(): Abstract(self){}\r\n    routine virtual(){...}\r\n}\r\n```\r\n\r\n6) Exclude `private` visibility of class members.\r\n`+` no need to choose between it and `protected` each time when writing a class\r\n`-` may expose sensitive data (albeit it can nevertheless be achieved by modifying the source)"},"comment":{"url":"https://api.github.com/repos/daokoder/dao/issues/comments/121196890","html_url":"https://github.com/daokoder/dao/issues/434#issuecomment-121196890","issue_url":"https://api.github.com/repos/daokoder/dao/issues/434","id":121196890,"user":{"login":"dumblob","id":2451044,"avatar_url":"https://avatars.githubusercontent.com/u/2451044?v=3","gravatar_id":"","url":"https://api.github.com/users/dumblob","html_url":"https://github.com/dumblob","followers_url":"https://api.github.com/users/dumblob/followers","following_url":"https://api.github.com/users/dumblob/following{/other_user}","gists_url":"https://api.github.com/users/dumblob/gists{/gist_id}","starred_url":"https://api.github.com/users/dumblob/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dumblob/subscriptions","organizations_url":"https://api.github.com/users/dumblob/orgs","repos_url":"https://api.github.com/users/dumblob/repos","events_url":"https://api.github.com/users/dumblob/events{/privacy}","received_events_url":"https://api.github.com/users/dumblob/received_events","type":"User","site_admin":false},"created_at":"2015-07-14T10:38:58Z","updated_at":"2015-07-14T10:38:58Z","body":">Well, static variable can always be replaced by a static method (or two methods).\r\n\r\nWith static *property*?\r\n\r\n>Then it's not real `private`. I see no reason for half-measures: either there is private or there isn't.\r\n\r\nCorrect. From this point of view of accepting only yes/no, there is no private thing in the whole programming world :) (sometimes something seems private, but time will **always** show, that there is a non-private use for it). So yes, I agree with private removal. The same actually holds for protected.\r\n\r\nThe only use case for these two keywords was always \"the initial orientation in a new code\" - i.e. initial decision what should I use and what rather not even without reading the code of methods and understanding the logic. This brings me to a more general problem of OOP. The internal state of an object and dependencies between methods. Nowadays I've seen so many objects which have weird dependencies between method calls and the internal state is so ad-hoc, that I've myself decided, that i'll promote OOP only in two cases:\r\n\r\n1) the object/class is designed so, that any method can be called at any time and it will always make sense and it won't cause any harm\r\n2) if there is any depency (i.e. required order) between method calls, the object must include a full-featured FSM, which'll ensure, that in as many cases as possible, the whole dependency tree will be called once the user (programmer) calls some method depending on something else; this case is usually very tricky and I'd rather discourage using OOP for such problems; unfortunately, such problems are very often \"solved\" by OOP and the result is just horrible bloatware :("}}