librelist archives

« back to archive

Thinking functionally

Thinking functionally

From:
Monte Johnston
Date:
2013-05-31 @ 14:11
I am slowly learning to think more functionally. As I was looking at some 
javascript code and trying to implement it in Clojure, I got  stuck.

The javascript function operates on an array on the object. It loops 
through the array, comparing each item in the array to every other item in
the area, and updates each element with the results.

Here is the code:

Layout.ForceDirected.prototype.applyCoulombsLaw = function() {
		this.eachNode(function(n1, point1) {
			this.eachNode(function(n2, point2) {
				if (point1 !== point2)
				{
					var d = point1.p.subtract(point2.p);
					var distance = d.magnitude() + 0.1; // avoid massive forces at small 
distances (and divide by zero)
					var direction = d.normalise();

					// apply force to each end point
					point1.applyForce(direction.multiply(this.repulsion).divide(distance 
* distance * 0.5));
					point2.applyForce(direction.multiply(this.repulsion).divide(distance 
* distance * -0.5));
				}
			});
		});
	};

Thanks in advance.

Re: [foray] Thinking functionally

From:
Sean Corfield
Date:
2013-06-02 @ 08:01
Without knowing more about what applyForce() does and how results are 
accumulated it's hard to say how best to convert this. It's inherently an 
OOP statement of a problem, relying heavily on mutable state.

The closest idiomatic Clojure would be a for comprehension with point1 and
point2 both bound to the sequence of points in the force-directed data 
structure, yielding ... well, I'm not quite sure at that point ... perhaps
a sequence of pairs of points with forces applied which you'd then group 
by point and reduce to combine the forces?

Sean

On May 31, 2013, at 7:11 AM, Monte Johnston wrote:

> 
> I am slowly learning to think more functionally. As I was looking at 
some javascript code and trying to implement it in Clojure, I got  stu ck.
> 
> The javascript function operates on an array on the object. It loops 
through the array, compar ing each item in the array to every other item 
in the area, and updates each element with the results.
> 
> Here is the code:
> 
> Layout.ForceDirected.prototype.applyCoulombsLaw = function() {
> 		this.eachNode(function(n1, point1) {
> 			this.eachNode(function(n2, point2) {
> 				if (point1 !== point2)
> 				{
> 					var d = point1.p.subtract(point2.p);
> 					var distance = d.magnitude() + 0.1; // avoid massive forces at 
small distances (and di vide by zero)
> 					var direction = d.normalise();
> 
> 					// apply force to each end point
> 					
point1.applyForce(direction.multiply(this.repulsion).divide(distance * 
distance * 0.5));
> 					point2.applyForce(direction.mu 
ltiply(this.repulsion).divide(distance * distance * -0.5));
> 				}
> 			});
> 		});
> 	};
> 
> Thanks in advance.
> 

Re: [foray] Thinking functionally

From:
Sean Chalmers
Date:
2013-06-03 @ 12:19
Continuing along the lines of wanting to think functionally, I've actually
been dabbling with some Haskell and having a crack at some of the 99
Haskell problems and it's actually been helping me with thinking
functionally (Strangely enough). Regrettably I've not been able to progress
through the book at all so I'm waaaayyyy behind everybody.. :(

One of the cool problems was the 'compress' problem...

(compress "aaaabbbcccaaadddddeeee")
> "abcade"

This is about as close as I've managed to get and I was wondering if anyone
had any thoughts...

(defn compress [x]
  (let [a (first x) b (rest x)]
    (if (= a (first b))
      (when-not (empty? (rest b))
        (cons a (compress (rest b))))
      (recur (rest x)))))

I have a feeling I'm trying to be too clever for my own good... :\

PS: It's about 10:20pm at the moment so if I don't reply I'm really not
being rude, I'm asleep. ^.^

--- Warning, Haskell Kool-Aid below :)

This is my Haskell 'well it passes the test' solution... The second
function is because I didn't like having the comparison twice and felt I
could do better. :P

import Data.List

testList = "aaaabccaadeeee"
desiredResult = "abcade"

compress [] = []
compress (x:y:xs)
  | x == y && null xs = []
  | x == y = [head xs] ++ compress xs
  | otherwise = [y] ++ compress xs

compressTwo [] = []
compressTwo (x:y:xs) =
  if x == y
  then if null xs
       then []
       else [head xs] ++ compress xs
  else compress (init xs)

main = do
  print $ compress testList == desiredResult
  print $ compressTwo testList == desiredResult


On 2 June 2013 18:01, Sean Corfield <sean@corfield.org> wrote:

> Without knowing more about what applyForce() does and how results are
> accumulated it's hard to say how best to convert this. It's inherently an
> OOP statement of a problem, relying heavily on mutable state.
>
> The closest idiomatic Clojure would be a for comprehension with point1 and
> point2 both bound to the sequence of points in the force-directed data
> structure, yielding ... well, I'm not quite sure at that point ... perhaps
> a sequence of pairs of points with forces applied which you'd then group by
> point and reduce to combine the forces?
>
> Sean
>
> On May 31, 2013, at 7:11 AM, Monte Johnston wrote:
>
> >
> > I am slowly learning to think more functionally. As I was looking at
> some javascript code and trying to implement it in Clojure, I got  stu ck.
> >
> > The javascript function operates on an array on the object. It loops
> through the array, compar ing each item in the array to every other item in
> the area, and updates each element with the results.
> >
> > Here is the code:
> >
> > Layout.ForceDirected.prototype.applyCoulombsLaw = function() {
> >               this.eachNode(function(n1, point1) {
> >                       this.eachNode(function(n2, point2) {
> >                               if (point1 !== point2)
> >                               {
> >                                       var d =
> point1.p.subtract(point2.p);
> >                                       var distance = d.magnitude() +
> 0.1; // avoid massive forces at small distances (and di vide by zero)
> >                                       var direction = d.normalise();
> >
> >                                       // apply force to each end point
> >
> point1.applyForce(direction.multiply(this.repulsion).divide(distance *
> distance * 0.5));
> >                                       
point2.applyForce(direction.multiply(this.repulsion).divide(distance * 
distance * -0.5));
> >                               }
> >                       });
> >               });
> >       };
> >
> > Thanks in advance.
> >
>
>
>

Re: [foray] Thinking functionally

From:
Ali Baitam
Date:
2013-06-03 @ 12:56
Sean C.
Most of the time, I, like you did above, resort to thinking of a recursive
solution. But it is very likely that their is a much simpler solution using
the higher-level sequence api. Here is my solution on 4Clojure to the
compress a sequence:

```
(defn compress
  [s]
  (map first (partition-by identity s)))

(apply str (compress "aaaabccaadeeee") => "abcade"
```

That's why I decided to slow down and give myself more time to practice
this api before moving on to the state management and way behind in my
reading as well.


On Mon, Jun 3, 2013 at 8:19 AM, Sean Chalmers <sclhiannan@gmail.com> wrote:

> Continuing along the lines of wanting to think functionally, I've actually
> been dabbling with some Haskell and having a crack at some of the 99
> Haskell problems and it's actually been helping me with thinking
> functionally (Strangely enough). Regrettably I've not been able to progress
> through the book at all so I'm waaaayyyy behind everybody.. :(
>
> One of the cool problems was the 'compress' problem...
>
> (compress "aaaabbbcccaaadddddeeee")
> > "abcade"
>
> This is about as close as I've managed to get and I was wondering if
> anyone had any thoughts...
>
> (defn compress [x]
>   (let [a (first x) b (rest x)]
>     (if (= a (first b))
>       (when-not (empty? (rest b))
>         (cons a (compress (rest b))))
>       (recur (rest x)))))
>
> I have a feeling I'm trying to be too clever for my own good... :\
>
> PS: It's about 10:20pm at the moment so if I don't reply I'm really not
> being rude, I'm asleep. ^.^
>
> --- Warning, Haskell Kool-Aid below :)
>
> This is my Haskell 'well it passes the test' solution... The second
> function is because I didn't like having the comparison twice and felt I
> could do better. :P
>
> import Data.List
>
> testList = "aaaabccaadeeee"
> desiredResult = "abcade"
>
> compress [] = []
> compress (x:y:xs)
>   | x == y && null xs = []
>   | x == y = [head xs] ++ compress xs
>   | otherwise = [y] ++ compress xs
>
> compressTwo [] = []
> compressTwo (x:y:xs) =
>   if x == y
>   then if null xs
>        then []
>        else [head xs] ++ compress xs
>   else compress (init xs)
>
> main = do
>   print $ compress testList == desiredResult
>   print $ compressTwo testList == desiredResult
>
>
> On 2 June 2013 18:01, Sean Corfield <sean@corfield.org> wrote:
>
>> Without knowing more about what applyForce() does and how results are
>> accumulated it's hard to say how best to convert this. It's inherently an
>> OOP statement of a problem, relying heavily on mutable state.
>>
>> The closest idiomatic Clojure would be a for comprehension with point1
>> and point2 both bound to the sequence of points in the force-directed data
>> structure, yielding ... well, I'm not quite sure at that point ... perhaps
>> a sequence of pairs of points with forces applied which you'd then group by
>> point and reduce to combine the forces?
>>
>> Sean
>>
>> On May 31, 2013, at 7:11 AM, Monte Johnston wrote:
>>
>> >
>> > I am slowly learning to think more functionally. As I was looking at
>> some javascript code and trying to implement it in Clojure, I got  stu ck.
>> >
>> > The javascript function operates on an array on the object. It loops
>> through the array, compar ing each item in the array to every other item in
>> the area, and updates each element with the results.
>> >
>> > Here is the code:
>> >
>> > Layout.ForceDirected.prototype.applyCoulombsLaw = function() {
>> >               this.eachNode(function(n1, point1) {
>> >                       this.eachNode(function(n2, point2) {
>> >                               if (point1 !== point2)
>> >                               {
>> >                                       var d =
>> point1.p.subtract(point2.p);
>> >                                       var distance = d.magnitude() +
>> 0.1; // avoid massive forces at small distances (and di vide by zero)
>> >                                       var direction = d.normalise();
>> >
>> >                                       // apply force to each end point
>> >
>> point1.applyForce(direction.multiply(this.repulsion).divide(distance *
>> distance * 0.5));
>> >                                       
point2.applyForce(direction.multiply(this.repulsion).divide(distance * 
distance * -0.5));
>> >                               }
>> >                       });
>> >               });
>> >       };
>> >
>> > Thanks in advance.
>> >
>>
>>
>>
>

Re: [foray] Thinking functionally

From:
Sean Williamson
Date:
2013-06-03 @ 16:11
+1 to Ali's answer

Having been through a good portion of the Haskell 99, I can say that 
MOST solutions are easily expressible in terms of map, foldl, or scanl.

Its a fantastic resource for learning to think about those 
functions/that sort of "traverse and reduce" mentality.

There is also this: 

http://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html,

if you would like to see the same problems expressed in a lisp.

Sean

On 6/3/13 5:56 AM, Ali Baitam wrote:
> Sean C.
> Most of the time, I, like you did above, resort to thinking of a 
> recursive solution. But it is very likely that their is a much simpler 
> solution using the higher-level sequence api. Here is my solution on 
> 4Clojure to the compress a sequence:
>
> ```
> (defn compress
>   [s]
>   (map first (partition-by identity s)))
>
> (apply str (compress "aaaabccaadeeee") => "abcade"
> ```
>
> That's why I decided to slow down and give myself more time to 
> practice this api before moving on to the state management and way 
> behind in my reading as well.
>
>
> On Mon, Jun 3, 2013 at 8:19 AM, Sean Chalmers <sclhiannan@gmail.com 
> <mailto:sclhiannan@gmail.com>> wrote:
>
>     Continuing along the lines of wanting to think functionally, I've
>     actually been dabbling with some Haskell and having a crack at
>     some of the 99 Haskell problems and it's actually been helping me
>     with thinking functionally (Strangely enough). Regrettably I've
>     not been able to progress through the book at all so I'm waaaayyyy
>     behind everybody.. :(
>
>     One of the cool problems was the 'compress' problem...
>
>     (compress "aaaabbbcccaaadddddeeee")
>     > "abcade"
>
>     This is about as close as I've managed to get and I was wondering
>     if anyone had any thoughts...
>
>     (defn compress [x]
>       (let [a (first x) b (rest x)]
>         (if (= a (first b))
>           (when-not (empty? (rest b))
>             (cons a (compress (rest b))))
>           (recur (rest x)))))
>
>     I have a feeling I'm trying to be too clever for my own good... :\
>
>     PS: It's about 10:20pm at the moment so if I don't reply I'm
>     really not being rude, I'm asleep. ^.^
>
>     --- Warning, Haskell Kool-Aid below :)
>
>     This is my Haskell 'well it passes the test' solution... The
>     second function is because I didn't like having the comparison
>     twice and felt I could do better. :P
>
>     import Data.List
>
>     testList = "aaaabccaadeeee"
>     desiredResult = "abcade"
>
>     compress [] = []
>     compress (x:y:xs)
>       | x == y && null xs = []
>       | x == y = [head xs] ++ compress xs
>       | otherwise = [y] ++ compress xs
>
>     compressTwo [] = []
>     compressTwo (x:y:xs) =
>       if x == y
>       then if null xs
>            then []
>            else [head xs] ++ compress xs
>       else compress (init xs)
>     main = do
>       print $ compress testList == desiredResult
>       print $ compressTwo testList == desiredResult
>
>
>     On 2 June 2013 18:01, Sean Corfield <sean@corfield.org
>     <mailto:sean@corfield.org>> wrote:
>
>         Without knowing more about what applyForce() does and how
>         results are accumulated it's hard to say how best to convert
>         this. It's inherently an OOP statement of a problem, relying
>         heavily on mutable state.
>
>         The closest idiomatic Clojure would be a for comprehension
>         with point1 and point2 both bound to the sequence of points in
>         the force-directed data structure, yielding ... well, I'm not
>         quite sure at that point ... perhaps a sequence of pairs of
>         points with forces applied which you'd then group by point and
>         reduce to combine the forces?
>
>         Sean
>
>         On May 31, 2013, at 7:11 AM, Monte Johnston wrote:
>
>         >
>         > I am slowly learning to think more functionally. As I was
>         looking at some javascript code and trying to implement it in
>         Clojure, I got  stu ck.
>         >
>         > The javascript function operates on an array on the object.
>         It loops through the array, compar ing each item in the array
>         to every other item in the area, and updates each element with
>         the results.
>         >
>         > Here is the code:
>         >
>         > Layout.ForceDirected.prototype.applyCoulombsLaw = function() {
>         >               this.eachNode(function(n1, point1) {
>         > this.eachNode(function(n2, point2) {
>         >                               if (point1 !== point2)
>         >                               {
>         >                                       var d =
>         point1.p.subtract(point2.p);
>         >                                       var distance =
>         d.magnitude() + 0.1; // avoid massive forces at small
>         distances (and di vide by zero)
>         >                                       var direction =
>         d.normalise();
>         >
>         >                                       // apply force to each
>         end point
>         >
>         point1.applyForce(direction.multiply(this.repulsion).divide(distance
>         * distance * 0.5));
>         > point2.applyForce(direction.mu <http://direction.mu>
>         ltiply(this.repulsion).divide(distance * distance * -0.5));
>         >                               }
>         >                       });
>         >               });
>         >       };
>         >
>         > Thanks in advance.
>         >
>
>
>
>

Re: [foray] Thinking functionally

From:
Sean Chalmers
Date:
2013-06-03 @ 22:04
Thanks Sean, I'll have a look at the 99 Lisp problems as 4Clojure has been
frustrating me of late. As Ali points out, when you encounter a need for
recursion it is likely that a higher level process exists to help you
through. But what I've found is that 4Clojure doesn't let you use that
function when solving that problem, so you have to come up with your own...

Maybe I just need to pull the problems from there and work on them without
the restrictions, because it frustrates me more than helps me. :(


On 4 June 2013 02:11, Sean Williamson <supernullset@wereprobablywrong.com>wrote:

>  +1 to Ali's answer
>
> Having been through a good portion of the Haskell 99, I can say that MOST
> solutions are easily expressible in terms of map, foldl, or scanl.
>
> Its a fantastic resource for learning to think about those functions/that
> sort of "traverse and reduce" mentality.
>
> There is also this:
> 
http://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html,
> if you would like to see the same problems expressed in a lisp.
>
> Sean
>
>
> On 6/3/13 5:56 AM, Ali Baitam wrote:
>
> Sean C.
> Most of the time, I, like you did above, resort to thinking of a recursive
> solution. But it is very likely that their is a much simpler solution using
> the higher-level sequence api. Here is my solution on 4Clojure to the
> compress a sequence:
>
>  ```
> (defn compress
>   [s]
>   (map first (partition-by identity s)))
>
>  (apply str (compress "aaaabccaadeeee") => "abcade"
> ```
>
>  That's why I decided to slow down and give myself more time to practice
> this api before moving on to the state management and way behind in my
> reading as well.
>
>
> On Mon, Jun 3, 2013 at 8:19 AM, Sean Chalmers <sclhiannan@gmail.com>wrote:
>
>> Continuing along the lines of wanting to think functionally, I've
>> actually been dabbling with some Haskell and having a crack at some of the
>> 99 Haskell problems and it's actually been helping me with thinking
>> functionally (Strangely enough). Regrettably I've not been able to progress
>> through the book at all so I'm waaaayyyy behind everybody.. :(
>>
>>  One of the cool problems was the 'compress' problem...
>>
>>  (compress "aaaabbbcccaaadddddeeee")
>>  > "abcade"
>>
>>  This is about as close as I've managed to get and I was wondering if
>> anyone had any thoughts...
>>
>>  (defn compress [x]
>>   (let [a (first x) b (rest x)]
>>     (if (= a (first b))
>>       (when-not (empty? (rest b))
>>         (cons a (compress (rest b))))
>>       (recur (rest x)))))
>>
>>  I have a feeling I'm trying to be too clever for my own good... :\
>>
>>  PS: It's about 10:20pm at the moment so if I don't reply I'm really not
>> being rude, I'm asleep. ^.^
>>
>>  --- Warning, Haskell Kool-Aid below :)
>>
>>  This is my Haskell 'well it passes the test' solution... The second
>> function is because I didn't like having the comparison twice and felt I
>> could do better. :P
>>
>>  import Data.List
>>
>>  testList = "aaaabccaadeeee"
>> desiredResult = "abcade"
>>
>>  compress [] = []
>> compress (x:y:xs)
>>   | x == y && null xs = []
>>   | x == y = [head xs] ++ compress xs
>>   | otherwise = [y] ++ compress xs
>>
>>  compressTwo [] = []
>> compressTwo (x:y:xs) =
>>    if x == y
>>   then if null xs
>>        then []
>>        else [head xs] ++ compress xs
>>   else compress (init xs)
>>
>> main = do
>>   print $ compress testList == desiredResult
>>   print $ compressTwo testList == desiredResult
>>
>>
>> On 2 June 2013 18:01, Sean Corfield <sean@corfield.org> wrote:
>>
>>> Without knowing more about what applyForce() does and how results are
>>> accumulated it's hard to say how best to convert this. It's inherently an
>>> OOP statement of a problem, relying heavily on mutable state.
>>>
>>> The closest idiomatic Clojure would be a for comprehension with point1
>>> and point2 both bound to the sequence of points in the force-directed data
>>> structure, yielding ... well, I'm not quite sure at that point ... perhaps
>>> a sequence of pairs of points with forces applied which you'd then group by
>>> point and reduce to combine the forces?
>>>
>>> Sean
>>>
>>> On May 31, 2013, at 7:11 AM, Monte Johnston wrote:
>>>
>>> >
>>> > I am slowly learning to think more functionally. As I was looking at
>>> some javascript code and trying to implement it in Clojure, I got  stu ck.
>>> >
>>> > The javascript function operates on an array on the object. It loops
>>> through the array, compar ing each item in the array to every other item in
>>> the area, and updates each element with the results.
>>> >
>>> > Here is the code:
>>> >
>>> > Layout.ForceDirected.prototype.applyCoulombsLaw = function() {
>>> >               this.eachNode(function(n1, point1) {
>>> >                       this.eachNode(function(n2, point2) {
>>> >                               if (point1 !== point2)
>>> >                               {
>>> >                                       var d =
>>> point1.p.subtract(point2.p);
>>> >                                       var distance = d.magnitude() +
>>> 0.1; // avoid massive forces at small distances (and di vide by zero)
>>> >                                       var direction = d.normalise();
>>> >
>>> >                                       // apply force to each end point
>>> >
>>> point1.applyForce(direction.multiply(this.repulsion).divide(distance *
>>> distance * 0.5));
>>> >                                       
point2.applyForce(direction.multiply(this.repulsion).divide(distance * 
distance * -0.5));
>>> >                               }
>>> >                       });
>>> >               });
>>> >       };
>>> >
>>> > Thanks in advance.
>>> >
>>>
>>>
>>>
>>
>
>

Re: [foray] Thinking functionally

From:
Sean Corfield
Date:
2013-06-03 @ 22:13
Well, even with partition-by being outlawed for compress, there's still a 
nice HOF approach to solving compress:

(defn compress [s]
  (apply str (reduce (fn [cs c] (if (= c (last cs)) s (conj cs c))) [] s))

The Other Sean

On Jun 3, 2013, at 3:04 PM, Sean Chalmers wrote:
> Thanks Sean, I'll have a look at the 99 Lisp problems as 4Clojure has 
been frustrating me of late. As Ali points out, when you encounter a need 
for recursion it is likely that a higher level process exists to help you 
through. But what I've found is that 4Clojure doesn't let you use that 
function when solving that problem, so you have to come up with your 
own... 
> 
> Maybe I just need to pull the problems from there and work on them 
without the restrictions, because it frustrates me more than helps me. :(

Re: [foray] Thinking functionally

From:
Sean Chalmers
Date:
2013-06-03 @ 22:16
Show off... :P

Thank you !! :)


On 4 June 2013 08:13, Sean Corfield <sean@corfield.org> wrote:

> Well, even with partition-by being outlawed for compress, there's still a
> nice HOF approach to solving compress:
>
> (defn compress [s]
>   (apply str (reduce (fn [cs c] (if (= c (last cs)) s (conj cs c))) [] s))
>
> The Other Sean
>
> On Jun 3, 2013, at 3:04 PM, Sean Chalmers wrote:
> > Thanks Sean, I'll have a look at the 99 Lisp problems as 4Clojure has
> been frustrating me of late. As Ali points out, when you encounter a need
> for recursion it is likely that a higher level process exists to help you
> through. But what I've found is that 4Clojure doesn't let you use that
> function when solving that problem, so you have to come up with your own...
> >
> > Maybe I just need to pull the problems from there and work on them
> without the restrictions, because it frustrates me more than helps me. :(
>
>
>

Re: [foray] Thinking functionally

From:
Sean Williamson
Date:
2013-06-03 @ 23:19
Wait, we have *three* Seans? How did I not catch this.

I propose the title "The Sean Triumvirate" or possibly "1(or 2 or 3) of 
Three"


On 6/3/13 3:16 PM, Sean Chalmers wrote:
> Show off... :P
>
> Thank you !! :)
>
>
> On 4 June 2013 08:13, Sean Corfield <sean@corfield.org 
> <mailto:sean@corfield.org>> wrote:
>
>     Well, even with partition-by being outlawed for compress, there's
>     still a nice HOF approach to solving compress:
>
>     (defn compress [s]
>       (apply str (reduce (fn [cs c] (if (= c (last cs)) s (conj cs
>     c))) [] s))
>
>     The Other Sean
>
>     On Jun 3, 2013, at 3:04 PM, Sean Chalmers wrote:
>     > Thanks Sean, I'll have a look at the 99 Lisp problems as
>     4Clojure has been frustrating me of late. As Ali points out, when
>     you encounter a need for recursion it is likely that a higher
>     level process exists to help you through. But what I've found is
>     that 4Clojure doesn't let you use that function when solving that
>     problem, so you have to come up with your own...
>     >
>     > Maybe I just need to pull the problems from there and work on
>     them without the restrictions, because it frustrates me more than
>     helps me. :(
>
>
>

Re: [foray] Thinking functionally

From:
Sean Corfield
Date:
2013-06-03 @ 23:26
There can be only one!

(do I get to pull the "old codger" card, given that I already have my AARP card?)

Sean The Elder

On Jun 3, 2013, at 4:19 PM, Sean Williamson wrote:
> Wait, we have *three* Seans? How did I not catch this.
> 
> I propose the title "The Sean Triumvirate" or possibly "1(or 2 or 3) of Three"
> 
> 
> On 6/3/13 3:16 PM, Sean Chalmers wrote:
>> Show off... :P
>> 
>> Thank you !! :)
>> 
>> 
>> On 4 June 2013 08:13, Sean Corfield <sean@corfield.org> wrote:
>> Well, even with partition-by being outlawed for compress, there's still
a nice HOF approach to solving compress:
>> 
>> (defn compress [s]
>>   (apply str (reduce (fn [cs c] (if (= c (last cs)) s (conj cs c))) [] s))
>> 
>> The Other Sean

Re: [foray] Thinking functionally

From:
Sean Williamson
Date:
2013-06-03 @ 23:31
lambda-battle to the stack overflow?

On 6/3/13 4:26 PM, Sean Corfield wrote:
> There can be only one!
>
> (do I get to pull the "old codger" card, given that I already have my 
> AARP card?)
>
> Sean The Elder
>
> On Jun 3, 2013, at 4:19 PM, Sean Williamson wrote:
>> Wait, we have *three* Seans? How did I not catch this.
>>
>> I propose the title "The Sean Triumvirate" or possibly "1(or 2 or 3) 
>> of Three"
>>
>>
>> On 6/3/13 3:16 PM, Sean Chalmers wrote:
>>> Show off... :P
>>>
>>> Thank you !! :)
>>>
>>>
>>> On 4 June 2013 08:13, Sean Corfield <sean@corfield.org 
>>> <mailto:sean@corfield.org>> wrote:
>>>
>>>     Well, even with partition-by being outlawed for compress,
>>>     there's still a nice HOF approach to solving compress:
>>>
>>>     (defn compress [s]
>>>       (apply str (reduce (fn [cs c] (if (= c (last cs)) s (conj cs
>>>     c))) [] s))
>>>
>>>     The Other Sean
>>>
>
>

Re: [foray] Thinking functionally

From:
Fumiko Hanreich
Date:
2013-06-03 @ 23:16
I ended up with the same idea as Sean's.

(defn compress [s]
  (reduce #(if (not= (last %1) %2) (str %1 %2) %1) "" s))

If only unique chars,
(defn compress-unique [s]
  (apply str (distinct s)))


On Mon, Jun 3, 2013 at 3:16 PM, Sean Chalmers <sclhiannan@gmail.com> wrote:

> Show off... :P
>
> Thank you !! :)
>
>
> On 4 June 2013 08:13, Sean Corfield <sean@corfield.org> wrote:
>
>> Well, even with partition-by being outlawed for compress, there's still a
>> nice HOF approach to solving compress:
>>
>> (defn compress [s]
>>   (apply str (reduce (fn [cs c] (if (= c (last cs)) s (conj cs c))) [] s))
>>
>> The Other Sean
>>
>> On Jun 3, 2013, at 3:04 PM, Sean Chalmers wrote:
>> > Thanks Sean, I'll have a look at the 99 Lisp problems as 4Clojure has
>> been frustrating me of late. As Ali points out, when you encounter a need
>> for recursion it is likely that a higher level process exists to help you
>> through. But what I've found is that 4Clojure doesn't let you use that
>> function when solving that problem, so you have to come up with your own...
>> >
>> > Maybe I just need to pull the problems from there and work on them
>> without the restrictions, because it frustrates me more than helps me. :(
>>
>>
>>
>

Re: [foray] Thinking functionally

From:
Sean Corfield
Date:
2013-06-03 @ 23:33
On Jun 3, 2013, at 4:16 PM, Fumiko Hanreich wrote:
> I ended up with the same idea as Sean's.
> 
> (defn compress [s]
>   (reduce #(if (not= (last %1) %2) (str %1 %2) %1) "" s))

Very nice!!

I realized after posting my solution - and it applies to yours too - that 
`last` is O(n) so it's not very efficient for long strings. I'd assumed 
(incorrectly) that `(last some-vector)` would be optimized to be O(1) but 
it's a simple recursive walk of the collection.

The efficient way to do `last` - on both String and vector - is (nth % 
(dec (count %))) as far as I can see although for String, resorting 
directly to the underlying Java API is going to be even faster.

Mind you, if you're that obsessed with performance, concatenating strings 
won't cut it either so perhaps we shouldn't even bother worrying about 
performance at all for a challenge like this... :)

Sean A 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)



Re: [foray] Thinking functionally

From:
Fumiko Hanreich
Date:
2013-06-03 @ 23:40
Thank you so much, Sean :)  You should know I'm almost obsessed with
O-notation ;-)  So, this is very informative for me.  As our data becomes
larger and I mostly work with finite set of data, I will keep this info in
mind.  Thank you!

P.S. Remember I also got burnt by drop-last recently.  This is all really
good for me ;-)


On Mon, Jun 3, 2013 at 4:33 PM, Sean Corfield <sean@corfield.org> wrote:

> On Jun 3, 2013, at 4:16 PM, Fumiko Hanreich wrote:
> > I ended up with the same idea as Sean's.
> >
> > (defn compress [s]
> >   (reduce #(if (not= (last %1) %2) (str %1 %2) %1) "" s))
>
> Very nice!!
>
> I realized after posting my solution - and it applies to yours too - that
> `last` is O(n) so it's not very efficient for long strings. I'd assumed
> (incorrectly) that `(last some-vector)` would be optimized to be O(1) but
> it's a simple recursive walk of the collection.
>
> The efficient way to do `last` - on both String and vector - is (nth %
> (dec (count %))) as far as I can see although for String, resorting
> directly to the underlying Java API is going to be even faster.
>
> Mind you, if you're that obsessed with performance, concatenating strings
> won't cut it either so perhaps we shouldn't even bother worrying about
> performance at all for a challenge like this... :)
>
> Sean A 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)
>
>
>
>
>

Re: [foray] Thinking functionally

From:
Sean Chalmers
Date:
2013-06-03 @ 23:45
I'm going to have to set aside Fumiko's solution for dissection later, it
looks amazing!

Looking to sell university projects... willing to trade for time to spend
on Clojure/Haskell ... -.-


On 4 June 2013 09:40, Fumiko Hanreich <fhanreich@gmail.com> wrote:

> Thank you so much, Sean :)  You should know I'm almost obsessed with
> O-notation ;-)  So, this is very informative for me.  As our data becomes
> larger and I mostly work with finite set of data, I will keep this info in
> mind.  Thank you!
>
> P.S. Remember I also got burnt by drop-last recently.  This is all really
> good for me ;-)
>
>
> On Mon, Jun 3, 2013 at 4:33 PM, Sean Corfield <sean@corfield.org> wrote:
>
>> On Jun 3, 2013, at 4:16 PM, Fumiko Hanreich wrote:
>> > I ended up with the same idea as Sean's.
>> >
>> > (defn compress [s]
>> >   (reduce #(if (not= (last %1) %2) (str %1 %2) %1) "" s))
>>
>> Very nice!!
>>
>> I realized after posting my solution - and it applies to yours too - that
>> `last` is O(n) so it's not very efficient for long strings. I'd assumed
>> (incorrectly) that `(last some-vector)` would be optimized to be O(1) but
>> it's a simple recursive walk of the collection.
>>
>> The efficient way to do `last` - on both String and vector - is (nth %
>> (dec (count %))) as far as I can see although for String, resorting
>> directly to the underlying Java API is going to be even faster.
>>
>> Mind you, if you're that obsessed with performance, concatenating strings
>> won't cut it either so perhaps we shouldn't even bother worrying about
>> performance at all for a challenge like this... :)
>>
>> Sean A 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)
>>
>>
>>
>>
>>
>

Re: [foray] Thinking functionally

From:
Sean Williamson
Date:
2013-06-04 @ 16:04
The comments on O notation got me thinking: Is there a Clojure doc 
resource that shows the O complexity for functions on collections?


On 6/3/13 4:45 PM, Sean Chalmers wrote:
> I'm going to have to set aside Fumiko's solution for dissection later, 
> it looks amazing!
>
> Looking to sell university projects... willing to trade for time to 
> spend on Clojure/Haskell ... -.-
>
>
> On 4 June 2013 09:40, Fumiko Hanreich <fhanreich@gmail.com 
> <mailto:fhanreich@gmail.com>> wrote:
>
>     Thank you so much, Sean :)  You should know I'm almost obsessed
>     with O-notation ;-)  So, this is very informative for me.  As our
>     data becomes larger and I mostly work with finite set of data, I
>     will keep this info in mind.  Thank you!
>
>     P.S. Remember I also got burnt by drop-last recently. This is all
>     really good for me ;-)
>
>
>     On Mon, Jun 3, 2013 at 4:33 PM, Sean Corfield <sean@corfield.org
>     <mailto:sean@corfield.org>> wrote:
>
>         On Jun 3, 2013, at 4:16 PM, Fumiko Hanreich wrote:
>         > I ended up with the same idea as Sean's.
>         >
>         > (defn compress [s]
>         >   (reduce #(if (not= (last %1) %2) (str %1 %2) %1) "" s))
>
>         Very nice!!
>
>         I realized after posting my solution - and it applies to yours
>         too - that `last` is O(n) so it's not very efficient for long
>         strings. I'd assumed (incorrectly) that `(last some-vector)`
>         would be optimized to be O(1) but it's a simple recursive walk
>         of the collection.
>
>         The efficient way to do `last` - on both String and vector -
>         is (nth % (dec (count %))) as far as I can see although for
>         String, resorting directly to the underlying Java API is going
>         to be even faster.
>
>         Mind you, if you're that obsessed with performance,
>         concatenating strings won't cut it either so perhaps we
>         shouldn't even bother worrying about performance at all for a
>         challenge like this... :)
>
>         Sean A 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)
>
>
>
>
>
>

Re: [foray] Thinking functionally

From:
Sean Corfield
Date:
2013-06-06 @ 00:05
http://clojure.org/data_structures#Data Structures-Collections - this
states O(1) / O(n) etc for various operations on various collections.


On Tue, Jun 4, 2013 at 9:04 AM, Sean Williamson <
supernullset@wereprobablywrong.com> wrote:

>  The comments on O notation got me thinking: Is there a Clojure doc
> resource that shows the O complexity for functions on collections?
>
>
>
> On 6/3/13 4:45 PM, Sean Chalmers wrote:
>
> I'm going to have to set aside Fumiko's solution for dissection later, it
> looks amazing!
>
>  Looking to sell university projects... willing to trade for time to
> spend on Clojure/Haskell ... -.-
>
>
> On 4 June 2013 09:40, Fumiko Hanreich <fhanreich@gmail.com> wrote:
>
>>  Thank you so much, Sean :)  You should know I'm almost obsessed with
>> O-notation ;-)  So, this is very informative for me.  As our data becomes
>> larger and I mostly work with finite set of data, I will keep this info in
>> mind.  Thank you!
>>
>>  P.S. Remember I also got burnt by drop-last recently.  This is all
>> really good for me ;-)
>>
>>
>> On Mon, Jun 3, 2013 at 4:33 PM, Sean Corfield <sean@corfield.org> wrote:
>>
>>> On Jun 3, 2013, at 4:16 PM, Fumiko Hanreich wrote:
>>> > I ended up with the same idea as Sean's.
>>> >
>>> > (defn compress [s]
>>> >   (reduce #(if (not= (last %1) %2) (str %1 %2) %1) "" s))
>>>
>>>  Very nice!!
>>>
>>> I realized after posting my solution - and it applies to yours too -
>>> that `last` is O(n) so it's not very efficient for long strings. I'd
>>> assumed (incorrectly) that `(last some-vector)` would be optimized to be
>>> O(1) but it's a simple recursive walk of the collection.
>>>
>>> The efficient way to do `last` - on both String and vector - is (nth %
>>> (dec (count %))) as far as I can see although for String, resorting
>>> directly to the underlying Java API is going to be even faster.
>>>
>>> Mind you, if you're that obsessed with performance, concatenating
>>> strings won't cut it either so perhaps we shouldn't even bother worrying
>>> about performance at all for a challenge like this... :)
>>>
>>> Sean A 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)
>>>
>>>
>>>
>>>
>>>
>>
>
>