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.

Reply via email to