+1 This separation of behaviour and state is a key part of Clojure's
philosophy. That isn't to say that stateful components are bad as such
(Stuart Sierra's https://github.com/stuartsierra/component is an
obvious analog here) only that they aren't a given as they are in OO
languages.

As Jony says, when functions only depend on their parameters it makes
many things simpler and more flexible, but can appear 'noisy'.

http://thinkrelevance.com/blog/2009/08/12/rifle-oriented-programming-with-clojure-2
is another good resource here, although I must say I haven't seen some
of those examples in the wild :).

>From a similar background (Java) and having learnt some lessons, I
wish somebody hammered me on the head with the following:
 - get real familiar with the notion of data transformations, particularly maps
 - internalise map, reduce, filter, apply, loop/recur and into
 - before writing any code check the API doesn't already provide it
 - repeat the above three points
 - embrace vanilla maps, they really are all you need (and also watch
https://www.youtube.com/watch?v=ZQkIWWTygio)
 - small functions (10 lines is uncomfortable) always
 - embrace pre/post conditions, documentation (defn doc and
marginalia) and prismatic schema
 - read as much Clojure code as you can get your hands on
 - TDD is still a helpful process/technique in Clojure ;)

Longer term, watch anything from Rich Hickey.

By far the biggest conceptual shift was thinking in terms of data
being the public API and data transformation over blobs of state and
data.

Hope this helps.


On 8 February 2015 at 14:21, Jony Hudson <jonyepsi...@gmail.com> wrote:
> To put take a different angle on it: you might soon get to *like* that it's
> usual to pass in everything as a parameter explicitly. It has the advantage
> that it's easy to reason about what a function does just by looking at the
> function. In the example above, when reading AccountRepository.Save you need
> to check elsewhere to see how _connection is defined. Whereas with the
> function save, so long as the parameters you feed in are sensible, then you
> can be pretty sure what it will do.
>
> Making the functions self-contained like this is also a boon when it comes
> to working at the REPL. The OO approach you have often makes it difficult
> (for less trivial examples) to run a particular function in the right
> context. But with the self-contained function it's just a case of getting
> the parameters right, which is often easier to think about.
>
>
> Jony
>
>
> On Saturday, 7 February 2015 16:07:45 UTC, Dru Sellers wrote:
>>
>> Greetings,
>>
>> I am trying to convert my mind from OO (C#) to one more functionally
>> friendly. I am increasingly comfortable with simple applications in clojure,
>> but as I start to build more complex applications, I start to fall down
>> about how to structure my application. I don't want to just shove OO ideas
>> into the functional nature of Clojure. I'm looking for any help someone can
>> provide to help shimmy my brain into the right mental patterns.
>>
>> Background: Long time C# developer who leans heavily on IoC / DI /
>> Interfaces / Testing / Object Encapsulation.
>>
>>
>> Specific Question: Object Encapsulation
>> I feel like my function parameter lists are much "wider" than they would
>> be in C#. This is due to the "lack" of a constructor. So if I previously had
>> a C# class that looked like:
>>
>>
>> public class AccountRepository : IAccountRepository
>> {
>>   IDatabaseConnection _connection;
>>
>>   public AccountRepository(IDatabaseConnection connection)
>>   {
>>     _connection = connection;
>>   }
>>
>>   public void Save(Account account)
>>   {
>>     _connection.Execute("UPDATE accounts SET coupon=@coupon WHERE id=@id",
>> { coupon = account.Coupon, id=account.Id});
>>   }
>> }
>>
>> In the above I have encapsulated the "_connection", the other methods
>> don't have to deal with it. In Clojure (especially if you are following
>> Sierra's Component pattern) you end up with
>>
>> (defn save [db account]
>>   (update db (:coupon account) (:id account))
>> )
>>
>> I end up having to pass this 'db' around all over the place. I think that
>> this is just something I'll have to get used to more than anything. Am I
>> missing anything?
>>
>> Thank you for your time.
>>
>> -d
>
> --
> 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.

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