>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