thanks On Tuesday, 9 December 2014 08:01:58 UTC, Colin Yates wrote: > > 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.joh...@googlemail.com > <javascript:>> 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 clo...@googlegroups.com >> <javascript:> >> 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 <javascript:> >> 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+u...@googlegroups.com <javascript:>. >> 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.