(self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[76822],{94697:function(e,t,n){(window.__NEXT_P=window.__NEXT_P||[]).push(["/issues/clojure-gazette-1-76",function(){return n(58506)}])},12719:function(e,t,n){"use strict";n.d(t,{Z:function(){return d}});var s=n(85893),i=n(9008),r=n.n(i),a=n(56490),o=n(99490),l=n(67294);function h(e){return e.headline||e.title}function c(e){return e.seoDescription||e.excerpt||e.summary}function d(e){let{children:t,meta:n}=e;return!function(e,t){let n=typeof fathom;(0,l.useEffect)(()=>{if("undefined"!==n){for(let n of t)if(n.tags.every(t=>e.includes(t))){fathom.trackEvent(n.event),console.log(n.event);return}}},[n,e,t])}(n.tags,[{tags:["clojure","beginner"],event:"Page View: Beginner Clojure"},{tags:["functional-programming"],event:"Page View: Functional Programming"}]),(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(r(),{children:[(0,s.jsx)("title",{children:h(n)}),(0,s.jsx)("meta",{name:"description",content:c(n)}),(0,s.jsx)("meta",{name:"twitter:title",content:h(n)}),(0,s.jsx)("meta",{name:"twitter:description",content:c(n)}),n.image&&(0,s.jsx)("meta",{name:"twitter:image",content:"https://ericnormand.me".concat(n.image)}),n.image?(0,s.jsx)("meta",{property:"og:image",content:"https://ericnormand.me".concat(n.image)}):null,(0,s.jsx)("meta",{property:"og:title",content:h(n)}),(0,s.jsx)("meta",{property:"og:description",content:c(n)})]}),(n.extraScripts||[]).map(e=>{let{url:t,async:n}=e;return(0,s.jsx)("script",{src:t,async:n},t)}),(0,s.jsxs)("div",{className:"px-4 sm:px-6 lg:px-8 max-w-full lg:max-w-7xl mx-auto",children:[(0,s.jsxs)("article",{className:"mx-auto lg:max-w-full wide-code",children:[(0,s.jsx)("h1",{id:"title",className:"mb-4 font-bold font-head text-4xl lg:text-5xl",children:n.title}),(0,s.jsxs)("div",{className:"prose prose-xl text-xs by-line-for-hiding",children:["Written by Eric Normand. Published:"," ",o.ou.fromISO(n.published).toLocaleString(o.ou.DATE_FULL),".",n.updated&&" Updated: "+o.ou.fromISO(n.updated).toLocaleString(o.ou.DATE_FULL)+"."]}),(0,s.jsxs)("div",{className:"prose lg:prose-xl mt-8",children:[(0,s.jsx)("div",{className:"text-center",children:(0,s.jsx)(a.PG,{meta:n})}),n.summary&&(0,s.jsxs)("p",{children:["Summary: ",(0,s.jsx)("em",{children:n.summary})]}),t]})]}),(0,s.jsx)("div",{className:"mt-16",style:{maxWidth:811.641},children:(0,s.jsx)(a.hr,{meta:n})})]})]})}},58506:function(e,t,n){"use strict";n.r(t),n.d(t,{meta:function(){return r}});var s=n(85893),i=n(12719);let r={title:"Clojure Gazette 1.76",published:"2014-05-18",tags:["newsletter"]},a=e=>{let{children:t}=e;return(0,s.jsx)(i.Z,{meta:r,children:t})};function o(e){let t=Object.assign({p:"p",h1:"h1",h3:"h3",em:"em",br:"br",h2:"h2",a:"a"},e.components);return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(t.p,{children:"Pyramids, Hypermedia, and Clojure-land"}),"\n",(0,s.jsx)(t.h1,{children:"Clojure Gazette"}),"\n",(0,s.jsx)(t.h1,{children:"Issue 1.76May 18, 2014"}),"\n",(0,s.jsx)(t.h3,{children:(0,s.jsx)(t.em,{children:"Editorial"})}),"\n",(0,s.jsx)(t.p,{children:"Hi Clojurites!"}),"\n",(0,s.jsx)(t.p,{children:"You will notice something new in each link this week. There is now a\nlink to a discussion for each page. (Note: Now defunct.) is the best\nplace to talk about functional programming or talk about anything with\nfunctional programmers. Come participate in the discussions!"}),"\n",(0,s.jsx)(t.p,{children:"Enjoy the issue."}),"\n",(0,s.jsxs)(t.p,{children:["Sincerely,",(0,s.jsx)(t.br,{}),"\n","Eric Normand"]}),"\n",(0,s.jsx)(t.p,{children:"PS Have a suggestion for the Gazette? Just reply to this email!"}),"\n",(0,s.jsx)(t.h2,{children:(0,s.jsx)(t.a,{href:"http://pchristensen.com/blog/articles/software-talks-for-the-ages/",children:"Software Talks for the Ages"})}),"\n",(0,s.jsx)(t.p,{children:"It may come as no surprise, but I watch, read, and listen to lots of\nstuff online. The main reason to start the Gazette was to share the\ngreat stuff I found. At first, I was a little skeptical that what I was\nsharing could be new to people. I like sharing classics, which are the\nmost likely to be known."}),"\n",(0,s.jsx)(t.p,{children:"However, there will always be an audience for great content, no matter\nhow old. It may be new to you, or it may be worth rewatching. It's\nprobably better than most of the new stuff out there, anyway. Peter\nChristensen has put together a list of his favorite talks, with a\nsimilar sentiment."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"http://discuss.purelyfunctional.tv/t/software-talks-for-the-ages/29",children:"DISCUSS"})}),"\n",(0,s.jsx)(t.h2,{children:(0,s.jsx)(t.a,{href:"http://www.oopsla.org/podcasts/Keynote_DavidLorgeParnas.mp3",children:"David Lorge Parnas Keynote at OOPSLA 2007"})}),"\n",(0,s.jsxs)(t.p,{children:["When I first heard about David Parnas's work, I was a little skeptical.\nIt sounds so much like waterfall and lots of work that I just don't have\nthe energy to do. But the more I work in software engineering, the more\nI believe that specs and precise documentation is a great way to force\nyou to think. Read ",(0,s.jsx)(t.a,{href:"http://fm06.mcmaster.ca/req_slides_landscape.pdf",children:"these\nslides"})," to see a\nsummary of his process to create complete specs."]}),"\n",(0,s.jsx)(t.p,{children:"Parnas's idea of tabular expressions is a huge step forward for software\nengineering. Civil engineers have blueprints and plans. They are\nunderstandable by the builders, the customer, and anyone else involved\nin the project. We need that kind of document that all of the\nstakeholders in a software project can understand."}),"\n",(0,s.jsxs)(t.p,{children:["Although I'm increasingly a fan of this kind of thing, I also like an\nopposing view. If an engineer produces documents for a builder to follow\nto build the product, who are the engineers writing documents? What are\nthe documents? Who are the builders? What is the product? In the\nwaterfall model, the system architects write specs, which are passed to\nthe programmers who build a program. ",(0,s.jsx)(t.a,{href:"http://www.infoq.com/presentations/Software-Engineering",children:"Glenn\nVanderburg"}),"\nclaims that the programmers are the engineers, their program is the\ndocument, the ",(0,s.jsx)(t.em,{children:"compiler"})," is the builder, and the product is the complied\nsoftware. His talk has a pretty sophisticated argument."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"http://discuss.purelyfunctional.tv/t/david-lorge-parnas-keynote-at-oopsla-2007/30",children:"DISCUSS"})}),"\n",(0,s.jsx)(t.h2,{children:(0,s.jsx)(t.a,{href:"http://javascriptjabber.com/104-jsj-hypermedia-apis-with-steve-klabnik/",children:"Hypermedia APIs with Steve Klabnik (JavaScript Jabber)"})}),"\n",(0,s.jsx)(t.p,{children:'REST is one of those things that seems to be used only to say what is\nnot REST. That\'s probably because people call things REST without\nunderstanding what it means. Then people correct them---"REST is not\nCRUD", "REST is not JSON", "REST is not concatenating strings into\nURLs"---and REST comes off looking like it\'s negative.'}),"\n",(0,s.jsx)(t.p,{children:'While there is a lot of "that\'s not REST" in this podcast, it also\nincludes a lot of "this *is* REST". It\'s a hard concept to explain.\nBut this podcast is the best short description I\'ve heard. I recommend\nit to you. Afterward, you\'ll be saying "that\'s not REST" yourself.'}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"http://discuss.purelyfunctional.tv/t/hypermedia-apis-with-steve-klabnik-javascript-jabber/32",children:"DISCUSS"})}),"\n",(0,s.jsx)(t.h2,{children:(0,s.jsx)(t.a,{href:"http://writings.quilt.org/2014/05/12/distributed-systems-and-the-end-of-the-api/",children:"Distributed Systems and the End of the API"})}),"\n",(0,s.jsx)(t.p,{children:"I often find myself designing systems in my head, only to realize too\nlate that the communication required between the parts would not work.\nComplex syncing, peer-to-peer topologies, or some other difficult\npattern."}),"\n",(0,s.jsx)(t.p,{children:"But why is it difficult? It's only difficult because most of our tools\nare made to build Client/Server applications, which is just one of many\npossible configurations."}),"\n",(0,s.jsxs)(t.p,{children:["Chas Emerick has been working on a new project called\n",(0,s.jsx)(t.a,{href:"http://quilt.org/",children:"Quilt"})," . While it's still somewhat secretive, it is\nobviously about facilitating distributed systems without traditional\nAPIs. This post is a great introduction to the history of the API and a\nbeginning of a way forward."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"http://discuss.purelyfunctional.tv/t/distributed-systems-and-the-end-of-the-api/33",children:"DISCUSS"})}),"\n",(0,s.jsx)(t.h2,{children:(0,s.jsx)(t.a,{href:"http://www.testblogpleaseignore.com/wp-content/uploads/2012/04/thesis.pdf",children:"Elm: Concurrent FRP for Functional GUIs"})}),"\n",(0,s.jsxs)(t.p,{children:["I recently read Evan Czaplicki's thesis about Elm. It is extremely\nreadable and adds a lot to the state of the art of Functional Reactive\nProgramming. I don't know if I'll ever use Elm myself, but Functional\nReactive Programming is definitely in my future. The ",(0,s.jsx)(t.a,{href:"http://elm-lang.org/edit/examples/Intermediate/Mario.elm",children:"40-line Mario\ndemo"})," is\nreassuring that Elm is onto something. There's lots of possibilities\nthere."]}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"http://discuss.purelyfunctional.tv/t/elm-concurrent-frp-for-functional-guis/34",children:"DISCUSS"})}),"\n",(0,s.jsx)(t.h2,{children:(0,s.jsx)(t.a,{href:"http://crossclj.info/",children:"CrossClj"})}),"\n",(0,s.jsx)(t.p,{children:"An interesting tool to explore the interdependencies of Clojure\nlibraries."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"http://discuss.purelyfunctional.tv/t/crossclj-a-clojure-library-exploration-tool/35",children:"DISCUSS"})}),"\n",(0,s.jsx)(t.h2,{children:(0,s.jsx)(t.a,{href:"http://www.infoq.com/presentations/Archeology-Mark-Lehner",children:"Social Programming a Pyramid"})}),"\n",(0,s.jsx)(t.p,{children:"I was actually at OOPSLA back in 2008 when this talk was given, but I\nmissed it. I found it last week and, well, it's a great talk about how\nlabor was organized to build the pyramids."}),"\n",(0,s.jsx)(t.p,{children:"What struck me most is that the structure of the pyramids was so ad hoc,\nwhile the process of construction and organization evolved so rapidly.\nIt reminds me a lot of people developing processes, managing scrums, and\ndefining best practices, all to organize labor to brute-force a\nsolution. Where is the architecture process?"}),"\n",(0,s.jsx)(t.p,{children:"[DISCUSS](http://discuss.purelyfunctional.tv\n/t/social-programming-a-pyramid/36)"}),"\n",(0,s.jsx)(t.h2,{children:(0,s.jsx)(t.a,{href:"https://www.youtube.com/watch?v=PbeCeM344z8",children:"A Rubyist in Clojure-land"})}),"\n",(0,s.jsx)(t.p,{children:"I don't know Ruby, but I do know that learning multiple languages has a\nprofound effect on your code in any language. David Chelimsky shows how\nlearning Clojure helped him refactor some Ruby code to be shorter,\nclearer, and faster."}),"\n",(0,s.jsx)(t.p,{children:(0,s.jsx)(t.a,{href:"http://discuss.purelyfunctional.tv/t/a-rubyist-in-clojure-land/37",children:"DISCUSS"})})]})}t.default=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return(0,s.jsx)(a,Object.assign({},e,{children:(0,s.jsx)(o,e)}))}}},function(e){e.O(0,[49809,80959,56490,49774,92888,40179],function(){return e(e.s=94697)}),_N_E=e.O()}]);