Re: what do you think about this code?
Hi David In fact, at this point I prefer using Prismatic's schema ( https://github.com/Prismatic/schema https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2FPrismatic%2Fschemasa=Dsntz=1usg=AFQjCNFIdJn-v4ShLockO3sVBrwopRZiOQ) to document as well as provide further safety for my functions goes on my todo list 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 javascript:: 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
Re: what do you think about this code?
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 javascript:: 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 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, 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.
Re: what do you think about this code?
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 javascript:: 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 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, 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.
Re: what do you think about this code?
Hi Colin, Clojure code tends to be much more about the shape of transformations than the semantics of those transformations. Interesting, thanks I think most people would inline that. Extracting it however, give helpful information about the structure which isn't captured by the call to concat, namely the vertical nature (top/bottom). Of course, if the variable names were retained then is also sufficient but they almost certainly wouldn't be. Yes I am on the fence, and fall down frequently either side (you wouldn't believe the chaffing :)) - Yes, I may soon be in the same position But I also *feel the loss of the info captured in variable names/function names* as well. Yes the more Clojure you write the more you start to realise that the same shapes of functions come up time and time again - the structural shape of the code imparts knowledge sometimes. OK Philip On Saturday, 6 December 2014 18:40:16 UTC, Colin Yates wrote: Excellent question and I will be watching this thread with interest. Similar to David Della Costa, I find a bit difference between Clojure and Java for example is that there is much less naming-of-concepts. Clojure code tends to be much more about the shape of transformations than the semantics of those transformations. A case in point, you wrote [code](defn put-one-on-top-of-the-other [top-half-of-diamond bottom-half-of-diamond] (concat top-half-of-diamond bottom-half-of-diamond))[/code]. I think most people would inline that. Extracting it however, give helpful information about the structure which isn't captured by the call to concat, namely the vertical nature (top/bottom). Of course, if the variable names were retained then is also sufficient but they almost certainly wouldn't be. I am on the fence, and fall down frequently either side (you wouldn't believe the chaffing :)) - the more Clojure I write the more comfortable I am with dense calls to core.clj functions. But I also feel the loss of the info captured in variable names/function names as well. Another point worth mentioning is that the more Clojure you write the more you start to realise that the same shapes of functions come up time and time again - the structural shape of the code imparts knowledge sometimes. As David says, if you haven't looked at Prismatic Schema then have a look. I find the definition of the schema is also an excellent place to capture this extra layer of info in the names of those structures. Good question. On Saturday, 6 December 2014 10:48:02 UTC, 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.
Re: what do you think about this code?
Hi Leif, You have the idea of a palindrome in your solution: neat! 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.
Re: what do you think about this code?
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
Re: what do you think about this code?
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.
Re: what do you think about this code?
the structure which isn't captured by the call to concat, namely the vertical nature (top/bottom). Of course, if the variable names were retained then is also sufficient but they almost certainly wouldn't be. I am on the fence, and fall down frequently either side (you wouldn't believe the chaffing :)) - the more Clojure I write the more comfortable I am with dense calls to core.clj functions. But I also feel the loss of the info captured in variable names/function names as well. Another point worth mentioning is that the more Clojure you write the more you start to realise that the same shapes of functions come up time and time again - the structural shape of the code imparts knowledge sometimes. As David says, if you haven't looked at Prismatic Schema then have a look. I find the definition of the schema is also an excellent place to capture this extra layer of info in the names of those structures. Good question. On Saturday, 6 December 2014 10:48:02 UTC, 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.
Re: what do you think about this code?
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 javascript:: 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 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, 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.
Re: what do you think about this code?
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.
Re: what do you think about this code?
Hi Leif, I also favor a slightly less verbose style. A function is an abstraction, and you seem to be writing functions for very concrete steps. yes, in the programming culture I am part of, method extraction is quite aggressive. Here is Martin Fowler on the subject (in Refactoring, Improving the Design of Existing Code http://martinfowler.com/books/refactoring.html): You should be much more aggressive about decomposing methods. A heuristic we follow is that whenever we feel the need to comment something, we write a method instead. Such a method contains the code that was commented, but is *named after the intention of the code rather than how it does it*. We may do this on a group of lines or on as little as a single line of code. We do this even if the method call is longer than the code it replaces, *provided the method name explains the purpose of the code*. *The key here is not method length but the semantic distance between what the method does and how it does it.* I accept that that extraction of the following method is pretty aggressive: (defn reverse-every-row [sequence-of-sequences-of-chars] (map reverse sequence-of-sequences-of-chars)) What I am trying to find out is if this sort of practice is (or will ever be) used, or it use at least contemplated, by functional programmers. By the way, I guess if this was Scala then the overlong parameter name might be replaced with a something like 'rows : Seq[Seq[Char]]' 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.
Re: what do you think about this code?
Hi Leif, 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 flip: which way? flip-vertically: yes, that may be good enough after all. I went for flip-bottom-up because I didn't want the reader to have to ask themselves: what does he mean by vertical flip? e.g. if you search google images for vertical flip you get both of the following images: https://lh5.googleusercontent.com/-dNAVKelygfo/VI0pMSemS9I/AOQ/J5fLWi_ACzI/s1600/Screen%2BShot%2B2014-12-14%2Bat%2B06.05.19.png https://lh5.googleusercontent.com/-HH-ZnujIaHM/VI0o_hOJQ9I/AOI/BrM10DB97Mc/s1600/Screen%2BShot%2B2014-12-14%2Bat%2B06.05.10.png beside: genius! that is what I looked for, but could not come up with. stack: yes, that was my first choice, but then I worried that a foreign reader might not be familiar with the word (which I don't hear that often), or that a developer might think about FILO, etc. I think I did consider 'above' (in the vein of your 'beside'), but discarded it. I think put-one-on-top-of-the-other is pretty irritating in some respects. I can see beside and above working well. Thanks, 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: -- 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.
Re: what do you think about this code?
)) 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.
Re: what do you think about this code?
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 javascript:: 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 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, 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.
Re: what do you think about this code?
, 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 javascript:: 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 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, 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.
Re: what do you think about this code?
! Dave 2014-12-06 19:48 GMT+09:00 Philip Schwarz philip.joh...@googlemail.com javascript:: 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 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, 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.
Re: what do you think about this code?
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 javascript:: 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 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, 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.
Re: what do you think about this code?
picking up from my e-mail below... In Smalltalk Best Practice Patterns http://www.amazon.co.uk/Smalltalk-Best-Practice-Patterns-Kent/dp/013476904X (STBPP) Kent Beck describes a 'good programming' style guide, a system or language of 92 patterns. Five of them stand out as being: - Fundamental – key to achieving good style - Interrelated – they form their own subsystem - Very simply stated – but have far reaching effects Here are some basic slides I put together on these five patterns: https://lh4.googleusercontent.com/-bejlDZw4H50/VIdxKZOHTsI/ANE/7QfdiJsqAYY/s1600/Screen%2BShot%2B2014-12-09%2Bat%2B21.55.55.png === https://lh3.googleusercontent.com/-P8AyATDblt0/VIdxTwxcnBI/ANM/t1JCk6BgMUY/s1600/Screen%2BShot%2B2014-12-09%2Bat%2B21.56.09.png === https://lh5.googleusercontent.com/-EMibDIQA6dk/VIdxv9YO6nI/ANU/4J98YeGMqSQ/s1600/Screen%2BShot%2B2014-12-09%2Bat%2B21.56.21.png === https://lh6.googleusercontent.com/-OXoEpnjXllI/VIdx9sQgfyI/ANc/GUVyOsp9SZ8/s1600/Screen%2BShot%2B2014-12-09%2Bat%2B21.56.32.png === https://lh5.googleusercontent.com/-fM7PwQFOyFM/VIdyGv53KxI/ANk/MS9UM2ODQMc/s1600/Screen%2BShot%2B2014-12-09%2Bat%2B21.56.44.png === If you find these slides insufficient, I have a whole presentation on the five patterns here https://github.com/philipschwarz/presentations/blob/master/Four%20Patterns%20at%20the%20Heart%20of%20Good%20Programming%20Style.pdf?raw=true (make sure you read the notes for each slide, otherwise you'll just see eye candy). The key about Intention Revealing Method is that instead of getting you to name a method after “how” it accomplishes its task, it gets you to name the method after “what” it is supposed to accomplish, and to leave “how” to the method's body. The effort of moving the name of methods from “how” to “what” is worth it, both in the short term and the long term. The resulting code will be easier to read and understand. A Composed Method is a small, simple method that you can understand in seconds. When you can't rapidly understand a method's logic, transform the logic into a small number of intention-revealing steps at the same level of detail. The key about Composed method is that although it is true that a Composed Method's name communicates what it does, while its body communicates how it does what it does (which is usually what slows down readers), it consists purely or primarily of calls to methods with Intention Revealing names, and so it actually reveals only a little bit of the ‘how’, hiding the rest behind said calls. So composed method reveals implementation (how) only a little bit at a time (which is what makes reading and understanding composed methods so easy/quick). I found this fact mentioned in Alan Shalloway’s (et al.) ‘Essential Skills For The Agile Developer’ (chapter 1 Programming by Intention http://www.netobjectives.com/system/files/essential-skills-programming-by-intention.pdf ). The four patterns we have looked at are part of what in Extreme Programming is called Intentional Programming. The key organizing principle in (composed) methods written in the Intentional Programming style is that their body contains all the steps (the what), but very little of the actual implementation (the how). What Intentional Programming (and composed method) do is allow us to *separate the process by which something is done from the actual accomplishing of the thing.* And here is a good example of composed method from the book: https://lh6.googleusercontent.com/-JhpDq75d_0k/VId5_XHhOmI/AN0/Gc8RGKL6TCU/s1600/Screen%2BShot%2B2014-12-09%2Bat%2B22.38.13.png We can clearly see the focus on the WHAT, and the minimal amount of HOW that the method reveals: this is what makes the method easy to quickly read and understand. So, https://github.com/philipschwarz/diamond-problem-in-clojure/blob/master/src/diamond_problem_in_clojure/core.clj is the result of refactoring https://gist.github.com/philipschwarz/c7e3be1ac97e482d04bf to a style informed by the five patterns described above. Is this separation of WHAT from HOW something that is practiced in the Clojure community? The separation of WHAT from HOW seems to have a parallel in the [design by] *wishful thinking* approach described in the following section of the LISP bible, Structure and Interpretation of Computer Programs: http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#%_idx_1306 Philip On Tuesday, 9 December 2014 00:24:42 UTC, Philip Schwarz 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
Re: what do you think about this code?
TIL: butlast Nice. 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 javascript:: 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
Re: what do you think about this code?
*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 javascript:: 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 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 the Google Groups Clojure group. To unsubscribe from this group and stop receiving emails from it, 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.
Re: what do you think about this code?
btw, my first impression when first looking at your solution is positive - the feeling I get is that I probably won't have problems understanding how it works 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 javascript:: 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
Re: what do you think about this code?
Hey David, thank you for taking the time to review my code and come up with suggestions. I look forward to chewing over your reply soon (job and daughter permitting). 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 javascript:: 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
Re: what do you think about this code?
Hi David thanks for you reply. I'll get back to you as soon as possible. Philip On Saturday, 6 December 2014 18:40:16 UTC, Colin Yates wrote: Excellent question and I will be watching this thread with interest. Similar to David Della Costa, I find a bit difference between Clojure and Java for example is that there is much less naming-of-concepts. Clojure code tends to be much more about the shape of transformations than the semantics of those transformations. A case in point, you wrote [code](defn put-one-on-top-of-the-other [top-half-of-diamond bottom-half-of-diamond] (concat top-half-of-diamond bottom-half-of-diamond))[/code]. I think most people would inline that. Extracting it however, give helpful information about the structure which isn't captured by the call to concat, namely the vertical nature (top/bottom). Of course, if the variable names were retained then is also sufficient but they almost certainly wouldn't be. I am on the fence, and fall down frequently either side (you wouldn't believe the chaffing :)) - the more Clojure I write the more comfortable I am with dense calls to core.clj functions. But I also feel the loss of the info captured in variable names/function names as well. Another point worth mentioning is that the more Clojure you write the more you start to realise that the same shapes of functions come up time and time again - the structural shape of the code imparts knowledge sometimes. As David says, if you haven't looked at Prismatic Schema then have a look. I find the definition of the schema is also an excellent place to capture this extra layer of info in the names of those structures. Good question. On Saturday, 6 December 2014 10:48:02 UTC, 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.
what do you think about this code?
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.
Re: map versus pmap
yes, I started out trying the following example from Practical Clojure: (defn make-heavy [f] (fn [ args] (Thread/sleep 1000) (apply f args))) user= (time (+ 5 5)) Elapsed time: 0.06403 msecs 10 user= (time ((make-heavy +) 5 5)) Elapsed time: 1000.622706 msecs 10 user= (time (doall (map (make-heavy inc) [1 2 3 4 5]))) Elapsed time: 5003.314909 msecs (2 3 4 5 6) user= (time (doall (pmap (make-heavy inc) [1 2 3 4 5]))) Elapsed time: 1000.720951 msecs (2 3 4 5 6) in this case, pmap is faster. On Nov 7, 3:25 am, André Thieme splendidl...@googlemail.com wrote: Am 06.11.2010 12:57, schrieb philip schwarz: Hi all, be gentle please: I have only just started using clojure. I run the following on an Intel Core 2 Duo CPU (starting clojure with java -Xms1000m -Xmx1000m -jar clojure.jar): user= (time (nth (doall (map inc (range 1000))) 999)) Elapsed time: 5944.068355 msecs 1000 user= (time (nth (doall (pmap inc (range 1000))) 999)) Elapsed time: 108837.451146 msecs 1000 I was expecting pmap to take less time then map, instead it took much much longer. Any thoughts? Try (time (count (map (fn [_] (Thread/sleep 1)) (range 1000 vs. (time (count (pmap (fn [_] (Thread/sleep 1)) (range 1000 On my system this is 1002 msecs vs. 39 msecs. -- 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
map versus pmap
Hi all, be gentle please: I have only just started using clojure. I run the following on an Intel Core 2 Duo CPU (starting clojure with java -Xms1000m -Xmx1000m -jar clojure.jar): user= (time (nth (doall (map inc (range 1000))) 999)) Elapsed time: 5944.068355 msecs 1000 user= (time (nth (doall (pmap inc (range 1000))) 999)) Elapsed time: 108837.451146 msecs 1000 I was expecting pmap to take less time then map, instead it took much much longer. Any thoughts? -- 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
Re: map versus pmap
thanks On Nov 6, 6:04 pm, Andy Fingerhut andy.finger...@gmail.com wrote: The amount of work in each element of the pmap is so small that the overhead per element is dominating the CPU usage, e.g. overhead like constructing a future for each element of the collection you are mapping over. Try a test case where the computation being done in the function you supply to map is a lot more than inc. Note that total CPU time for pmap will always have some extra overhead above the corresponding map - it is recommended to use it when that extra overhead is small compared to the total computation time required. Andy Sent from my iPhone On Nov 6, 2010, at 4:57 AM, philip schwarz philip.johann.schw...@googlemail.com wrote: Hi all, be gentle please: I have only just started using clojure. I run the following on an Intel Core 2 Duo CPU (starting clojure with java -Xms1000m -Xmx1000m -jar clojure.jar): user= (time (nth (doall (map inc (range 1000))) 999)) Elapsed time: 5944.068355 msecs 1000 user= (time (nth (doall (pmap inc (range 1000))) 999)) Elapsed time: 108837.451146 msecs 1000 I was expecting pmap to take less time then map, instead it took much much longer. Any thoughts? -- 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 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