I forgot to mention but https://github.com/bbatsov/clojure-style-guide is a
pretty good resource.
On 9 Dec 2014 00:24, "Philip Schwarz" <philip.johann.schw...@googlemail.com>
wrote:

> Hello David,
>
> I had set myself the constraint that I wanted the solution to exploit two
> symmetries:
> (1) The top left and top right of the diamond are mirror images
> (2) The top half and bottom half of the diamond are also mirror images
>
> >I'm assuming you used a TDD process to write this (correct me if
> wrong--basing that on the articles you linked to)
> I was on a train commuting back home, and what I did was sit in a loop
> where I wrote some code and then tweaked it until executing it in the REPL
> gave me the part of the diamond that I wanted, by eyeballing the console
> output. What a coincidence that in your gist you linked to
> http://blog.jayfields.com/2014/01/repl-driven-development.html . I was
> looking at exactly that blog post on Sunday to determine if what I had been
> doing could be classified as REPL-based? Still not sure. Thoughts?
>
> My first version of the code was this
> <https://gist.github.com/philipschwarz/c7e3be1ac97e482d04bf>:
>
> (defn print-diamond [letter]
>   (let [alphabet "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
>         position-of (fn [letter] (inc (- (int letter) (int \A))))
>         number-of-letters (position-of letter)
>         dashes (fn [n] (repeat n \-))
>         fixed-text-for (fn [letter] (concat (dashes (dec (position-of 
> letter))) (list letter)))
>         template (map fixed-text-for (take number-of-letters alphabet))
>         pad-with-trailing-dashes (fn [index line] (concat line (dashes (dec 
> (- number-of-letters index)))))
>         top-right-quadrant (map-indexed pad-with-trailing-dashes template)
>         top-left-quadrant (map reverse (map rest (take number-of-letters 
> top-right-quadrant)))
>         top-half (map concat top-left-quadrant top-right-quadrant)
>         diamond (concat top-half (drop 1 (reverse top-half)))]
>     (doseq [line (map #(apply str %) diamond)]
>       (println line))))
>
> I showed it to Extreme Programming and Agile Guru Ron Jeffries, and the 
> following conversation ensued:
>
>
> @philip_schwarz 1st stab at Clojure print-diamond using symmetries
> identified by @TotherAlistair @RonJeffries @gdinwiddie @sebrose
> https://gist.github.com/philipschwarz/c7e3be1ac97e482d04bf
> @RonJeffries @philip_schwarz *can people read that and figure out what it
> does? *i can't but not a closure person. @totheralistair @gdinwiddie
> @sebrose
> @philip_schwarz @RonJeffries @TotherAlistair @gdinwiddie @sebrose *I like
> defns of top-half & diamond & think they r graspable-ish; top-left-quadrant
> less so*
> @philip_schwarz one interesting Q for us all is *if one didn't know the
> prob could one grok the prog* @totheralistair @gdinwiddie @sebrose
> @gdinwiddie .@RonJeffries I think *the program is generally easier to
> grok if you've got the tests, too.* @philip_schwarz @TotherAlistair
> @sebrose
> @philip_schwarz  Dec 3
> @gdinwiddie @RonJeffries @TotherAlistair @sebrose agree - I have added
> tests:
> https://github.com/philipschwarz/diamond-problem-in-clojure/blob/master/test/diamond_problem_in_clojure/core_test.clj
>
>
> I notice you did not write tests. I also notice that you added comments to
> your methods. I like your comments. Find them useful. I am not saying the
> following applies to your comments, but it will give you an idea of the
> programming culture I am part of. In that culture, comments are looked at
> with suspicion:
> e.g. 1: https://twitter.com/nzkoz/status/538892801941848064
>
> <https://pbs.twimg.com/media/B3qIJLFCcAEJLWm.jpg>
>
> e.g. 2: "The proper use of comments is to compensate for our failure to
> express ourself in code." - Robert C. Martin
> e.g. 3: "Comments often are used as a deodorant... often ....comments are
> there because the code is bad." - Martin Fowler
> e.g. 4:
>
>    - Primary Rule: Comments are for things that *cannot* be expressed in
>    code.
>    - Redundancy Rule: Comments which restate code must be deleted.
>    - Single Truth Rule: If the comment says what the code *could* say,
>    then the code must change to make the comment redundant.
>
>
> In that culture, we aim to use certain implementation patterns that make
> comments unnecessary. Also, where possible, the tests act as (executable,
> more reliable) documentation.
>
> Moving on, after writing the terse first version of the code, I set out to 
> *make
> my code more readable*.
>
> Are you familiar with Robert Martin's dictum?:
>
> The Three Functions of a s/w module:
> * The function it performs while executing
> * To afford change. A module that is difficult to change is broken and
> needs fixing, even though it works
> * *To communicate to its readers. A module that does not communicate is
> broken and needs fixing.*
>
> The rationale for making code more readable is an economic one. Here is a
> brief summary of Ken't Beck's thoughts on the matter:
>
> o Economics is the underlying driver of software design
> o Software should be designed to reduce its overall cost
> o COST(total) = COST(develop) + COST(maintain)
> o The cost of maintenance is much higher than the initial cost of
> development
> o Maintenance is expensive because understanding existing code is
> time-consuming and error-prone
> o Making changes is generally easy once you know what needs changing
> o COST(maintain) =  COST(understand) + COST(change)+ COST(test)+
> COST(deploy)
> o Learning what the code does is the expensive part
> o One strategy for reducing overall cost is to invest more in initial
> development in hope of reducing or eliminating the need for change
> o Such efforts have generally failed
> o Beck’s strategy for reducing overall costs is to ask all programmers to
> address the cost of understanding code during the maintenance phase, by
> communicating programmer to programmer
> o The immediate benefits of clear code are fewer defects, easier sharing
> of code, and smoother development
>
> TO BE CONTINUED...
>
> Philip
>
> On Saturday, 6 December 2014 13:36:47 UTC, David Della Costa wrote:
>>
>> Hi Philip,
>>
>> I read your message and immediately wanted to try it myself--I intended
>> to leave it at that but I realized I would be remiss if I did not give you
>> a little bit of feedback based on my experience.  I should add that I was
>> kind of fast and loose with my solution (that is, I didn't really read the
>> instructions), but it does print out the diamond shape according to what I
>> saw in the blog post examples.
>>
>> First of all, here's what I came up with:
>>
>> https://gist.github.com/ddellacosta/ba7e03951ba1bafd3ec9
>>
>> As you said, you weren't looking for alternative algorithms and I
>> recognize that that's not the point.  But there are a few things that I
>> think are good and/or common Clojure practice that I think I've
>> internalized, and writing out an alternative solution helped me to see them.
>>
>> - I'm assuming you used a TDD process to write this (correct me if
>> wrong--basing that on the articles you linked to), but I think a
>> repl-driven process may be more common for working through a problem like
>> this--i.e. something you can wrap your head around as a whole and solve
>> iteratively.  That's not to say I and others don't use TDD in Clojure dev,
>> but just that it's also quite common to do a lot of this kind of
>> development in the repl.
>>
>> - you're grouping your side-effecting code w/the code that generates the
>> diamond data structure here: https://gist.github.com/ddellacosta/
>> ba7e03951ba1bafd3ec9
>>
>> While of course the diamond kata is a bit contrived and the point is to
>> print stuff out in the end, it also looks like you are trying to be
>> thoughtful about how you structure your code.  So I would suggest isolating
>> your pure functions from your side-effecting code as a sort of basic
>> separation, and avoid monolithic functions like the one I linked to above.
>> This gives you the freedom to apply the data structure to other processes
>> if need be, rather than having to refactor that code later on as soon as
>> you need to do something other than printing to the final diamond data
>> structure.  That is a more compositional approach that is good to follow as
>> part of functional programming practice in general.  And otherwise it seems
>> like you are following this approach--I think you can see this in the shape
>> of your code overall.
>>
>> - Stylistically, I found your naming conventions to be too verbose, with
>> not enough information about the actual input and output--I would prefer a
>> style like I used in my solution which aims for readable conciseness, while
>> documenting what is going in and coming out of my functions.  I assume
>> Clojure developers reading my code will have a good understanding of the
>> core data structures and functions available to manipulate them, and so I
>> want to leverage that as much as possible in how I write and document my
>> code.
>>
>> In fact, at this point I prefer using Prismatic's schema (
>> https://github.com/Prismatic/schema) to document as well as provide
>> further safety for my functions, and am of the opinion that Clojure's one
>> glaring weakness is its approach to typing--but that's another discussion
>> and I recognize this is not necessarily a widely-held opinion.
>>
>> More generally, I think reasonable people could disagree on naming
>> conventions and so I would hesitate to say you're doing something "wrong"
>> here--I would rather say: the more Clojure code you read the more you'll
>> get a sense of how people tend to write.  You'll figure out what you want
>> to adopt in your own style, and what Clojure devs are going to expect.
>>
>> - I don't want to get too deep into the algorithm itself but I think you
>> would find it more natural to work line by line vs. the way you constructed
>> blocks and flipped them right/left, and you'd have less code overall.  I
>> will boldly claim that my solution may be closer to how other developers
>> familiar with Clojure (or functional programming in general) may approach
>> it--not that I'm claiming it's the best approach.  I do think it is more
>> concise without sacrificing readability (which is subjective, I fully
>> appreciate).
>>
>> - I don't know if I've ever once used a main function, and you don't see
>> them in libraries, certainly.  But that is minor--there's no reason *not*
>> to use it, just that I wouldn't expect to see it.
>>
>> I hope this is useful feedback--good luck in your journey and enjoy
>> Clojure!
>>
>> Dave
>>
>>
>> 2014-12-06 19:48 GMT+09:00 Philip Schwarz <philip.joh...@googlemail.com>:
>>
>>> 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 clo...@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+u...@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+u...@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 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