Urk , one bit of my post came across wrong: "I said before, and I think it needs repeating as you asked again" refers to how long these posts are and I thought it had gotten lost in the walls of text. I didn't mean it in the sanctimonious or condescending way it comes across. I really shouldn't try and write these responses whilst entertaining 4 under 10s :). On 14 Dec 2014 10:32, "Colin Yates" <colin.ya...@gmail.com> wrote:
> From my own experience I think the following is relevant: > - functions are either specific to a context or abstract. Specific > functions need to be understood in the context of their call site and the > domain. Trying to make the name of the specific functions capture the > entire context leads to noise. I would gently suggest that most of your > functions are specific, particularly the ones motivated by extracting > intent. They aren't and almost certainly can't be reusable so their call > site is part of their context. If you do want the to be reusable then all > that context caotured in the label works against you > - again, the drive for reusability and the drive for "future proofing" > often lead us astray. In the solution domain there is only one sensible > interpretation of flipping vertically > - there is a hint of trying to make the code completely unambiguous and > self contained. This is also very similar to trying to make it idiot-proof. > I don't think any of these are achievable. (Collective gasp whilst I out > on my fireproof coat). The syntax of any programming just isn't expressive > enough. Literate programming rocks, but that is because you aren't writing > code, you are writing prose > - FP programmers tend to be more familiar with the inbuilt catalogue of > idiomatic FP solutions, and dare I say I have met many more "average" OO > programmers than FP programmers :). This, coupled with the succinctness of > Clojure means idiomatic Clojure already contains a bunch of context. You > don't need to tell me what your code is doing because idiomatic Clojure > code is inherently readable *once I grok idiomatic Clojure*. For me, I > found myself writing that sort of code at the beginning because I was > compensating for my lack of familiarity. > > Nowadays, I tend to find it much more successful producing code that has a > certain number of assumptions: > - it will be maintained for far longer than it took to write (some of our > apps are decades old) > - readers will be competant wielders of the toolsets used > - idiomatic code is strongly preferred, as are coding conventions > - reader understands the problem domain and the solution domain > > Trying to write code that is somehow a training manual, a design document > etc. Is a hiding to nothing. The best communication tool I have found is > regular discussions with the relevant people. Corporate mindshare is best > maintained through words not code. > > I said before, and I think I it needs repeating as you asked again, but > no, I dont think FP is any less concerned with the WHY or the HOW etc. I do > think it uses seperate tools to achieve the same goals. I would claim that > my code still satisfies all of the excellent points rsised in the best > practices literature, but Clojure doesn't require the same verbosity. > > As ever, this is only my opinion :). > On 14 Dec 2014 07:34, "Philip Schwarz" < > philip.johann.schw...@googlemail.com> wrote: > >> Hi Leif, >> >> if I compare your suggestion >> >> (let [top-right (create-top-right-quadrant-for letter) >>> right (stack top-right >>> (flip top-right)) >>> diamond (beside (map reverse (drop-first-col right)) right)] >>> (display diamond)) >> >> >> with mine >> >> (let [top-right-quadrant (create-top-right-quadrant-for letter) >> top-left-quadrant (drop-first-column-and-reverse-every-row-of >> top-right-quadrant) >> top-half-of-diamond (join-together-side-by-side top-left-quadrant >> top-right-quadrant) >> bottom-half-of-diamond (flip-bottom-up-and-drop-first-row-of >> top-half-of-diamond) >> diamond (put-one-on-top-of-the-other top-half-of-diamond >> bottom-half-of-diamond)] >> >> yours is more inviting, and mine just looks like a barrage of verbiage. >> >> But with some judicious spacing and syntax highlighting, I think mine >> regains IMHO its effectiveness >> >> (let [*top-right-quadrant **(**create-top-right-quadrant-for * >> *letter**)* >> *top-left-quadrant * *(* >> *drop-first-column-and-reverse-every-row-of* *top-right-quadrant**)* >> *top-half-of-diamond* *(**join-together-side-by-side* >> *top-left-quadrant * >> * >> top-right-quadrant**)* >> *bottom-half-of-diamond* *(* >> *flip-bottom-up-and-drop-first-row-of* *top-half-of-diamond)* >> *diamond* *(*put-one-on-top-of-the-other >> *top-half-of-diamond* >> >> *bottom-half-of-diamond**)*] >> even better if I adopt the 'beside' you suggested, and its 'above' >> counterpart: >> >> (let [*top-right-quadrant **(**create-top-right-quadrant-for * >> *letter**)* >> *top-left-quadrant * *(* >> *drop-first-column-and-reverse-every-row-of* *top-right-quadrant**)* >> *top-half-of-diamond* *(**beside* *top-left-quadrant * >> * top-right-quadrant**)* >> *bottom-half-of-diamond* *(* >> *flip-bottom-up-and-drop-first-row-of* *top-half-of-diamond)* >> *diamond* *(*above *top-half-of-diamond* >> *bottom-half-of-diamond**)*] >> >> Do you see the value of hiding the HOW at all? Imagine if this was >> something more complicated, e.g. a financial application: wouldn't you be >> thankful for being spared the detail of HOW things are implemented until >> that time when you consider it useful to understand it? >> >> We talked elsewhere in this thread of separating intention from >> implementation by using the Extract Method refactoring and implementation >> patterns like Composed Method, Intention Revealing Method Name, Explaining >> Message, etc. But the above code also highlights that other simple >> technique we can use to separate WHAT from HOW: the Introduce Explaining >> Variable refactoring (http://c2.com/cgi/wiki?IntroduceExplainingVariable >> - AKA Extract Variable >> http://refactoring.com/catalog/extractVariable.html). Instead of forcing >> the reader to deal with the whole of a non-trivial expression which is all >> about the HOW, we can factor out one or more sub-expressions and give them >> a name that says WHAT the expression(s) do. In your 'let', you have two >> explaining variables, whereas I have four. >> >> Do you see the value of hiding the HOW in this way? >> >> Philip >> >> >> On Tuesday, 9 December 2014 05:06:22 UTC, Leif wrote: >>> >>> Hi, Philip. >>> >>> I had the same urge as David--I tried it out, glossing over any formal >>> rules. Here's what I came up with: >>> https://gist.github.com/leifp/ae37c3b6f1b497f13f1e >>> >>> In truth, I think David's solution is more readable and maintainable. >>> But I think "maintainability" is a pretty tricky concept: >>> >>> My code makes a seq of maps describing rows, and then turns them into >>> strings at the end. This is probably more work to understand than David's >>> solution. But is it less maintainable? Well, currently, the answer is >>> "yes," but what if I need to output a diamond in several different >>> formats? What if marketing wants each row to be a different color and >>> font? I would start to favor my solution in that case. My point is that >>> the difference between "maintainable" and "horrible" is evident, but the >>> difference between "maintainable" and "easily maintainable" depends on >>> predicting the future somewhat. >>> >>> I also favor a slightly less verbose style. A function is an >>> abstraction, and you seem to be writing functions for very concrete steps. >>> I think you have most of the correct abstractions for your solution method, >>> you just need to consolidate the more concrete steps. Something like: >>> >>> flip-bottom-up -> flip (or vertical- and horizontal-flip) >>> join-together-side-by-side -> beside >>> put-one-on-top-of-the-other -> stack (or ontop, or ...) >>> reverse-every-row -> (map reverse rows) ; very readable to clojure >>> programmers >>> >>> (let [top-right (create-top-right-quadrant-for letter) >>> right (stack top-right >>> (flip top-right)) >>> diamond (beside (map reverse (drop-first-col right)) right)] >>> (display diamond)) >>> >>> The broad takeaway is: if I write a function I only use once, I usually >>> just inline it. Unless of course I believe deep in my heart I'll have need >>> of it somewhere else soon :). >>> This is somewhat a matter of taste, and again, the requirements history >>> usually determines what gets abstracted into functions, and history can be >>> messy. :) >>> >>> Hope that helps, >>> Leif >>> >>> On Saturday, December 6, 2014 5:48:02 AM UTC-5, Philip Schwarz wrote: >>>> >>>> Hello, >>>> >>>> can you please review my first solution to the diamond kata [1] and >>>> tear it to bits: let me know all the ways in which YOU would improve the >>>> code. >>>> >>>> I am not so interested in a better algorithm for solving the kata. I am >>>> learning Clojure and what I want to know is what YOU would do to make the >>>> code more readable/understandable/maintainable, or just to make it >>>> follow Clojure idioms and/or conventions that YOU find effective, or to >>>> follow a coding style that YOU find more effective. >>>> >>>> Thanks, >>>> >>>> Philip >>>> >>>> [1] https://github.com/philipschwarz/diamond-problem-in-clojure >>>> >>> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clojure@googlegroups.com >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+unsubscr...@googlegroups.com >> For more options, visit this group at >> http://groups.google.com/group/clojure?hl=en >> --- >> You received this message because you are subscribed to a topic in the >> Google Groups "Clojure" group. >> To unsubscribe from this topic, visit >> https://groups.google.com/d/topic/clojure/zR5Ny7aoBM0/unsubscribe. >> To unsubscribe from this group and all its topics, send an email to >> clojure+unsubscr...@googlegroups.com. >> For more options, visit https://groups.google.com/d/optout. >> > -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.