Hi Leif,

>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. 
>...the difference between "maintainable" and "easily maintainable" depends 
on predicting the future somewhat.
There are interesting views on the subject in Agile and Extreme 
Programming.  

Have you heard of Extreme Programming's YAGNI principle: You Ain't Gonna 
Need It <http://en.wikipedia.org/wiki/You_aren%27t_gonna_need_it>

In Refactoring 
<http://www.informit.com/articles/article.aspx?p=1400866&seqNum=13>, Martin 
Fowler has a code smell called *Speculative Generality*:

You get it when people say, "Oh, I think we need the ability to this kind 
> of thing someday" and thus want all sorts of hooks and special cases to 
> handle things that aren't required. The result often is harder to 
> understand and maintain. If all this machinery were being used, it would be 
> worth it. But if it isn't, it isn't. The machinery just gets in the way, so 
> get rid of it.


In ASD:PPP 
<http://www.amazon.co.uk/Software-Development-Principles-Patterns-Practices/dp/0132760584>
 
Robert Martin has a Design Smell called *Needless Complexity*
 

> A design smells of needless complexity when it contains elements that 
> aren't currently useful. This frequently happens when developers anticipate 
> changes to the requirements and put facilities in the software to deal with 
> those potential changes. At first, this may seem like a good thing to do. 
> After all, preparing for future changes should keep our code flexible and 
> prevent nightmarish changes later.
>
> Unfortunately, the effect is often just the opposite. By preparing for 
> many contingencies, the design becomes littered with constructs that are 
> never used. Some of those preparations may pay off, but many more do not. 
> Meanwhile, the design carries the weight of these unused design elements. 
> This makes the software complex and difficult to understand.


I already mentioned elsewhere in the thread that according to Kent Beck, 

   - cost(total) = cost(develop) + cost(maintain) 
   - cost(maintain) = cost(understand) + cost(change) + cost(test) + 
   cost(deploy)
   - learning what the current code does is the expensive part

So his strategy for reducing overall costs is to *ask all programmers to 
address the cost of understanding code during the maintenance phase by 
focusing on communicating, programmer-to-programmer, i.e. writing clear 
code.*

Those ideas are from Implementation Patterns 
<http://www.amazon.co.uk/Implementation-Patterns-Addison-Wesley-Signature-Kent/dp/0321413091>.
 
In the same book Beck has has an interesting section on flexibility:

...flexibility is the justification used for the most ineffective coding 
> and design practices. e.g. ... Why all the complexity? Flexibility. 
> Programs should be flexible, but only in ways they change. If ... never 
> changes, all that complexity is cost without benefit.
>
> Since most of the cost of a program will be incurred after it is first 
> deployed, programs should be easy to change. *The flexibility I imagine 
> will be needed tomorrow, though, is likely to be not what I need when I 
> change the code*. That's why *the flexibility of simplicity and extensive 
> tests is more effective than the flexibility offered by speculative design.*
>
> *Choose patterns that encourage flexibility and bring immediate benefits. 
> For patterns with immediate costs and only deferred benefits, often 
> patience is the best strategy.* Put them back in the bag until they are 
> needed. Then you can apply them in precisely the way they are needed.
>
> Flexibility can come at the cost of increased complexity. For instance, 
> ... Simplicity can encourage flexibility. In the above example, if you can 
> find a way to eliminate ... without losing value, you will have a program 
> that is easier to change later.
>
> *Enhancing the communicability of software also adds to flexibility. The 
> more people who can quickly read, understand, and modify the code, the more 
> options your organization has for future change.*


The patterns in Beck's book "encourage flexibility by helping programmers 
create simple, understandable applications that can be changed"

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 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