{"action":"created","issue":{"url":"https://api.github.com/repos/purescript/purescript/issues/1928","repository_url":"https://api.github.com/repos/purescript/purescript","labels_url":"https://api.github.com/repos/purescript/purescript/issues/1928/labels{/name}","comments_url":"https://api.github.com/repos/purescript/purescript/issues/1928/comments","events_url":"https://api.github.com/repos/purescript/purescript/issues/1928/events","html_url":"https://github.com/purescript/purescript/issues/1928","id":138953822,"number":1928,"title":"Syntax to reduce indentation for exceptional cases","user":{"login":"kRITZCREEK","id":6189397,"avatar_url":"https://avatars.githubusercontent.com/u/6189397?v=3","gravatar_id":"","url":"https://api.github.com/users/kRITZCREEK","html_url":"https://github.com/kRITZCREEK","followers_url":"https://api.github.com/users/kRITZCREEK/followers","following_url":"https://api.github.com/users/kRITZCREEK/following{/other_user}","gists_url":"https://api.github.com/users/kRITZCREEK/gists{/gist_id}","starred_url":"https://api.github.com/users/kRITZCREEK/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kRITZCREEK/subscriptions","organizations_url":"https://api.github.com/users/kRITZCREEK/orgs","repos_url":"https://api.github.com/users/kRITZCREEK/repos","events_url":"https://api.github.com/users/kRITZCREEK/events{/privacy}","received_events_url":"https://api.github.com/users/kRITZCREEK/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":9,"created_at":"2016-03-07T11:14:06Z","updated_at":"2016-03-07T14:13:46Z","closed_at":null,"body":"## Syntax extension proposal\r\n\r\nTaking a cue from Idris which in turn was inspired by Perl's [or die syntax](https://youtu.be/rXXn4UunOkE?t=1851), I suggest adding syntax for handling exceptional cases in do blocks.\r\n\r\nTurning this situation:\r\n```purescript\r\nmain = do\r\n  c <- getCanvasById \"canvas\"\r\n  case c of\r\n    Nothing -> throwError \"Canvas Element could not be found\"\r\n    Just c' -> do\r\n       ctx <- getContext2D c'\r\n       ...\r\n```\r\n... into this (which still passes the totality checker):\r\n```purescript\r\nmain = do\r\n  Just c <- getCanvasById \"canvas\" | Nothing => throwError \"Canvas Element could not be found\"\r\n  ctx <- getContext2D c\r\n  ...\r\n```\r\n\r\nThe general idea is to reduce the indentation level incurred by exceptional cases that just return with a single statement.\r\n\r\nIn case the line gets too long I suggest we allow breaking the exceptional case onto it's own line with indentation:\r\n\r\n```purescript\r\nmain = do\r\n  Just c <- getCanvasById \"canvas\" \r\n    | Nothing => throwError \"Canvas Element could not be found\"\r\n  ctx <- getContext2D c\r\n  ...\r\n```\r\n\r\nAnother consideration to make is if we wanted to allow multiple cases to be specified:\r\n\r\n```purescript\r\nmain = do\r\n  Just (Just c) <- getCanvasById \"canvas\"\r\n    | (Just Nothing) => throwError \"Element was not a Canvas element\"\r\n    | Nothing        => throwError \"Canvas Element could not be found\"\r\n  ctx <- getContext2D c\r\n  ...\r\n```\r\n\r\nRight now I think it would be better to only allow one alternative to reduce the urge to cram more extensive errorhandling into oneliners. The main purpose is to reduce partiality without taking a hit on readability."},"comment":{"url":"https://api.github.com/repos/purescript/purescript/issues/comments/193262907","html_url":"https://github.com/purescript/purescript/issues/1928#issuecomment-193262907","issue_url":"https://api.github.com/repos/purescript/purescript/issues/1928","id":193262907,"user":{"login":"kRITZCREEK","id":6189397,"avatar_url":"https://avatars.githubusercontent.com/u/6189397?v=3","gravatar_id":"","url":"https://api.github.com/users/kRITZCREEK","html_url":"https://github.com/kRITZCREEK","followers_url":"https://api.github.com/users/kRITZCREEK/followers","following_url":"https://api.github.com/users/kRITZCREEK/following{/other_user}","gists_url":"https://api.github.com/users/kRITZCREEK/gists{/gist_id}","starred_url":"https://api.github.com/users/kRITZCREEK/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kRITZCREEK/subscriptions","organizations_url":"https://api.github.com/users/kRITZCREEK/orgs","repos_url":"https://api.github.com/users/kRITZCREEK/repos","events_url":"https://api.github.com/users/kRITZCREEK/events{/privacy}","received_events_url":"https://api.github.com/users/kRITZCREEK/received_events","type":"User","site_admin":false},"created_at":"2016-03-07T14:13:46Z","updated_at":"2016-03-07T14:13:46Z","body":"@hdgarrood But branching that is meant to ensure totality and catch errors early isn't real \"branching\" in the sense that your logic branches out but rather that you need to bail in case of an unexpected input.\r\n\r\nmultipac is a great piece of \"realworld\" PureScript to demonstrate this:\r\n\r\nIf we take https://github.com/hdgarrood/multipac/blob/b78c45c0003e608157fe8c3b3888f51fc9de5f29/src/BaseServer.purs#L175-L207 and apply the sugar:\r\n\r\nhttps://gist.github.com/kRITZCREEK/5f157d23e40fc779089e\r\n\r\nIt doesn't look too invasive or terse and captures a very common pattern.\r\n\r\n@jdegoes `ContT` would give the same semantics as exceptions I guess? That doesn't work too well with resource handling. One field where this syntax could be used is in serverside code dealing with filesystems and networks.\r\n\r\nPrisms reduce the verbosity of pattern matching but I'm not sure how I would use them to walk multiple branches.\r\n\r\n"}}