Nice presentation (although I didn't see anything about comments. ?.).

As I mentioned before, there seem to be significantly less examples of
capturing semantic knowledge in names. I think a significant reason is the
higher level abstractions you get to play with in FP and Clojure.

This leads to  a much smaller set of idiomatic solutions to common
problems,  or to put it another way, I frequently found my journey from OO
to FP paved with large chunks of handwritten code which were then reduced
with clojure.core functions. The composition of those core functions were
then replaced by other existing functions. At the end you frequently
realise that what required lots of custom code in Java (for example) could
be expressed incredibly succinctly just using the core API.

The succinctness of Clojure compared to Java is also important as those 4
lines of Clojure might well be 20 or so lines of Java.

The other significant fact I think is the lack of ceremony in capturing
data models. The vehicle is usually just a map, but I have noticed a
significant reduction in the things I want to model. The number of types I
have is much smaller in Clojure than java (or groovy or scala etc.). To put
it another way, looking back I can see in some of my old projects a
non-trivial amount of incidental complexity which just isnt there in the
Clojure implementations.

For me, a large part of getting Clojure was realising that it already has
its own ubiquitous language and where as in java most problems were unique
(or at
least ended up with uniqueish implementations), in Clojure most problems
can be expressed in terms of a few powerful abstractions. "Intention
revealing" happens because of the sufficiency of the core API/abstractions.

Somebody once wrote something along the lines of "if you end up writing
your own Clojure code you are probably doing it wrong".  :).

I wouldn't call myself a Clojurian (because of experience, but that not
withstanding i don't think I would ever call myself that:))  but it
wouldn't surprise me if the claim was made that all of those long labels
actually made it less maintainable as they just got in the way of allowing
the natural shapes to emerge. Don't get me wrong, in OO land I write code
very close to that so I am not challenging the merit, merely suggesting it
is solving a problem that isn't so prevelant and isn't the best solution to
that problem.

In summary, I at least have found Clojure has a much higher signal to noise
ratio,  provides a much larger set of design paterns if you will (or has
many more idiomatic solutions than Java), and can provide a significant
reduction in incidental complexity, thus reducing the problem that some of
these approaches are solving.

(It is late in the UK and I hate typing on a tablet horizontally so I hope
that made sense!  ;)).
On 9 Dec 2014 22:56, "Philip Schwarz" <philip.johann.schw...@googlemail.com>
wrote:

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

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to