Re: is there a way to use drip to speed up the running of unit tests?

2016-06-26 Thread Daniel Compton
I would recommend looking at bolth . It’s
an extremely fast test runner, has nice stacktraces, diffs, e.t.c.

On Mon, Jun 27, 2016 at 6:28 AM Alan Thompson  wrote:

> I also highly recommend test-refersh!
> Alan
>
> On Sat, Jun 25, 2016 at 8:47 AM, Jake McCrary 
> wrote:
>
>> Hi Fenton,
>>
>> In my experience the way to get faster feedback from your tests is to
>> have them run in a way that doesn’t require stopping and starting a
>> process. This can be done by either evaluating your tests in a REPL or
>> using one of the Clojure testing tools that reload your code and run your
>> tests on changes. My preference is using a tool to manage reloading my code
>> and rerunning my tests.
>>
>> If you’re using clojure.test there are a few such tools but I’ll
>> recommend lein-test-refresh
>>  (I’m biased given that it
>> is the one I wrote). If you scroll to the bottom of this article
>> 
>> you’ll see my recommended settings for turning on some of
>> lein-test-refresh's advanced settings. Some more information can be found
>> in this
>> 
>> Clojure mailing list message.
>>
>> If you’re using expectations 
>> then there is also lein-autoexpect
>>  for running your tests on
>> code change. Midje and speclj have their own autotest runners.
>>
>> On Thursday, June 23, 2016 at 4:13:34 PM UTC-5, Fenton Travers wrote:
>>
>> is there a way to use drip to speed up the running of unit tests?
>>>
>>> I'm not sure if there is way to use drip to speed up the launching and
>>> running of tests, but that would be great if there was.
>>>
>> ​
>>
>> --
>> 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.
>
-- 
—
Daniel

-- 
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: Avoiding repetition while still using 'recur'

2016-06-26 Thread Botond Balázs
I didn't know that reduction can be stopped with reduced. Thanks Andy!

On Sunday, June 26, 2016 at 10:08:47 PM UTC+2, Andy- wrote:
>
> To add a little variant of James Reeve's code: You can avoid the 
> loop/recur by using reduce:
>
>
> (defn valid-parens? [s]
>   (let [opening-brackets {\( \), \[ \], \{ \}}
> closing-brackets (clojure.set/map-invert opening-brackets)]
> (empty?
>   (reduce
> (fn [stack c]
>   (if (opening-brackets c)
> (conj stack c)
> (if-let [b (closing-brackets c)]
>   (if (= (peek stack) b)
> (pop stack)
> (reduced [false]))
>   stack)))
> []
> (seq s)
>
>
> HTH
>
> On Sunday, June 26, 2016 at 4:06:27 PM UTC+2, Botond Balázs wrote:
>>
>> Thanks guys.
>>
>> Very nice and simple solution, James.
>>
>> On Sunday, June 26, 2016 at 3:21:56 PM UTC+2, James Reeves wrote:
>>>
>>> The easiest way would be to factor out the bracket matching code, since 
>>> that's the only thing that changes between your different case statements. 
>>> For instance:
>>>
>>>   (defn valid-parens? [s]
>>> (let [opening-brackets {\( \), \[ \], \{ \}}
>>>   closing-brackets (clojure.set/map-invert opening-brackets)]
>>>   (loop [cs (seq s), stack []]
>>> (if-not cs
>>>   (empty? stack)
>>>   (let [c (first cs), cs (next cs)]
>>> (if (opening-brackets c)
>>>   (recur cs (conj stack c))
>>>   (if-let [b (closing-brackets c)]
>>> (if (= (peek stack) b)
>>>   (recur cs (pop stack))
>>>   false)
>>> (recur cs stack)))
>>>
>>> Another way you could do it is to replace your recursive call with a 
>>> continuation.
>>>
>>> - James
>>>
>>> On 26 June 2016 at 13:43, Botond Balázs  wrote:
>>>
 Hi,

 Here is my solution to 4clojure problem #177:

 Write a function that takes in a string and returns truthy if all 
> square [ ] round ( ) and curly { } brackets are properly paired and 
> legally 
> nested, or returns falsey otherwise.
>

 (defn valid-parens?
   [s]
   (loop [[ch & chs] s stack []]
 (if (nil? ch)
   (empty? stack)
   (case ch
 (\( \[ \{) (recur chs (conj stack ch))
 \) (if (= (peek stack) \()
  (recur chs (pop stack))
  false)
 \] (if (= (peek stack) \[)
  (recur chs (pop stack))
  false)
 \} (if (= (peek stack) \{)
  (recur chs (pop stack))
  false)
 (recur chs stack)

 This works but I don't like the repetition in the case branches. But 
 the repeated code contains a recur call so I can't simply refactor it 
 into a helper function. How can I achieves something like the following, 
 but without consuming the stack?

 (defn valid-parens?
   ([s]
(valid-parens? s []))
   ([[ch & chs] stack]
(if (nil? ch)
  (empty? stack)
  (letfn [(match? [p]
(if (= (peek stack) p)
  (valid-parens? chs (pop stack))
  false))]
(case ch
  (\( \[ \{) (valid-parens? chs (conj stack ch))
  \) (match? \()
  \] (match? \[)
  \} (match? \{)
  (valid-parens? chs stack))

 Thanks!
 Botond

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

Workshop report: Generative design systems with Clojure

2016-06-26 Thread Karsten Schmidt
Hi everyone,

last week I've been teaching a 2-day workshop about building
generative design systems with Clojure and have just published a
report incl. various outputs & code samples produced:

https://medium.com/@thi.ng/workshop-report-generative-design-with-clojure-7d6d8ea9a6e8#.mai46g3no

Since this isn't a very much talked about topic in this community, I
hope some of you find it interesting...

Best, K.
-- 
Karsten Schmidt
http://thi.ng

-- 
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: Avoiding repetition while still using 'recur'

2016-06-26 Thread Andy-
To add a little variant of James Reeve's code: You can avoid the loop/recur 
by using reduce:


(defn valid-parens? [s]
  (let [opening-brackets {\( \), \[ \], \{ \}}
closing-brackets (clojure.set/map-invert opening-brackets)]
(empty?
  (reduce
(fn [stack c]
  (if (opening-brackets c)
(conj stack c)
(if-let [b (closing-brackets c)]
  (if (= (peek stack) b)
(pop stack)
(reduced [false]))
  stack)))
[]
(seq s)


HTH

On Sunday, June 26, 2016 at 4:06:27 PM UTC+2, Botond Balázs wrote:
>
> Thanks guys.
>
> Very nice and simple solution, James.
>
> On Sunday, June 26, 2016 at 3:21:56 PM UTC+2, James Reeves wrote:
>>
>> The easiest way would be to factor out the bracket matching code, since 
>> that's the only thing that changes between your different case statements. 
>> For instance:
>>
>>   (defn valid-parens? [s]
>> (let [opening-brackets {\( \), \[ \], \{ \}}
>>   closing-brackets (clojure.set/map-invert opening-brackets)]
>>   (loop [cs (seq s), stack []]
>> (if-not cs
>>   (empty? stack)
>>   (let [c (first cs), cs (next cs)]
>> (if (opening-brackets c)
>>   (recur cs (conj stack c))
>>   (if-let [b (closing-brackets c)]
>> (if (= (peek stack) b)
>>   (recur cs (pop stack))
>>   false)
>> (recur cs stack)))
>>
>> Another way you could do it is to replace your recursive call with a 
>> continuation.
>>
>> - James
>>
>> On 26 June 2016 at 13:43, Botond Balázs  wrote:
>>
>>> Hi,
>>>
>>> Here is my solution to 4clojure problem #177:
>>>
>>> Write a function that takes in a string and returns truthy if all square 
 [ ] round ( ) and curly { } brackets are properly paired and legally 
 nested, or returns falsey otherwise.

>>>
>>> (defn valid-parens?
>>>   [s]
>>>   (loop [[ch & chs] s stack []]
>>> (if (nil? ch)
>>>   (empty? stack)
>>>   (case ch
>>> (\( \[ \{) (recur chs (conj stack ch))
>>> \) (if (= (peek stack) \()
>>>  (recur chs (pop stack))
>>>  false)
>>> \] (if (= (peek stack) \[)
>>>  (recur chs (pop stack))
>>>  false)
>>> \} (if (= (peek stack) \{)
>>>  (recur chs (pop stack))
>>>  false)
>>> (recur chs stack)
>>>
>>> This works but I don't like the repetition in the case branches. But 
>>> the repeated code contains a recur call so I can't simply refactor it 
>>> into a helper function. How can I achieves something like the following, 
>>> but without consuming the stack?
>>>
>>> (defn valid-parens?
>>>   ([s]
>>>(valid-parens? s []))
>>>   ([[ch & chs] stack]
>>>(if (nil? ch)
>>>  (empty? stack)
>>>  (letfn [(match? [p]
>>>(if (= (peek stack) p)
>>>  (valid-parens? chs (pop stack))
>>>  false))]
>>>(case ch
>>>  (\( \[ \{) (valid-parens? chs (conj stack ch))
>>>  \) (match? \()
>>>  \] (match? \[)
>>>  \} (match? \{)
>>>  (valid-parens? chs stack))
>>>
>>> Thanks!
>>> Botond
>>>
>>> -- 
>>> 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: is there a way to use drip to speed up the running of unit tests?

2016-06-26 Thread Alan Thompson
I also highly recommend test-refersh!
Alan

On Sat, Jun 25, 2016 at 8:47 AM, Jake McCrary  wrote:

> Hi Fenton,
>
> In my experience the way to get faster feedback from your tests is to have
> them run in a way that doesn’t require stopping and starting a process.
> This can be done by either evaluating your tests in a REPL or using one of
> the Clojure testing tools that reload your code and run your tests on
> changes. My preference is using a tool to manage reloading my code and
> rerunning my tests.
>
> If you’re using clojure.test there are a few such tools but I’ll recommend
> lein-test-refresh  (I’m
> biased given that it is the one I wrote). If you scroll to the bottom of this
> article
> 
> you’ll see my recommended settings for turning on some of
> lein-test-refresh's advanced settings. Some more information can be found
> in this
> 
> Clojure mailing list message.
>
> If you’re using expectations 
> then there is also lein-autoexpect
>  for running your tests on
> code change. Midje and speclj have their own autotest runners.
>
> On Thursday, June 23, 2016 at 4:13:34 PM UTC-5, Fenton Travers wrote:
>
> is there a way to use drip to speed up the running of unit tests?
>>
>> I'm not sure if there is way to use drip to speed up the launching and
>> running of tests, but that would be great if there was.
>>
> ​
>
> --
> 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: Avoiding repetition while still using 'recur'

2016-06-26 Thread Botond Balázs
Thanks guys.

Very nice and simple solution, James.

On Sunday, June 26, 2016 at 3:21:56 PM UTC+2, James Reeves wrote:
>
> The easiest way would be to factor out the bracket matching code, since 
> that's the only thing that changes between your different case statements. 
> For instance:
>
>   (defn valid-parens? [s]
> (let [opening-brackets {\( \), \[ \], \{ \}}
>   closing-brackets (clojure.set/map-invert opening-brackets)]
>   (loop [cs (seq s), stack []]
> (if-not cs
>   (empty? stack)
>   (let [c (first cs), cs (next cs)]
> (if (opening-brackets c)
>   (recur cs (conj stack c))
>   (if-let [b (closing-brackets c)]
> (if (= (peek stack) b)
>   (recur cs (pop stack))
>   false)
> (recur cs stack)))
>
> Another way you could do it is to replace your recursive call with a 
> continuation.
>
> - James
>
> On 26 June 2016 at 13:43, Botond Balázs 
> > wrote:
>
>> Hi,
>>
>> Here is my solution to 4clojure problem #177:
>>
>> Write a function that takes in a string and returns truthy if all square 
>>> [ ] round ( ) and curly { } brackets are properly paired and legally 
>>> nested, or returns falsey otherwise.
>>>
>>
>> (defn valid-parens?
>>   [s]
>>   (loop [[ch & chs] s stack []]
>> (if (nil? ch)
>>   (empty? stack)
>>   (case ch
>> (\( \[ \{) (recur chs (conj stack ch))
>> \) (if (= (peek stack) \()
>>  (recur chs (pop stack))
>>  false)
>> \] (if (= (peek stack) \[)
>>  (recur chs (pop stack))
>>  false)
>> \} (if (= (peek stack) \{)
>>  (recur chs (pop stack))
>>  false)
>> (recur chs stack)
>>
>> This works but I don't like the repetition in the case branches. But the 
>> repeated code contains a recur call so I can't simply refactor it into a 
>> helper function. How can I achieves something like the following, but 
>> without consuming the stack?
>>
>> (defn valid-parens?
>>   ([s]
>>(valid-parens? s []))
>>   ([[ch & chs] stack]
>>(if (nil? ch)
>>  (empty? stack)
>>  (letfn [(match? [p]
>>(if (= (peek stack) p)
>>  (valid-parens? chs (pop stack))
>>  false))]
>>(case ch
>>  (\( \[ \{) (valid-parens? chs (conj stack ch))
>>  \) (match? \()
>>  \] (match? \[)
>>  \} (match? \{)
>>  (valid-parens? chs stack))
>>
>> Thanks!
>> Botond
>>
>> -- 
>> 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: Avoiding repetition while still using 'recur'

2016-06-26 Thread James Reeves
The easiest way would be to factor out the bracket matching code, since
that's the only thing that changes between your different case statements.
For instance:

  (defn valid-parens? [s]
(let [opening-brackets {\( \), \[ \], \{ \}}
  closing-brackets (clojure.set/map-invert opening-brackets)]
  (loop [cs (seq s), stack []]
(if-not cs
  (empty? stack)
  (let [c (first cs), cs (next cs)]
(if (opening-brackets c)
  (recur cs (conj stack c))
  (if-let [b (closing-brackets c)]
(if (= (peek stack) b)
  (recur cs (pop stack))
  false)
(recur cs stack)))

Another way you could do it is to replace your recursive call with a
continuation.

- James

On 26 June 2016 at 13:43, Botond Balázs  wrote:

> Hi,
>
> Here is my solution to 4clojure problem #177:
>
> Write a function that takes in a string and returns truthy if all square [
>> ] round ( ) and curly { } brackets are properly paired and legally nested,
>> or returns falsey otherwise.
>>
>
> (defn valid-parens?
>   [s]
>   (loop [[ch & chs] s stack []]
> (if (nil? ch)
>   (empty? stack)
>   (case ch
> (\( \[ \{) (recur chs (conj stack ch))
> \) (if (= (peek stack) \()
>  (recur chs (pop stack))
>  false)
> \] (if (= (peek stack) \[)
>  (recur chs (pop stack))
>  false)
> \} (if (= (peek stack) \{)
>  (recur chs (pop stack))
>  false)
> (recur chs stack)
>
> This works but I don't like the repetition in the case branches. But the
> repeated code contains a recur call so I can't simply refactor it into a
> helper function. How can I achieves something like the following, but
> without consuming the stack?
>
> (defn valid-parens?
>   ([s]
>(valid-parens? s []))
>   ([[ch & chs] stack]
>(if (nil? ch)
>  (empty? stack)
>  (letfn [(match? [p]
>(if (= (peek stack) p)
>  (valid-parens? chs (pop stack))
>  false))]
>(case ch
>  (\( \[ \{) (valid-parens? chs (conj stack ch))
>  \) (match? \()
>  \] (match? \[)
>  \} (match? \{)
>  (valid-parens? chs stack))
>
> Thanks!
> Botond
>
> --
> 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: Avoiding repetition while still using 'recur'

2016-06-26 Thread Colin Yates
Skimming through but that `case` resolves to either false or a recur
so sure you can move that case to an helper fn which returns true or
false. If false then `return` else `recur`?

On 26 June 2016 at 13:43, Botond Balázs  wrote:
> Hi,
>
> Here is my solution to 4clojure problem #177:
>
>> Write a function that takes in a string and returns truthy if all square [
>> ] round ( ) and curly { } brackets are properly paired and legally nested,
>> or returns falsey otherwise.
>
>
> (defn valid-parens?
>   [s]
>   (loop [[ch & chs] s stack []]
> (if (nil? ch)
>   (empty? stack)
>   (case ch
> (\( \[ \{) (recur chs (conj stack ch))
> \) (if (= (peek stack) \()
>  (recur chs (pop stack))
>  false)
> \] (if (= (peek stack) \[)
>  (recur chs (pop stack))
>  false)
> \} (if (= (peek stack) \{)
>  (recur chs (pop stack))
>  false)
> (recur chs stack)
>
> This works but I don't like the repetition in the case branches. But the
> repeated code contains a recur call so I can't simply refactor it into a
> helper function. How can I achieves something like the following, but
> without consuming the stack?
>
> (defn valid-parens?
>   ([s]
>(valid-parens? s []))
>   ([[ch & chs] stack]
>(if (nil? ch)
>  (empty? stack)
>  (letfn [(match? [p]
>(if (= (peek stack) p)
>  (valid-parens? chs (pop stack))
>  false))]
>(case ch
>  (\( \[ \{) (valid-parens? chs (conj stack ch))
>  \) (match? \()
>  \] (match? \[)
>  \} (match? \{)
>  (valid-parens? chs stack))
>
> Thanks!
> Botond
>
> --
> 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.


Avoiding repetition while still using 'recur'

2016-06-26 Thread Botond Balázs
Hi,

Here is my solution to 4clojure problem #177:

Write a function that takes in a string and returns truthy if all square [ 
> ] round ( ) and curly { } brackets are properly paired and legally nested, 
> or returns falsey otherwise.
>

(defn valid-parens?
  [s]
  (loop [[ch & chs] s stack []]
(if (nil? ch)
  (empty? stack)
  (case ch
(\( \[ \{) (recur chs (conj stack ch))
\) (if (= (peek stack) \()
 (recur chs (pop stack))
 false)
\] (if (= (peek stack) \[)
 (recur chs (pop stack))
 false)
\} (if (= (peek stack) \{)
 (recur chs (pop stack))
 false)
(recur chs stack)

This works but I don't like the repetition in the case branches. But the 
repeated code contains a recur call so I can't simply refactor it into a 
helper function. How can I achieves something like the following, but 
without consuming the stack?

(defn valid-parens?
  ([s]
   (valid-parens? s []))
  ([[ch & chs] stack]
   (if (nil? ch)
 (empty? stack)
 (letfn [(match? [p]
   (if (= (peek stack) p)
 (valid-parens? chs (pop stack))
 false))]
   (case ch
 (\( \[ \{) (valid-parens? chs (conj stack ch))
 \) (match? \()
 \] (match? \[)
 \} (match? \{)
 (valid-parens? chs stack))

Thanks!
Botond

-- 
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 for the Brave and True - infix notation exercise

2016-06-26 Thread Botond Balázs
Thanks miner!

On Friday, June 24, 2016 at 10:20:54 PM UTC+2, miner wrote:
>
> Not exactly the same problem, but you might like to see an infix 
> implementation from “The Joy of Clojure” by Fogus and Chouser. 
>
> http://fogus.me/fun/unfix/infix-src.html 
>
> The “Joy” code makes intermediate calculations as it goes.  I tweaked it a 
> bit to make a data-reader that only does the infix to prefix 
> transformation.  That’s probably closer to what you want. 
>
> https://gist.github.com/miner/5224709 
>
> Note: the “Joy” code uses vector notation for grouping.  You would have to 
> adapt it to use lists. 
>
> Here’s the relevant code from my gist, leaving out the data-reader part: 
>
> (def && #(and % %2)) 
> (def || #(or  % %2)) 
>
> (def ops '[- + * / < > && || =]) 
> (def rank (zipmap ops (iterate inc 1))) 
> (def op? rank) 
>
> (defn infix 
>   [[a b & [c d e & m]]] 
>   (cond 
>(vector? a) (recur (list* (infix a) b c d e m)) 
>(vector? c) (recur (list* a b (infix c) d e m)) 
>(op? b) (if (and d (< (rank b 0) (rank d 0))) 
>  (recur (list a b (infix (list* c d e m 
>  (recur (list* (list b a c) d e m))) 
>:else a)) 
>
> ;; example 
> (infix '[1 + 3 * 4 - 5]) 
> ;=> (+ 1 (- (* 3 4) 5)) 
>
>
> > On Jun 24, 2016, at 2:28 PM, Botond Balázs  > wrote: 
> > 
> > Hi, 
> > 
> > I'm working through Clojure for the Brave and True and there's a little 
> exercise at the end of Chapter 7: 
> > 
> > Create an infix function that takes a list like (1 + 3 * 4 - 5) and 
> transforms it into the lists that Clojure needs in order to correctly 
> evaluate the expression using operator precedence rules. 
> > 
> > I ended up implementing the shunting yard algorithm in Clojure to solve 
> it (65 lines, many functions), but I have the suspicion that this exercise 
> isn't meant to be this complicated and that I'm missing a very obvious and 
> elegant solution. What do you think? 
> > 
> > Thanks, 
> > Botond 
>
>

-- 
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 for the Brave and True - infix notation exercise

2016-06-26 Thread Botond Balázs
Thank you Jason, this is indeed a much nicer solution.

On Friday, June 24, 2016 at 8:51:26 PM UTC+2, Jason Felice wrote:
>
> Recursive descent parsers are much smaller for simple cases.  Basically, 
> you write one function per level of precedence, and each tries, greedily, 
> to consume as much as possible for that level of precedence.  e.g.
>
> (defn parse-level1 ;; + and -
>   [list]
>   ... ; calls parse-level2 repeatedly so long as next operator is + or -
>   [l1-expr remaining-tokens])
>
> (defn parse-level2 ;; * and /
>   ... ; calls parse-level3 repeatedly so long as next operator is * or /
>   [list]
>   ...
>   [l2-expr remaining-tokens])
>
> (defn parse-level3 ;; numbers
>   [list]
>   (if (number? list)
> [(first list) (rest list)]))
>
>
>
> On Fri, Jun 24, 2016 at 2:28 PM, Botond Balázs  > wrote:
>
>> Hi,
>>
>> I'm working through Clojure for the Brave and True and there's a little 
>> exercise at the end of Chapter 7 
>> :
>>
>> Create an infix function that takes a list like (1 + 3 * 4 - 5) and 
>>> transforms it into the lists that Clojure needs in order to correctly 
>>> evaluate the expression using operator precedence rules.
>>
>>
>> I ended up implementing the shunting yard algorithm 
>>  in Clojure to 
>> solve it (65 lines, many functions), but I have the suspicion that this 
>> exercise isn't meant to be this complicated and that I'm missing a very 
>> obvious and elegant solution. What do you think?
>>
>> Thanks,
>> Botond
>>
>> -- 
>> 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.