Re: style question on tightly coupled functions

2014-11-20 Thread Alex Baranosky
Sean James, yes of course there are times that it is _needed_. Agreed.

I just would never opt for using tools like declare and letfn as the _go to
tool_.  I think of cyclic dependencies as less simple, harder to grok etc.
When you need it, by all means have the power to do so, but when you don't
need it, then no need for adding extra mental weight for code-readers to
have to go through to understand your code.

On Thu, Nov 20, 2014 at 2:41 PM, James Reeves  wrote:

> On 20 November 2014 19:33, Alex Baranosky 
> wrote:
>
>> Imo, that makes the let version even better. The Clojure compiler doesn't
>> to allow circular dependencies, so I would consider the letfn behavior as
>> "surprising" and therefore unideal.
>>
>
> It does, via declare. This is often necessary in parsers, as often
> languages have some form of recursive definition (e.g. expressions can be
> nested in expressions).
>
> The letfn macro allows for local mutual recursion and is sometimes
> necessary.
>
> - James
>
> --
> 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.


Re: style question on tightly coupled functions

2014-11-20 Thread James Reeves
On 20 November 2014 19:33, Alex Baranosky 
wrote:

> Imo, that makes the let version even better. The Clojure compiler doesn't
> to allow circular dependencies, so I would consider the letfn behavior as
> "surprising" and therefore unideal.
>

It does, via declare. This is often necessary in parsers, as often
languages have some form of recursive definition (e.g. expressions can be
nested in expressions).

The letfn macro allows for local mutual recursion and is sometimes
necessary.

- James

-- 
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: style question on tightly coupled functions

2014-11-20 Thread Sean Corfield
On Nov 20, 2014, at 11:33 AM, Alex Baranosky  
wrote:
> Imo, that makes the let version even better. The Clojure compiler doesn't to 
> allow circular dependencies, so I would consider the letfn behavior as 
> "surprising" and therefore unideal.

Mutual recursion is a useful technique in some situations. Would you just 
outlaw it?

Sean Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)



-- 
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: style question on tightly coupled functions

2014-11-20 Thread Alex Baranosky
Imo, that makes the let version even better. The Clojure compiler doesn't
to allow circular dependencies, so I would consider the letfn behavior as
"surprising" and therefore unideal.

On Thu, Nov 20, 2014 at 2:21 PM, Dan Girellini  wrote:

> Using letfn allows the local functions to reference each other
> arbitrarily. In your example, f2 can call f1 but not vice versa.
>
> On Thu, Nov 20, 2014 at 11:08 AM, Alex Baranosky <
> alexander.barano...@gmail.com> wrote:
>
>> letfn has no value imo. It is an unwritten stylistic rule I have to never
>> use it.  Why introduce a new macro syntax for something that could just as
>> easily be written as?:
>>
>> (let [f1 (fn [] ...)
>>f2 (fn [] ...)]
>>   (+ (f1) (f2)))
>>
>>
>> On Thu, Nov 20, 2014 at 12:41 PM, henry w  wrote:
>>
>>> I never heard of letfn before. that looks like a clear way to do what i
>>> need.
>>>
>>> just found this stackoverflow thread which is relevant:
>>> http://stackoverflow.com/questions/23255798/clojure-style-defn-vs-letfn
>>>
>>> On Thu, Nov 20, 2014 at 3:34 PM, Alex Baranosky <
>>> alexander.barano...@gmail.com> wrote:
>>>
 I'd structure my app like this.

 Say there's one "pages" ns with code for different webpages

 pages/index is a pretty short function
 pages/dashboard is a more elaborate function and has two subcomponents:
 ->analytics, and ->user-info
 pages.analytics/->analytics
 pages.user-info/->user-info

 On Thu, Nov 20, 2014 at 9:23 AM, Tassilo Horn  wrote:

> henry w  writes:
>
> > you have understood my arguments pretty much. again the thing that
> > bothers me is that f and g are logically part of x only, but are
> > visible from y and z (even if and and y are declared higher up, the
> > same problem applies to their own related, private fns and x).
>
> Then declare f and g inside of x using `let' or `letfn'.
>
> Bye,
> Tassilo
>
> --
> 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.
>>
>
>  --
> 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.


Re: style question on tightly coupled functions

2014-11-20 Thread Dan Girellini
Using letfn allows the local functions to reference each other arbitrarily.
In your example, f2 can call f1 but not vice versa.

On Thu, Nov 20, 2014 at 11:08 AM, Alex Baranosky <
alexander.barano...@gmail.com> wrote:

> letfn has no value imo. It is an unwritten stylistic rule I have to never
> use it.  Why introduce a new macro syntax for something that could just as
> easily be written as?:
>
> (let [f1 (fn [] ...)
>f2 (fn [] ...)]
>   (+ (f1) (f2)))
>
>
> On Thu, Nov 20, 2014 at 12:41 PM, henry w  wrote:
>
>> I never heard of letfn before. that looks like a clear way to do what i
>> need.
>>
>> just found this stackoverflow thread which is relevant:
>> http://stackoverflow.com/questions/23255798/clojure-style-defn-vs-letfn
>>
>> On Thu, Nov 20, 2014 at 3:34 PM, Alex Baranosky <
>> alexander.barano...@gmail.com> wrote:
>>
>>> I'd structure my app like this.
>>>
>>> Say there's one "pages" ns with code for different webpages
>>>
>>> pages/index is a pretty short function
>>> pages/dashboard is a more elaborate function and has two subcomponents:
>>> ->analytics, and ->user-info
>>> pages.analytics/->analytics
>>> pages.user-info/->user-info
>>>
>>> On Thu, Nov 20, 2014 at 9:23 AM, Tassilo Horn  wrote:
>>>
 henry w  writes:

 > you have understood my arguments pretty much. again the thing that
 > bothers me is that f and g are logically part of x only, but are
 > visible from y and z (even if and and y are declared higher up, the
 > same problem applies to their own related, private fns and x).

 Then declare f and g inside of x using `let' or `letfn'.

 Bye,
 Tassilo

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

-- 
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: style question on tightly coupled functions

2014-11-20 Thread Alex Baranosky
letfn has no value imo. It is an unwritten stylistic rule I have to never
use it.  Why introduce a new macro syntax for something that could just as
easily be written as?:

(let [f1 (fn [] ...)
   f2 (fn [] ...)]
  (+ (f1) (f2)))


On Thu, Nov 20, 2014 at 12:41 PM, henry w  wrote:

> I never heard of letfn before. that looks like a clear way to do what i
> need.
>
> just found this stackoverflow thread which is relevant:
> http://stackoverflow.com/questions/23255798/clojure-style-defn-vs-letfn
>
> On Thu, Nov 20, 2014 at 3:34 PM, Alex Baranosky <
> alexander.barano...@gmail.com> wrote:
>
>> I'd structure my app like this.
>>
>> Say there's one "pages" ns with code for different webpages
>>
>> pages/index is a pretty short function
>> pages/dashboard is a more elaborate function and has two subcomponents:
>> ->analytics, and ->user-info
>> pages.analytics/->analytics
>> pages.user-info/->user-info
>>
>> On Thu, Nov 20, 2014 at 9:23 AM, Tassilo Horn  wrote:
>>
>>> henry w  writes:
>>>
>>> > you have understood my arguments pretty much. again the thing that
>>> > bothers me is that f and g are logically part of x only, but are
>>> > visible from y and z (even if and and y are declared higher up, the
>>> > same problem applies to their own related, private fns and x).
>>>
>>> Then declare f and g inside of x using `let' or `letfn'.
>>>
>>> Bye,
>>> Tassilo
>>>
>>> --
>>> 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.


Re: style question on tightly coupled functions

2014-11-20 Thread henry w
I never heard of letfn before. that looks like a clear way to do what i
need.

just found this stackoverflow thread which is relevant:
http://stackoverflow.com/questions/23255798/clojure-style-defn-vs-letfn

On Thu, Nov 20, 2014 at 3:34 PM, Alex Baranosky <
alexander.barano...@gmail.com> wrote:

> I'd structure my app like this.
>
> Say there's one "pages" ns with code for different webpages
>
> pages/index is a pretty short function
> pages/dashboard is a more elaborate function and has two subcomponents:
> ->analytics, and ->user-info
> pages.analytics/->analytics
> pages.user-info/->user-info
>
> On Thu, Nov 20, 2014 at 9:23 AM, Tassilo Horn  wrote:
>
>> henry w  writes:
>>
>> > you have understood my arguments pretty much. again the thing that
>> > bothers me is that f and g are logically part of x only, but are
>> > visible from y and z (even if and and y are declared higher up, the
>> > same problem applies to their own related, private fns and x).
>>
>> Then declare f and g inside of x using `let' or `letfn'.
>>
>> Bye,
>> Tassilo
>>
>> --
>> 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.


Re: style question on tightly coupled functions

2014-11-20 Thread Alex Baranosky
I'd structure my app like this.

Say there's one "pages" ns with code for different webpages

pages/index is a pretty short function
pages/dashboard is a more elaborate function and has two subcomponents:
->analytics, and ->user-info
pages.analytics/->analytics
pages.user-info/->user-info

On Thu, Nov 20, 2014 at 9:23 AM, Tassilo Horn  wrote:

> henry w  writes:
>
> > you have understood my arguments pretty much. again the thing that
> > bothers me is that f and g are logically part of x only, but are
> > visible from y and z (even if and and y are declared higher up, the
> > same problem applies to their own related, private fns and x).
>
> Then declare f and g inside of x using `let' or `letfn'.
>
> Bye,
> Tassilo
>
> --
> 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.


Re: style question on tightly coupled functions

2014-11-20 Thread Tassilo Horn
henry w  writes:

> you have understood my arguments pretty much. again the thing that
> bothers me is that f and g are logically part of x only, but are
> visible from y and z (even if and and y are declared higher up, the
> same problem applies to their own related, private fns and x).

Then declare f and g inside of x using `let' or `letfn'.

Bye,
Tassilo

-- 
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: style question on tightly coupled functions

2014-11-20 Thread henry w
ok thanks for those thoughts. 

you have understood my arguments pretty much. again the thing that bothers 
me is that f and g are logically part of x only, but are visible from y and 
z (even if and and y are declared higher up, the same problem applies to 
their own related, private fns and x). 

i agree this is not clj specific and there is the same thing with private 
methods in oo. was just curious if anyone had a favoured technique to scope 
f and g so they are only visible to x.

-- 
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: style question on tightly coupled functions

2014-11-20 Thread Gary Verhaegen
I'm not sure I understand your tidiness argument. If x uses g and f, and g
and f are private, that's plenty related enough for me to put them in the
same namespace, preferably right before x.

If f and g are meant to be private, the only reason I would see to put them
in a separate namespace is if the current one is so big that it gets
unwieldy. This can be a matter of taste, but as a data point I find that
point around a thousand lines of Clojure.

Do keep in mind, however, that if f and g are put in a separate namespace,
they are no longer private, as x will need to call them. (x could use
direct var access, but that feels very messy to me.)

On Wednesday, 19 November 2014, henry w  wrote:

>
> imagine in a namespace you have functions x, y, and z which are public.
>
> function x grows a bit big, so is broken out so that it calls 2 other
> functions, f and g.
>
> now, imagine with all the clean code and refactoring in the world, still f
> and g have nothing to do with y and z - but are declared in the same
> namespace and that looks untidy and  lacks cohesion - even if f and g are
> private.
>
> should x, f and g now move into their own namespace?
>
> in that case, x doesnt live with y and z, which it should do.
> moving just f and g into their own ns 'guts-of-x' feels overblown.
> or keep x just as a var that refers to var guts-of-x/x-impl, which is a
> var that has the contents of the old x.
>
> or, should f and g not be top level? they could be let within x. x is then
> still big, but at least f and g have names and x doesnt look like a big
> inline jumble.
>
> please advise. thanks.
>
> --
> 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.


Re: style question on tightly coupled functions

2014-11-20 Thread dm3
I guess the question is - why do the extracted functions look ugly or lack 
cohesion if they still accomplish part of the task previously done by `x`? 
If they are very general - you can consider moving them somewhere else and 
making them public, otherwise they should stay in the same namespace, just 
like private methods in OO design.

On Wednesday, 19 November 2014 20:00:49 UTC+1, henry w wrote:
>
>
> imagine in a namespace you have functions x, y, and z which are public.
>
> function x grows a bit big, so is broken out so that it calls 2 other 
> functions, f and g.
>
> now, imagine with all the clean code and refactoring in the world, still f 
> and g have nothing to do with y and z - but are declared in the same 
> namespace and that looks untidy and  lacks cohesion - even if f and g are 
> private.
>
> should x, f and g now move into their own namespace?  
>
> in that case, x doesnt live with y and z, which it should do.
> moving just f and g into their own ns 'guts-of-x' feels overblown.
> or keep x just as a var that refers to var guts-of-x/x-impl, which is a 
> var that has the contents of the old x.
>
> or, should f and g not be top level? they could be let within x. x is then 
> still big, but at least f and g have names and x doesnt look like a big 
> inline jumble.
>
> please advise. thanks.
>

-- 
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: Style-question: self-named attribute getters?

2014-06-26 Thread Alex Miller
This answer says everything I would want to say better than I would say it. 
Second!

Alex

On Wednesday, June 25, 2014 9:12:01 PM UTC-5, Ryan Schmitt wrote:
>
> In object-oriented programming, encapsulation is always and everywhere 
> regarded as a highly significant design virtue, but the Clojure people have 
> a bit of a different assessment, particularly when it comes to information. 
> In one talk, Rich Hickey pointed out that encapsulation is for hiding 
> implementation details, but information doesn't *have* an implementation; 
> there are no innards to encapsulate *unless you add them*. Stuart 
> Halloway gave one talk where he made a brilliant point about how 
> abstraction is valuable for *commands*, because then it limits what you 
> have to know, but it's not valuable for *queries*, because then the 
> abstraction (i.e. the custom accessors that "encapsulate" your data) only 
> limits what you can perceive.
>
> And of course, there's Alan Perlis's old saw that "it is better to have a 
> hundred functions operate on one data structure than to have ten functions 
> operate on ten data structures"--that is to say, by using generic data 
> structures (e.g. maps) to directly represent information in your domain, 
> you can reuse all of the generic functions that operate on those data 
> structures, whereas encapsulated data screws your clients because it 
> renders all of their generic collections libraries useless. (This is one of 
> the ways in which OOP has failed to deliver on its promise of pervasive 
> code reuse.)
>
> Some of Rich Hickey's talks that touch on the subject:
>
> http://www.infoq.com/presentations/Value-Values
> http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
>
> As for your particular example, I recommend looking at defrecord, which 
> generates a data structure that behaves like a map (it can be perceived and 
> manipulated generically), as well as various constructors and readers and 
> so forth for that type. defrecord also lets you specify protocols for your 
> data type. See:
>
> http://clojure.org/datatypes
>
> Also be sure to check out Prismatic's survey of Clojure's choices for 
> doing "object"-like things:
>
>
> https://github.com/Prismatic/eng-practices/blob/master/clojure/20130926-data-representation.md#data-types
>
> On Wednesday, June 25, 2014 6:34:50 PM UTC-7, Mark P wrote:
>>
>> I've only recently started real clojure development, so very much still 
>> learning what styles work and what don't.  I have a question about naming 
>> attribute getters...
>>
>> Suppose I want to model "fruit" entities.  I will use a hash-map to 
>> represent the data for each such entity, and will defn a "make" function to 
>> construct fruit instances.  I will put "make" and any other fruit-related 
>> functions within a new namespace "myprog.fruit".
>>
>> Because my data representation is a map, strictly speaking I don't need 
>> any attribute getter functions.  Because I could simply use the attribute 
>> keywords in the map as my getter functions, eg (:color fru).  But I will 
>> create actual getter functions within my namespace anyway, for a few 
>> reasons.
>>
>>1. It will signal to any users of my fruit library, which attributes 
>>are "official" and are expected to be used / supported, versus attributes 
>>which are more of an implementation detail.
>>2. Some attributes will simply be (defn color [fru] (:color fru)), 
>>whereas others are less direct, eg (defn red? [fru] (= :red fru)) or 
>>another eg (defn packingvol [{:keys [size]}] (* size size size)).  
>>3. Down the track I can change my data representation, and just 
>>reimplement the getter functions.  Users of my fruit library who have 
>> stuck 
>>to my getter functions interface will not need to change a thing.
>>
>> This approach seems okay to me so far, though I am open to critiques and 
>> alternative suggestions.  But one issue has come to mind... leading to the 
>> question of this post...
>>
>> At the end of 2. above, I have defined a local let symbol "size" as part 
>> of the map destructuring.  But it so happens I have already defined a size 
>> getter, namely (defn size [fru] (:size fru)).  So within the definition of 
>> packingvol my size getter is masked by the local symbol "size".  Now I'm 
>> not sure this masking causes much harm... I don't actually need to use the 
>> size getter here, and if I really needed it I could always use 
>> "myprog.fruit/size"...  But something still makes me feel uncomfortable 
>> about it, maybe because this masking could end up happening a lot within my 
>> fruit.clj source code file.
>>
>> Now I could just switch to a new naming convention for my getters, ie 
>> "color-get", "red?-get", "size-get", "packingvol-get" etc.  But I'm not 
>> sure I like the extra verbosity.  And for users of my fruit library - who 
>> will be working in a different namespace - this problem mostly goes away as 
>> they will probably be name

Re: Style-question: self-named attribute getters?

2014-06-26 Thread Ryan Schmitt
Most Clojure libraries I've seen only give you a handful of namespaces. I 
would expect a moderately large Clojure library to expose, say, half a 
dozen at most. Remember that Clojure has no concept of star imports, even 
for Java classes, and imports will generally be qualified somehow (e.g. 
clojure.set :as set), so exposing a large number of fragmented namespaces 
will make things seriously inconvenient for your users.

On Wednesday, June 25, 2014 6:34:50 PM UTC-7, Mark P wrote:
>
> I've only recently started real clojure development, so very much still 
> learning what styles work and what don't.  I have a question about naming 
> attribute getters...
>
> Suppose I want to model "fruit" entities.  I will use a hash-map to 
> represent the data for each such entity, and will defn a "make" function to 
> construct fruit instances.  I will put "make" and any other fruit-related 
> functions within a new namespace "myprog.fruit".
>
> Because my data representation is a map, strictly speaking I don't need 
> any attribute getter functions.  Because I could simply use the attribute 
> keywords in the map as my getter functions, eg (:color fru).  But I will 
> create actual getter functions within my namespace anyway, for a few 
> reasons.
>
>1. It will signal to any users of my fruit library, which attributes 
>are "official" and are expected to be used / supported, versus attributes 
>which are more of an implementation detail.
>2. Some attributes will simply be (defn color [fru] (:color fru)), 
>whereas others are less direct, eg (defn red? [fru] (= :red fru)) or 
>another eg (defn packingvol [{:keys [size]}] (* size size size)).  
>3. Down the track I can change my data representation, and just 
>reimplement the getter functions.  Users of my fruit library who have 
> stuck 
>to my getter functions interface will not need to change a thing.
>
> This approach seems okay to me so far, though I am open to critiques and 
> alternative suggestions.  But one issue has come to mind... leading to the 
> question of this post...
>
> At the end of 2. above, I have defined a local let symbol "size" as part 
> of the map destructuring.  But it so happens I have already defined a size 
> getter, namely (defn size [fru] (:size fru)).  So within the definition of 
> packingvol my size getter is masked by the local symbol "size".  Now I'm 
> not sure this masking causes much harm... I don't actually need to use the 
> size getter here, and if I really needed it I could always use 
> "myprog.fruit/size"...  But something still makes me feel uncomfortable 
> about it, maybe because this masking could end up happening a lot within my 
> fruit.clj source code file.
>
> Now I could just switch to a new naming convention for my getters, ie 
> "color-get", "red?-get", "size-get", "packingvol-get" etc.  But I'm not 
> sure I like the extra verbosity.  And for users of my fruit library - who 
> will be working in a different namespace - this problem mostly goes away as 
> they will probably be namespace-qualifying access to my getters.
>
> Is using self-named attribute getters a good idea?
>
> Thanks,
>
> Mark.
>
>

-- 
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: Style-question: self-named attribute getters?

2014-06-26 Thread Mark P
Thanks Ryan and James - that gives me a few more ideas on how to think 
about things.  Hopefully some of the links Ryan posted will clarify things 
for me also.

Ryan - yes my question about namespaces was to do with understanding the 
ideal granularity of namespaces.  And more specifically, whether it's a 
good idea to have a separate namespace for each data entity of interest (eg 
fruit), or whether it's better to use namespaces more sparingly.  I guess 
in part, I was using the namespace to group my getter functions, much like 
what a class name might do in an OOP language.  So again, wondering whether 
my C++ background is influencing me in the wrong direction here.

Cheers,

Mark.

-- 
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: Style-question: self-named attribute getters?

2014-06-26 Thread James Reeves
It sounds like you're building an API to provide documentation, but instead
why not just document the data structure directly?

Once you have your data structure design, add functions for non-trivial
tasks. So something like "red?" seems a little too trivial and specific.
The raw s-expression, (= (:color fruit) :red), is just as clear, if not
clearer, than (red? fruit).

On the other hand, something like "packingvol" seems non-obvious enough to
have a function for it.

Think about constructors in the same way. Use them when they simplify the
code, don't use them if they're trivial or obvious.

In a language with immutable data structures, you can sometimes use
constants instead of constructors. In one of the projects I'm currently
working on, rather than have a "make-system" function, I've created an
"empty-system" constant that can be built upon.

- James


On 26 June 2014 04:37, Mark P  wrote:

> Thanks Ryan, Mike and James for your comments and info.  Ryan I will
> follow up the links you posted.
>
> In the meantime, a request for some clarification...
>
> I have read / watched clojure stuff along these lines... ie that data
> hiding (in an immutable data context) is bad.  I thought my approach was
> taking this into account.  Ie, I am actually using a hash-map for my fruit
> instance data (rather than say closures for true data hiding) and this is
> not hidden - it is freely accessible to users of my fruit library.  Users
> can choose to use getter functions or use more direct map access
> techniques.  The getter functions sort of provide self documentation about
> interface intent, without restricting/forcing users to be limited to this
> if the interface has weaknesses.  I guess I was trying to "take the best
> from both approaches".  But maybe you are telling me that even this
> watered-down-encapsulation is not good?
>
> Ryan you are suggesting that maybe defrecord is the way to go.  I haven't
> read about that yet, so I will look into that.
>
> But just suppose I wanted to stick with using raw hash-maps for my data.
>  Would you suggest that instead of my current approach, I should...
>
>- Not implement any getter function when a keyword accessor will do.
> Eg don't implement (defn color [fru] (:color fru)), just let library users
>do (:color fru) themselves.
>- Do still implement other getters, eg (defn red? [fru] (= :red fru))
>and eg (defn packingvol [{:keys [size]}] (* size size size)).
>- What about "make"?  Do I still implement a fruit constructor
>function, or do I leave it to users to use usual hash-map constructors?
> (And if I should not implement a fruit constructor, how do I indicate to
>users the shape that a fruit hash-map should take?  Do I just document this
>in comments?)
>- Was I right to construct a new namespace for my fruit-related data
>and functions?
>
> Thanks,
>
> Mark.
>
> On Thursday, 26 June 2014 11:42:01 UTC+9:30, Ryan Schmitt wrote:
>>
>> In object-oriented programming, encapsulation is always and everywhere
>> regarded as a highly significant design virtue, but the Clojure people have
>> a bit of a different assessment, particularly when it comes to information.
>> In one talk, Rich Hickey pointed out that encapsulation is for hiding
>> implementation details, but information doesn't *have* an
>> implementation; there are no innards to encapsulate *unless you add them*.
>> Stuart Halloway gave one talk where he made a brilliant point about how
>> abstraction is valuable for *commands*, because then it limits what you
>> have to know, but it's not valuable for *queries*, because then the
>> abstraction (i.e. the custom accessors that "encapsulate" your data) only
>> limits what you can perceive.
>>
>> And of course, there's Alan Perlis's old saw that "it is better to have a
>> hundred functions operate on one data structure than to have ten functions
>> operate on ten data structures"--that is to say, by using generic data
>> structures (e.g. maps) to directly represent information in your domain,
>> you can reuse all of the generic functions that operate on those data
>> structures, whereas encapsulated data screws your clients because it
>> renders all of their generic collections libraries useless. (This is one of
>> the ways in which OOP has failed to deliver on its promise of pervasive
>> code reuse.)
>>
>> Some of Rich Hickey's talks that touch on the subject:
>>
>> http://www.infoq.com/presentations/Value-Values
>> http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
>>
>> As for your particular example, I recommend looking at defrecord, which
>> generates a data structure that behaves like a map (it can be perceived and
>> manipulated generically), as well as various constructors and readers and
>> so forth for that type. defrecord also lets you specify protocols for your
>> data type. See:
>>
>> http://clojure.org/datatypes
>>
>> Also be sure to check out Prismatic's survey of Clojure's choices for
>>

Re: Style-question: self-named attribute getters?

2014-06-25 Thread Ryan Schmitt
The question of how to specify the "shape" of your data is an important 
one, and I think one of the contributions of Clojure is the way it isolates 
that problem, instead of complecting it with object-oriented design or 
static type checking. You might look at Prismatic Schema, a library that 
offers declarative data description and validation without the baggage of 
OOP or the complexity of static typing:

https://www.youtube.com/watch?v=o_jtwIs2Ot8
https://github.com/Prismatic/schema

There's also core.typed, an optional static type system for Clojure that 
allows you to specify your data's shape as a type of map, called a 
heterogeneous map:

https://github.com/clojure/core.typed/wiki/Types#heterogeneous-maps

There's also my own dynamic-object, which is an attempt to bring these 
ideas to Java development without ruining them:

https://github.com/rschmitt/dynamic-object (see in particular 
https://github.com/rschmitt/dynamic-object#schema-validation)

You can implement all the convenience functions you want; as long as you're 
not using them to encapsulate or abstract away your data, they're probably 
harmless. A function like 'red?' doesn't seem like it's adding too much 
value, but a less trivial function could easily be worth providing as part 
of your API. Just because your clients *can* use generic collections 
operations doesn't necessarily mean that they should *have to*.

I'm not sure I understand your question about namespacing. Creating a 
namespace for your code is basically mandatory--are you asking about the 
ideal granularity of namespaces? Prismatic has another eng-practices 
document dealing with namespace organization:

https://github.com/Prismatic/eng-practices/blob/master/clojure/20130927-ns-organization.md

On Wednesday, June 25, 2014 8:37:26 PM UTC-7, Mark P wrote:
>
> Thanks Ryan, Mike and James for your comments and info.  Ryan I will 
> follow up the links you posted.
>
> In the meantime, a request for some clarification...
>
> I have read / watched clojure stuff along these lines... ie that data 
> hiding (in an immutable data context) is bad.  I thought my approach was 
> taking this into account.  Ie, I am actually using a hash-map for my fruit 
> instance data (rather than say closures for true data hiding) and this is 
> not hidden - it is freely accessible to users of my fruit library.  Users 
> can choose to use getter functions or use more direct map access 
> techniques.  The getter functions sort of provide self documentation about 
> interface intent, without restricting/forcing users to be limited to this 
> if the interface has weaknesses.  I guess I was trying to "take the best 
> from both approaches".  But maybe you are telling me that even this 
> watered-down-encapsulation is not good?
>
> Ryan you are suggesting that maybe defrecord is the way to go.  I haven't 
> read about that yet, so I will look into that.
>
> But just suppose I wanted to stick with using raw hash-maps for my data. 
>  Would you suggest that instead of my current approach, I should...
>
>- Not implement any getter function when a keyword accessor will do. 
> Eg don't implement (defn color [fru] (:color fru)), just let library 
> users 
>do (:color fru) themselves.
>- Do still implement other getters, eg (defn red? [fru] (= :red fru)) 
>and eg (defn packingvol [{:keys [size]}] (* size size size)).
>- What about "make"?  Do I still implement a fruit constructor 
>function, or do I leave it to users to use usual hash-map constructors? 
> (And if I should not implement a fruit constructor, how do I indicate to 
>users the shape that a fruit hash-map should take?  Do I just document 
> this 
>in comments?)
>- Was I right to construct a new namespace for my fruit-related data 
>and functions?
>
> Thanks,
>
> Mark.
>
> On Thursday, 26 June 2014 11:42:01 UTC+9:30, Ryan Schmitt wrote:
>>
>> In object-oriented programming, encapsulation is always and everywhere 
>> regarded as a highly significant design virtue, but the Clojure people have 
>> a bit of a different assessment, particularly when it comes to information. 
>> In one talk, Rich Hickey pointed out that encapsulation is for hiding 
>> implementation details, but information doesn't *have* an 
>> implementation; there are no innards to encapsulate *unless you add them*. 
>> Stuart Halloway gave one talk where he made a brilliant point about how 
>> abstraction is valuable for *commands*, because then it limits what you 
>> have to know, but it's not valuable for *queries*, because then the 
>> abstraction (i.e. the custom accessors that "encapsulate" your data) only 
>> limits what you can perceive.
>>
>> And of course, there's Alan Perlis's old saw that "it is better to have a 
>> hundred functions operate on one data structure than to have ten functions 
>> operate on ten data structures"--that is to say, by using generic data 
>> structures (e.g. maps) to directly represent information in 

Re: Style-question: self-named attribute getters?

2014-06-25 Thread Mark P
Thanks Ryan, Mike and James for your comments and info.  Ryan I will follow 
up the links you posted.

In the meantime, a request for some clarification...

I have read / watched clojure stuff along these lines... ie that data 
hiding (in an immutable data context) is bad.  I thought my approach was 
taking this into account.  Ie, I am actually using a hash-map for my fruit 
instance data (rather than say closures for true data hiding) and this is 
not hidden - it is freely accessible to users of my fruit library.  Users 
can choose to use getter functions or use more direct map access 
techniques.  The getter functions sort of provide self documentation about 
interface intent, without restricting/forcing users to be limited to this 
if the interface has weaknesses.  I guess I was trying to "take the best 
from both approaches".  But maybe you are telling me that even this 
watered-down-encapsulation is not good?

Ryan you are suggesting that maybe defrecord is the way to go.  I haven't 
read about that yet, so I will look into that.

But just suppose I wanted to stick with using raw hash-maps for my data. 
 Would you suggest that instead of my current approach, I should...

   - Not implement any getter function when a keyword accessor will do.  Eg 
   don't implement (defn color [fru] (:color fru)), just let library users do 
   (:color fru) themselves.
   - Do still implement other getters, eg (defn red? [fru] (= :red fru)) 
   and eg (defn packingvol [{:keys [size]}] (* size size size)).
   - What about "make"?  Do I still implement a fruit constructor function, 
   or do I leave it to users to use usual hash-map constructors?  (And if I 
   should not implement a fruit constructor, how do I indicate to users the 
   shape that a fruit hash-map should take?  Do I just document this in 
   comments?)
   - Was I right to construct a new namespace for my fruit-related data and 
   functions?

Thanks,

Mark.

On Thursday, 26 June 2014 11:42:01 UTC+9:30, Ryan Schmitt wrote:
>
> In object-oriented programming, encapsulation is always and everywhere 
> regarded as a highly significant design virtue, but the Clojure people have 
> a bit of a different assessment, particularly when it comes to information. 
> In one talk, Rich Hickey pointed out that encapsulation is for hiding 
> implementation details, but information doesn't *have* an implementation; 
> there are no innards to encapsulate *unless you add them*. Stuart 
> Halloway gave one talk where he made a brilliant point about how 
> abstraction is valuable for *commands*, because then it limits what you 
> have to know, but it's not valuable for *queries*, because then the 
> abstraction (i.e. the custom accessors that "encapsulate" your data) only 
> limits what you can perceive.
>
> And of course, there's Alan Perlis's old saw that "it is better to have a 
> hundred functions operate on one data structure than to have ten functions 
> operate on ten data structures"--that is to say, by using generic data 
> structures (e.g. maps) to directly represent information in your domain, 
> you can reuse all of the generic functions that operate on those data 
> structures, whereas encapsulated data screws your clients because it 
> renders all of their generic collections libraries useless. (This is one of 
> the ways in which OOP has failed to deliver on its promise of pervasive 
> code reuse.)
>
> Some of Rich Hickey's talks that touch on the subject:
>
> http://www.infoq.com/presentations/Value-Values
> http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey
>
> As for your particular example, I recommend looking at defrecord, which 
> generates a data structure that behaves like a map (it can be perceived and 
> manipulated generically), as well as various constructors and readers and 
> so forth for that type. defrecord also lets you specify protocols for your 
> data type. See:
>
> http://clojure.org/datatypes
>
> Also be sure to check out Prismatic's survey of Clojure's choices for 
> doing "object"-like things:
>
>
> https://github.com/Prismatic/eng-practices/blob/master/clojure/20130926-data-representation.md#data-types
>
> On Wednesday, June 25, 2014 6:34:50 PM UTC-7, Mark P wrote:
>>
>> I've only recently started real clojure development, so very much still 
>> learning what styles work and what don't.  I have a question about naming 
>> attribute getters...
>>
>> Suppose I want to model "fruit" entities.  I will use a hash-map to 
>> represent the data for each such entity, and will defn a "make" function to 
>> construct fruit instances.  I will put "make" and any other fruit-related 
>> functions within a new namespace "myprog.fruit".
>>
>> Because my data representation is a map, strictly speaking I don't need 
>> any attribute getter functions.  Because I could simply use the attribute 
>> keywords in the map as my getter functions, eg (:color fru).  But I will 
>> create actual getter functions within my namespace anyway, for a few 

Re: Style-question: self-named attribute getters?

2014-06-25 Thread James Reeves
OOP places a strong emphasis on information hiding, particularly by
wrapping data structures in APIs. Developers with a strong background in
OOP tend to try to replicate this style of programming in Clojure.

However, idiomatic Clojure emphasises exactly the opposite of this. In
Clojure, a bare data structure is generally preferable to one hidden behind
an API. In an OOP language, you typically start by considering your API,
but in Clojure, you start by considering how to structure your data.

This does mean doing without a safety net. In an OOP language, you can
perform some changes to the internal data structures without affecting the
API, but this comes at the price of repetition. Every time you create a new
data structure in an OOP language, you need to implement an API for it, but
if we discard the idea of information hiding, then we remove the need to
keep reinventing APIs.

- James


On 26 June 2014 02:34, Mark P  wrote:

> I've only recently started real clojure development, so very much still
> learning what styles work and what don't.  I have a question about naming
> attribute getters...
>
> Suppose I want to model "fruit" entities.  I will use a hash-map to
> represent the data for each such entity, and will defn a "make" function to
> construct fruit instances.  I will put "make" and any other fruit-related
> functions within a new namespace "myprog.fruit".
>
> Because my data representation is a map, strictly speaking I don't need
> any attribute getter functions.  Because I could simply use the attribute
> keywords in the map as my getter functions, eg (:color fru).  But I will
> create actual getter functions within my namespace anyway, for a few
> reasons.
>
>1. It will signal to any users of my fruit library, which attributes
>are "official" and are expected to be used / supported, versus attributes
>which are more of an implementation detail.
>2. Some attributes will simply be (defn color [fru] (:color fru)),
>whereas others are less direct, eg (defn red? [fru] (= :red fru)) or
>another eg (defn packingvol [{:keys [size]}] (* size size size)).
>3. Down the track I can change my data representation, and just
>reimplement the getter functions.  Users of my fruit library who have stuck
>to my getter functions interface will not need to change a thing.
>
> This approach seems okay to me so far, though I am open to critiques and
> alternative suggestions.  But one issue has come to mind... leading to the
> question of this post...
>
> At the end of 2. above, I have defined a local let symbol "size" as part
> of the map destructuring.  But it so happens I have already defined a size
> getter, namely (defn size [fru] (:size fru)).  So within the definition of
> packingvol my size getter is masked by the local symbol "size".  Now I'm
> not sure this masking causes much harm... I don't actually need to use the
> size getter here, and if I really needed it I could always use
> "myprog.fruit/size"...  But something still makes me feel uncomfortable
> about it, maybe because this masking could end up happening a lot within my
> fruit.clj source code file.
>
> Now I could just switch to a new naming convention for my getters, ie
> "color-get", "red?-get", "size-get", "packingvol-get" etc.  But I'm not
> sure I like the extra verbosity.  And for users of my fruit library - who
> will be working in a different namespace - this problem mostly goes away as
> they will probably be namespace-qualifying access to my getters.
>
> Is using self-named attribute getters a good idea?
>
> Thanks,
>
> Mark.
>
>  --
> 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.go

Re: Style-question: self-named attribute getters?

2014-06-25 Thread Ryan Schmitt
In object-oriented programming, encapsulation is always and everywhere 
regarded as a highly significant design virtue, but the Clojure people have 
a bit of a different assessment, particularly when it comes to information. 
In one talk, Rich Hickey pointed out that encapsulation is for hiding 
implementation details, but information doesn't *have* an implementation; 
there are no innards to encapsulate *unless you add them*. Stuart Halloway 
gave one talk where he made a brilliant point about how abstraction is 
valuable for *commands*, because then it limits what you have to know, but 
it's not valuable for *queries*, because then the abstraction (i.e. the 
custom accessors that "encapsulate" your data) only limits what you can 
perceive.

And of course, there's Alan Perlis's old saw that "it is better to have a 
hundred functions operate on one data structure than to have ten functions 
operate on ten data structures"--that is to say, by using generic data 
structures (e.g. maps) to directly represent information in your domain, 
you can reuse all of the generic functions that operate on those data 
structures, whereas encapsulated data screws your clients because it 
renders all of their generic collections libraries useless. (This is one of 
the ways in which OOP has failed to deliver on its promise of pervasive 
code reuse.)

Some of Rich Hickey's talks that touch on the subject:

http://www.infoq.com/presentations/Value-Values
http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

As for your particular example, I recommend looking at defrecord, which 
generates a data structure that behaves like a map (it can be perceived and 
manipulated generically), as well as various constructors and readers and 
so forth for that type. defrecord also lets you specify protocols for your 
data type. See:

http://clojure.org/datatypes

Also be sure to check out Prismatic's survey of Clojure's choices for doing 
"object"-like things:

https://github.com/Prismatic/eng-practices/blob/master/clojure/20130926-data-representation.md#data-types

On Wednesday, June 25, 2014 6:34:50 PM UTC-7, Mark P wrote:
>
> I've only recently started real clojure development, so very much still 
> learning what styles work and what don't.  I have a question about naming 
> attribute getters...
>
> Suppose I want to model "fruit" entities.  I will use a hash-map to 
> represent the data for each such entity, and will defn a "make" function to 
> construct fruit instances.  I will put "make" and any other fruit-related 
> functions within a new namespace "myprog.fruit".
>
> Because my data representation is a map, strictly speaking I don't need 
> any attribute getter functions.  Because I could simply use the attribute 
> keywords in the map as my getter functions, eg (:color fru).  But I will 
> create actual getter functions within my namespace anyway, for a few 
> reasons.
>
>1. It will signal to any users of my fruit library, which attributes 
>are "official" and are expected to be used / supported, versus attributes 
>which are more of an implementation detail.
>2. Some attributes will simply be (defn color [fru] (:color fru)), 
>whereas others are less direct, eg (defn red? [fru] (= :red fru)) or 
>another eg (defn packingvol [{:keys [size]}] (* size size size)).  
>3. Down the track I can change my data representation, and just 
>reimplement the getter functions.  Users of my fruit library who have 
> stuck 
>to my getter functions interface will not need to change a thing.
>
> This approach seems okay to me so far, though I am open to critiques and 
> alternative suggestions.  But one issue has come to mind... leading to the 
> question of this post...
>
> At the end of 2. above, I have defined a local let symbol "size" as part 
> of the map destructuring.  But it so happens I have already defined a size 
> getter, namely (defn size [fru] (:size fru)).  So within the definition of 
> packingvol my size getter is masked by the local symbol "size".  Now I'm 
> not sure this masking causes much harm... I don't actually need to use the 
> size getter here, and if I really needed it I could always use 
> "myprog.fruit/size"...  But something still makes me feel uncomfortable 
> about it, maybe because this masking could end up happening a lot within my 
> fruit.clj source code file.
>
> Now I could just switch to a new naming convention for my getters, ie 
> "color-get", "red?-get", "size-get", "packingvol-get" etc.  But I'm not 
> sure I like the extra verbosity.  And for users of my fruit library - who 
> will be working in a different namespace - this problem mostly goes away as 
> they will probably be namespace-qualifying access to my getters.
>
> Is using self-named attribute getters a good idea?
>
> Thanks,
>
> Mark.
>
>

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

Re: Style question (predicates)

2014-04-17 Thread Leif
My personal preference is that fns ending in ? return a strict boolean, to 
be consistent with clojure.core.  If I need the value I create another fn.  
So I would have nsf-code? *and* get-nsf-code.  Plus for more complicated 
values, if you change their representation you don't have to change the 
code calling the predicate, only the getter fn (if that),

--Leif

On Thursday, April 17, 2014 12:33:42 PM UTC-4, Sean Corfield wrote:
>
> The library coding standards[1] say: 
>
> * Use '?' suffix for predicates. 
>   - N.B. - predicates return booleans 
>
> and the community Clojure style guide[2] says: 
>
> * The names of predicate methods (methods that return a boolean value) 
> should end in a question mark. (i.e.even?). 
>
> Both of these imply that if you have a function that returns a boolean 
> (and that is intended for use as a predicate), it should be named to end in 
> '?'. Fair enough. 
>
> My question is about the reverse implication: 
>
> * Should a function whose name ends in '?' return a (strict) boolean 
> value? 
>
> Looking at the docstrings of a random selection of functions found by 
> (apropos "?"), they all seem to return specifically true or false. I did 
> not do an exhaustive check. 
>
> Is the intent that foo? implies a result of true or false - or could foo? 
> return any truthy / falsey value (and therefore any Clojure value). 
>
> Concrete example that spurred this discussion from some code at work: 
>
> (defn is-nsf-code? 
>   "Given an error code, return truthy if it is NSF." 
>   [code] 
>   (#{"BE1" "BE2"} code)) 
>
> Clearly the result here could be nil or a string but it's definitely meant 
> to be used as a predicate. Similarly: 
>
> (defn nsf? 
>   "Given the result of an SBW sale, return true if it failed with NSF." 
>   [result] 
>   (and (= "failure" (:result result)) 
>(some is-nsf-code? (:errors result 
>
> Again, the result could be false or nil or a string but is meant to be 
> used as a predicate. 
>
> As an aside, for core.typed, we annotate the first as [String -> Boolean] 
> with ^:no-check so it type checks as a true/false predicate and then we 
> annotate the second as [SBWResult -> (Nilable Boolean)] and that's all 
> fine... but is it "good style"? 
>
> [1] http://dev.clojure.org/display/community/Library+Coding+Standards 
> [2] https://github.com/bbatsov/clojure-style-guide#naming 
>
> Sean Corfield -- (904) 302-SEAN 
> An Architect's View -- http://corfield.org/ 
>
> "Perfection is the enemy of the good." 
> -- Gustave Flaubert, French realist novelist (1821-1880) 
>
>
>
>

-- 
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: Style question (predicates)

2014-04-17 Thread Zach Oakes
This is a bit tangential, but your function "is-nsf-code?" brings up 
another style question. Is it really necessary to use the "is-" prefix? I 
used to do this too, but I realized recently that it is a Java-ism and 
seems out of place in Clojure.

Clojure's boolean functions do fine without it because the question mark 
conveys the fact that it is boolean. I removed all instances of this prefix 
from my active projects, including many places in Nightcode and a few in 
play-clj.

On Thursday, April 17, 2014 12:33:42 PM UTC-4, Sean Corfield wrote:
>
> The library coding standards[1] say: 
>
> * Use '?' suffix for predicates. 
>   - N.B. - predicates return booleans 
>
> and the community Clojure style guide[2] says: 
>
> * The names of predicate methods (methods that return a boolean value) 
> should end in a question mark. (i.e.even?). 
>
> Both of these imply that if you have a function that returns a boolean 
> (and that is intended for use as a predicate), it should be named to end in 
> '?'. Fair enough. 
>
> My question is about the reverse implication: 
>
> * Should a function whose name ends in '?' return a (strict) boolean 
> value? 
>
> Looking at the docstrings of a random selection of functions found by 
> (apropos "?"), they all seem to return specifically true or false. I did 
> not do an exhaustive check. 
>
> Is the intent that foo? implies a result of true or false - or could foo? 
> return any truthy / falsey value (and therefore any Clojure value). 
>
> Concrete example that spurred this discussion from some code at work: 
>
> (defn is-nsf-code? 
>   "Given an error code, return truthy if it is NSF." 
>   [code] 
>   (#{"BE1" "BE2"} code)) 
>
> Clearly the result here could be nil or a string but it's definitely meant 
> to be used as a predicate. Similarly: 
>
> (defn nsf? 
>   "Given the result of an SBW sale, return true if it failed with NSF." 
>   [result] 
>   (and (= "failure" (:result result)) 
>(some is-nsf-code? (:errors result 
>
> Again, the result could be false or nil or a string but is meant to be 
> used as a predicate. 
>
> As an aside, for core.typed, we annotate the first as [String -> Boolean] 
> with ^:no-check so it type checks as a true/false predicate and then we 
> annotate the second as [SBWResult -> (Nilable Boolean)] and that's all 
> fine... but is it "good style"? 
>
> [1] http://dev.clojure.org/display/community/Library+Coding+Standards 
> [2] https://github.com/bbatsov/clojure-style-guide#naming 
>
> Sean Corfield -- (904) 302-SEAN 
> An Architect's View -- http://corfield.org/ 
>
> "Perfection is the enemy of the good." 
> -- Gustave Flaubert, French realist novelist (1821-1880) 
>
>
>
>

-- 
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: Style question (predicates)

2014-04-17 Thread Mars0i
While *every?* and *not-any?* return true or false, *some* returns the 
first truthy value in a sequence, or nil if there are none.

Similarly, *empty?* returns true or false, while *empty* and *not-empty*return 
a collection or nil.

However, it seems as if* some*, *empty*, and *not-empty *are intended to be 
used like predicates, as well other ways.  They are predicates in the 
Common Lisp sense.

This makes me think that question marks are supposed to be reserved for 
functions that return booleans.

-- 
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: Style question (predicates)

2014-04-17 Thread John Wiseman
In the Common Lisp world it's common for predicates to return a useful
value instead of T, when applicable.  It seems possible the same principle
could apply to clojure.

>From CLtL2 :

Often a predicate will return nil if it ``fails'' and some useful value if
it ``succeeds''; such a function can be used not only as a test but also
for the useful value provided in case of success. An example is
member
.





On Thu, Apr 17, 2014 at 10:20 AM, Colin Yates  wrote:

> My 2p - I interpret the contract as being boolean.  Truthy values are
> 'polymorphically' equivalent*1 so sure.  The concern would be people
> relying on the implementation and treating the values as none-truthy (i.e.
> in your example relying on the fact it is a string being returned, so (=
> "someString" (is-nsf-code? "someString")))
>
> I should reduce it to 1p really as I am only contributing in an abstract
> design sense, not in the specifics of the coding standards you mentioned.
>
> *1 If this doesn't hold (i.e. caller depends upon receiving a
> java.lang.Boolean or associated primitive) then I think the caller has
> bigger problems.
>
>
> On Thursday, April 17, 2014 5:33:42 PM UTC+1, Sean Corfield wrote:
>>
>> The library coding standards[1] say:
>>
>> * Use '?' suffix for predicates.
>>   - N.B. - predicates return booleans
>>
>> and the community Clojure style guide[2] says:
>>
>> * The names of predicate methods (methods that return a boolean value)
>> should end in a question mark. (i.e.even?).
>>
>> Both of these imply that if you have a function that returns a boolean
>> (and that is intended for use as a predicate), it should be named to end in
>> '?'. Fair enough.
>>
>> My question is about the reverse implication:
>>
>> * Should a function whose name ends in '?' return a (strict) boolean
>> value?
>>
>> Looking at the docstrings of a random selection of functions found by
>> (apropos "?"), they all seem to return specifically true or false. I did
>> not do an exhaustive check.
>>
>> Is the intent that foo? implies a result of true or false - or could foo?
>> return any truthy / falsey value (and therefore any Clojure value).
>>
>> Concrete example that spurred this discussion from some code at work:
>>
>> (defn is-nsf-code?
>>   "Given an error code, return truthy if it is NSF."
>>   [code]
>>   (#{"BE1" "BE2"} code))
>>
>> Clearly the result here could be nil or a string but it's definitely
>> meant to be used as a predicate. Similarly:
>>
>> (defn nsf?
>>   "Given the result of an SBW sale, return true if it failed with NSF."
>>   [result]
>>   (and (= "failure" (:result result))
>>(some is-nsf-code? (:errors result
>>
>> Again, the result could be false or nil or a string but is meant to be
>> used as a predicate.
>>
>> As an aside, for core.typed, we annotate the first as [String -> Boolean]
>> with ^:no-check so it type checks as a true/false predicate and then we
>> annotate the second as [SBWResult -> (Nilable Boolean)] and that's all
>> fine... but is it "good style"?
>>
>> [1] http://dev.clojure.org/display/community/Library+Coding+Standards
>> [2] https://github.com/bbatsov/clojure-style-guide#naming
>>
>> Sean Corfield -- (904) 302-SEAN
>> An Architect's View -- http://corfield.org/
>>
>> "Perfection is the enemy of the good."
>> -- Gustave Flaubert, French realist novelist (1821-1880)
>>
>>
>>
>>  --
> 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.


Re: Style question (predicates)

2014-04-17 Thread Colin Yates
My 2p - I interpret the contract as being boolean.  Truthy values are 
'polymorphically' equivalent*1 so sure.  The concern would be people 
relying on the implementation and treating the values as none-truthy (i.e. 
in your example relying on the fact it is a string being returned, so (= 
"someString" (is-nsf-code? "someString")))

I should reduce it to 1p really as I am only contributing in an abstract 
design sense, not in the specifics of the coding standards you mentioned.

*1 If this doesn't hold (i.e. caller depends upon receiving a 
java.lang.Boolean or associated primitive) then I think the caller has 
bigger problems.

On Thursday, April 17, 2014 5:33:42 PM UTC+1, Sean Corfield wrote:
>
> The library coding standards[1] say: 
>
> * Use '?' suffix for predicates. 
>   - N.B. - predicates return booleans 
>
> and the community Clojure style guide[2] says: 
>
> * The names of predicate methods (methods that return a boolean value) 
> should end in a question mark. (i.e.even?). 
>
> Both of these imply that if you have a function that returns a boolean 
> (and that is intended for use as a predicate), it should be named to end in 
> '?'. Fair enough. 
>
> My question is about the reverse implication: 
>
> * Should a function whose name ends in '?' return a (strict) boolean 
> value? 
>
> Looking at the docstrings of a random selection of functions found by 
> (apropos "?"), they all seem to return specifically true or false. I did 
> not do an exhaustive check. 
>
> Is the intent that foo? implies a result of true or false - or could foo? 
> return any truthy / falsey value (and therefore any Clojure value). 
>
> Concrete example that spurred this discussion from some code at work: 
>
> (defn is-nsf-code? 
>   "Given an error code, return truthy if it is NSF." 
>   [code] 
>   (#{"BE1" "BE2"} code)) 
>
> Clearly the result here could be nil or a string but it's definitely meant 
> to be used as a predicate. Similarly: 
>
> (defn nsf? 
>   "Given the result of an SBW sale, return true if it failed with NSF." 
>   [result] 
>   (and (= "failure" (:result result)) 
>(some is-nsf-code? (:errors result 
>
> Again, the result could be false or nil or a string but is meant to be 
> used as a predicate. 
>
> As an aside, for core.typed, we annotate the first as [String -> Boolean] 
> with ^:no-check so it type checks as a true/false predicate and then we 
> annotate the second as [SBWResult -> (Nilable Boolean)] and that's all 
> fine... but is it "good style"? 
>
> [1] http://dev.clojure.org/display/community/Library+Coding+Standards 
> [2] https://github.com/bbatsov/clojure-style-guide#naming 
>
> Sean Corfield -- (904) 302-SEAN 
> An Architect's View -- http://corfield.org/ 
>
> "Perfection is the enemy of the good." 
> -- Gustave Flaubert, French realist novelist (1821-1880) 
>
>
>
>

-- 
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: Style Question

2010-10-10 Thread Stephen C. Gilardi
I think I see the goal now: to allow calling with either a map or sequential 
key-value pairs.

What you have appears correct and minimal for that purpose.

For a function taking a sequence, you can accomplish something similar without 
a second arity by choosing to call directly or call using apply. For a map the 
apply case isn't as simple.

Given:

(defn blah
 [& {:as blah-map}]
 ;; do stuff with blah-map)

(def m {:1 :2 :3 :4})

To call it "apply-style" with a map, you could use:

(apply blah (reduce concat m))

--Steve

On Oct 10, 2010, at 12:39 AM, Grayswx wrote:

> Recently, I've been coding functions that take a map as follows.  I
> feel like it is slightly messy, though, and was wondering if any one
> else could think of a reason not to do it:
> 
> (defn blah
>  ([blah-map]
>;; do stuff with blah-map)
>  ([key val & {:as blah-map}]
>(blah (assoc blah-map key val

-- 
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: Style Question

2010-10-10 Thread Stephen C. Gilardi
The answer depends on what you're trying to accomplish. 

Does this simpler definition allow you to call blah in the ways you want to?

(defn blah
  [& {:as blah-map}]
  ;; do stuff with blah-map)

--Steve

On Oct 10, 2010, at 12:39 AM, Grayswx wrote:

> Recently, I've been coding functions that take a map as follows.  I
> feel like it is slightly messy, though, and was wondering if any one
> else could think of a reason not to do it:
> 
> (defn blah
>  ([blah-map]
>;; do stuff with blah-map)
>  ([key val & {:as blah-map}]
>(blah (assoc blah-map key val

-- 
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: Style question

2008-10-16 Thread Meikel Brandmeyer

Hi,

Am 16.10.2008 um 23:36 schrieb Tom Emerson:


I'd like to solicit comments on better ways I could have written it:

(defn- split-line
[line]
(let [parts (seq (.split line ":"))]
   (loop [mills (drop 1 parts)
  result (list (first parts))]
 (if (nil? mills)
   (reverse result)
   (recur (drop 2 mills) (conj result (take 2 mills)))


(defn split-line
  [line]
  (let [parts (. line split ":")]
(list*
  (first parts)
  (partition 2 (rest parts)

Sincerely
Meikel



smime.p7s
Description: S/MIME cryptographic signature


Re: Style question

2008-10-16 Thread Tom Emerson

Meikel,

Many thanks: I *knew* there had to be a more succinct way to do it...
think I need to stare at the Clojure API documentation a bit more. :)

Kind regards,

-tree

On Thu, Oct 16, 2008 at 5:48 PM, Meikel Brandmeyer <[EMAIL PROTECTED]> wrote:
> Hi,
>
> Am 16.10.2008 um 23:36 schrieb Tom Emerson:
>
>> I'd like to solicit comments on better ways I could have written it:
>>
>> (defn- split-line
>> [line]
>> (let [parts (seq (.split line ":"))]
>>   (loop [mills (drop 1 parts)
>>  result (list (first parts))]
>> (if (nil? mills)
>>   (reverse result)
>>   (recur (drop 2 mills) (conj result (take 2 mills)))
>
> (defn split-line
>  [line]
>  (let [parts (. line split ":")]
>(list*
>  (first parts)
>  (partition 2 (rest parts)
>
> Sincerely
> Meikel
>
>



-- 
Tom Emerson
[EMAIL PROTECTED]
http://www.dreamersrealm.net/~tree

--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---



Re: Style question

2008-10-16 Thread Rich Hickey



On Oct 16, 5:36 pm, "Tom Emerson" <[EMAIL PROTECTED]> wrote:
> Hello all,
>
> I wrote a function that behaves as:
>
> user> (split-line "785:3:39334:1:43103")
> ("785" ("3" "39334") ("1" "43103"))
>
> I'd like to solicit comments on better ways I could have written it:
>
> (defn- split-line
>   [line]
>   (let [parts (seq (.split line ":"))]
> (loop [mills (drop 1 parts)
>result (list (first parts))]
>   (if (nil? mills)
> (reverse result)
> (recur (drop 2 mills) (conj result (take 2 mills)))
>
> Thanks in advance for your time,
>

You didn't really describe the function's behavior - a doc string
would help us. It would also possibly help you find the higher-level
functions to do the job.

Here's one way:

(defn split-line [line]
  (let [parts (.split line ":")]
(cons (first parts) (partition 2 (rest parts)

One guideline - in Clojure we tend to produce our results in order.
Having to call reverse is a warning sign. Another is - if your loop/
recur only walks through one sequence there's likely a higher-level
function (or combination of them) that will let you avoid the loop.

Rich
--~--~-~--~~~---~--~~
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
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/clojure?hl=en
-~--~~~~--~~--~--~---