[{"data":1,"prerenderedAt":1410},["ShallowReactive",2],{"authors":3,"article-2022-06-23-the-interesting-properties-of-pure-functions":331},[4,23,35,48,61,73,85,98,111,124,136,148,161,173,185,197,209,221,233,245,258,270,282,295,307,319],{"id":5,"title":6,"body":7,"description":11,"extension":14,"meta":15,"name":16,"navigation":17,"path":18,"readingTime":19,"seo":20,"stem":21,"__hash__":22},"authors\u002Fauthors\u002Falexandre-guillon.md","Software Engineer",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"md",{},"Alexandre Guillon",true,"\u002Fauthors\u002Falexandre-guillon",1,{"title":6,"description":11},"authors\u002Falexandre-guillon","4tf48mjyjFNqItOHaulICbrjeCyMag1o6801uHeTz98",{"id":24,"title":6,"body":25,"description":11,"extension":14,"meta":29,"name":30,"navigation":17,"path":31,"readingTime":19,"seo":32,"stem":33,"__hash__":34},"authors\u002Fauthors\u002Falexis-ablain.md",{"type":8,"value":26,"toc":27},[],{"title":11,"searchDepth":12,"depth":12,"links":28},[],{},"Alexis Ablain","\u002Fauthors\u002Falexis-ablain",{"title":6,"description":11},"authors\u002Falexis-ablain","_SIAtB7f-39e5t3GiJof81NP47s6MGo2n4gaHkTy1uQ",{"id":36,"title":37,"body":38,"description":11,"extension":14,"meta":42,"name":43,"navigation":17,"path":44,"readingTime":19,"seo":45,"stem":46,"__hash__":47},"authors\u002Fauthors\u002Faxel-shaita.md","Engineering Manager",{"type":8,"value":39,"toc":40},[],{"title":11,"searchDepth":12,"depth":12,"links":41},[],{},"Axel Shaïta","\u002Fauthors\u002Faxel-shaita",{"title":37,"description":11},"authors\u002Faxel-shaita","fK0argUhsBkWLjpTAhY13oYLVzQthcEYkCEdtHWmIgE",{"id":49,"title":50,"body":51,"description":11,"extension":14,"meta":55,"name":56,"navigation":17,"path":57,"readingTime":19,"seo":58,"stem":59,"__hash__":60},"authors\u002Fauthors\u002Fbaptiste-faure.md","Head of Talent Acquisition",{"type":8,"value":52,"toc":53},[],{"title":11,"searchDepth":12,"depth":12,"links":54},[],{},"Baptiste Faure","\u002Fauthors\u002Fbaptiste-faure",{"title":50,"description":11},"authors\u002Fbaptiste-faure","ELisToYtcgHmgdVWZkCclTPV6exZtfyXqhpx1jjbJHs",{"id":62,"title":6,"body":63,"description":11,"extension":14,"meta":67,"name":68,"navigation":17,"path":69,"readingTime":19,"seo":70,"stem":71,"__hash__":72},"authors\u002Fauthors\u002Fbenjamin-bouillot.md",{"type":8,"value":64,"toc":65},[],{"title":11,"searchDepth":12,"depth":12,"links":66},[],{},"Benjamin Bouillot","\u002Fauthors\u002Fbenjamin-bouillot",{"title":6,"description":11},"authors\u002Fbenjamin-bouillot","tbhCFZyfTt7ZM5b5YgqQ2nhgnSTl8BweaQQryc87fHo",{"id":74,"title":37,"body":75,"description":11,"extension":14,"meta":79,"name":80,"navigation":17,"path":81,"readingTime":19,"seo":82,"stem":83,"__hash__":84},"authors\u002Fauthors\u002Fcedric-nicoloso.md",{"type":8,"value":76,"toc":77},[],{"title":11,"searchDepth":12,"depth":12,"links":78},[],{},"Cédric Nicoloso","\u002Fauthors\u002Fcedric-nicoloso",{"title":37,"description":11},"authors\u002Fcedric-nicoloso","ibSoh4VZYiWYTuLOnZTedaAfcnvet1Q9H7ogW0LgorY",{"id":86,"title":87,"body":88,"description":11,"extension":14,"meta":92,"name":93,"navigation":17,"path":94,"readingTime":19,"seo":95,"stem":96,"__hash__":97},"authors\u002Fauthors\u002Fdavid-touzet.md","Staff Engineer",{"type":8,"value":89,"toc":90},[],{"title":11,"searchDepth":12,"depth":12,"links":91},[],{},"David Touzet","\u002Fauthors\u002Fdavid-touzet",{"title":87,"description":11},"authors\u002Fdavid-touzet","dHWwnQxb1Ubt-WwXWEODGEo9AFoq1cJUhfg3kdnYSBM",{"id":99,"title":100,"body":101,"description":11,"extension":14,"meta":105,"name":106,"navigation":17,"path":107,"readingTime":19,"seo":108,"stem":109,"__hash__":110},"authors\u002Fauthors\u002Feloise-chizat.md","Data Engineer",{"type":8,"value":102,"toc":103},[],{"title":11,"searchDepth":12,"depth":12,"links":104},[],{},"Eloïse Chizat","\u002Fauthors\u002Feloise-chizat",{"title":100,"description":11},"authors\u002Feloise-chizat","Utd72Vm9qT4hh2ZbFi6a2_nXw5Wb494Ed_HL1ra5yw8",{"id":112,"title":113,"body":114,"description":11,"extension":14,"meta":118,"name":119,"navigation":17,"path":120,"readingTime":19,"seo":121,"stem":122,"__hash__":123},"authors\u002Fauthors\u002Femmanuel-auclair.md","Staff engineer",{"type":8,"value":115,"toc":116},[],{"title":11,"searchDepth":12,"depth":12,"links":117},[],{},"Emmanuel Auclair","\u002Fauthors\u002Femmanuel-auclair",{"title":113,"description":11},"authors\u002Femmanuel-auclair","MtsA8THNLEn0dTtYEIQaGwDuf7MjQL55IOeei5gugEg",{"id":125,"title":6,"body":126,"description":11,"extension":14,"meta":130,"name":131,"navigation":17,"path":132,"readingTime":19,"seo":133,"stem":134,"__hash__":135},"authors\u002Fauthors\u002Fhoreb-parraud.md",{"type":8,"value":127,"toc":128},[],{"title":11,"searchDepth":12,"depth":12,"links":129},[],{},"Horeb Parraud","\u002Fauthors\u002Fhoreb-parraud",{"title":6,"description":11},"authors\u002Fhoreb-parraud","ajjsnUX4ohZI-ghMdbb92q_taWDkKXVZSLZXoAeLQtg",{"id":137,"title":37,"body":138,"description":11,"extension":14,"meta":142,"name":143,"navigation":17,"path":144,"readingTime":19,"seo":145,"stem":146,"__hash__":147},"authors\u002Fauthors\u002Fhugo-contreras.md",{"type":8,"value":139,"toc":140},[],{"title":11,"searchDepth":12,"depth":12,"links":141},[],{},"Hugo Contreras","\u002Fauthors\u002Fhugo-contreras",{"title":37,"description":11},"authors\u002Fhugo-contreras","2nc3VMu9ASq9Z6Pwx2-7-Ye991Pww4p-UEDBQFfjF-Q",{"id":149,"title":150,"body":151,"description":11,"extension":14,"meta":155,"name":156,"navigation":17,"path":157,"readingTime":19,"seo":158,"stem":159,"__hash__":160},"authors\u002Fauthors\u002Fjulien-tassin.md","Head of Engineering",{"type":8,"value":152,"toc":153},[],{"title":11,"searchDepth":12,"depth":12,"links":154},[],{},"Julien Tassin","\u002Fauthors\u002Fjulien-tassin",{"title":150,"description":11},"authors\u002Fjulien-tassin","iUIHI7SITje38Jh9X9uvYs4-VsHx4eCdt6hAlyLFG_o",{"id":162,"title":6,"body":163,"description":11,"extension":14,"meta":167,"name":168,"navigation":17,"path":169,"readingTime":19,"seo":170,"stem":171,"__hash__":172},"authors\u002Fauthors\u002Flaurent-renard.md",{"type":8,"value":164,"toc":165},[],{"title":11,"searchDepth":12,"depth":12,"links":166},[],{},"Laurent Renard","\u002Fauthors\u002Flaurent-renard",{"title":6,"description":11},"authors\u002Flaurent-renard","5BP7Ed-pt1SQHjh0UJ1XUrlLTcdlFaDoKBCP4deHq8A",{"id":174,"title":6,"body":175,"description":11,"extension":14,"meta":179,"name":180,"navigation":17,"path":181,"readingTime":19,"seo":182,"stem":183,"__hash__":184},"authors\u002Fauthors\u002Fleo-martin.md",{"type":8,"value":176,"toc":177},[],{"title":11,"searchDepth":12,"depth":12,"links":178},[],{},"Léo Martin","\u002Fauthors\u002Fleo-martin",{"title":6,"description":11},"authors\u002Fleo-martin","eYxCHkRgbGDV7shKdTA9s7Tu0zGV4yDGFoKR5MHQntY",{"id":186,"title":6,"body":187,"description":11,"extension":14,"meta":191,"name":192,"navigation":17,"path":193,"readingTime":19,"seo":194,"stem":195,"__hash__":196},"authors\u002Fauthors\u002Floic-bousquet.md",{"type":8,"value":188,"toc":189},[],{"title":11,"searchDepth":12,"depth":12,"links":190},[],{},"Loïc Bousquet","\u002Fauthors\u002Floic-bousquet",{"title":6,"description":11},"authors\u002Floic-bousquet","ko12qZwiGL8XNjAoy9oWypPkIjr29Pbq7vhdtgldqeQ",{"id":198,"title":6,"body":199,"description":11,"extension":14,"meta":203,"name":204,"navigation":17,"path":205,"readingTime":19,"seo":206,"stem":207,"__hash__":208},"authors\u002Fauthors\u002Floic-poullain.md",{"type":8,"value":200,"toc":201},[],{"title":11,"searchDepth":12,"depth":12,"links":202},[],{},"Loïc Poullain","\u002Fauthors\u002Floic-poullain",{"title":6,"description":11},"authors\u002Floic-poullain","oRIyJhFRTqxy5dLCYQ2OnYZ1DB-gLDUM-85vTSYuTF0",{"id":210,"title":100,"body":211,"description":11,"extension":14,"meta":215,"name":216,"navigation":17,"path":217,"readingTime":19,"seo":218,"stem":219,"__hash__":220},"authors\u002Fauthors\u002Fmaud-lelu.md",{"type":8,"value":212,"toc":213},[],{"title":11,"searchDepth":12,"depth":12,"links":214},[],{},"Maud Lélu","\u002Fauthors\u002Fmaud-lelu",{"title":100,"description":11},"authors\u002Fmaud-lelu","MMbsCKuE41OMHusrl12FIEsI-Trx7l8Nn_ANhvj2_y4",{"id":222,"title":37,"body":223,"description":11,"extension":14,"meta":227,"name":228,"navigation":17,"path":229,"readingTime":19,"seo":230,"stem":231,"__hash__":232},"authors\u002Fauthors\u002Fnicolas-poirier.md",{"type":8,"value":224,"toc":225},[],{"title":11,"searchDepth":12,"depth":12,"links":226},[],{},"Nicolas Poirier","\u002Fauthors\u002Fnicolas-poirier",{"title":37,"description":11},"authors\u002Fnicolas-poirier","dXrJkYo8az4SN_D23aYc3fQ7z8s1dR2a0lt1ogjAjJs",{"id":234,"title":37,"body":235,"description":11,"extension":14,"meta":239,"name":240,"navigation":17,"path":241,"readingTime":19,"seo":242,"stem":243,"__hash__":244},"authors\u002Fauthors\u002Fraphael-sauget.md",{"type":8,"value":236,"toc":237},[],{"title":11,"searchDepth":12,"depth":12,"links":238},[],{},"Raphaël Sauget","\u002Fauthors\u002Fraphael-sauget",{"title":37,"description":11},"authors\u002Fraphael-sauget","Uri9bcq0QDuxRA0PbBoNtu7p_5L3dALu4kzcXVW0xyM",{"id":246,"title":247,"body":248,"description":11,"extension":14,"meta":252,"name":253,"navigation":17,"path":254,"readingTime":19,"seo":255,"stem":256,"__hash__":257},"authors\u002Fauthors\u002Fromain-koenig.md","Co-funder & Head of innovation",{"type":8,"value":249,"toc":250},[],{"title":11,"searchDepth":12,"depth":12,"links":251},[],{},"Romain Koenig","\u002Fauthors\u002Fromain-koenig",{"title":247,"description":11},"authors\u002Fromain-koenig","uyS8--eG2_ezyqRABcJnMJmQKKuSArhPWd14aUvFeEw",{"id":259,"title":37,"body":260,"description":11,"extension":14,"meta":264,"name":265,"navigation":17,"path":266,"readingTime":19,"seo":267,"stem":268,"__hash__":269},"authors\u002Fauthors\u002Fromaric-juniet.md",{"type":8,"value":261,"toc":262},[],{"title":11,"searchDepth":12,"depth":12,"links":263},[],{},"Romaric Juniet","\u002Fauthors\u002Fromaric-juniet",{"title":37,"description":11},"authors\u002Fromaric-juniet","4Zb2artgT-eo-PHLXi3xi4d5t7s6PfhUxeSfXIikSUY",{"id":271,"title":6,"body":272,"description":11,"extension":14,"meta":276,"name":277,"navigation":17,"path":278,"readingTime":19,"seo":279,"stem":280,"__hash__":281},"authors\u002Fauthors\u002Fstanyslas-bres.md",{"type":8,"value":273,"toc":274},[],{"title":11,"searchDepth":12,"depth":12,"links":275},[],{},"Stanyslas Bres","\u002Fauthors\u002Fstanyslas-bres",{"title":6,"description":11},"authors\u002Fstanyslas-bres","Xa0SahETuiN4q1jrmR2ych3moAqcZ2LbU7vSfEt2RuU",{"id":283,"title":284,"body":285,"description":11,"extension":14,"meta":289,"name":290,"navigation":17,"path":291,"readingTime":19,"seo":292,"stem":293,"__hash__":294},"authors\u002Fauthors\u002Ftalent-acquisition.md","Talent Acquisition",{"type":8,"value":286,"toc":287},[],{"title":11,"searchDepth":12,"depth":12,"links":288},[],{},"Équipe Talent Acquisition","\u002Fauthors\u002Ftalent-acquisition",{"description":11},"authors\u002Ftalent-acquisition","doDfE76txftQ4wIiKjJoDmSpyzSKk0tzlgVAp6-opAY",{"id":296,"title":6,"body":297,"description":11,"extension":14,"meta":301,"name":302,"navigation":17,"path":303,"readingTime":19,"seo":304,"stem":305,"__hash__":306},"authors\u002Fauthors\u002Fvictor-borg.md",{"type":8,"value":298,"toc":299},[],{"title":11,"searchDepth":12,"depth":12,"links":300},[],{},"Victor Borg","\u002Fauthors\u002Fvictor-borg",{"title":6,"description":11},"authors\u002Fvictor-borg","-Za-JweoiP6hyclue_WkxMXdRUDTczPGlJf6AZckjUc",{"id":308,"title":6,"body":309,"description":11,"extension":14,"meta":313,"name":314,"navigation":17,"path":315,"readingTime":19,"seo":316,"stem":317,"__hash__":318},"authors\u002Fauthors\u002Fvirgil-roger.md",{"type":8,"value":310,"toc":311},[],{"title":11,"searchDepth":12,"depth":12,"links":312},[],{},"Virgil Roger","\u002Fauthors\u002Fvirgil-roger",{"title":6,"description":11},"authors\u002Fvirgil-roger","DfVFe5j0bCgXeEr381ZYOM5DP4m-pWb93J9-m_muKJ0",{"id":320,"title":6,"body":321,"description":11,"extension":14,"meta":325,"name":326,"navigation":17,"path":327,"readingTime":19,"seo":328,"stem":329,"__hash__":330},"authors\u002Fauthors\u002Fyukan-zhao.md",{"type":8,"value":322,"toc":323},[],{"title":11,"searchDepth":12,"depth":12,"links":324},[],{},"Yukan Zhao","\u002Fauthors\u002Fyukan-zhao",{"title":6,"description":11},"authors\u002Fyukan-zhao","LRPHugtAJnWHsmHxy9_SR5Zas_C5p-GR_uHEs1Fhk_E",{"id":332,"title":333,"author":334,"body":335,"date":1400,"description":1401,"extension":14,"lang":1402,"meta":1403,"navigation":17,"path":1404,"published":17,"readingTime":423,"seo":1405,"stem":1406,"tags":1407,"__hash__":1409},"articles\u002Farticles\u002F2022-06-23-the-interesting-properties-of-pure-functions.md","The interesting properties of pure functions","nicolas-poirier",{"type":8,"value":336,"toc":1384},[337,342,346,356,360,363,366,494,497,548,551,556,563,568,571,574,597,600,609,616,619,675,683,687,690,694,697,844,848,851,958,961,1018,1025,1029,1032,1043,1262,1266,1269,1273,1276,1279,1287,1291,1294,1302,1306,1309,1380],[338,339,341],"h2",{"id":340},"what-is-a-pure-function","What is a pure function?",[343,344,345],"p",{},"A pure function has two properties :",[347,348,349,353],"ol",{},[350,351,352],"li",{},"Output depends only on input",[350,354,355],{},"No side effects",[357,358,352],"h3",{"id":359},"output-depends-only-on-input",[343,361,362],{},"Output only depends on input, no matter when or where you call the function in your code.",[343,364,365],{},"To implement such a function, you could simply map input to output.",[367,368,372],"pre",{"className":369,"code":370,"language":371,"meta":11,"style":11},"language-ts shiki shiki-themes github-light github-dark","const square = {\n    0: 0,\n    1: 1,\n    2: 4,\n    3: 9,\n    4: 16,\n    …\n};\n\nsquare[2]; \u002F\u002F is always 4\n","ts",[373,374,375,394,408,421,434,447,460,466,472,478],"code",{"__ignoreMap":11},[376,377,379,383,387,390],"span",{"class":378,"line":19},"line",[376,380,382],{"class":381},"szBVR","const",[376,384,386],{"class":385},"sj4cs"," square",[376,388,389],{"class":381}," =",[376,391,393],{"class":392},"sVt8B"," {\n",[376,395,396,399,402,405],{"class":378,"line":12},[376,397,398],{"class":385},"    0",[376,400,401],{"class":392},": ",[376,403,404],{"class":385},"0",[376,406,407],{"class":392},",\n",[376,409,411,414,416,419],{"class":378,"line":410},3,[376,412,413],{"class":385},"    1",[376,415,401],{"class":392},[376,417,418],{"class":385},"1",[376,420,407],{"class":392},[376,422,424,427,429,432],{"class":378,"line":423},4,[376,425,426],{"class":385},"    2",[376,428,401],{"class":392},[376,430,431],{"class":385},"4",[376,433,407],{"class":392},[376,435,437,440,442,445],{"class":378,"line":436},5,[376,438,439],{"class":385},"    3",[376,441,401],{"class":392},[376,443,444],{"class":385},"9",[376,446,407],{"class":392},[376,448,450,453,455,458],{"class":378,"line":449},6,[376,451,452],{"class":385},"    4",[376,454,401],{"class":392},[376,456,457],{"class":385},"16",[376,459,407],{"class":392},[376,461,463],{"class":378,"line":462},7,[376,464,465],{"class":392},"    …\n",[376,467,469],{"class":378,"line":468},8,[376,470,471],{"class":392},"};\n",[376,473,475],{"class":378,"line":474},9,[376,476,477],{"emptyLinePlaceholder":17},"\n",[376,479,481,484,487,490],{"class":378,"line":480},10,[376,482,483],{"class":392},"square[",[376,485,486],{"class":385},"2",[376,488,489],{"class":392},"]; ",[376,491,493],{"class":492},"sJ8bj","\u002F\u002F is always 4\n",[343,495,496],{},"Writing all possible pairs (input, output) can be tedious. So you calculate the output from the\ninput",[367,498,500],{"className":369,"code":499,"language":371,"meta":11,"style":11},"const square = (x) => x * x;\nsquare(2); \u002F\u002F is always 4\n",[373,501,502,533],{"__ignoreMap":11},[376,503,504,506,509,511,514,518,521,524,527,530],{"class":378,"line":19},[376,505,382],{"class":381},[376,507,386],{"class":508},"sScJk",[376,510,389],{"class":381},[376,512,513],{"class":392}," (",[376,515,517],{"class":516},"s4XuR","x",[376,519,520],{"class":392},") ",[376,522,523],{"class":381},"=>",[376,525,526],{"class":392}," x ",[376,528,529],{"class":381},"*",[376,531,532],{"class":392}," x;\n",[376,534,535,538,541,543,546],{"class":378,"line":12},[376,536,537],{"class":508},"square",[376,539,540],{"class":392},"(",[376,542,486],{"class":385},[376,544,545],{"class":392},"); ",[376,547,493],{"class":492},[343,549,550],{},"These two implementations of square are equivalent and you always have",[343,552,553],{},[373,554,555],{},"square(2) = square(2)",[343,557,558,559,562],{},"On the contrary, ",[373,560,561],{},"Math.random()"," is impure as the output depends on when it is called.",[343,564,565],{},[373,566,567],{},"Math.random() ≠ Math.random()",[357,569,355],{"id":570},"no-side-effects",[343,572,573],{},"A side effect is an observable effect other than returning a value:",[575,576,577,594],"ul",{},[350,578,579,580],{},"I\u002FO operation\n",[575,581,582,585,588,591],{},[350,583,584],{},"Writing to database or file",[350,586,587],{},"making an HTTP call",[350,589,590],{},"Logging",[350,592,593],{},"Printing on screen",[350,595,596],{},"Mutation",[343,598,599],{},"Being pure means leaving I\u002FO operations outside of the function and using immutability.",[343,601,602,605,606],{},[373,603,604],{},"const a = square(2)"," is equivalent to ",[373,607,608],{},"const a = 4",[343,610,611,612,615],{},"Nothing happens during the computation of ",[373,613,614],{},"square(2)"," other than returning 4.",[343,617,618],{},"An implementation with side effect could be",[367,620,622],{"className":369,"code":621,"language":371,"meta":11,"style":11},"const impureSquare = (x) => {\n  console.log(\"square\", x);\n  return x * x;\n};\n",[373,623,624,643,660,671],{"__ignoreMap":11},[376,625,626,628,631,633,635,637,639,641],{"class":378,"line":19},[376,627,382],{"class":381},[376,629,630],{"class":508}," impureSquare",[376,632,389],{"class":381},[376,634,513],{"class":392},[376,636,517],{"class":516},[376,638,520],{"class":392},[376,640,523],{"class":381},[376,642,393],{"class":392},[376,644,645,648,651,653,657],{"class":378,"line":12},[376,646,647],{"class":392},"  console.",[376,649,650],{"class":508},"log",[376,652,540],{"class":392},[376,654,656],{"class":655},"sZZnC","\"square\"",[376,658,659],{"class":392},", x);\n",[376,661,662,665,667,669],{"class":378,"line":410},[376,663,664],{"class":381},"  return",[376,666,526],{"class":392},[376,668,529],{"class":381},[376,670,532],{"class":392},[376,672,673],{"class":378,"line":423},[376,674,471],{"class":392},[343,676,677,680,681],{},[373,678,679],{},"const a = impureSquare(2)"," is not equivalent to ",[373,682,608],{},[338,684,686],{"id":685},"why-is-it-interesting","Why is it interesting?",[343,688,689],{},"As output only depends on input without side effects, pure functions are independent of time and\nstate. Pure functions are predictable.",[357,691,693],{"id":692},"referentially-transparent","Referentially transparent",[343,695,696],{},"An expression is referentially transparent when it may be replaced by its value without changing the\nresult of the program. It makes the code easier to read, understand and test.",[367,698,700],{"className":369,"code":699,"language":371,"meta":11,"style":11},"const add2 = (x) => x + 2;\nconst multiplyBy2 = (x) => x * 2;\nconst add2AndMultiplyBy2 = (x) => multiplyBy2(add2(x));\n\nconst result = add2AndMultiplyBy2(3);\n\u002F\u002F is equivalent to\nconst result = multiplyBy2(5);\n\u002F\u002F is equivalent to\nconst result = 10;\n",[373,701,702,730,755,782,786,805,810,827,831],{"__ignoreMap":11},[376,703,704,706,709,711,713,715,717,719,721,724,727],{"class":378,"line":19},[376,705,382],{"class":381},[376,707,708],{"class":508}," add2",[376,710,389],{"class":381},[376,712,513],{"class":392},[376,714,517],{"class":516},[376,716,520],{"class":392},[376,718,523],{"class":381},[376,720,526],{"class":392},[376,722,723],{"class":381},"+",[376,725,726],{"class":385}," 2",[376,728,729],{"class":392},";\n",[376,731,732,734,737,739,741,743,745,747,749,751,753],{"class":378,"line":12},[376,733,382],{"class":381},[376,735,736],{"class":508}," multiplyBy2",[376,738,389],{"class":381},[376,740,513],{"class":392},[376,742,517],{"class":516},[376,744,520],{"class":392},[376,746,523],{"class":381},[376,748,526],{"class":392},[376,750,529],{"class":381},[376,752,726],{"class":385},[376,754,729],{"class":392},[376,756,757,759,762,764,766,768,770,772,774,776,779],{"class":378,"line":410},[376,758,382],{"class":381},[376,760,761],{"class":508}," add2AndMultiplyBy2",[376,763,389],{"class":381},[376,765,513],{"class":392},[376,767,517],{"class":516},[376,769,520],{"class":392},[376,771,523],{"class":381},[376,773,736],{"class":508},[376,775,540],{"class":392},[376,777,778],{"class":508},"add2",[376,780,781],{"class":392},"(x));\n",[376,783,784],{"class":378,"line":423},[376,785,477],{"emptyLinePlaceholder":17},[376,787,788,790,793,795,797,799,802],{"class":378,"line":436},[376,789,382],{"class":381},[376,791,792],{"class":385}," result",[376,794,389],{"class":381},[376,796,761],{"class":508},[376,798,540],{"class":392},[376,800,801],{"class":385},"3",[376,803,804],{"class":392},");\n",[376,806,807],{"class":378,"line":449},[376,808,809],{"class":492},"\u002F\u002F is equivalent to\n",[376,811,812,814,816,818,820,822,825],{"class":378,"line":462},[376,813,382],{"class":381},[376,815,792],{"class":385},[376,817,389],{"class":381},[376,819,736],{"class":508},[376,821,540],{"class":392},[376,823,824],{"class":385},"5",[376,826,804],{"class":392},[376,828,829],{"class":378,"line":468},[376,830,809],{"class":492},[376,832,833,835,837,839,842],{"class":378,"line":474},[376,834,382],{"class":381},[376,836,792],{"class":385},[376,838,389],{"class":381},[376,840,841],{"class":385}," 10",[376,843,729],{"class":392},[357,845,847],{"id":846},"testable","Testable",[343,849,850],{},"Pure functions are easily testable.",[367,852,854],{"className":369,"code":853,"language":371,"meta":11,"style":11},"const tomorrow = today => today.add({ days: 1 });\n\n\u002F\u002F You simply test it with\nexpect(tomorrow(Temporal.PlainDate.from(‘2022-05-28’)))\n    .toEqual(Temporal.PlainDate.from(‘2022-05-29’));\n",[373,855,856,885,889,894,930],{"__ignoreMap":11},[376,857,858,860,863,865,868,871,874,877,880,882],{"class":378,"line":19},[376,859,382],{"class":381},[376,861,862],{"class":508}," tomorrow",[376,864,389],{"class":381},[376,866,867],{"class":516}," today",[376,869,870],{"class":381}," =>",[376,872,873],{"class":392}," today.",[376,875,876],{"class":508},"add",[376,878,879],{"class":392},"({ days: ",[376,881,418],{"class":385},[376,883,884],{"class":392}," });\n",[376,886,887],{"class":378,"line":12},[376,888,477],{"emptyLinePlaceholder":17},[376,890,891],{"class":378,"line":410},[376,892,893],{"class":492},"\u002F\u002F You simply test it with\n",[376,895,896,899,901,904,907,910,913,916,919,922,924,927],{"class":378,"line":423},[376,897,898],{"class":508},"expect",[376,900,540],{"class":392},[376,902,903],{"class":508},"tomorrow",[376,905,906],{"class":392},"(Temporal.PlainDate.",[376,908,909],{"class":508},"from",[376,911,912],{"class":392},"(‘",[376,914,915],{"class":385},"2022",[376,917,918],{"class":381},"-",[376,920,921],{"class":385},"05",[376,923,918],{"class":381},[376,925,926],{"class":385},"28",[376,928,929],{"class":392},"’)))\n",[376,931,932,935,938,940,942,944,946,948,950,952,955],{"class":378,"line":436},[376,933,934],{"class":392},"    .",[376,936,937],{"class":508},"toEqual",[376,939,906],{"class":392},[376,941,909],{"class":508},[376,943,912],{"class":392},[376,945,915],{"class":385},[376,947,918],{"class":381},[376,949,921],{"class":385},[376,951,918],{"class":381},[376,953,954],{"class":385},"29",[376,956,957],{"class":392},"’));\n",[343,959,960],{},"What if it were an impure function?",[367,962,964],{"className":369,"code":963,"language":371,"meta":11,"style":11},"const impureTomorrow = () => {\n  const today = Temporal.Now.plainDateISO();\n  return today.add({ days: 1 });\n};\n",[373,965,966,982,1000,1014],{"__ignoreMap":11},[376,967,968,970,973,975,978,980],{"class":378,"line":19},[376,969,382],{"class":381},[376,971,972],{"class":508}," impureTomorrow",[376,974,389],{"class":381},[376,976,977],{"class":392}," () ",[376,979,523],{"class":381},[376,981,393],{"class":392},[376,983,984,987,989,991,994,997],{"class":378,"line":12},[376,985,986],{"class":381},"  const",[376,988,867],{"class":385},[376,990,389],{"class":381},[376,992,993],{"class":392}," Temporal.Now.",[376,995,996],{"class":508},"plainDateISO",[376,998,999],{"class":392},"();\n",[376,1001,1002,1004,1006,1008,1010,1012],{"class":378,"line":410},[376,1003,664],{"class":381},[376,1005,873],{"class":392},[376,1007,876],{"class":508},[376,1009,879],{"class":392},[376,1011,418],{"class":385},[376,1013,884],{"class":392},[376,1015,1016],{"class":378,"line":423},[376,1017,471],{"class":392},[343,1019,1020,1021,1024],{},"Impure function is tricky to test as you have to mock ",[373,1022,1023],{},"Temporal.Now.plainDateISO()",".",[357,1026,1028],{"id":1027},"cacheable","Cacheable",[343,1030,1031],{},"Pure function output is cacheable. Simply map input to output and the next time you need the result\nof this extensive function call, use the cached value. No need to worry about time to live.",[343,1033,1034,1035,1042],{},"To do that, you can use ",[1036,1037,1041],"a",{"href":1038,"rel":1039},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FMemoization",[1040],"nofollow","memoization",". Here is a basic\nimplementation:",[367,1044,1046],{"className":369,"code":1045,"language":371,"meta":11,"style":11},"const memoize = (f) => {\n  const cache = {};\n\n  return (...args) => {\n    const key = JSON.stringify(args);\n\n    if (key in cache) {\n      return cache[key];\n    }\n\n    const result = f(...args);\n    cache[key] = result;\n    return result;\n  };\n};\n\nconst memoizedSquare = memoize(square);\n\nmemoizedSquare(2); \u002F\u002F is 4. It calls square()\nmemoizedSquare(2); \u002F\u002F is 4. It uses the cached result. Doesn’t call square()\n",[373,1047,1048,1068,1080,1084,1102,1123,1127,1141,1149,1154,1158,1177,1189,1197,1203,1208,1213,1228,1233,1248],{"__ignoreMap":11},[376,1049,1050,1052,1055,1057,1059,1062,1064,1066],{"class":378,"line":19},[376,1051,382],{"class":381},[376,1053,1054],{"class":508}," memoize",[376,1056,389],{"class":381},[376,1058,513],{"class":392},[376,1060,1061],{"class":516},"f",[376,1063,520],{"class":392},[376,1065,523],{"class":381},[376,1067,393],{"class":392},[376,1069,1070,1072,1075,1077],{"class":378,"line":12},[376,1071,986],{"class":381},[376,1073,1074],{"class":385}," cache",[376,1076,389],{"class":381},[376,1078,1079],{"class":392}," {};\n",[376,1081,1082],{"class":378,"line":410},[376,1083,477],{"emptyLinePlaceholder":17},[376,1085,1086,1088,1090,1093,1096,1098,1100],{"class":378,"line":423},[376,1087,664],{"class":381},[376,1089,513],{"class":392},[376,1091,1092],{"class":381},"...",[376,1094,1095],{"class":516},"args",[376,1097,520],{"class":392},[376,1099,523],{"class":381},[376,1101,393],{"class":392},[376,1103,1104,1107,1110,1112,1115,1117,1120],{"class":378,"line":436},[376,1105,1106],{"class":381},"    const",[376,1108,1109],{"class":385}," key",[376,1111,389],{"class":381},[376,1113,1114],{"class":385}," JSON",[376,1116,1024],{"class":392},[376,1118,1119],{"class":508},"stringify",[376,1121,1122],{"class":392},"(args);\n",[376,1124,1125],{"class":378,"line":449},[376,1126,477],{"emptyLinePlaceholder":17},[376,1128,1129,1132,1135,1138],{"class":378,"line":462},[376,1130,1131],{"class":381},"    if",[376,1133,1134],{"class":392}," (key ",[376,1136,1137],{"class":381},"in",[376,1139,1140],{"class":392}," cache) {\n",[376,1142,1143,1146],{"class":378,"line":468},[376,1144,1145],{"class":381},"      return",[376,1147,1148],{"class":392}," cache[key];\n",[376,1150,1151],{"class":378,"line":474},[376,1152,1153],{"class":392},"    }\n",[376,1155,1156],{"class":378,"line":480},[376,1157,477],{"emptyLinePlaceholder":17},[376,1159,1161,1163,1165,1167,1170,1172,1174],{"class":378,"line":1160},11,[376,1162,1106],{"class":381},[376,1164,792],{"class":385},[376,1166,389],{"class":381},[376,1168,1169],{"class":508}," f",[376,1171,540],{"class":392},[376,1173,1092],{"class":381},[376,1175,1176],{"class":392},"args);\n",[376,1178,1180,1183,1186],{"class":378,"line":1179},12,[376,1181,1182],{"class":392},"    cache[key] ",[376,1184,1185],{"class":381},"=",[376,1187,1188],{"class":392}," result;\n",[376,1190,1192,1195],{"class":378,"line":1191},13,[376,1193,1194],{"class":381},"    return",[376,1196,1188],{"class":392},[376,1198,1200],{"class":378,"line":1199},14,[376,1201,1202],{"class":392},"  };\n",[376,1204,1206],{"class":378,"line":1205},15,[376,1207,471],{"class":392},[376,1209,1211],{"class":378,"line":1210},16,[376,1212,477],{"emptyLinePlaceholder":17},[376,1214,1216,1218,1221,1223,1225],{"class":378,"line":1215},17,[376,1217,382],{"class":381},[376,1219,1220],{"class":385}," memoizedSquare",[376,1222,389],{"class":381},[376,1224,1054],{"class":508},[376,1226,1227],{"class":392},"(square);\n",[376,1229,1231],{"class":378,"line":1230},18,[376,1232,477],{"emptyLinePlaceholder":17},[376,1234,1236,1239,1241,1243,1245],{"class":378,"line":1235},19,[376,1237,1238],{"class":508},"memoizedSquare",[376,1240,540],{"class":392},[376,1242,486],{"class":385},[376,1244,545],{"class":392},[376,1246,1247],{"class":492},"\u002F\u002F is 4. It calls square()\n",[376,1249,1251,1253,1255,1257,1259],{"class":378,"line":1250},20,[376,1252,1238],{"class":508},[376,1254,540],{"class":392},[376,1256,486],{"class":385},[376,1258,545],{"class":392},[376,1260,1261],{"class":492},"\u002F\u002F is 4. It uses the cached result. Doesn’t call square()\n",[357,1263,1265],{"id":1264},"runnable-in-parallel","Runnable in parallel",[343,1267,1268],{},"Pure functions can run in parallel as no access to shared memory means no race condition.",[338,1270,1272],{"id":1271},"how-do-we-use-them-at-indy","How do we use them at Indy?",[343,1274,1275],{},"Due to the power of pure functions, we use them at Indy.",[343,1277,1278],{},"We have two kind of functions:",[575,1280,1281,1284],{},[350,1282,1283],{},"model functions (pure) contain all the logic of the application",[350,1285,1286],{},"service functions (impure) handle I\u002FO operations",[357,1288,1290],{"id":1289},"model-functions","Model functions",[343,1292,1293],{},"Model functions are pure and contain all the logic of the application. No logic should be in impure\nfunctions.",[575,1295,1296,1299],{},[350,1297,1298],{},"Calculating business (mainly bookkeeping) rules",[350,1300,1301],{},"Mapping data at interfaces (business model \u002F database, business model \u002F web)",[357,1303,1305],{"id":1304},"service-functions","Service functions",[343,1307,1308],{},"Service functions gather data, use model functions and save results. No logic here.",[367,1310,1312],{"className":369,"code":1311,"language":371,"meta":11,"style":11},"async function doSomething() {\n  const data = await getData();\n  \u002F\u002F all the logic is in this pure function from the model\n  const result = computeSomething(data);\n  await saveResult(result);\n}\n",[373,1313,1314,1328,1345,1350,1364,1375],{"__ignoreMap":11},[376,1315,1316,1319,1322,1325],{"class":378,"line":19},[376,1317,1318],{"class":381},"async",[376,1320,1321],{"class":381}," function",[376,1323,1324],{"class":508}," doSomething",[376,1326,1327],{"class":392},"() {\n",[376,1329,1330,1332,1335,1337,1340,1343],{"class":378,"line":12},[376,1331,986],{"class":381},[376,1333,1334],{"class":385}," data",[376,1336,389],{"class":381},[376,1338,1339],{"class":381}," await",[376,1341,1342],{"class":508}," getData",[376,1344,999],{"class":392},[376,1346,1347],{"class":378,"line":410},[376,1348,1349],{"class":492},"  \u002F\u002F all the logic is in this pure function from the model\n",[376,1351,1352,1354,1356,1358,1361],{"class":378,"line":423},[376,1353,986],{"class":381},[376,1355,792],{"class":385},[376,1357,389],{"class":381},[376,1359,1360],{"class":508}," computeSomething",[376,1362,1363],{"class":392},"(data);\n",[376,1365,1366,1369,1372],{"class":378,"line":436},[376,1367,1368],{"class":381},"  await",[376,1370,1371],{"class":508}," saveResult",[376,1373,1374],{"class":392},"(result);\n",[376,1376,1377],{"class":378,"line":449},[376,1378,1379],{"class":392},"}\n",[1381,1382,1383],"style",{},"html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":11,"searchDepth":12,"depth":12,"links":1385},[1386,1390,1396],{"id":340,"depth":12,"text":341,"children":1387},[1388,1389],{"id":359,"depth":410,"text":352},{"id":570,"depth":410,"text":355},{"id":685,"depth":12,"text":686,"children":1391},[1392,1393,1394,1395],{"id":692,"depth":410,"text":693},{"id":846,"depth":410,"text":847},{"id":1027,"depth":410,"text":1028},{"id":1264,"depth":410,"text":1265},{"id":1271,"depth":12,"text":1272,"children":1397},[1398,1399],{"id":1289,"depth":410,"text":1290},{"id":1304,"depth":410,"text":1305},"2022-06-23","What is a pure function, why is it interesting and how do we use them at Indy?","en",{},"\u002Farticles\u002F2022-06-23-the-interesting-properties-of-pure-functions",{"title":333,"description":1401},"articles\u002F2022-06-23-the-interesting-properties-of-pure-functions",[1408],"Tech","cZKQgi_vTPRSNKbphM80ENxdQ7O8tpg_7RNMt8wa9pA",1778159243866]