Re: Ultralight Components

2015-11-23 Thread Atamert Ölçgen
Hi William,

How is this different than Yo-yo? (
https://groups.google.com/forum/#!topic/clojure/PvCc5sSeSRY)

> Justifying things is generally impossible.

Actually, no. It is possible, at least when you are dealing with reasonable
people. And when you make claims like "lightweight" or "ultralight", people
will naturally ask "oh, interesting, how so?"

-

Some functional programming folks are allergic to exceptions. They go out
of their ways to prevent any and all exceptions and they end up
unnecessarily complicating their types for little or no gain.

It seems to me, you are trying to avoid using protocols like it's a plague.

> I am tired of doing ongoing refactorings interrupted periodically by
complete rewrites. Class hierarchies are the worst...

When your ultralight function based components get out of hand, you will
have a worse time refactoring. With component you only have two functions,
your lightweight design will end up having (* n 2) functions.

Also, looking at a component's code (it's defrecord form I mean) I can see
what other components it depends on. Your design would bury them inside
functions making it harder to read.


On Tue, Nov 24, 2015 at 6:57 AM, James Reeves  wrote:

> Have you watched Simple Made Easy
> ?
>
> I mention it because you remark about being tired of refactoring. It's my
> opinion that's a symptom of complexity, in the Hickey definition of the
> term.
>
> - James
>
> On 24 November 2015 at 03:31, William la Forge 
> wrote:
>
>> James,
>>
>> Being fun is important but not a justification. We should strive to keep
>> things fun, but there are plenty of thing worth doing and our resources are
>> always limited. And if it is not fun, you are not going to do your best
>> work.
>>
>> Justifying things is generally impossible. If vanilla clojure meets your
>> needs, then vanilla clojure it is. If macros solve the problems you have
>> been dealt in the past, then three cheers for macros. If unifying client
>> and server addresses your needs, then Om Next may well be a major blessing
>> for you.
>>
>> For me, the winner is avoiding static structures. I am tired of doing
>> ongoing refactorings interrupted periodically by complete rewrites. Class
>> hierarchies are the worst--being the largest, they are the least stable. I
>> like small files that I can put to bed as finished. And self-defining
>> aggregation. Because these meet my very real needs. I constantly
>> reconceptualize what I am working on while bringing projects to completion.
>> So having a programming style which keeps code relevant in the face of such
>> an onslaught is very helpful and also a genuine delight.
>>
>> --b
>>
>> On Mon, Nov 23, 2015 at 10:08 PM, James Reeves 
>> wrote:
>>
>>> I feel you might be barking up the wrong tree with this approach, as it
>>> seems to complicate things without providing any compelling advantages.
>>>
>>> That said, if it's fun then by all means continue to experiment. Maybe
>>> I'm wrong :)
>>>
>>> - James
>>>
>>> On 24 November 2015 at 02:45, William la Forge 
>>> wrote:
>>>
 I think you have read too deeply into my thoughts on reserving the
 first argument of a function. I haven't actually written any polymorphic
 functions relating to this.

 Really, the take off point for me is being able to operate on an object
 by implementing it as a map of functions and data. That is to say, making
 objects data. Implementing multiple inheritance becomes trivial and without
 having to define any classes or any interfaces. And with full support for
 circular references without needing to do declares.

 What I like about it is that I get separation of concerns and maximal
 reuse without, I suspect, the usual usage coupling. The small maps which
 define traits can even participate in the lifecycle of the aggregate, so
 they start taking on the characteristics of components.

 My biggest problem with writing code over the decades has been the
 constant desire to do rewrites--which are costly and devastating in their
 impact. That is *why *I am fascinated with this approach.

 A second *why *is that when I have clear separation of concerns and
 the pieces of code can be easily tested independently, documentation
 becomes clearer and more fun to write. And keeping code fun is a critical
 driver for open source.

 On Mon, Nov 23, 2015 at 9:24 PM, Timothy Baldridge <
 tbaldri...@gmail.com> wrote:

> So I feel compelled at this point to ask..."why?". The whole point of
> functional programming in Clojure is to de-couple state from data. When 
> you
> need polymorphic dispatch on the contents of a map, you have access to
> multi methods. Sure this is a fun thought experiment, but I don't
> understand the design goals. It's a fairly verbose way to write more
> complex code to accomplish what we already h

Re: Ultralight Components

2015-11-23 Thread James Reeves
Have you watched Simple Made Easy
?

I mention it because you remark about being tired of refactoring. It's my
opinion that's a symptom of complexity, in the Hickey definition of the
term.

- James

On 24 November 2015 at 03:31, William la Forge  wrote:

> James,
>
> Being fun is important but not a justification. We should strive to keep
> things fun, but there are plenty of thing worth doing and our resources are
> always limited. And if it is not fun, you are not going to do your best
> work.
>
> Justifying things is generally impossible. If vanilla clojure meets your
> needs, then vanilla clojure it is. If macros solve the problems you have
> been dealt in the past, then three cheers for macros. If unifying client
> and server addresses your needs, then Om Next may well be a major blessing
> for you.
>
> For me, the winner is avoiding static structures. I am tired of doing
> ongoing refactorings interrupted periodically by complete rewrites. Class
> hierarchies are the worst--being the largest, they are the least stable. I
> like small files that I can put to bed as finished. And self-defining
> aggregation. Because these meet my very real needs. I constantly
> reconceptualize what I am working on while bringing projects to completion.
> So having a programming style which keeps code relevant in the face of such
> an onslaught is very helpful and also a genuine delight.
>
> --b
>
> On Mon, Nov 23, 2015 at 10:08 PM, James Reeves 
> wrote:
>
>> I feel you might be barking up the wrong tree with this approach, as it
>> seems to complicate things without providing any compelling advantages.
>>
>> That said, if it's fun then by all means continue to experiment. Maybe
>> I'm wrong :)
>>
>> - James
>>
>> On 24 November 2015 at 02:45, William la Forge 
>> wrote:
>>
>>> I think you have read too deeply into my thoughts on reserving the first
>>> argument of a function. I haven't actually written any polymorphic
>>> functions relating to this.
>>>
>>> Really, the take off point for me is being able to operate on an object
>>> by implementing it as a map of functions and data. That is to say, making
>>> objects data. Implementing multiple inheritance becomes trivial and without
>>> having to define any classes or any interfaces. And with full support for
>>> circular references without needing to do declares.
>>>
>>> What I like about it is that I get separation of concerns and maximal
>>> reuse without, I suspect, the usual usage coupling. The small maps which
>>> define traits can even participate in the lifecycle of the aggregate, so
>>> they start taking on the characteristics of components.
>>>
>>> My biggest problem with writing code over the decades has been the
>>> constant desire to do rewrites--which are costly and devastating in their
>>> impact. That is *why *I am fascinated with this approach.
>>>
>>> A second *why *is that when I have clear separation of concerns and the
>>> pieces of code can be easily tested independently, documentation becomes
>>> clearer and more fun to write. And keeping code fun is a critical driver
>>> for open source.
>>>
>>> On Mon, Nov 23, 2015 at 9:24 PM, Timothy Baldridge >> > wrote:
>>>
 So I feel compelled at this point to ask..."why?". The whole point of
 functional programming in Clojure is to de-couple state from data. When you
 need polymorphic dispatch on the contents of a map, you have access to
 multi methods. Sure this is a fun thought experiment, but I don't
 understand the design goals. It's a fairly verbose way to write more
 complex code to accomplish what we already have good tools for
 (protocols/multimethods, etc).  Maybe I'm missing something.

 Timothy

 On Mon, Nov 23, 2015 at 7:15 PM, William la Forge 
 wrote:

> James, when I used the term mixin I was referring to a map that acts
> like a trait that gets merged into a larger map. You would define several
> such smaller maps that can then be used in various combinations to compose
> "objects". The identity of the composite object (this) is the map which
> holds the merged contents of the smaller maps. I.E. The entries in the
> smaller maps get copied into the larger map.
>
> When executing functions held by a map, the last parameter is always
> the map itself, i.e. the "this". On the other hand, when placing closures
> into the map, the self reference is no longer needed as it is implicit in
> the closure. But this means that a closure can only reference the contents
> of the map when the closure was created, while a function can reference 
> any
> of the contents of the map passed as its last argument.
>
> Why did I make the map reference the last argument for functions held
> by the map? So that we can do type polymorphism on the first argument
> passed to the function. But we should make an exception to this. To
> facil

Re: Ultralight Components

2015-11-23 Thread William la Forge
James,

Being fun is important but not a justification. We should strive to keep
things fun, but there are plenty of thing worth doing and our resources are
always limited. And if it is not fun, you are not going to do your best
work.

Justifying things is generally impossible. If vanilla clojure meets your
needs, then vanilla clojure it is. If macros solve the problems you have
been dealt in the past, then three cheers for macros. If unifying client
and server addresses your needs, then Om Next may well be a major blessing
for you.

For me, the winner is avoiding static structures. I am tired of doing
ongoing refactorings interrupted periodically by complete rewrites. Class
hierarchies are the worst--being the largest, they are the least stable. I
like small files that I can put to bed as finished. And self-defining
aggregation. Because these meet my very real needs. I constantly
reconceptualize what I am working on while bringing projects to completion.
So having a programming style which keeps code relevant in the face of such
an onslaught is very helpful and also a genuine delight.

--b

On Mon, Nov 23, 2015 at 10:08 PM, James Reeves 
wrote:

> I feel you might be barking up the wrong tree with this approach, as it
> seems to complicate things without providing any compelling advantages.
>
> That said, if it's fun then by all means continue to experiment. Maybe I'm
> wrong :)
>
> - James
>
> On 24 November 2015 at 02:45, William la Forge 
> wrote:
>
>> I think you have read too deeply into my thoughts on reserving the first
>> argument of a function. I haven't actually written any polymorphic
>> functions relating to this.
>>
>> Really, the take off point for me is being able to operate on an object
>> by implementing it as a map of functions and data. That is to say, making
>> objects data. Implementing multiple inheritance becomes trivial and without
>> having to define any classes or any interfaces. And with full support for
>> circular references without needing to do declares.
>>
>> What I like about it is that I get separation of concerns and maximal
>> reuse without, I suspect, the usual usage coupling. The small maps which
>> define traits can even participate in the lifecycle of the aggregate, so
>> they start taking on the characteristics of components.
>>
>> My biggest problem with writing code over the decades has been the
>> constant desire to do rewrites--which are costly and devastating in their
>> impact. That is *why *I am fascinated with this approach.
>>
>> A second *why *is that when I have clear separation of concerns and the
>> pieces of code can be easily tested independently, documentation becomes
>> clearer and more fun to write. And keeping code fun is a critical driver
>> for open source.
>>
>> On Mon, Nov 23, 2015 at 9:24 PM, Timothy Baldridge 
>> wrote:
>>
>>> So I feel compelled at this point to ask..."why?". The whole point of
>>> functional programming in Clojure is to de-couple state from data. When you
>>> need polymorphic dispatch on the contents of a map, you have access to
>>> multi methods. Sure this is a fun thought experiment, but I don't
>>> understand the design goals. It's a fairly verbose way to write more
>>> complex code to accomplish what we already have good tools for
>>> (protocols/multimethods, etc).  Maybe I'm missing something.
>>>
>>> Timothy
>>>
>>> On Mon, Nov 23, 2015 at 7:15 PM, William la Forge 
>>> wrote:
>>>
 James, when I used the term mixin I was referring to a map that acts
 like a trait that gets merged into a larger map. You would define several
 such smaller maps that can then be used in various combinations to compose
 "objects". The identity of the composite object (this) is the map which
 holds the merged contents of the smaller maps. I.E. The entries in the
 smaller maps get copied into the larger map.

 When executing functions held by a map, the last parameter is always
 the map itself, i.e. the "this". On the other hand, when placing closures
 into the map, the self reference is no longer needed as it is implicit in
 the closure. But this means that a closure can only reference the contents
 of the map when the closure was created, while a function can reference any
 of the contents of the map passed as its last argument.

 Why did I make the map reference the last argument for functions held
 by the map? So that we can do type polymorphism on the first argument
 passed to the function. But we should make an exception to this. To
 facilitate threading, functions which return an updated map should take
 that map as the first argument. But that is an API change and needs to wait
 for release 0.6.0.

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

Re: Ultralight Components

2015-11-23 Thread James Reeves
I feel you might be barking up the wrong tree with this approach, as it
seems to complicate things without providing any compelling advantages.

That said, if it's fun then by all means continue to experiment. Maybe I'm
wrong :)

- James

On 24 November 2015 at 02:45, William la Forge  wrote:

> I think you have read too deeply into my thoughts on reserving the first
> argument of a function. I haven't actually written any polymorphic
> functions relating to this.
>
> Really, the take off point for me is being able to operate on an object by
> implementing it as a map of functions and data. That is to say, making
> objects data. Implementing multiple inheritance becomes trivial and without
> having to define any classes or any interfaces. And with full support for
> circular references without needing to do declares.
>
> What I like about it is that I get separation of concerns and maximal
> reuse without, I suspect, the usual usage coupling. The small maps which
> define traits can even participate in the lifecycle of the aggregate, so
> they start taking on the characteristics of components.
>
> My biggest problem with writing code over the decades has been the
> constant desire to do rewrites--which are costly and devastating in their
> impact. That is *why *I am fascinated with this approach.
>
> A second *why *is that when I have clear separation of concerns and the
> pieces of code can be easily tested independently, documentation becomes
> clearer and more fun to write. And keeping code fun is a critical driver
> for open source.
>
> On Mon, Nov 23, 2015 at 9:24 PM, Timothy Baldridge 
> wrote:
>
>> So I feel compelled at this point to ask..."why?". The whole point of
>> functional programming in Clojure is to de-couple state from data. When you
>> need polymorphic dispatch on the contents of a map, you have access to
>> multi methods. Sure this is a fun thought experiment, but I don't
>> understand the design goals. It's a fairly verbose way to write more
>> complex code to accomplish what we already have good tools for
>> (protocols/multimethods, etc).  Maybe I'm missing something.
>>
>> Timothy
>>
>> On Mon, Nov 23, 2015 at 7:15 PM, William la Forge 
>> wrote:
>>
>>> James, when I used the term mixin I was referring to a map that acts
>>> like a trait that gets merged into a larger map. You would define several
>>> such smaller maps that can then be used in various combinations to compose
>>> "objects". The identity of the composite object (this) is the map which
>>> holds the merged contents of the smaller maps. I.E. The entries in the
>>> smaller maps get copied into the larger map.
>>>
>>> When executing functions held by a map, the last parameter is always the
>>> map itself, i.e. the "this". On the other hand, when placing closures into
>>> the map, the self reference is no longer needed as it is implicit in the
>>> closure. But this means that a closure can only reference the contents of
>>> the map when the closure was created, while a function can reference any of
>>> the contents of the map passed as its last argument.
>>>
>>> Why did I make the map reference the last argument for functions held by
>>> the map? So that we can do type polymorphism on the first argument passed
>>> to the function. But we should make an exception to this. To facilitate
>>> threading, functions which return an updated map should take that map as
>>> the first argument. But that is an API change and needs to wait for release
>>> 0.6.0.
>>>
>>> --
>>> 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.
>>>
>>
>>
>>
>> --
>> “One of the main causes of the fall of the Roman Empire was that–lacking
>> zero–they had no way to indicate successful termination of their C
>> programs.”
>> (Robert Firth)
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to a topic in the
>> Google Groups "Clojure"

Re: Ultralight Components

2015-11-23 Thread William la Forge
Raoul,

The problem for me here is that all that terminology refers to classes.
What I am dealing with here are objects implemented as persistent maps and
operations on those maps. Which is why I'm grasping for terminology.

Perhaps I should just define a new term like UltraLight Component (ULC).

--b

On Mon, Nov 23, 2015 at 7:48 PM, Raoul Duke  wrote:

> re: mixins, traits, etc. those terms have all been used in both
> research & shipped languages. Please see e.g. how Scala evolved with
> those terms. :)
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/7Q7QvlSUGL4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: Ultralight Components

2015-11-23 Thread William la Forge
I think you have read too deeply into my thoughts on reserving the first
argument of a function. I haven't actually written any polymorphic
functions relating to this.

Really, the take off point for me is being able to operate on an object by
implementing it as a map of functions and data. That is to say, making
objects data. Implementing multiple inheritance becomes trivial and without
having to define any classes or any interfaces. And with full support for
circular references without needing to do declares.

What I like about it is that I get separation of concerns and maximal reuse
without, I suspect, the usual usage coupling. The small maps which define
traits can even participate in the lifecycle of the aggregate, so they
start taking on the characteristics of components.

My biggest problem with writing code over the decades has been the constant
desire to do rewrites--which are costly and devastating in their impact.
That is *why *I am fascinated with this approach.

A second *why *is that when I have clear separation of concerns and the
pieces of code can be easily tested independently, documentation becomes
clearer and more fun to write. And keeping code fun is a critical driver
for open source.

On Mon, Nov 23, 2015 at 9:24 PM, Timothy Baldridge 
wrote:

> So I feel compelled at this point to ask..."why?". The whole point of
> functional programming in Clojure is to de-couple state from data. When you
> need polymorphic dispatch on the contents of a map, you have access to
> multi methods. Sure this is a fun thought experiment, but I don't
> understand the design goals. It's a fairly verbose way to write more
> complex code to accomplish what we already have good tools for
> (protocols/multimethods, etc).  Maybe I'm missing something.
>
> Timothy
>
> On Mon, Nov 23, 2015 at 7:15 PM, William la Forge 
> wrote:
>
>> James, when I used the term mixin I was referring to a map that acts like
>> a trait that gets merged into a larger map. You would define several such
>> smaller maps that can then be used in various combinations to compose
>> "objects". The identity of the composite object (this) is the map which
>> holds the merged contents of the smaller maps. I.E. The entries in the
>> smaller maps get copied into the larger map.
>>
>> When executing functions held by a map, the last parameter is always the
>> map itself, i.e. the "this". On the other hand, when placing closures into
>> the map, the self reference is no longer needed as it is implicit in the
>> closure. But this means that a closure can only reference the contents of
>> the map when the closure was created, while a function can reference any of
>> the contents of the map passed as its last argument.
>>
>> Why did I make the map reference the last argument for functions held by
>> the map? So that we can do type polymorphism on the first argument passed
>> to the function. But we should make an exception to this. To facilitate
>> threading, functions which return an updated map should take that map as
>> the first argument. But that is an API change and needs to wait for release
>> 0.6.0.
>>
>> --
>> 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.
>>
>
>
>
> --
> “One of the main causes of the fall of the Roman Empire was that–lacking
> zero–they had no way to indicate successful termination of their C
> programs.”
> (Robert Firth)
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/7Q7QvlSUGL4/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send e

Re: Ultralight Components

2015-11-23 Thread Timothy Baldridge
correction"decouple state from behavior"

On Mon, Nov 23, 2015 at 7:24 PM, Timothy Baldridge 
wrote:

> So I feel compelled at this point to ask..."why?". The whole point of
> functional programming in Clojure is to de-couple state from data. When you
> need polymorphic dispatch on the contents of a map, you have access to
> multi methods. Sure this is a fun thought experiment, but I don't
> understand the design goals. It's a fairly verbose way to write more
> complex code to accomplish what we already have good tools for
> (protocols/multimethods, etc).  Maybe I'm missing something.
>
> Timothy
>
> On Mon, Nov 23, 2015 at 7:15 PM, William la Forge 
> wrote:
>
>> James, when I used the term mixin I was referring to a map that acts like
>> a trait that gets merged into a larger map. You would define several such
>> smaller maps that can then be used in various combinations to compose
>> "objects". The identity of the composite object (this) is the map which
>> holds the merged contents of the smaller maps. I.E. The entries in the
>> smaller maps get copied into the larger map.
>>
>> When executing functions held by a map, the last parameter is always the
>> map itself, i.e. the "this". On the other hand, when placing closures into
>> the map, the self reference is no longer needed as it is implicit in the
>> closure. But this means that a closure can only reference the contents of
>> the map when the closure was created, while a function can reference any of
>> the contents of the map passed as its last argument.
>>
>> Why did I make the map reference the last argument for functions held by
>> the map? So that we can do type polymorphism on the first argument passed
>> to the function. But we should make an exception to this. To facilitate
>> threading, functions which return an updated map should take that map as
>> the first argument. But that is an API change and needs to wait for release
>> 0.6.0.
>>
>> --
>> 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.
>>
>
>
>
> --
> “One of the main causes of the fall of the Roman Empire was that–lacking
> zero–they had no way to indicate successful termination of their C
> programs.”
> (Robert Firth)
>



-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

-- 
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: Ultralight Components

2015-11-23 Thread Timothy Baldridge
So I feel compelled at this point to ask..."why?". The whole point of
functional programming in Clojure is to de-couple state from data. When you
need polymorphic dispatch on the contents of a map, you have access to
multi methods. Sure this is a fun thought experiment, but I don't
understand the design goals. It's a fairly verbose way to write more
complex code to accomplish what we already have good tools for
(protocols/multimethods, etc).  Maybe I'm missing something.

Timothy

On Mon, Nov 23, 2015 at 7:15 PM, William la Forge 
wrote:

> James, when I used the term mixin I was referring to a map that acts like
> a trait that gets merged into a larger map. You would define several such
> smaller maps that can then be used in various combinations to compose
> "objects". The identity of the composite object (this) is the map which
> holds the merged contents of the smaller maps. I.E. The entries in the
> smaller maps get copied into the larger map.
>
> When executing functions held by a map, the last parameter is always the
> map itself, i.e. the "this". On the other hand, when placing closures into
> the map, the self reference is no longer needed as it is implicit in the
> closure. But this means that a closure can only reference the contents of
> the map when the closure was created, while a function can reference any of
> the contents of the map passed as its last argument.
>
> Why did I make the map reference the last argument for functions held by
> the map? So that we can do type polymorphism on the first argument passed
> to the function. But we should make an exception to this. To facilitate
> threading, functions which return an updated map should take that map as
> the first argument. But that is an API change and needs to wait for release
> 0.6.0.
>
> --
> 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.
>



-- 
“One of the main causes of the fall of the Roman Empire was that–lacking
zero–they had no way to indicate successful termination of their C
programs.”
(Robert Firth)

-- 
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: Ultralight Components

2015-11-23 Thread William la Forge
James, when I used the term mixin I was referring to a map that acts like a 
trait that gets merged into a larger map. You would define several such 
smaller maps that can then be used in various combinations to compose 
"objects". The identity of the composite object (this) is the map which 
holds the merged contents of the smaller maps. I.E. The entries in the 
smaller maps get copied into the larger map. 

When executing functions held by a map, the last parameter is always the 
map itself, i.e. the "this". On the other hand, when placing closures into 
the map, the self reference is no longer needed as it is implicit in the 
closure. But this means that a closure can only reference the contents of 
the map when the closure was created, while a function can reference any of 
the contents of the map passed as its last argument.

Why did I make the map reference the last argument for functions held by 
the map? So that we can do type polymorphism on the first argument passed 
to the function. But we should make an exception to this. To facilitate 
threading, functions which return an updated map should take that map as 
the first argument. But that is an API change and needs to wait for release 
0.6.0.

-- 
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: Ultralight Components

2015-11-23 Thread James Reeves
I didn't look at wikipedia, I was trying to guess what you meant from your
post. I'm still unclear what you mean in the context of Clojure.

- James

On 24 November 2015 at 00:45, William la Forge  wrote:

> Sounds like you looked at wikipedia, which is the only place where I've
> seen mixin refer to the aggregate class. I've always seen mixin, or at
> least my understanding was that a mixin was the class that got added to the
> mixture. Could be just bad editing at the start of the wikipedia page, as
> they seem to reverse the sense of the term as you read further down the
> page. But as I look at other references to mixin, things become less and
> less clear.
>
> Yeah, I am talking about creating compositions by aggregating the contents
> of other maps. It looks like a clearer term for the map being mixed into an
> aggregate would be trait. So I would have a db-file trait, the closer
> trait, the actor trait and the async-channel trait, all of which can be
> used in the composition of a database. Trait is clearer and nicely puts the
> emphasis on the functionality/capability being added.
>
> It is hard coming up with good terms. I very much appreciate your help
> here James.
>
> --b
>
> On Monday, November 23, 2015 at 6:50:21 PM UTC-5, James Reeves wrote:
>>
>> Just to be clear, by "mixin" you're referring to merging two maps of
>> functions?
>>
>> Have you considered using composition instead of mixins?
>>
>> - James
>>
>> On 23 November 2015 at 20:01, William la Forge  wrote:
>>
>>> When an object is built from a map, aggregating mixins is a trivial
>>> operation. But when a mixin needs to be closed, it is better to have a
>>> common mechanism to manage a stack of the close functions of all the
>>> aggregated mixins than to depend on application logic to do so. Case in
>>> point, I'd like to use an actor mixin or an alternative async channel mixin
>>> when composing a database. The async channel mixin will require a close but
>>> the actor mixin will not. So I developed the closer mixin to handle the
>>> calls to both the async channel and db file close functions. The database
>>> will only know the closer's do-close method. And it is the responsibility
>>> of the async channel and the db file mixins to register their close
>>> functions with the closer mixin.
>>>
>>>
>>> My inspiration is Stuart Sierra's component library
>>> . But I am not handling
>>> dependencies per say, only managing a stack of close functions. And the
>>> "components" are only functions and atoms added to a common map structure,
>>> not records or deftypes. The result is a very lightweight pattern for
>>> components. The closer code itself is a lock-free mixin that gets added to
>>> the common map as needed when the on-close method is called.
>>>
>>> For more information, see Closer
>>> .
>>>
>>> (ns aatree.closer
>>>   (:require [clojure.tools.logging :as log]))
>>>
>>> (set! *warn-on-reflection* true)
>>>
>>> (defn on-close [f opts]
>>>   (let [fsa (:closer-fsa opts)]
>>> (if fsa
>>>   (do
>>> (swap! fsa
>>>(fn [fs]
>>>  (if fs
>>>(conj fs f)
>>>(atom (list f)
>>> opts)
>>>   (assoc opts :closer-fsa (atom (list f))
>>>
>>> (defn- do-closer [fs opts]
>>>   (when fs
>>> (try
>>>   ((first fs) opts)
>>>   (catch Exception e
>>> (log/warn e "exception on close")))
>>> (recur (next fs) opts)))
>>>
>>> (defn do-close [opts]
>>>   (let [fsa (:closer-fsa opts)]
>>> (if fsa
>>>   (let [fs @fsa]
>>> (if fs
>>>   (if (compare-and-set! fsa fs nil)
>>> (do-closer fs opts)
>>> (recur opts)))
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clo...@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+u...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+u...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>

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

Re: Ultralight Components

2015-11-23 Thread Raoul Duke
re: mixins, traits, etc. those terms have all been used in both
research & shipped languages. Please see e.g. how Scala evolved with
those terms. :)

-- 
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: Ultralight Components

2015-11-23 Thread William la Forge
Sounds like you looked at wikipedia, which is the only place where I've 
seen mixin refer to the aggregate class. I've always seen mixin, or at 
least my understanding was that a mixin was the class that got added to the 
mixture. Could be just bad editing at the start of the wikipedia page, as 
they seem to reverse the sense of the term as you read further down the 
page. But as I look at other references to mixin, things become less and 
less clear.

Yeah, I am talking about creating compositions by aggregating the contents 
of other maps. It looks like a clearer term for the map being mixed into an 
aggregate would be trait. So I would have a db-file trait, the closer 
trait, the actor trait and the async-channel trait, all of which can be 
used in the composition of a database. Trait is clearer and nicely puts the 
emphasis on the functionality/capability being added.

It is hard coming up with good terms. I very much appreciate your help here 
James.

--b

On Monday, November 23, 2015 at 6:50:21 PM UTC-5, James Reeves wrote:
>
> Just to be clear, by "mixin" you're referring to merging two maps of 
> functions?
>
> Have you considered using composition instead of mixins? 
>
> - James
>
> On 23 November 2015 at 20:01, William la Forge  > wrote:
>
>> When an object is built from a map, aggregating mixins is a trivial 
>> operation. But when a mixin needs to be closed, it is better to have a 
>> common mechanism to manage a stack of the close functions of all the 
>> aggregated mixins than to depend on application logic to do so. Case in 
>> point, I'd like to use an actor mixin or an alternative async channel mixin 
>> when composing a database. The async channel mixin will require a close but 
>> the actor mixin will not. So I developed the closer mixin to handle the 
>> calls to both the async channel and db file close functions. The database 
>> will only know the closer's do-close method. And it is the responsibility 
>> of the async channel and the db file mixins to register their close 
>> functions with the closer mixin.
>>
>>
>> My inspiration is Stuart Sierra's component library 
>> . But I am not handling 
>> dependencies per say, only managing a stack of close functions. And the 
>> "components" are only functions and atoms added to a common map structure, 
>> not records or deftypes. The result is a very lightweight pattern for 
>> components. The closer code itself is a lock-free mixin that gets added to 
>> the common map as needed when the on-close method is called.
>>
>> For more information, see Closer 
>> .
>>
>> (ns aatree.closer
>>   (:require [clojure.tools.logging :as log]))
>>
>> (set! *warn-on-reflection* true)
>>
>> (defn on-close [f opts]
>>   (let [fsa (:closer-fsa opts)]
>> (if fsa
>>   (do
>> (swap! fsa
>>(fn [fs]
>>  (if fs
>>(conj fs f)
>>(atom (list f)
>> opts)
>>   (assoc opts :closer-fsa (atom (list f))
>>
>> (defn- do-closer [fs opts]
>>   (when fs
>> (try
>>   ((first fs) opts)
>>   (catch Exception e
>> (log/warn e "exception on close")))
>> (recur (next fs) opts)))
>>
>> (defn do-close [opts]
>>   (let [fsa (:closer-fsa opts)]
>> (if fsa
>>   (let [fs @fsa]
>> (if fs
>>   (if (compare-and-set! fsa fs nil)
>> (do-closer fs opts)
>> (recur opts)))
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@googlegroups.com 
>> 
>> Note that posts from new members are moderated - please be patient with 
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+u...@googlegroups.com 
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> --- 
>> You received this message because you are subscribed to the Google Groups 
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to 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: Ultralight Components

2015-11-23 Thread James Reeves
Just to be clear, by "mixin" you're referring to merging two maps of
functions?

Have you considered using composition instead of mixins?

- James

On 23 November 2015 at 20:01, William la Forge  wrote:

> When an object is built from a map, aggregating mixins is a trivial
> operation. But when a mixin needs to be closed, it is better to have a
> common mechanism to manage a stack of the close functions of all the
> aggregated mixins than to depend on application logic to do so. Case in
> point, I'd like to use an actor mixin or an alternative async channel mixin
> when composing a database. The async channel mixin will require a close but
> the actor mixin will not. So I developed the closer mixin to handle the
> calls to both the async channel and db file close functions. The database
> will only know the closer's do-close method. And it is the responsibility
> of the async channel and the db file mixins to register their close
> functions with the closer mixin.
>
>
> My inspiration is Stuart Sierra's component library
> . But I am not handling
> dependencies per say, only managing a stack of close functions. And the
> "components" are only functions and atoms added to a common map structure,
> not records or deftypes. The result is a very lightweight pattern for
> components. The closer code itself is a lock-free mixin that gets added to
> the common map as needed when the on-close method is called.
>
> For more information, see Closer
> .
>
> (ns aatree.closer
>   (:require [clojure.tools.logging :as log]))
>
> (set! *warn-on-reflection* true)
>
> (defn on-close [f opts]
>   (let [fsa (:closer-fsa opts)]
> (if fsa
>   (do
> (swap! fsa
>(fn [fs]
>  (if fs
>(conj fs f)
>(atom (list f)
> opts)
>   (assoc opts :closer-fsa (atom (list f))
>
> (defn- do-closer [fs opts]
>   (when fs
> (try
>   ((first fs) opts)
>   (catch Exception e
> (log/warn e "exception on close")))
> (recur (next fs) opts)))
>
> (defn do-close [opts]
>   (let [fsa (:closer-fsa opts)]
> (if fsa
>   (let [fs @fsa]
> (if fs
>   (if (compare-and-set! fsa fs nil)
> (do-closer fs opts)
> (recur opts)))
>
> --
> 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: Clojure Objects

2015-11-23 Thread Gregg Reynolds
On Nov 23, 2015 4:23 PM, "Gregg Reynolds"  wrote:
>
>
> On Nov 23, 2015 6:34 AM, "Bobby Bobble"  wrote:
> >
> > functions.  E.g. it's as nullary fns.

Sorry, "ints", not "it's ".  How I hate spell-checkers!!

-- 
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: Clojure Objects

2015-11-23 Thread Gregg Reynolds
On Nov 23, 2015 6:34 AM, "Bobby Bobble"  wrote:
>
> let's not forget that Clojure's datastructures are objects. They respond
to messages like seq, first, rest etc (which requires a bit more complexity
than what Clojurians hail as "just data", which would be like
1010101101010100011011...what Clojurians really mean by that
term is something like "uniform access to objects")

Hmm.  If by "object" you mean entity, thing, value, etc. - i.e.
mathematical structure - then I'd agree, but in my view Clojure does not
involve OO "objects" in any way, _conceptually_.   "This function is
defined on that type" != "that type 'responds to' this function" .

>
> (Clojure's vocabulary is not to be questioned...why say "conflate" or
"confuse" when you can say "complect" to reinforce in-group membership ?)
/rant

THANK YOU!  I can't count the number of times I've had to restrain myself
from an apoplectic rant about this hideous non-word.  What is wrong with
"complicate" FFS?!

>
> anyway to the point, it depends what you mean by "objects".

>
> What you propose is to use maps as a kind of namespace for functions.
It's a good idea. I use this pattern too. Really, namespaces should be
maps...actually I think there was a project called Kiss to that end.

To the OP's original point: you can view functions as data, but I find
myself moving toward a view of data as functions.  E.g. it's as nullary fns.
>
> But real OO, as realized by Smalltalk and Self is about messaging, not
objects.

Thank you again.  Objective C is another good example.  Dunno why they
called it OO in the first place.

AFAIA there's no way in Clojure to represent "the invocation of a function
on a thing" the way you can represent "the sending of a message to an
object" in Smalltalk.

Not quite sure what you mean, but with stuff like core.async and protocols
it's possible to support an explicit msg - passing idiom in Clojure.  But I
think I agree with you.  It would be something you build on more primitive
notions.

Gregg

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


Ultralight Components

2015-11-23 Thread William la Forge


When an object is built from a map, aggregating mixins is a trivial 
operation. But when a mixin needs to be closed, it is better to have a 
common mechanism to manage a stack of the close functions of all the 
aggregated mixins than to depend on application logic to do so. Case in 
point, I'd like to use an actor mixin or an alternative async channel mixin 
when composing a database. The async channel mixin will require a close but 
the actor mixin will not. So I developed the closer mixin to handle the 
calls to both the async channel and db file close functions. The database 
will only know the closer's do-close method. And it is the responsibility 
of the async channel and the db file mixins to register their close 
functions with the closer mixin.


My inspiration is Stuart Sierra's component library 
. But I am not handling 
dependencies per say, only managing a stack of close functions. And the 
"components" are only functions and atoms added to a common map structure, 
not records or deftypes. The result is a very lightweight pattern for 
components. The closer code itself is a lock-free mixin that gets added to 
the common map as needed when the on-close method is called.

For more information, see Closer 
.

(ns aatree.closer
  (:require [clojure.tools.logging :as log]))

(set! *warn-on-reflection* true)

(defn on-close [f opts]
  (let [fsa (:closer-fsa opts)]
(if fsa
  (do
(swap! fsa
   (fn [fs]
 (if fs
   (conj fs f)
   (atom (list f)
opts)
  (assoc opts :closer-fsa (atom (list f))

(defn- do-closer [fs opts]
  (when fs
(try
  ((first fs) opts)
  (catch Exception e
(log/warn e "exception on close")))
(recur (next fs) opts)))

(defn do-close [opts]
  (let [fsa (:closer-fsa opts)]
(if fsa
  (let [fs @fsa]
(if fs
  (if (compare-and-set! fsa fs nil)
(do-closer fs opts)
(recur opts)))

-- 
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: Largest Clojure codebases?

2015-11-23 Thread Sean Corfield
I know I've seen mentions of 50k-100k LOC projects (World Singles, if I'm 
remembering correctly), but are there any that are larger?

Our code base is "only" about 30kloc of production Clojure so far (and 7.5kloc 
of unit tests and 2kloc WebDriver tests). As we refactor our legacy code base, 
we’re rewriting quite a bit of it from a dynamic OO scripting language to 
Clojure and finding we need less code — sometimes a lot less — for FP compared 
to OOP. If we were using Java, our OOP codebase would be even bigger so the 
"compression" from Java to Clojure would be even more extreme. That means that 
a "large" codebase in OOP is likely to be much, much larger than the equivalent 
"large" codebase in FP — in general — making it somewhat hard to compare 
numbers in any meaningful way.

I’m not quite sure what you mean by "old-school OOP programmer" but, for 
comparison, I’ve been doing software development commercially since the early 
80’s and OOP specifically since the early 90’s. I did FP at college in the 80’s 
and I’ve been doing it commercially for the last six years now. Based on that 
comparative experience, I’m pretty comfortable asserting that a) you do not 
need objects to make large-scale codebases legible and maintainable and b) an 
object-based codebase is likely to be larger than the equivalent functional 
codebase (and a smaller codebase is more legible and maintainable anyway).

Sean Corfield -- (904) 302-SEAN
World Singles -- http://worldsingles.com/


-- 
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: [ANN] Specter book approach: please evaluate

2015-11-23 Thread Francesco Bellomi
Brian,

I bought the current version of book.
I really liked both the content and the approach.

best,
Francesco




On Sunday, November 22, 2015 at 7:18:02 PM UTC+1, Brian Marick wrote:
>
> I announced a while back that I'd be writing a short book on Specter 
> https://github.com/nathanmarz/specter After some thrashing and the usual 
> interruptions, I have the first chapter written. I've taken an unusual 
> approach: teaching Specter by having you implement parts of it. I'm 
> curious to hear people's opinions. 
>
> Here: https://leanpub.com/specter 
>
> 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: Clojure Objects

2015-11-23 Thread Bobby Bobble
let's not forget that Clojure's datastructures are objects. They respond to 
messages like seq, first, rest etc (which requires a bit more complexity 
than what Clojurians hail as "just data", which would be like 
1010101101010100011011...what Clojurians really mean by that 
term is something like "uniform access to objects")

(Clojure's vocabulary is not to be questioned...why say "conflate" or 
"confuse" when you can say "complect" to reinforce in-group membership ?) 
/rant

anyway to the point, it depends what you mean by "objects".

What you propose is to use maps as a kind of namespace for functions. It's 
a good idea. I use this pattern too. Really, namespaces should be 
maps...actually I think there was a project called Kiss to that end.

But real OO, as realized by Smalltalk and Self is about messaging, not 
objects. AFAIA there's no way in Clojure to represent "the invocation of a 
function on a thing" the way you can represent "the sending of a message to 
an object" in Smalltalk.


On Saturday, November 21, 2015 at 2:54:15 AM UTC, William la Forge wrote:
>
> Code as data is the mantra. Functions and closures as data. So why not 
> objects as data? What I propose is nothing new, but perhaps a new style.
>
> Making objects from map structures is simple enough in Clojure. And easy 
> enough to put functions in a map. So why not closures? A closure in a map 
> is a lot like an object method, hmm?
>
> I found clojure components to be inspirational. But as light-weight as 
> they are, components are still too heavy-weight to be objects. But a simple 
> map seems ideal. And with only a map instead of a record or deftype, 
> composition is simplicity itself. But the key idea here comes from clojure 
> components: contents of the map should be configuration parameters or 
> architecture, but not state. Put state in an atom and then (optionally) put 
> the atom in the map. But once an object is formed, the contents of the map 
> should not change. There should be no need to update a reference to this 
> map.
>
> Below is what I am calling a Clojure Object. Like a Java object, the 
> method holds both data and methods (closures). Note that, because we are 
> using closures, local data can be accessed without having to be put in the 
> map. For example, the file-channel variable is not accessed via the map and 
> need not have been added to the map.
>
> Bill
>
> (ns aatree.db-file
>   (:require [clojure.tools.logging :as log])
>   (:import (java.nio.channels FileChannel)
>(java.nio.file OpenOption StandardOpenOption)))
>
> (defn db-file-open
>   ([file opts]
> (db-file-open (assoc opts :db-file file)))
>   ([opts]
> (if (not (:db-file opts))
>   (throw (Exception. "missing :db-file option")))
>(let [file (:db-file opts)
>  ^FileChannel file-channel
>  (FileChannel/open (.toPath file)
>(into-array OpenOption
>[StandardOpenOption/CREATE
> StandardOpenOption/READ
> StandardOpenOption/WRITE]))
>  opts (assoc opts :db-file-channel file-channel)
>  opts (assoc opts
> :db-close
> (fn []
>   (try
> (.close file-channel)
> (catch Exception e
>   (log/warn e "exception on close of db-file")))
>   (dissoc opts :db-file-channel)))
>  opts (assoc opts
> :db-file-empty?
> (fn []
>   (= 0 (.size file-channel
>  opts (assoc opts
> :db-file-read
> (fn [byte-buffer position]
>   (.read file-channel byte-buffer position)))
>  opts (assoc opts
> :db-file-write
> (fn [byte-buffer position]
>   (.write file-channel byte-buffer position)))
>  opts (assoc opts
> :db-file-write-root
> (fn [byte-buffer position]
>   (.force file-channel true)
>   (.write file-channel byte-buffer position)
>   (.force file-channel true)))
>  opts (assoc opts
> :db-file-force
> (fn []
>   (.force file-channel true)))]
>  opts)))
>
>

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

Re: ANN: ClojureScript 1.7.170, Enhanced Build Pipeline

2015-11-23 Thread Nikita Prokopov
Any advice what to do with deps.cljs?

Exception in thread "main" java.lang.AssertionError: No ns form found in 
/Users/prokopov/Dropbox/ws/cognician/c3/src/deps.cljs, 
compiling:(/private/var/folders/0h/9vv4g3d955l6ctwwl4k9xjy4gn/T/form-init7898631568113094426.clj:1:125)

$ cat src/deps.cljs
{
  :externs ["cognician/chat/externs.js"]
}
$

I’m using CLJS 1.7.170 and lein-cljsbuild 1.1.1

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