{"action":"created","comment":{"url":"https://api.github.com/repos/mesosphere/marathon/pulls/comments/156821234","pull_request_review_id":83361379,"id":156821234,"diff_hunk":"@@ -0,0 +1,121 @@\n+# Code Culture\n+\n+## Overview\n+\n+The code culture is a set of defaults ascribed to by the Marathon developer team. Since writing software is an optimization problem, we guide our design decisions with defaults, not rules. Deviations from our defaults require justification.\n+\n+Our defaults are:\n+\n+* Code is legible on GitHub\n+* Immutability over mutability\n+* No smelly code\n+* Fail loud and proud\n+* Let it crash\n+* Don't panic\n+\n+## Code is Legible on GitHub\n+\n+This default speaks to the desire to write code that can be understood without needing an IDE. Marathon is written in Scala, so our defaults are specific as such.\n+\n+### On Implicits\n+\n+Implicits are an important feature in Scala and are critical for the implementation of type-classes and DSLs.\n+\n+Prefer:\n+\n+* Explicit conversion over implicit\n+* Explicit passing over implicit\n+\n+\n+For our case, if implicits don't help improve the design of code, we don't use them. We don't use implicit conversions. We don't do multi-priority implicits. When type classes help improve the design of code, we use implicits for type classes (IE serialization logic).\n+\n+We prefer implicits to be used contextual values, such as execution contexts. However, we prefer to be conservative, and pass the value explicitly for things like validators, authenticators, and normalizers.\n+\n+### On Type Inference\n+\n+If you are writing some function chain that has multiple levels of inferred function parameter types, we prefer to specify the parameter types.\n+\n+Prefer:\n+\n+```\n+groups.map { group: Group =>\n+  group.apps\n+    .groupBy(_.container.image)\n+    .map { case (image: String, apps: Seq[App]) =>\n+      image -> apps.length\n+    }\n+    }\n+```\n+\n+Over:\n+\n+```\n+groups.map { group =>\n+  group.apps.groupBy(_.container.image).map { case(k, v) =>\n+    k -> v.length\n+  }\n+}\n+```\n+\n+### On Playing Code Golf\n+\n+Code golf is a game in which you implement some program in as few characters as possible.\n+\n+We prefer not to play this game when working on Marathon. Instead, we focus on removing noise (boilerplate), while preserving valuable signal pertaining to the problem at hand.\n+\n+### On Imports\n+\n+We prefer, almost always, that implicits go at the top of the file.\n+\n+Prefer:\n+\n+```\n+import org.company.{Stringifier, Demuxer}\n+```\n+\n+Over:\n+\n+```\n+import org.company._\n+```\n+\n+## Immutability Over Mutability\n+\n+Functional programming is what follows when you don't mutate state. We prefer it, except in performance critical parts of our code.\n+\n+We have a strong preference to encapsulate mutable state. References to data crossing the boundary of some module should be immutable.\n+\n+## No Smelly Code\n+\n+We pay attention to [code smells](https://en.wikipedia.org/wiki/Code_smell) and strive to write well encapsulated code.\n+\n+* A method should not receive more data than it needs to do its job.\n+* Changing some behavior should not result in \"shotgun surgery\"\n+\n+## Fail Loud and Proud\n+\n+It is better to do nothing, than to do the wrong thing.\n+\n+One of my favorite non-examples of this is found in PHP 5:\n+\n+```\n+$ echo '<? print(strftime(\"%Y-%m-%d\",strtotime(\"lol\"))) ?>' | php\n+1970-01-01\n+```\n+\n+We are strict in what we accept, and in what we emit. If input is not what we expect, don't be fancy.\n+\n+Fail loudly. Fail proudly.\n+\n+## Let it Crash\n+\n+We prefer to focus on state recovery, and not graceful tear down. We'd prefer to just crash and restart, rather than implement many complex special error handlers.\n+\n+## Don't Panic\n+\n+We prefer to that Exceptions are used only when something goes unexpectedly wrong.","path":"docs/docs/code-culture.md","position":116,"original_position":116,"commit_id":"22b78574543de35d232870d1e30befd52aff0c2c","original_commit_id":"22b78574543de35d232870d1e30befd52aff0c2c","user":{"login":"timcharper","id":183,"avatar_url":"https://avatars1.githubusercontent.com/u/183?v=4","gravatar_id":"","url":"https://api.github.com/users/timcharper","html_url":"https://github.com/timcharper","followers_url":"https://api.github.com/users/timcharper/followers","following_url":"https://api.github.com/users/timcharper/following{/other_user}","gists_url":"https://api.github.com/users/timcharper/gists{/gist_id}","starred_url":"https://api.github.com/users/timcharper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/timcharper/subscriptions","organizations_url":"https://api.github.com/users/timcharper/orgs","repos_url":"https://api.github.com/users/timcharper/repos","events_url":"https://api.github.com/users/timcharper/events{/privacy}","received_events_url":"https://api.github.com/users/timcharper/received_events","type":"User","site_admin":false},"body":"Yeah, this is hard to describe. I tried to paint the picture with examples.","created_at":"2017-12-14T00:00:30Z","updated_at":"2017-12-14T00:00:30Z","html_url":"https://github.com/mesosphere/marathon/pull/5821#discussion_r156821234","pull_request_url":"https://api.github.com/repos/mesosphere/marathon/pulls/5821","author_association":"CONTRIBUTOR","_links":{"self":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/comments/156821234"},"html":{"href":"https://github.com/mesosphere/marathon/pull/5821#discussion_r156821234"},"pull_request":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/5821"}},"in_reply_to_id":156608885},"pull_request":{"url":"https://api.github.com/repos/mesosphere/marathon/pulls/5821","id":157860089,"html_url":"https://github.com/mesosphere/marathon/pull/5821","diff_url":"https://github.com/mesosphere/marathon/pull/5821.diff","patch_url":"https://github.com/mesosphere/marathon/pull/5821.patch","issue_url":"https://api.github.com/repos/mesosphere/marathon/issues/5821","number":5821,"state":"open","locked":false,"title":"Code culture wip","user":{"login":"timcharper","id":183,"avatar_url":"https://avatars1.githubusercontent.com/u/183?v=4","gravatar_id":"","url":"https://api.github.com/users/timcharper","html_url":"https://github.com/timcharper","followers_url":"https://api.github.com/users/timcharper/followers","following_url":"https://api.github.com/users/timcharper/following{/other_user}","gists_url":"https://api.github.com/users/timcharper/gists{/gist_id}","starred_url":"https://api.github.com/users/timcharper/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/timcharper/subscriptions","organizations_url":"https://api.github.com/users/timcharper/orgs","repos_url":"https://api.github.com/users/timcharper/repos","events_url":"https://api.github.com/users/timcharper/events{/privacy}","received_events_url":"https://api.github.com/users/timcharper/received_events","type":"User","site_admin":false},"body":"","created_at":"2017-12-12T15:35:10Z","updated_at":"2017-12-14T00:00:30Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7520a63b73aea7905f2bc29ed285debc0e1febc5","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/mesosphere/marathon/pulls/5821/commits","review_comments_url":"https://api.github.com/repos/mesosphere/marathon/pulls/5821/comments","review_comment_url":"https://api.github.com/repos/mesosphere/marathon/pulls/comments{/number}","comments_url":"https://api.github.com/repos/mesosphere/marathon/issues/5821/comments","statuses_url":"https://api.github.com/repos/mesosphere/marathon/statuses/22b78574543de35d232870d1e30befd52aff0c2c","head":{"label":"mesosphere:tharper/code-culture","ref":"tharper/code-culture","sha":"22b78574543de35d232870d1e30befd52aff0c2c","user":{"login":"mesosphere","id":3458585,"avatar_url":"https://avatars0.githubusercontent.com/u/3458585?v=4","gravatar_id":"","url":"https://api.github.com/users/mesosphere","html_url":"https://github.com/mesosphere","followers_url":"https://api.github.com/users/mesosphere/followers","following_url":"https://api.github.com/users/mesosphere/following{/other_user}","gists_url":"https://api.github.com/users/mesosphere/gists{/gist_id}","starred_url":"https://api.github.com/users/mesosphere/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mesosphere/subscriptions","organizations_url":"https://api.github.com/users/mesosphere/orgs","repos_url":"https://api.github.com/users/mesosphere/repos","events_url":"https://api.github.com/users/mesosphere/events{/privacy}","received_events_url":"https://api.github.com/users/mesosphere/received_events","type":"Organization","site_admin":false},"repo":{"id":10941409,"name":"marathon","full_name":"mesosphere/marathon","owner":{"login":"mesosphere","id":3458585,"avatar_url":"https://avatars0.githubusercontent.com/u/3458585?v=4","gravatar_id":"","url":"https://api.github.com/users/mesosphere","html_url":"https://github.com/mesosphere","followers_url":"https://api.github.com/users/mesosphere/followers","following_url":"https://api.github.com/users/mesosphere/following{/other_user}","gists_url":"https://api.github.com/users/mesosphere/gists{/gist_id}","starred_url":"https://api.github.com/users/mesosphere/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mesosphere/subscriptions","organizations_url":"https://api.github.com/users/mesosphere/orgs","repos_url":"https://api.github.com/users/mesosphere/repos","events_url":"https://api.github.com/users/mesosphere/events{/privacy}","received_events_url":"https://api.github.com/users/mesosphere/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mesosphere/marathon","description":"Deploy and manage containers (including Docker) on top of Apache Mesos at scale.","fork":false,"url":"https://api.github.com/repos/mesosphere/marathon","forks_url":"https://api.github.com/repos/mesosphere/marathon/forks","keys_url":"https://api.github.com/repos/mesosphere/marathon/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mesosphere/marathon/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mesosphere/marathon/teams","hooks_url":"https://api.github.com/repos/mesosphere/marathon/hooks","issue_events_url":"https://api.github.com/repos/mesosphere/marathon/issues/events{/number}","events_url":"https://api.github.com/repos/mesosphere/marathon/events","assignees_url":"https://api.github.com/repos/mesosphere/marathon/assignees{/user}","branches_url":"https://api.github.com/repos/mesosphere/marathon/branches{/branch}","tags_url":"https://api.github.com/repos/mesosphere/marathon/tags","blobs_url":"https://api.github.com/repos/mesosphere/marathon/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mesosphere/marathon/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mesosphere/marathon/git/refs{/sha}","trees_url":"https://api.github.com/repos/mesosphere/marathon/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mesosphere/marathon/statuses/{sha}","languages_url":"https://api.github.com/repos/mesosphere/marathon/languages","stargazers_url":"https://api.github.com/repos/mesosphere/marathon/stargazers","contributors_url":"https://api.github.com/repos/mesosphere/marathon/contributors","subscribers_url":"https://api.github.com/repos/mesosphere/marathon/subscribers","subscription_url":"https://api.github.com/repos/mesosphere/marathon/subscription","commits_url":"https://api.github.com/repos/mesosphere/marathon/commits{/sha}","git_commits_url":"https://api.github.com/repos/mesosphere/marathon/git/commits{/sha}","comments_url":"https://api.github.com/repos/mesosphere/marathon/comments{/number}","issue_comment_url":"https://api.github.com/repos/mesosphere/marathon/issues/comments{/number}","contents_url":"https://api.github.com/repos/mesosphere/marathon/contents/{+path}","compare_url":"https://api.github.com/repos/mesosphere/marathon/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mesosphere/marathon/merges","archive_url":"https://api.github.com/repos/mesosphere/marathon/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mesosphere/marathon/downloads","issues_url":"https://api.github.com/repos/mesosphere/marathon/issues{/number}","pulls_url":"https://api.github.com/repos/mesosphere/marathon/pulls{/number}","milestones_url":"https://api.github.com/repos/mesosphere/marathon/milestones{/number}","notifications_url":"https://api.github.com/repos/mesosphere/marathon/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mesosphere/marathon/labels{/name}","releases_url":"https://api.github.com/repos/mesosphere/marathon/releases{/id}","deployments_url":"https://api.github.com/repos/mesosphere/marathon/deployments","created_at":"2013-06-25T14:56:34Z","updated_at":"2017-12-13T15:37:57Z","pushed_at":"2017-12-13T23:53:26Z","git_url":"git://github.com/mesosphere/marathon.git","ssh_url":"git@github.com:mesosphere/marathon.git","clone_url":"https://github.com/mesosphere/marathon.git","svn_url":"https://github.com/mesosphere/marathon","homepage":"https://mesosphere.github.io/marathon/","size":32948,"stargazers_count":3533,"watchers_count":3533,"language":"Scala","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":821,"mirror_url":null,"archived":false,"open_issues_count":16,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":821,"open_issues":16,"watchers":3533,"default_branch":"master"}},"base":{"label":"mesosphere:master","ref":"master","sha":"2f2f1b5a97529b3b10479e8dcca1e44db4d58eed","user":{"login":"mesosphere","id":3458585,"avatar_url":"https://avatars0.githubusercontent.com/u/3458585?v=4","gravatar_id":"","url":"https://api.github.com/users/mesosphere","html_url":"https://github.com/mesosphere","followers_url":"https://api.github.com/users/mesosphere/followers","following_url":"https://api.github.com/users/mesosphere/following{/other_user}","gists_url":"https://api.github.com/users/mesosphere/gists{/gist_id}","starred_url":"https://api.github.com/users/mesosphere/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mesosphere/subscriptions","organizations_url":"https://api.github.com/users/mesosphere/orgs","repos_url":"https://api.github.com/users/mesosphere/repos","events_url":"https://api.github.com/users/mesosphere/events{/privacy}","received_events_url":"https://api.github.com/users/mesosphere/received_events","type":"Organization","site_admin":false},"repo":{"id":10941409,"name":"marathon","full_name":"mesosphere/marathon","owner":{"login":"mesosphere","id":3458585,"avatar_url":"https://avatars0.githubusercontent.com/u/3458585?v=4","gravatar_id":"","url":"https://api.github.com/users/mesosphere","html_url":"https://github.com/mesosphere","followers_url":"https://api.github.com/users/mesosphere/followers","following_url":"https://api.github.com/users/mesosphere/following{/other_user}","gists_url":"https://api.github.com/users/mesosphere/gists{/gist_id}","starred_url":"https://api.github.com/users/mesosphere/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mesosphere/subscriptions","organizations_url":"https://api.github.com/users/mesosphere/orgs","repos_url":"https://api.github.com/users/mesosphere/repos","events_url":"https://api.github.com/users/mesosphere/events{/privacy}","received_events_url":"https://api.github.com/users/mesosphere/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/mesosphere/marathon","description":"Deploy and manage containers (including Docker) on top of Apache Mesos at scale.","fork":false,"url":"https://api.github.com/repos/mesosphere/marathon","forks_url":"https://api.github.com/repos/mesosphere/marathon/forks","keys_url":"https://api.github.com/repos/mesosphere/marathon/keys{/key_id}","collaborators_url":"https://api.github.com/repos/mesosphere/marathon/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/mesosphere/marathon/teams","hooks_url":"https://api.github.com/repos/mesosphere/marathon/hooks","issue_events_url":"https://api.github.com/repos/mesosphere/marathon/issues/events{/number}","events_url":"https://api.github.com/repos/mesosphere/marathon/events","assignees_url":"https://api.github.com/repos/mesosphere/marathon/assignees{/user}","branches_url":"https://api.github.com/repos/mesosphere/marathon/branches{/branch}","tags_url":"https://api.github.com/repos/mesosphere/marathon/tags","blobs_url":"https://api.github.com/repos/mesosphere/marathon/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/mesosphere/marathon/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/mesosphere/marathon/git/refs{/sha}","trees_url":"https://api.github.com/repos/mesosphere/marathon/git/trees{/sha}","statuses_url":"https://api.github.com/repos/mesosphere/marathon/statuses/{sha}","languages_url":"https://api.github.com/repos/mesosphere/marathon/languages","stargazers_url":"https://api.github.com/repos/mesosphere/marathon/stargazers","contributors_url":"https://api.github.com/repos/mesosphere/marathon/contributors","subscribers_url":"https://api.github.com/repos/mesosphere/marathon/subscribers","subscription_url":"https://api.github.com/repos/mesosphere/marathon/subscription","commits_url":"https://api.github.com/repos/mesosphere/marathon/commits{/sha}","git_commits_url":"https://api.github.com/repos/mesosphere/marathon/git/commits{/sha}","comments_url":"https://api.github.com/repos/mesosphere/marathon/comments{/number}","issue_comment_url":"https://api.github.com/repos/mesosphere/marathon/issues/comments{/number}","contents_url":"https://api.github.com/repos/mesosphere/marathon/contents/{+path}","compare_url":"https://api.github.com/repos/mesosphere/marathon/compare/{base}...{head}","merges_url":"https://api.github.com/repos/mesosphere/marathon/merges","archive_url":"https://api.github.com/repos/mesosphere/marathon/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/mesosphere/marathon/downloads","issues_url":"https://api.github.com/repos/mesosphere/marathon/issues{/number}","pulls_url":"https://api.github.com/repos/mesosphere/marathon/pulls{/number}","milestones_url":"https://api.github.com/repos/mesosphere/marathon/milestones{/number}","notifications_url":"https://api.github.com/repos/mesosphere/marathon/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/mesosphere/marathon/labels{/name}","releases_url":"https://api.github.com/repos/mesosphere/marathon/releases{/id}","deployments_url":"https://api.github.com/repos/mesosphere/marathon/deployments","created_at":"2013-06-25T14:56:34Z","updated_at":"2017-12-13T15:37:57Z","pushed_at":"2017-12-13T23:53:26Z","git_url":"git://github.com/mesosphere/marathon.git","ssh_url":"git@github.com:mesosphere/marathon.git","clone_url":"https://github.com/mesosphere/marathon.git","svn_url":"https://github.com/mesosphere/marathon","homepage":"https://mesosphere.github.io/marathon/","size":32948,"stargazers_count":3533,"watchers_count":3533,"language":"Scala","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":821,"mirror_url":null,"archived":false,"open_issues_count":16,"license":{"key":"apache-2.0","name":"Apache License 2.0","spdx_id":"Apache-2.0","url":"https://api.github.com/licenses/apache-2.0"},"forks":821,"open_issues":16,"watchers":3533,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/5821"},"html":{"href":"https://github.com/mesosphere/marathon/pull/5821"},"issue":{"href":"https://api.github.com/repos/mesosphere/marathon/issues/5821"},"comments":{"href":"https://api.github.com/repos/mesosphere/marathon/issues/5821/comments"},"review_comments":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/5821/comments"},"review_comment":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/mesosphere/marathon/pulls/5821/commits"},"statuses":{"href":"https://api.github.com/repos/mesosphere/marathon/statuses/22b78574543de35d232870d1e30befd52aff0c2c"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"timcharper"}}