{"action":"closed","number":86,"pull_request":{"url":"https://api.github.com/repos/typedefs/typedefs/pulls/86","id":237416054,"node_id":"MDExOlB1bGxSZXF1ZXN0MjM3NDE2MDU0","html_url":"https://github.com/typedefs/typedefs/pull/86","diff_url":"https://github.com/typedefs/typedefs/pull/86.diff","patch_url":"https://github.com/typedefs/typedefs/pull/86.patch","issue_url":"https://api.github.com/repos/typedefs/typedefs/issues/86","number":86,"state":"closed","locked":false,"title":"prettyprint and interface for backends","user":{"login":"kjekac","id":2727556,"node_id":"MDQ6VXNlcjI3Mjc1NTY=","avatar_url":"https://avatars0.githubusercontent.com/u/2727556?v=4","gravatar_id":"","url":"https://api.github.com/users/kjekac","html_url":"https://github.com/kjekac","followers_url":"https://api.github.com/users/kjekac/followers","following_url":"https://api.github.com/users/kjekac/following{/other_user}","gists_url":"https://api.github.com/users/kjekac/gists{/gist_id}","starred_url":"https://api.github.com/users/kjekac/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kjekac/subscriptions","organizations_url":"https://api.github.com/users/kjekac/orgs","repos_url":"https://api.github.com/users/kjekac/repos","events_url":"https://api.github.com/users/kjekac/events{/privacy}","received_events_url":"https://api.github.com/users/kjekac/received_events","type":"User","site_admin":false},"body":"The central idea here is to split the backend into two parts and create an interface for these two parts, as can be seen here:\r\n```idris\r\n-- Interface for codegens. lang is a type representing (the syntactic structure of)\r\n-- a type declaration in the target language.\r\ninterface Backend lang where\r\n\t-- Given a TDef and a matching environment, generate a list of type definitions\r\n\t-- in the target language.\r\n  generateDefs : Env n -> TDef n -> List lang\r\n\r\n  -- Given a type definition in the target language, generate its code.\r\n  generateCode : lang -> Doc\r\n```\r\n\r\nGiven this interface, we can expose a function `generate : Backend lang => {n: Nat} -> TDef n -> Doc` which can be called as e.g. `generate {lang=Haskell} td`.\r\n\r\n# Issues\r\n\r\n## Orthogonal approach to PR #85 \r\nPR #85 uses a `record` instead of an `interface` to generalize backends. There are also some diffences in the functions that are expected to be implemented. I can see merits in both.\r\n\r\nFor example, the interface used in this PR only cares about actual type definitions and completely disregards how a single type signature is generated, which to me seems like a desirable abstraction. Or do we actually want to generate a single type signature anywhere outside of the backend itself? I imagine that the generation of (de)serializers will be part of the backends, too.\r\n\r\nOn the other hand, the record used in PR #85 disregards the syntactic structure of the target language, which also seems like a desirable abstraction – I have been a bit uncomfortable with the intermediate step my solution introduced.\r\n\r\nIn this PR, I also assumed that `freshEnv` can be reused across backends but realize that due to syntactic differences this might not be the case.\r\n\r\nGiven this, I suggest that we unify the two approaches into something like the following:\r\n\r\n```idris\r\nrecord Backend where\r\n  constructor MkBackend\r\n  ||| Generate data definitions\r\n  generateDefs : Env n -> TDef n -> Doc\r\n  freshEnv : (n : Nat) -> Env n\r\n```\r\n\r\n## Code repetition\r\nI am not completely happy with the amount of code repetition between the Haskell and ReasonML backend; I suspect that a lot can be extracted into language agnostic code. However, given the high similarities of the two languages' syntaxes, I want to avoid doing this at this moment. If this is a priority, I believe we should add a backend for a third, preferably fairly different, language, in order to see clearly which parts that are in fact irrelevant to the target language, and which parts just happen to be similar between Haskell and ReasonML. This should also wait until after we have solved the issue above.","created_at":"2018-12-10T18:08:45Z","updated_at":"2018-12-21T10:21:05Z","closed_at":"2018-12-21T10:21:05Z","merged_at":"2018-12-21T10:21:05Z","merge_commit_sha":"b4b253167446ea5774506452c853efee797064e7","assignee":null,"assignees":[],"requested_reviewers":[{"login":"clayrat","id":321557,"node_id":"MDQ6VXNlcjMyMTU1Nw==","avatar_url":"https://avatars0.githubusercontent.com/u/321557?v=4","gravatar_id":"","url":"https://api.github.com/users/clayrat","html_url":"https://github.com/clayrat","followers_url":"https://api.github.com/users/clayrat/followers","following_url":"https://api.github.com/users/clayrat/following{/other_user}","gists_url":"https://api.github.com/users/clayrat/gists{/gist_id}","starred_url":"https://api.github.com/users/clayrat/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/clayrat/subscriptions","organizations_url":"https://api.github.com/users/clayrat/orgs","repos_url":"https://api.github.com/users/clayrat/repos","events_url":"https://api.github.com/users/clayrat/events{/privacy}","received_events_url":"https://api.github.com/users/clayrat/received_events","type":"User","site_admin":false},{"login":"fredrikNordvallForsberg","id":481054,"node_id":"MDQ6VXNlcjQ4MTA1NA==","avatar_url":"https://avatars0.githubusercontent.com/u/481054?v=4","gravatar_id":"","url":"https://api.github.com/users/fredrikNordvallForsberg","html_url":"https://github.com/fredrikNordvallForsberg","followers_url":"https://api.github.com/users/fredrikNordvallForsberg/followers","following_url":"https://api.github.com/users/fredrikNordvallForsberg/following{/other_user}","gists_url":"https://api.github.com/users/fredrikNordvallForsberg/gists{/gist_id}","starred_url":"https://api.github.com/users/fredrikNordvallForsberg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fredrikNordvallForsberg/subscriptions","organizations_url":"https://api.github.com/users/fredrikNordvallForsberg/orgs","repos_url":"https://api.github.com/users/fredrikNordvallForsberg/repos","events_url":"https://api.github.com/users/fredrikNordvallForsberg/events{/privacy}","received_events_url":"https://api.github.com/users/fredrikNordvallForsberg/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/typedefs/typedefs/pulls/86/commits","review_comments_url":"https://api.github.com/repos/typedefs/typedefs/pulls/86/comments","review_comment_url":"https://api.github.com/repos/typedefs/typedefs/pulls/comments{/number}","comments_url":"https://api.github.com/repos/typedefs/typedefs/issues/86/comments","statuses_url":"https://api.github.com/repos/typedefs/typedefs/statuses/b4b253167446ea5774506452c853efee797064e7","head":{"label":"typedefs:prettyprint","ref":"prettyprint","sha":"b4b253167446ea5774506452c853efee797064e7","user":{"login":"typedefs","id":25362076,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI1MzYyMDc2","avatar_url":"https://avatars1.githubusercontent.com/u/25362076?v=4","gravatar_id":"","url":"https://api.github.com/users/typedefs","html_url":"https://github.com/typedefs","followers_url":"https://api.github.com/users/typedefs/followers","following_url":"https://api.github.com/users/typedefs/following{/other_user}","gists_url":"https://api.github.com/users/typedefs/gists{/gist_id}","starred_url":"https://api.github.com/users/typedefs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/typedefs/subscriptions","organizations_url":"https://api.github.com/users/typedefs/orgs","repos_url":"https://api.github.com/users/typedefs/repos","events_url":"https://api.github.com/users/typedefs/events{/privacy}","received_events_url":"https://api.github.com/users/typedefs/received_events","type":"Organization","site_admin":false},"repo":{"id":106309432,"node_id":"MDEwOlJlcG9zaXRvcnkxMDYzMDk0MzI=","name":"typedefs","full_name":"typedefs/typedefs","private":false,"owner":{"login":"typedefs","id":25362076,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI1MzYyMDc2","avatar_url":"https://avatars1.githubusercontent.com/u/25362076?v=4","gravatar_id":"","url":"https://api.github.com/users/typedefs","html_url":"https://github.com/typedefs","followers_url":"https://api.github.com/users/typedefs/followers","following_url":"https://api.github.com/users/typedefs/following{/other_user}","gists_url":"https://api.github.com/users/typedefs/gists{/gist_id}","starred_url":"https://api.github.com/users/typedefs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/typedefs/subscriptions","organizations_url":"https://api.github.com/users/typedefs/orgs","repos_url":"https://api.github.com/users/typedefs/repos","events_url":"https://api.github.com/users/typedefs/events{/privacy}","received_events_url":"https://api.github.com/users/typedefs/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/typedefs/typedefs","description":"Programming language agnostic type construction language based on polynomials.","fork":false,"url":"https://api.github.com/repos/typedefs/typedefs","forks_url":"https://api.github.com/repos/typedefs/typedefs/forks","keys_url":"https://api.github.com/repos/typedefs/typedefs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/typedefs/typedefs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/typedefs/typedefs/teams","hooks_url":"https://api.github.com/repos/typedefs/typedefs/hooks","issue_events_url":"https://api.github.com/repos/typedefs/typedefs/issues/events{/number}","events_url":"https://api.github.com/repos/typedefs/typedefs/events","assignees_url":"https://api.github.com/repos/typedefs/typedefs/assignees{/user}","branches_url":"https://api.github.com/repos/typedefs/typedefs/branches{/branch}","tags_url":"https://api.github.com/repos/typedefs/typedefs/tags","blobs_url":"https://api.github.com/repos/typedefs/typedefs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/typedefs/typedefs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/typedefs/typedefs/git/refs{/sha}","trees_url":"https://api.github.com/repos/typedefs/typedefs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/typedefs/typedefs/statuses/{sha}","languages_url":"https://api.github.com/repos/typedefs/typedefs/languages","stargazers_url":"https://api.github.com/repos/typedefs/typedefs/stargazers","contributors_url":"https://api.github.com/repos/typedefs/typedefs/contributors","subscribers_url":"https://api.github.com/repos/typedefs/typedefs/subscribers","subscription_url":"https://api.github.com/repos/typedefs/typedefs/subscription","commits_url":"https://api.github.com/repos/typedefs/typedefs/commits{/sha}","git_commits_url":"https://api.github.com/repos/typedefs/typedefs/git/commits{/sha}","comments_url":"https://api.github.com/repos/typedefs/typedefs/comments{/number}","issue_comment_url":"https://api.github.com/repos/typedefs/typedefs/issues/comments{/number}","contents_url":"https://api.github.com/repos/typedefs/typedefs/contents/{+path}","compare_url":"https://api.github.com/repos/typedefs/typedefs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/typedefs/typedefs/merges","archive_url":"https://api.github.com/repos/typedefs/typedefs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/typedefs/typedefs/downloads","issues_url":"https://api.github.com/repos/typedefs/typedefs/issues{/number}","pulls_url":"https://api.github.com/repos/typedefs/typedefs/pulls{/number}","milestones_url":"https://api.github.com/repos/typedefs/typedefs/milestones{/number}","notifications_url":"https://api.github.com/repos/typedefs/typedefs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/typedefs/typedefs/labels{/name}","releases_url":"https://api.github.com/repos/typedefs/typedefs/releases{/id}","deployments_url":"https://api.github.com/repos/typedefs/typedefs/deployments","created_at":"2017-10-09T16:44:56Z","updated_at":"2018-12-18T15:23:13Z","pushed_at":"2018-12-21T10:21:04Z","git_url":"git://github.com/typedefs/typedefs.git","ssh_url":"git@github.com:typedefs/typedefs.git","clone_url":"https://github.com/typedefs/typedefs.git","svn_url":"https://github.com/typedefs/typedefs","homepage":"http://typedefs.com/","size":189,"stargazers_count":39,"watchers_count":39,"language":"Idris","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"archived":false,"open_issues_count":26,"license":null,"forks":3,"open_issues":26,"watchers":39,"default_branch":"master"}},"base":{"label":"typedefs:master","ref":"master","sha":"2dbaef7607f0164271f421f6750f09471203b7e9","user":{"login":"typedefs","id":25362076,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI1MzYyMDc2","avatar_url":"https://avatars1.githubusercontent.com/u/25362076?v=4","gravatar_id":"","url":"https://api.github.com/users/typedefs","html_url":"https://github.com/typedefs","followers_url":"https://api.github.com/users/typedefs/followers","following_url":"https://api.github.com/users/typedefs/following{/other_user}","gists_url":"https://api.github.com/users/typedefs/gists{/gist_id}","starred_url":"https://api.github.com/users/typedefs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/typedefs/subscriptions","organizations_url":"https://api.github.com/users/typedefs/orgs","repos_url":"https://api.github.com/users/typedefs/repos","events_url":"https://api.github.com/users/typedefs/events{/privacy}","received_events_url":"https://api.github.com/users/typedefs/received_events","type":"Organization","site_admin":false},"repo":{"id":106309432,"node_id":"MDEwOlJlcG9zaXRvcnkxMDYzMDk0MzI=","name":"typedefs","full_name":"typedefs/typedefs","private":false,"owner":{"login":"typedefs","id":25362076,"node_id":"MDEyOk9yZ2FuaXphdGlvbjI1MzYyMDc2","avatar_url":"https://avatars1.githubusercontent.com/u/25362076?v=4","gravatar_id":"","url":"https://api.github.com/users/typedefs","html_url":"https://github.com/typedefs","followers_url":"https://api.github.com/users/typedefs/followers","following_url":"https://api.github.com/users/typedefs/following{/other_user}","gists_url":"https://api.github.com/users/typedefs/gists{/gist_id}","starred_url":"https://api.github.com/users/typedefs/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/typedefs/subscriptions","organizations_url":"https://api.github.com/users/typedefs/orgs","repos_url":"https://api.github.com/users/typedefs/repos","events_url":"https://api.github.com/users/typedefs/events{/privacy}","received_events_url":"https://api.github.com/users/typedefs/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/typedefs/typedefs","description":"Programming language agnostic type construction language based on polynomials.","fork":false,"url":"https://api.github.com/repos/typedefs/typedefs","forks_url":"https://api.github.com/repos/typedefs/typedefs/forks","keys_url":"https://api.github.com/repos/typedefs/typedefs/keys{/key_id}","collaborators_url":"https://api.github.com/repos/typedefs/typedefs/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/typedefs/typedefs/teams","hooks_url":"https://api.github.com/repos/typedefs/typedefs/hooks","issue_events_url":"https://api.github.com/repos/typedefs/typedefs/issues/events{/number}","events_url":"https://api.github.com/repos/typedefs/typedefs/events","assignees_url":"https://api.github.com/repos/typedefs/typedefs/assignees{/user}","branches_url":"https://api.github.com/repos/typedefs/typedefs/branches{/branch}","tags_url":"https://api.github.com/repos/typedefs/typedefs/tags","blobs_url":"https://api.github.com/repos/typedefs/typedefs/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/typedefs/typedefs/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/typedefs/typedefs/git/refs{/sha}","trees_url":"https://api.github.com/repos/typedefs/typedefs/git/trees{/sha}","statuses_url":"https://api.github.com/repos/typedefs/typedefs/statuses/{sha}","languages_url":"https://api.github.com/repos/typedefs/typedefs/languages","stargazers_url":"https://api.github.com/repos/typedefs/typedefs/stargazers","contributors_url":"https://api.github.com/repos/typedefs/typedefs/contributors","subscribers_url":"https://api.github.com/repos/typedefs/typedefs/subscribers","subscription_url":"https://api.github.com/repos/typedefs/typedefs/subscription","commits_url":"https://api.github.com/repos/typedefs/typedefs/commits{/sha}","git_commits_url":"https://api.github.com/repos/typedefs/typedefs/git/commits{/sha}","comments_url":"https://api.github.com/repos/typedefs/typedefs/comments{/number}","issue_comment_url":"https://api.github.com/repos/typedefs/typedefs/issues/comments{/number}","contents_url":"https://api.github.com/repos/typedefs/typedefs/contents/{+path}","compare_url":"https://api.github.com/repos/typedefs/typedefs/compare/{base}...{head}","merges_url":"https://api.github.com/repos/typedefs/typedefs/merges","archive_url":"https://api.github.com/repos/typedefs/typedefs/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/typedefs/typedefs/downloads","issues_url":"https://api.github.com/repos/typedefs/typedefs/issues{/number}","pulls_url":"https://api.github.com/repos/typedefs/typedefs/pulls{/number}","milestones_url":"https://api.github.com/repos/typedefs/typedefs/milestones{/number}","notifications_url":"https://api.github.com/repos/typedefs/typedefs/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/typedefs/typedefs/labels{/name}","releases_url":"https://api.github.com/repos/typedefs/typedefs/releases{/id}","deployments_url":"https://api.github.com/repos/typedefs/typedefs/deployments","created_at":"2017-10-09T16:44:56Z","updated_at":"2018-12-18T15:23:13Z","pushed_at":"2018-12-21T10:21:04Z","git_url":"git://github.com/typedefs/typedefs.git","ssh_url":"git@github.com:typedefs/typedefs.git","clone_url":"https://github.com/typedefs/typedefs.git","svn_url":"https://github.com/typedefs/typedefs","homepage":"http://typedefs.com/","size":189,"stargazers_count":39,"watchers_count":39,"language":"Idris","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":3,"mirror_url":null,"archived":false,"open_issues_count":26,"license":null,"forks":3,"open_issues":26,"watchers":39,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/typedefs/typedefs/pulls/86"},"html":{"href":"https://github.com/typedefs/typedefs/pull/86"},"issue":{"href":"https://api.github.com/repos/typedefs/typedefs/issues/86"},"comments":{"href":"https://api.github.com/repos/typedefs/typedefs/issues/86/comments"},"review_comments":{"href":"https://api.github.com/repos/typedefs/typedefs/pulls/86/comments"},"review_comment":{"href":"https://api.github.com/repos/typedefs/typedefs/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/typedefs/typedefs/pulls/86/commits"},"statuses":{"href":"https://api.github.com/repos/typedefs/typedefs/statuses/b4b253167446ea5774506452c853efee797064e7"}},"author_association":"CONTRIBUTOR","merged":true,"mergeable":null,"rebaseable":null,"mergeable_state":"unknown","merged_by":{"login":"kjekac","id":2727556,"node_id":"MDQ6VXNlcjI3Mjc1NTY=","avatar_url":"https://avatars0.githubusercontent.com/u/2727556?v=4","gravatar_id":"","url":"https://api.github.com/users/kjekac","html_url":"https://github.com/kjekac","followers_url":"https://api.github.com/users/kjekac/followers","following_url":"https://api.github.com/users/kjekac/following{/other_user}","gists_url":"https://api.github.com/users/kjekac/gists{/gist_id}","starred_url":"https://api.github.com/users/kjekac/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kjekac/subscriptions","organizations_url":"https://api.github.com/users/kjekac/orgs","repos_url":"https://api.github.com/users/kjekac/repos","events_url":"https://api.github.com/users/kjekac/events{/privacy}","received_events_url":"https://api.github.com/users/kjekac/received_events","type":"User","site_admin":false},"comments":3,"review_comments":6,"maintainer_can_modify":false,"commits":29,"additions":474,"deletions":181,"changed_files":10}}
{"actor":{"display_login":"kjekac"}}