{"id":203,"date":"2020-12-19T12:27:48","date_gmt":"2020-12-19T11:27:48","guid":{"rendered":"https:\/\/informedica.nl\/?p=203"},"modified":"2021-01-20T22:36:28","modified_gmt":"2021-01-20T21:36:28","slug":"feliz-indentation-and-fantomas","status":"publish","type":"post","link":"https:\/\/informedica.nl\/?p=203","title":{"rendered":"Feliz indentation and Fantomas"},"content":{"rendered":"\n<p>Indentation is important in F#, as it defines the code blocks and the separate code elements. Using <a href=\"https:\/\/github.com\/Zaid-Ajaj\/Feliz\" target=\"_blank\" rel=\"noreferrer noopener\">Feliz<\/a> to define a view, in a Fable.React application, the indentation matters just as much, and even more. <\/p>\n\n\n\n<p><a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/fsprojects\/fantomas-tools\" target=\"_blank\">Fantomas<\/a> is a beautiful tool that automatically formats your code and ensures consistency, also in indentation. But using code like with the  Feliz library, there some serious drawbacks.<\/p>\n\n\n<p><!--more--><\/p>\n\n\n<p>For example  this is Feliz code formatted by <a href=\"https:\/\/fsprojects.github.io\/fantomas-tools\/#\/fantomas\/preview?data=N4KABGBEDGD2AmBTSAuKEIHpNgGYEMA7AF1gFt8BnAHUIzAAliyAbAOngEsA3MAbTAAHAE6xBbSsQCeLRPzCSZiNhWEBzToQAqYsABYADGAC6teuYtDR46AAtOLeMMR0BAWQCunNtMGw1wviCtlLyImI%2BiAAexGDUkMS2cgQk5FRgAO74UvEmeaZ0lkUYZhjYYIhUnIjCYKQVMYHQsUTwYJpIJKUQTKwcPPLd5uHiirL8Q0Vjyqoa2rqGkxgFRSNsdg5OLhOFxWCe3r7%2BgcGhfEt7a8TRsfGVlNW19TdNLYRtHS7E8RfmK5b-CAFSAAGnAUEoiGIxE0akoqH44IgoAskAAJL5kGhIJpiKCkRh0dx8CwPFjEUUDGCipAAJLvL4AZU4AC9kNTLHoCUCCQBfDnI7lQDFSQTknEkfGotHE0nkvhCiAARgF5kgbnwUQAMppEFqXGpElLLEqAEwGIXGPmqlFqkVihGQABGsFgLGN9CJJLJCIVRVNqs9jMQZE4cBYsEIAEFiABRd4AeVwOsI7MVeBJkMt1oJts99vFLrdHsJMu98vTAGZA4TGYJ8NBEAAhRC4WDOAAK%2BECZChNRL9GIwjJ2fo-NzQvRmMdRfdNa9ct96b0NYgkDrDebrfbetgGRq0CoiHp3Fgh5hkYHGCHI4sVrHNsnBZnrrnT9lPrQfssAFZV1AN0bFs22cABVQQxWEQ9IRPM98AvQgrwgAgWCzO8c3oPNS2nbFZyvBdPwpSwADZ-3XesgO3ZwAGEWCoShqMjSRh2adskIzVDEFHDBx0wp8cKgPD5zLRcv3TAB2MjAK3EDEDcEMnX7f8ULQv4MIwLC12fXDX3wkTCO-CwAA4pIomSd0YiNEOUzMuPQh8J2lATnV04SPwrIoAE5TM3KNcGuYRGLICh2JvOy1IcvinNFQtXPfcslyKJUqXTcjN2Andg1DcNLxszjuIgXiNP4mKX2LNyErEpKVVS6S-ICrKwzdXL0zCgqwCKwVoodHTyvi0SiIsM0yPpTpiATbRhCkAB1TgjTy1T6HvHjH262K%2BuldzEpNatarMqNRA8d4ABFEBYThQwC0Lh3Cpb1K6u1nNxPStqqk0V1SjUolpXAtCSQhY04xlbHbYhZvgeblwteyVscx7SuxZ6KoGwzzCVP9Ps1elcE4KIE0g%2BD21jKIREQSgHhaoof2hiLYai%2BGeqgJH%2BoM9MlVIzGogAJUQOBhHgcHIaKQx2s6sBNOFJ7JWR1mkskzmeb5%2BAADkPDIRThCTWlrjIeF-yVUXVoZ8UyA8FgYXO1MADF2woaEai0UqZY8k0TNSxX23gTxzYcXUbeEO2rrIuxuwbAKAH0Mk4CHbEgQ24fzKW8Wd7ahu8zmDsCKQE2EHVJEF2P-xFmHCqNxOEaZ6WWZdixzTIr7M%2ByHO8%2BIVX1ZqLWdb1tn4-p8vGcgU2fctxB-cDh2ner1PzFNGqaUb7Pc84SRvYtv3bfgoPUpD14akj6OjV74q1sdZnNsqwaZ4DTmADVyybDpYQL9ji9p0uE%2BwiuJWTqe3tr3aaRfStkdZonBIwP3eE-A%2BhcoZHwev3cUZ87SvUvvQU0H1AGamOrAYgABxKExNSbkzAYQZ%2B-5qZwPFiVAeQlf6oIwKaDGgCzZr1TE2CM0AADWTYmicKhJQCajJ8C9ksmray6YVK3WWPdKhJ9epvnPijdMpoOY0mVogDII8WzEH3C4R2YpTo40IHNEhUZ3jyXbsIbuRRJGUIllOL%2BtDFGy0sKaeWNIADSiBECCB%2Bn9Fw9IhG9hTGmGxtk7HUMQVXZxNcZ5u0wVEQGoZKC2DIbAkuHUy6fxoXFGJ080HpxpMyQgahZAHTUGrL401EBOjcAgUJlhbEZLFvY7SglcnIIvqjeglYUrz3OmoQgwDCCgMjMyQZ8EPDOB0KNL48ESHsSaW-TJH8tLOScZ0pRRRKxz0sJAKM5saiEHmdwXcJSLEa0MZoExTFFnhOaVktZjiOn5hQd0jAlZr7MJ9iErUwinTwHwLRWADwSnqM0bqO5%2BUHmrMls8jamyXEWErAAvZx1l74CdLIJJy9bCMikCQTUULFrSMisfY2joXDwCTCExk0hZAvS6VWDBez4zUuTJC4OwgWC4DjjCvu2T1oKMRbEnpTC9l0uEGGYgdSkDEqkTyMc4JjAchxJQK2DwES2N5EAA\" target=\"_blank\" rel=\"noreferrer noopener\">Fantomas<\/a>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"fsharp\" class=\"language-fsharp\">let render (state: State) (dispatch: Msg -&gt; unit) =\n    let filter = createFilter state.Generics state.Indications state.Routes state.Patients dispatch\n    let details =\n        match state.Details with\n        | HasNotStartedYet -&gt; \"## Geen generiek gekozen\"\n        | InProgress -&gt; \"## Doseringen worden opgehaald ...\"\n        | Resolved s -&gt; s.Trim()\n        |&gt; markdown.source\n        |&gt; List.singleton\n        |&gt; List.append [ markdown.escapeHtml false ]\n        |&gt; Markdown.markdown\n    Mui.themeProvider\n        [ themeProvider.theme defaultTheme\n          themeProvider.children\n              [ Html.div\n                  [ [ Fable.MaterialUI.Icons.menuIcon \"\", (fun _ -&gt; ToggleEdit |&gt; dispatch) ]\n                    |&gt; Components.TitleBar.render (state.Versions |&gt; printTitle)\n\n                    if state.EditView then \n                        Html.div [ \n                            prop.style [ style.marginTop 100 ]\n                            prop.text \"Edit view\" \n                        ]\n                    else \n                        Mui.container\n                            [ prop.style\n                                [ style.marginTop 90\n                                  style.padding 10 ]\n                              container.maxWidth.md\n                              prop.children\n                                  [ \/\/ search\n                                    Html.div\n                                        [ prop.style [ style.padding 10 ]\n                                          paper.children filter ]\n                                    match state.Generics with\n                                    | Resolved _ -&gt;\n                                        \/\/ details\n                                        Mui.paper\n                                            [ prop.style\n                                                [ style.padding 10\n                                                  style.color Colors.indigo.``900`` ]\n                                              prop.children [ details ] ]\n                                    | _ -&gt; Html.none ] ] ] ] ]<\/code><\/pre>\n\n\n\n<p>This indentation however has a couple of problems. <\/p>\n\n\n\n<ol class=\"wp-block-list\"><li>It is very hard to see which are the different elements in the code. <\/li><li>When you indent pieces of this code, it quickly results in hard to debug indentation errors.<\/li><\/ol>\n\n\n\n<p>This is because of the following indentation structure:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"fsharp\" class=\"language-fsharp\">    Mui.themeProvider [ themeProvider.theme defaultTheme\n                        themeProvider.children [ Html.div [ [ Fable.MaterialUI.Icons.menuIcon \"\",\n                                                              (fun _ -&gt; ToggleEdit |&gt; dispatch) ]\n                                                            |&gt; Components.TitleBar.render (state.Versions |&gt; printTitle) ] ] ]\n<\/code><\/pre>\n\n\n\n<p>So every list argument starts at the same line as the list opening: i.e. <\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"fsharp\" class=\"language-fsharp\">\/\/ fantomas formatted\nHtml.div [ prop.style [ style.marginTop 40 ]\n           prop.children [ Mui.typography [ prop.text \"the fantomas way\" ] ] ]\n\/\/ easier to extract and indent\nHtml.div [ \n    prop.style [\n        style.marginTop 40\n    ]\n    prop.children [\n        Mui.typography [\n            prop.text \"easier to extract and indent\"\n        ]\n    ]\n]<\/code><\/pre>\n\n\n\n<p>When you reformat the original  code to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"fsharp\" class=\"language-fsharp\">let render (state: State) (dispatch: Msg -&gt; unit) =\n    let filter = createFilter state.Generics state.Indications state.Routes state.Patients dispatch\n\n    let details =\n        match state.Details with\n        | HasNotStartedYet -&gt; \"## Geen generiek gekozen\"\n        | InProgress -&gt; \"## Doseringen worden opgehaald ...\"\n        | Resolved s -&gt; s.Trim()\n        |&gt; markdown.source\n        |&gt; List.singleton\n        |&gt; List.append [ markdown.escapeHtml false ]\n        |&gt; Markdown.markdown\n\n    Mui.themeProvider [ \n            themeProvider.theme defaultTheme\n            themeProvider.children [ \n                Html.div [ \n                    [ \n                        Fable.MaterialUI.Icons.menuIcon \"\", (fun _ -&gt; ToggleEdit |&gt; dispatch) \n                    ]\n                    |&gt; Components.TitleBar.render (state.Versions |&gt; printTitle)\n\n                    if state.EditView then \n                        Html.div [ \n                            prop.style [ style.marginTop 100 ]\n                            prop.text \"Edit view\" \n                        ]\n                    else \n                        Mui.container [ \n                            prop.style [ \n                                style.marginTop 90\n                                style.padding 10 \n                            ]\n                            container.maxWidth.md\n                            prop.children [ \n                                \/\/ search\n                                Html.div [ \n                                    prop.style [ style.padding 10 ]\n                                    paper.children filter \n                                ]\n\n                                match state.Generics with\n                                | Resolved _ -&gt;\n                                    \/\/ details\n                                    Mui.paper [ \n                                        prop.style [ \n                                            style.padding 10\n                                            style.color Colors.indigo.``900`` \n                                        ]\n                                        prop.children [ details ] \n                                    ]\n                                | _ -&gt; Html.none \n                            ] \n                        ] \n                ] \n            ] \n        ]<\/code><\/pre>\n\n\n\n<p>This is easier to read and identify the different elements. Also, when you need to add indentation, because for example you want to wrap things in an additional div, this is far easier to do. <\/p>\n\n\n\n<p>Even the editor view is much nicer as it allows you to collapse each individual element:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"303\" src=\"https:\/\/informedica.nl\/wp-content\/uploads\/2020\/12\/image-1024x303.png\" alt=\"\" class=\"wp-image-206\" srcset=\"https:\/\/informedica.nl\/wp-content\/uploads\/2020\/12\/image-1024x303.png 1024w, https:\/\/informedica.nl\/wp-content\/uploads\/2020\/12\/image-300x89.png 300w, https:\/\/informedica.nl\/wp-content\/uploads\/2020\/12\/image-768x228.png 768w, https:\/\/informedica.nl\/wp-content\/uploads\/2020\/12\/image-1536x455.png 1536w, https:\/\/informedica.nl\/wp-content\/uploads\/2020\/12\/image-2048x607.png 2048w\" sizes=\"auto, (max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px\" \/><figcaption>With the right indentation formatting, you can collapse each different element.<\/figcaption><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Indentation is important in F#, as it defines the code blocks and the separate code elements. Using Feliz to define a view, in a Fable.React application, the indentation matters just as much, and even more. Fantomas is a beautiful tool that automatically formats your code and ensures consistency, also in indentation. But using code like &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/informedica.nl\/?p=203\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Feliz indentation and Fantomas&#8221;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9],"tags":[],"class_list":["post-203","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"https:\/\/informedica.nl\/index.php?rest_route=\/wp\/v2\/posts\/203","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/informedica.nl\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/informedica.nl\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/informedica.nl\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/informedica.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=203"}],"version-history":[{"count":6,"href":"https:\/\/informedica.nl\/index.php?rest_route=\/wp\/v2\/posts\/203\/revisions"}],"predecessor-version":[{"id":211,"href":"https:\/\/informedica.nl\/index.php?rest_route=\/wp\/v2\/posts\/203\/revisions\/211"}],"wp:attachment":[{"href":"https:\/\/informedica.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=203"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/informedica.nl\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=203"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/informedica.nl\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=203"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}