Change platform for reader conditionals

2018-07-18 Thread Nikita Beloglazov
Hi

Is it possible to read a string containing reader conditionals using a
platform different from "current". In particular in from clojure I want to
read a string that contains :cljs reader conditionals and evaluate them as
if current platform is cljs.

Example: if I run the following code from clj:

(read-string {:read-cond :allow} "#?(:clj 1 :cljs 2)")

then I get 1. But I want to get 2. Is there a way to do it in Clojure
somehow or maybe using tools.reader?

Thanks,
Nikita

-- 
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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Didier

>
> Concat does the job except for keeping the input collection type.  It will 
> seq anything you throw at it.
>

But that should not matter to a beginner. I mean, if you are at the point 
where you are teaching people the differences between the data structures, 
than teach them the difference between list, vector and seq, and that 
includes the behavior of conj. Otherwise, if not for performance, there's 
no difference between these, they're all ordered collections of items.


On Wednesday, 18 July 2018 04:04:36 UTC-7, Gary Trakhman wrote:
>
> Concat does the job except for keeping the input collection type.  It will 
> seq anything you throw at it.
>
> There's a general trade-off here. When I started working in ocaml recently 
> I was taken aback that the List.map call we used constantly would have to 
> build the new list backwards in linear time, and then reverse it in linear 
> time, with some crazy stack expansions as an optimization for smaller 
> lists. I've said stuff like 'i would be happy to have a map call that 
> changed type on me sometimes', but honestly I've never had to dig that deep 
> for performance, and when I do, it's to switch to a more async-incremental 
> Pipe thing analogous to core.async chans.
>
> On Wed, Jul 18, 2018, 3:16 AM Didier > 
> wrote:
>
>> It's never a good idea to use the wrong data structure for the job.
>>
>> And thus Clojure takes the stance that it won't make bad ideas easy for 
>> you to use. Yet, it will never prevent you from doing anything.
>>
>> If you want to do something bad, you'll need to get your own hands dirty.
>>
>> That's why slow data structure access functions don't exist as standard. 
>> That's why data transforms are lazy by default. And why the non lazy 
>> variant (transducers) do loop fusion for you. That's why mutability is ugly 
>> and requires you to wrap things in extra verbosity. That's why OOP isn't 
>> there, and forces you to use the host interop if you want it. That's why 
>> there's only recursive loops. Etc.
>>
>> The Clojure standard lib is opinionated. It's not trying to make 
>> everything easy and convenient. It's trying to make things simple to reason 
>> about, and promote Rich Hickeys opinion of what is a good idea, and what 
>> isn't.
>>
>> But, it can afford to be this way, because it made itself a Lisp, meaning 
>> it gave you all the power needed to disagree and make your own core, which 
>> follows your own opinions of good and bad.[1]
>>
>> Now, I recommend that everyone should have a core library of their own 
>> that they keep around for cases like this, where they disagree.
>>
>> And for beginners, I mean, what are you trying to teach them? What 
>> problem requires them to add items to the beginning and end of an ordered 
>> collection?
>>
>> Anyways, my advice is to teach them concat. It's even nicer then 
>> append/prepend. You just give it the arguments where you want them to go.
>>
>> (concat [1] [2 3])
>>
>> (concat [1 2] [3])
>>
>> And it works for any type of ordered collections, even arrays.
>>
>> Also, this blog I think does a great job at teaching all this to a 
>> beginner 
>> https://medium.com/@greg_63957/conj-cons-concat-oh-my-1398a2981eab
>>
>>
>>
>> [1] Except for reader macros. Rich didn't want you to be able to change 
>> the whole program syntax in unconstrained ways. That's probably a good 
>> thing to at least keep the foundation universal accross code bases.
>>
>> -- 
>> 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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Moe Aboulkheir
Christian,

Nice to have you here.  I guess a couple of things are being discussed in
parallel - a few trivial points:

 - 'you always get back a value of the concrete type you supplied for
argument X' isn't obviously less cognitively burdensome than 'you always
get back a sequence'
 - doesn't Python, in all its teachability, just throw a TypeError if you
try and concatenate differently typed collections, even in trivial cases
(e.g. (1,) + [2])?  Is there a way to do that in Python which doesn't
involve writing a concat function w/ a bunch of type checks
 - runtime list construction in Clojure is comparatively rare.  I'm not a
teacher, but in a practical educational setting I would focus on vectors as
the general-purpose ordered collection type - esp. if i were interested in
appending to them.

Take care,
Moe

On Wed, Jul 18, 2018 at 10:07 PM, Christian Seberino 
wrote:

> I'm just a Clojure beginner but it seems that the Lisp Way(TM) is to
> append and prepend one or more elements
> with a single command if possible.  The logical name for this command
> seems to be concat which led to this..
>
> (defn concat_ [a b]
>   (def c (concat a b))
>   (if (vector? a)
>   (into [] c)
>   c))
>
> (concat_ [1 2] [3 4]) => [1 2 3 4]
>
> (concat_ '(1 2) '(3 4)) => (1 2 3 4)
>
> (concat_ [1] [2 3]) => [1 2 3]
>
> Lists return lists and vectors return vectors.  Simple.
> Yes yes I know it is slow.  I also know I need to expand concat_ to handle
> other data structures.
>
> In my little newbie world, this "feels" like the ultimate "right" solution.
>
> Chris
>
> --
> 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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Christian Seberino
I'm just a Clojure beginner but it seems that the Lisp Way(TM) is to append
and prepend one or more elements
with a single command if possible.  The logical name for this command seems
to be concat which led to this..

(defn concat_ [a b]
  (def c (concat a b))
  (if (vector? a)
  (into [] c)
  c))

(concat_ [1 2] [3 4]) => [1 2 3 4]

(concat_ '(1 2) '(3 4)) => (1 2 3 4)

(concat_ [1] [2 3]) => [1 2 3]

Lists return lists and vectors return vectors.  Simple.
Yes yes I know it is slow.  I also know I need to expand concat_ to handle
other data structures.

In my little newbie world, this "feels" like the ultimate "right" solution.

Chris

-- 
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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Alan Thompson
There is also a function `glue`
 for
combining like collections:

-
Gluing Together Like Collections

The concat function can sometimes have rather surprising results:

(concat {:a 1} {:b 2} {:c 3} );=>   ( [:a 1] [:b 2] [:c 3] )

In this example, the user probably meant to merge the 3 maps into one.
Instead, the three maps were mysteriously converted into length-2 vectors,
which were then nested inside another sequence.

The conj function can also surprise the user:

(conj [1 2] [3 4] );=>   [1 2  [3 4] ]

Here the user probably wanted to get [1 2 3 4] back, but instead got a
nested vector by mistake.

Instead of having to wonder if the items to be combined will be merged,
nested, or converted into another data type, we provide the glue function to
 *always* combine like collections together into a result collection of the
same type:

; Glue together like collections:
(is (= (glue [ 1 2] '(3 4) [ 5 6] )   [ 1 2 3 4 5 6 ]  ))   ; all
sequential (vectors & lists)
(is (= (glue {:a 1} {:b 2} {:c 3} )   {:a 1 :c 3 :b 2} ))   ; all maps
(is (= (glue #{1 2} #{3 4} #{6 5} )  #{ 1 2 6 5 3 4 }  ))   ; all sets
(is (= (glue "I" " like " \a " nap!" )   "I like a nap!"   ))   ; all
text (strings & chars)
; If you want to convert to a sorted set or map, just put an empty one first:
(is (= (glue (sorted-map) {:a 1} {:b 2} {:c 3})   {:a 1 :b 2 :c 3} ))
(is (= (glue (sorted-set) #{1 2} #{3 4} #{6 5})  #{ 1 2 3 4 5 6  } ))

An Exception will be thrown if the collections to be 'glued' are not all of
the same type. The allowable input types are:

   -

   all sequential: any mix of lists & vectors (vector result)
   -

   all maps (sorted or not)
   -

   all sets (sorted or not)
   -

   all text: any mix of strings & characters (string result)



On Wed, Jul 18, 2018 at 1:13 PM, Alan Thompson  wrote:

> As someone mentioned, the functions `prepend` and `append` exist in the
> Tupelo library
> 
> to prevent this kind of confusion:
>
> from the README:
> 
> 
> Adding Values to the Beginning or End of a Sequence
>
> Clojure has the cons, conj, and concat functions, but it is not obvious
> how they should be used to add a new value to the beginning of a vector or
> list:
>
> ; Add to the end
> > (concat [1 2] 3);=> IllegalArgumentException
> > (cons   [1 2] 3);=> IllegalArgumentException
> > (conj   [1 2] 3);=> [1 2 3]
> > (conj   [1 2] 3 4)  ;=> [1 2 3 4]
> > (conj  '(1 2) 3);=> (3 1 2)   ; oops
> > (conj  '(1 2) 3 4)  ;=> (4 3 1 2) ; oops
> ; Add to the beginning
> > (conj 1  [2 3] ) ;=> ClassCastException
> > (concat   1  [2 3] ) ;=> IllegalArgumentException
> > (cons 1  [2 3] ) ;=> (1 2 3)
> > (cons   1 2  [3 4] ) ;=> ArityException
> > (cons 1 '(2 3) ) ;=> (1 2 3)
> > (cons   1 2 '(3 4) ) ;=> ArityException
>
> Do you know what conj does when you pass it nil instead of a sequence? It
> silently replaces it with an empty list: (conj nil 5) ⇒ (5) This can
> cause you to accumulate items in reverse order if you aren’t aware of the
> default behavior:
>
> (-> nil
>   (conj 1)
>   (conj 2)
>   (conj 3));=> (3 2 1)
>
> These failures are irritating and unproductive, and the error messages
> don’t make it obvious what went wrong. Instead, use the simple prepend and
>  append functions to add new elements to the beginning or end of a
> sequence, respectively:
>
> (append [1 2] 3  )   ;=> [1 2 3  ]
> (append [1 2] 3 4)   ;=> [1 2 3 4]
>
> (prepend   3 [2 1])  ;=> [  3 2 1]
> (prepend 4 3 [2 1])  ;=> [4 3 2 1]
>
> Both prepend and append always return a vector result.
> 
>
>
>
>
> On Wed, Jul 18, 2018 at 8:17 AM, Christian Seberino 
> wrote:
>
>> Actually I was just kicked out of paradise.  concat always returns a list
>> and does NOT return a vector for this (concat [1 2] [3 4]) sadly.
>>
>> cs
>>
>> ___
>>
>> Christian Seberino, Ph.D.
>> Phone: (936) 235-1139
>> Email: cseber...@gmail.com
>> ___
>>
>>
>>
>> On Wed, Jul 18, 2018 at 2:16 AM, Didier  wrote:
>>
>>> It's never a good idea to use the wrong data structure for the job.
>>>
>>> And thus Clojure takes the stance that it won't make bad ideas easy for
>>> you to use. Yet, it will never prevent you from doing anything.
>>>
>>> If you want to do something bad, you'll need to get your own hands dirty.
>>>
>>> That's why slow data structure access functions don't exist as standard.
>>> That's why data transforms are lazy by default. And why the non lazy
>>> variant (transducers) do loop fusion for you. That's why mutability is ugly
>>> and requires you to wrap things in extra 

Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Alan Thompson
As someone mentioned, the functions `prepend` and `append` exist in the
Tupelo library

to prevent this kind of confusion:

from the README:

Adding Values to the Beginning or End of a Sequence

Clojure has the cons, conj, and concat functions, but it is not obvious how
they should be used to add a new value to the beginning of a vector or list:

; Add to the end
> (concat [1 2] 3);=> IllegalArgumentException
> (cons   [1 2] 3);=> IllegalArgumentException
> (conj   [1 2] 3);=> [1 2 3]
> (conj   [1 2] 3 4)  ;=> [1 2 3 4]
> (conj  '(1 2) 3);=> (3 1 2)   ; oops
> (conj  '(1 2) 3 4)  ;=> (4 3 1 2) ; oops
; Add to the beginning
> (conj 1  [2 3] ) ;=> ClassCastException
> (concat   1  [2 3] ) ;=> IllegalArgumentException
> (cons 1  [2 3] ) ;=> (1 2 3)
> (cons   1 2  [3 4] ) ;=> ArityException
> (cons 1 '(2 3) ) ;=> (1 2 3)
> (cons   1 2 '(3 4) ) ;=> ArityException

Do you know what conj does when you pass it nil instead of a sequence? It
silently replaces it with an empty list: (conj nil 5) ⇒ (5) This can cause
you to accumulate items in reverse order if you aren’t aware of the default
behavior:

(-> nil
  (conj 1)
  (conj 2)
  (conj 3));=> (3 2 1)

These failures are irritating and unproductive, and the error messages
don’t make it obvious what went wrong. Instead, use the simple prepend and
append functions to add new elements to the beginning or end of a sequence,
respectively:

(append [1 2] 3  )   ;=> [1 2 3  ]
(append [1 2] 3 4)   ;=> [1 2 3 4]

(prepend   3 [2 1])  ;=> [  3 2 1]
(prepend 4 3 [2 1])  ;=> [4 3 2 1]

Both prepend and append always return a vector result.





On Wed, Jul 18, 2018 at 8:17 AM, Christian Seberino 
wrote:

> Actually I was just kicked out of paradise.  concat always returns a list
> and does NOT return a vector for this (concat [1 2] [3 4]) sadly.
>
> cs
>
> ___
>
> Christian Seberino, Ph.D.
> Phone: (936) 235-1139
> Email: cseber...@gmail.com
> ___
>
>
>
> On Wed, Jul 18, 2018 at 2:16 AM, Didier  wrote:
>
>> It's never a good idea to use the wrong data structure for the job.
>>
>> And thus Clojure takes the stance that it won't make bad ideas easy for
>> you to use. Yet, it will never prevent you from doing anything.
>>
>> If you want to do something bad, you'll need to get your own hands dirty.
>>
>> That's why slow data structure access functions don't exist as standard.
>> That's why data transforms are lazy by default. And why the non lazy
>> variant (transducers) do loop fusion for you. That's why mutability is ugly
>> and requires you to wrap things in extra verbosity. That's why OOP isn't
>> there, and forces you to use the host interop if you want it. That's why
>> there's only recursive loops. Etc.
>>
>> The Clojure standard lib is opinionated. It's not trying to make
>> everything easy and convenient. It's trying to make things simple to reason
>> about, and promote Rich Hickeys opinion of what is a good idea, and what
>> isn't.
>>
>> But, it can afford to be this way, because it made itself a Lisp, meaning
>> it gave you all the power needed to disagree and make your own core, which
>> follows your own opinions of good and bad.[1]
>>
>> Now, I recommend that everyone should have a core library of their own
>> that they keep around for cases like this, where they disagree.
>>
>> And for beginners, I mean, what are you trying to teach them? What
>> problem requires them to add items to the beginning and end of an ordered
>> collection?
>>
>> Anyways, my advice is to teach them concat. It's even nicer then
>> append/prepend. You just give it the arguments where you want them to go.
>>
>> (concat [1] [2 3])
>>
>> (concat [1 2] [3])
>>
>> And it works for any type of ordered collections, even arrays.
>>
>> Also, this blog I think does a great job at teaching all this to a
>> beginner https://medium.com/@greg_63957/conj-cons-concat-oh-my-1398a2
>> 981eab
>>
>>
>>
>> [1] Except for reader macros. Rich didn't want you to be able to change
>> the whole program syntax in unconstrained ways. That's probably a good
>> thing to at least keep the foundation universal accross code bases.
>>
>> --
>> 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 

Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread James Reeves
On Wed, 18 Jul 2018 at 20:40, Gregg Reynolds  wrote:

>
> On Wed, Jul 18, 2018, 2:25 PM Robert Levy  wrote:
>
>> Literals can be persisted to strings and read back in with no problem,
>> whereas non-literals can't.
>>
>
> That's a different definition of "literal", no? James talked about
> evaluation, not printed form. Value != Print representation?
>

In practical terms there's no real distinction. All data literals in
Clojure can be printed.

-- 
James Reeves
booleanknot.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: concat and mapcat not sufficiently lazy

2018-07-18 Thread Alan Thompson
I have added this to the Tupelo library 
 as `tupelo.lazy/join`:

API docs:http://cloojure.github.io/doc/tupelo/tupelo.lazy.html

source:

 (defn join
   "Lazily concatenates a sequence-of-sequences into a flat sequence."
   [sequences]
   (lazy-seq
 (when-let [seq-of-seqs (seq sequences)]
   (concat (first seq-of-seqs) (join (rest seq-of-seqs))

with tests:

(dotest
  (is= [](lazy/join [[]]))
  (is= [1]   (lazy/join [[1]]))
  (is= [1 2 3 ]  (lazy/join [[1] [2 3]]))
  (is= [1 2 3 4 5 6] (lazy/join [[1] [2 3] [4 5 6]]))
  (is= [1 2 3 4 5 6] (lazy/join [[] [1] [] [2 3] [4 5 6] []])))


On Wed, Jul 18, 2018 at 3:08 AM, Nicola Mometto  wrote:

> Yes, you’re right that neither directly handles `concat`, however CLJ-1583
> improves the behaviour of both your examples and is _necessary_ to fix any
> `apply` related laziness issues
>
> user=>  (first (apply concat (map #(do (println %) [%]) (list 1 2 3 4 5
> 1
> 2
> 3
> 1
> user=> (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
> 1
> 2
> 3
> 1
>
> While CLJ-1218 in conjunction with CLJ-1583 “fixes” the mapcat example:
>
> user=>  (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
> 1
> 1
>
> So to make all your examples as lazy as possible we need a combination of
> CLJ-1218, CLJ-1583 and a `join`-like `concat`
>
>
>
>
> On 18 Jul 2018, at 09:24, Mark Engelberg  wrote:
>
> Thanks, I hadn't seen those issues.
> https://dev.clojure.org/jira/browse/CLJ-1218 talks about mapcat, and
> https://dev.clojure.org/jira/browse/CLJ-1583 talks about apply. Those are
> aspects of the problem, for sure, but fixing those two issues would not
> solve the problem with (apply concat ...), I don't think, because another
> facet of the problem is that concat's args are of the form [x y & zs].
>
> Gary Fredericks recognizes this problem in the comments for CLJ-1218: "I
> realized that concat could actually be made lazier without changing its
> semantics, if it had a single [& args] clause that was then implemented
> similarly to join above."
>
> But for the most part, the comments are focused on fixing mapcat by
> implementing a new function, join, rather than fixing the problem with
> concat directly.  Seems better to fix concat, if possible.
>
> I'm truly astonished I haven't gotten bitten by this before.  This is a
> pattern I use frequently in my code; I guess I just never had deep enough
> recursion for it to slow things down enough for me to realize what was
> happening.
>
>
>
> On Wed, Jul 18, 2018 at 12:53 AM, Nicola Mometto 
> wrote:
>
>> This behaviour is known and there are a couple of tickets about it :
>>
>> https://dev.clojure.org/jira/browse/CLJ-1583
>> https://dev.clojure.org/jira/browse/CLJ-1218
>>
>> On Wed, 18 Jul 2018, 08:28 Mark Engelberg, 
>> wrote:
>>
>>> I'm kind of surprised I haven't run across this before, but tonight I
>>> was debugging a function that was doing an explosion of computation to
>>> return the first value of a lazy sequence, and I was able to reduce the
>>> problem down to this example:
>>>
>>> > (first (apply concat (map #(do (println %) [%]) (list 1 2 3 4 5
>>> 1
>>> 2
>>> 3
>>> 4
>>> 1
>>>
>>> The last 1 is the return value, but notice that it realized 4 values in
>>> order to return the 1.  This has nothing to do with chunked sequences, by
>>> the way -- a list is an unchunked sequence.  It appears to be that the way
>>> concat is written, it realizes the first two elements, and then another two
>>> elements in a recursive call before the lazy-seq kicks in.
>>>
>>> In the function in question, the "apply concat" was part of a recursion,
>>> causing that explosion of realizing values (four at each level of the
>>> recursion, it would seem) to get at the first element.
>>>
>>> Note that this affects mapcat as well, which relies on concat under the
>>> hood:
>>> > (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
>>> 1
>>> 2
>>> 3
>>> 4
>>> 1
>>>
>>> I don't see a quick fix other than writing my own improved
>>> concat/mapcat.  Do you?
>>>
>>> --
>>> 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 

Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread James Reeves
On Wed, 18 Jul 2018 at 20:19, Gregg Reynolds  wrote:

>
> On Wed, Jul 18, 2018, 1:55 PM James Reeves  wrote:
>
>>
>> Function expressions don't evaluate to themselves.
>>
>
> To me that means either the definition is wrong or your literal? is
> rigged. Probably the latter; "literal" is meta, it can't be in the language.
>

How can it be rigged? It's a one line function that just returns true if an
expression evaluates to itself.

You can run read-string directly and see that reading a function expression
results in a seq:

user=> (read-string "#(%)")
(fn* [p1__175#] (p1__175#))
user=> (seq? *1)
true

It doesn't become a function until it's evaluated

Look at it this way: the meaning ("value") of "lambda x.x+1" is just the
> function that increments its arg. Of course you have to "evaluate" to know
> that, but you also have to evaluate "2" in the same way to know what it
> means.
>

Clojure (and lisps in general) distinguish between reading data and
evaluating it. The integer expression "2" does not need to be evaluated:

user=> (read-string "2")
2
user=> (int? 2)
true

And evaluating it only returns itself:

user=> (eval 2)
2
user=> (= 2 (eval 2))
true

In Clojure terminology, you don't need to evaluate "2" to know what it
means. However, you do need to evaluate an expression like (fn [x] (+ x
1)). Merely reading it returns a list.

Anyway my point is that clojure, like lisp, is a form of the lambda
> calculus, where everything is a function, even the Nats like 2. To me at
> least that is one of the most important lessons of functional programming.
> Ymmv.
>

It isn't.

Certainly Clojure can trace some of its lineage back to the lambda
calculus, but that's all. Not everything in Clojure is a function, or even
resembles a function.

-- 
James Reeves
booleanknot.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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Gregg Reynolds
On Wed, Jul 18, 2018, 2:40 PM Gregg Reynolds  wrote:

>
>
> On Wed, Jul 18, 2018, 2:25 PM Robert Levy  wrote:
>
>> > Of course you have to "evaluate" to know that, but you also have to
>> evaluate "2" in the same way to know what it means.
>>
>> I think you're missing the point.
>>
>
> I think maybe we're talking about different things.
>
> 2 is literal because you read it, eval it, print it, and 2 (the result of
>> evaluation) as printed is the same as the original input. A function is
>> read, eval'd, printed and is *not* the same as what was read in. E.g  {:a
>> +}  => {:a #function[clojure.core/+]}
>>
>
> Same meaning?
>

I.e. alpha conversion. Just a rewrite, not an eval?


>
>> Literals can be persisted to strings and read back in with no problem,
>> whereas non-literals can't.
>>
>
> That's a different definition of "literal", no? James talked about
> evaluation, not printed form. Value != Print representation?
>
>>
>> On Wed, Jul 18, 2018 at 12:19 PM Gregg Reynolds 
>> wrote:
>>
>>>
>>>
>>> On Wed, Jul 18, 2018, 1:55 PM James Reeves 
>>> wrote:
>>>
 On Wed, 18 Jul 2018 at 19:38, Gregg Reynolds  wrote:

>
> On Tue, Jul 17, 2018, 4:11 PM James Reeves 
> wrote:
>
>>
>> A data literal evaluates to itself. So for example, `2` is a
>> literal, because we only need to read it to know its value, whereas `(+
>> 1 1)` isn't a literal, because we also need to evaluate it to work
>> out the value.
>>
>
> Fair enough. But by that definition function expressions are also
> literals.
>

 Not at all:

 user=> (defn literal? [s] (let [e (read-string s)] (= e (eval e
 #'user/literal?
 user=> (literal? "2")
 true
 user=> (literal? "(fn [x] x)")
 false
 user=> (literal? "#(%)")
 false
 user=> (literal? "+")
 false

 Function expressions don't evaluate to themselves.

>>>
>>> To me that means either the definition is wrong or your literal? is
>>> rigged. Probably the latter; "literal" is meta, it can't be in the language.
>>>
>>> Look at it this way: the meaning ("value") of "lambda x.x+1" is just the
>>> function that increments its arg. Of course you have to "evaluate" to know
>>> that, but you also have to evaluate "2" in the same way to know what it
>>> means. Meaning "reduce", and neither form can be further reduced.
>>>
>>> Anyway my point is that clojure, like lisp, is a form of the lambda
>>> calculus, where everything is a function, even the Nats like 2. To me at
>>> least that is one of the most important lessons of functional programming.
>>> Ymmv.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clojure@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+unsubscr...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

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


Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Gregg Reynolds
On Wed, Jul 18, 2018, 2:25 PM Robert Levy  wrote:

> > Of course you have to "evaluate" to know that, but you also have to
> evaluate "2" in the same way to know what it means.
>
> I think you're missing the point.
>

I think maybe we're talking about different things.

2 is literal because you read it, eval it, print it, and 2 (the result of
> evaluation) as printed is the same as the original input. A function is
> read, eval'd, printed and is *not* the same as what was read in. E.g  {:a
> +}  => {:a #function[clojure.core/+]}
>

Same meaning?


> Literals can be persisted to strings and read back in with no problem,
> whereas non-literals can't.
>

That's a different definition of "literal", no? James talked about
evaluation, not printed form. Value != Print representation?

>
> On Wed, Jul 18, 2018 at 12:19 PM Gregg Reynolds  wrote:
>
>>
>>
>> On Wed, Jul 18, 2018, 1:55 PM James Reeves  wrote:
>>
>>> On Wed, 18 Jul 2018 at 19:38, Gregg Reynolds  wrote:
>>>

 On Tue, Jul 17, 2018, 4:11 PM James Reeves 
 wrote:

>
> A data literal evaluates to itself. So for example, `2` is a literal,
> because we only need to read it to know its value, whereas `(+ 1 1)`
> isn't a literal, because we also need to evaluate it to work out the 
> value.
>

 Fair enough. But by that definition function expressions are also
 literals.

>>>
>>> Not at all:
>>>
>>> user=> (defn literal? [s] (let [e (read-string s)] (= e (eval e
>>> #'user/literal?
>>> user=> (literal? "2")
>>> true
>>> user=> (literal? "(fn [x] x)")
>>> false
>>> user=> (literal? "#(%)")
>>> false
>>> user=> (literal? "+")
>>> false
>>>
>>> Function expressions don't evaluate to themselves.
>>>
>>
>> To me that means either the definition is wrong or your literal? is
>> rigged. Probably the latter; "literal" is meta, it can't be in the language.
>>
>> Look at it this way: the meaning ("value") of "lambda x.x+1" is just the
>> function that increments its arg. Of course you have to "evaluate" to know
>> that, but you also have to evaluate "2" in the same way to know what it
>> means. Meaning "reduce", and neither form can be further reduced.
>>
>> Anyway my point is that clojure, like lisp, is a form of the lambda
>> calculus, where everything is a function, even the Nats like 2. To me at
>> least that is one of the most important lessons of functional programming.
>> Ymmv.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Robert Levy
> Of course you have to "evaluate" to know that, but you also have to
evaluate "2" in the same way to know what it means.

I think you're missing the point.  2 is literal because you read it, eval
it, print it, and 2 (the result of evaluation) as printed is the same as
the original input. A function is read, eval'd, printed and is *not* the
same as what was read in. E.g  {:a +}  => {:a #function[clojure.core/+]}

Literals can be persisted to strings and read back in with no problem,
whereas non-literals can't.

On Wed, Jul 18, 2018 at 12:19 PM Gregg Reynolds  wrote:

>
>
> On Wed, Jul 18, 2018, 1:55 PM James Reeves  wrote:
>
>> On Wed, 18 Jul 2018 at 19:38, Gregg Reynolds  wrote:
>>
>>>
>>> On Tue, Jul 17, 2018, 4:11 PM James Reeves 
>>> wrote:
>>>

 A data literal evaluates to itself. So for example, `2` is a literal,
 because we only need to read it to know its value, whereas `(+ 1 1)`
 isn't a literal, because we also need to evaluate it to work out the value.

>>>
>>> Fair enough. But by that definition function expressions are also
>>> literals.
>>>
>>
>> Not at all:
>>
>> user=> (defn literal? [s] (let [e (read-string s)] (= e (eval e
>> #'user/literal?
>> user=> (literal? "2")
>> true
>> user=> (literal? "(fn [x] x)")
>> false
>> user=> (literal? "#(%)")
>> false
>> user=> (literal? "+")
>> false
>>
>> Function expressions don't evaluate to themselves.
>>
>
> To me that means either the definition is wrong or your literal? is
> rigged. Probably the latter; "literal" is meta, it can't be in the language.
>
> Look at it this way: the meaning ("value") of "lambda x.x+1" is just the
> function that increments its arg. Of course you have to "evaluate" to know
> that, but you also have to evaluate "2" in the same way to know what it
> means. Meaning "reduce", and neither form can be further reduced.
>
> Anyway my point is that clojure, like lisp, is a form of the lambda
> calculus, where everything is a function, even the Nats like 2. To me at
> least that is one of the most important lessons of functional programming.
> Ymmv.
>
> --
> 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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Gregg Reynolds
On Wed, Jul 18, 2018, 1:55 PM James Reeves  wrote:

> On Wed, 18 Jul 2018 at 19:38, Gregg Reynolds  wrote:
>
>>
>> On Tue, Jul 17, 2018, 4:11 PM James Reeves  wrote:
>>
>>>
>>> A data literal evaluates to itself. So for example, `2` is a literal,
>>> because we only need to read it to know its value, whereas `(+ 1 1)`
>>> isn't a literal, because we also need to evaluate it to work out the value.
>>>
>>
>> Fair enough. But by that definition function expressions are also
>> literals.
>>
>
> Not at all:
>
> user=> (defn literal? [s] (let [e (read-string s)] (= e (eval e
> #'user/literal?
> user=> (literal? "2")
> true
> user=> (literal? "(fn [x] x)")
> false
> user=> (literal? "#(%)")
> false
> user=> (literal? "+")
> false
>
> Function expressions don't evaluate to themselves.
>

To me that means either the definition is wrong or your literal? is rigged.
Probably the latter; "literal" is meta, it can't be in the language.

Look at it this way: the meaning ("value") of "lambda x.x+1" is just the
function that increments its arg. Of course you have to "evaluate" to know
that, but you also have to evaluate "2" in the same way to know what it
means. Meaning "reduce", and neither form can be further reduced.

Anyway my point is that clojure, like lisp, is a form of the lambda
calculus, where everything is a function, even the Nats like 2. To me at
least that is one of the most important lessons of functional programming.
Ymmv.

-- 
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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread James Reeves
On Wed, 18 Jul 2018 at 19:38, Gregg Reynolds  wrote:

>
> On Tue, Jul 17, 2018, 4:11 PM James Reeves  wrote:
>
>>
>> A data literal evaluates to itself. So for example, `2` is a literal,
>> because we only need to read it to know its value, whereas `(+ 1 1)`
>> isn't a literal, because we also need to evaluate it to work out the value.
>>
>
> Fair enough. But by that definition function expressions are also literals.
>

Not at all:

user=> (defn literal? [s] (let [e (read-string s)] (= e (eval e
#'user/literal?
user=> (literal? "2")
true
user=> (literal? "(fn [x] x)")
false
user=> (literal? "#(%)")
false
user=> (literal? "+")
false

Function expressions don't evaluate to themselves.

-- 
James Reeves
booleanknot.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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Gregg Reynolds
On Tue, Jul 17, 2018, 4:11 PM James Reeves  wrote:

> On Tue, 17 Jul 2018 at 21:06, Christian Seberino 
> wrote:
>
>>
>> Clojure, on the other hand, takes great care to ensure that its data can
>>> always be represented as literals. For data that isn't a standard
>>> collection type, there are tagged literals. Clojure syntax starts from a
>>> representation of data, and in order to really understand it, I think it
>>> needs to be taught from this principle as well
>>>
>>
>> Can you elaborate?  I really want to get your point but I'm not so
>> proficient with the lingo.  What do you mean by a "literal" and "tagged
>> literals"?
>>
>
> A data literal evaluates to itself. So for example, `2` is a literal,
> because we only need to read it to know its value, whereas `(+ 1 1)`
> isn't a literal, because we also need to evaluate it to work out the value.
>

Fair enough. But by that definition function expressions are also literals.

The (pedogogical) point being that there is no bright line between code
(functions) and data.

IMHO this is hugely important. Among other things it means you can pass a
fn arg as data, which in my experience opens up design possibilities (or
ways of thinking about problems) that are just unavailable in
non-functional languages. That's my experience anyway.

Regarding OP's issue: teach that conj et al. can be viewed both ways: as a
fn that takes and returns a datum or a fn that takes and returns a fn.
Enlightenment arrives when you see it's the same thing.

G

-- 
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] Clojure 1.10.0-alpha5

2018-07-18 Thread Alex Miller
The only change in alpha6 was the asm fix (your patch!) :)

-- 
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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Robert Levy
I should have done even 30 seconds of research before sending that last
message.  RRB has been available in Clojure since 2014
https://github.com/clojure/core.rrb-vector/blob/master/README.md If you use
that data structure instead of the normal vector, then concats will perform
better.

On Wed, Jul 18, 2018 at 9:59 AM Robert Levy  wrote:

> Ironically, concat is one of the few operations in Clojure that actually
> very likely to cause you performance headaches that actually will matter.
> Concatting is extremely slow.  I think there's a Bagwell functional data
> structure (RRB ?) that addresses the performance issues with concat, but to
> my knowledge it has not been added to Clojure.
>
> On Wed, Jul 18, 2018 at 8:17 AM Christian Seberino 
> wrote:
>
>> Actually I was just kicked out of paradise.  concat always returns a list
>> and does NOT return a vector for this (concat [1 2] [3 4]) sadly.
>>
>> cs
>>
>> ___
>>
>> Christian Seberino, Ph.D.
>> Phone: (936) 235-1139
>> Email: cseber...@gmail.com
>> ___
>>
>>
>>
>> On Wed, Jul 18, 2018 at 2:16 AM, Didier  wrote:
>>
>>> It's never a good idea to use the wrong data structure for the job.
>>>
>>> And thus Clojure takes the stance that it won't make bad ideas easy for
>>> you to use. Yet, it will never prevent you from doing anything.
>>>
>>> If you want to do something bad, you'll need to get your own hands dirty.
>>>
>>> That's why slow data structure access functions don't exist as standard.
>>> That's why data transforms are lazy by default. And why the non lazy
>>> variant (transducers) do loop fusion for you. That's why mutability is ugly
>>> and requires you to wrap things in extra verbosity. That's why OOP isn't
>>> there, and forces you to use the host interop if you want it. That's why
>>> there's only recursive loops. Etc.
>>>
>>> The Clojure standard lib is opinionated. It's not trying to make
>>> everything easy and convenient. It's trying to make things simple to reason
>>> about, and promote Rich Hickeys opinion of what is a good idea, and what
>>> isn't.
>>>
>>> But, it can afford to be this way, because it made itself a Lisp,
>>> meaning it gave you all the power needed to disagree and make your own
>>> core, which follows your own opinions of good and bad.[1]
>>>
>>> Now, I recommend that everyone should have a core library of their own
>>> that they keep around for cases like this, where they disagree.
>>>
>>> And for beginners, I mean, what are you trying to teach them? What
>>> problem requires them to add items to the beginning and end of an ordered
>>> collection?
>>>
>>> Anyways, my advice is to teach them concat. It's even nicer then
>>> append/prepend. You just give it the arguments where you want them to go.
>>>
>>> (concat [1] [2 3])
>>>
>>> (concat [1 2] [3])
>>>
>>> And it works for any type of ordered collections, even arrays.
>>>
>>> Also, this blog I think does a great job at teaching all this to a
>>> beginner
>>> https://medium.com/@greg_63957/conj-cons-concat-oh-my-1398a2981eab
>>>
>>>
>>>
>>> [1] Except for reader macros. Rich didn't want you to be able to change
>>> the whole program syntax in unconstrained ways. That's probably a good
>>> thing to at least keep the foundation universal accross code bases.
>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To post to this group, send email to clojure@googlegroups.com
>>> Note that posts from new members are moderated - please be patient with
>>> your first post.
>>> To unsubscribe from this group, send email to
>>> clojure+unsubscr...@googlegroups.com
>>> For more options, visit this group at
>>> http://groups.google.com/group/clojure?hl=en
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "Clojure" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts 

RE: [ANN] Clojure 1.10.0-alpha5

2018-07-18 Thread Sean Corfield
Just FYI, we ran into all sorts of strange errors (class not found exceptions 
from Boot pods etc) trying Alpha 6 at work but I was about to head out of the 
country for two weeks vacation so I didn’t have time to dig into that. I’m back 
now and will try again shortly and see if I can repro outside of our build 
pipeline.

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

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood


From: Sean Corfield 
Sent: Wednesday, July 4, 2018 10:23:00 AM
To: clojure@googlegroups.com
Subject: RE: [ANN] Clojure 1.10.0-alpha5

I happened to notice this morning that the patch for CLJ-2367 was merged and 
Clojure 1.10.0-alpha6 has quietly gone up to Maven Central so we’re running a 
full pass of our tests at work on the new ASM/Java 8+ stuff.

The 1.10.0-master-SNAPSHOT is currently lagging behind (June 27) and does not 
yet include this fix.

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

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood


From: Sean Corfield 
Sent: Thursday, June 28, 2018 4:26:36 PM
To: clojure@googlegroups.com
Subject: RE: [ANN] Clojure 1.10.0-alpha5

Anyone using taoensso/nippy will encounter a compilation exception on Clojure 
1.10.0 Alpha 5. See https://dev.clojure.org/jira/browse/CLJ-2367 for details 
(an unexpected – and probably unintended – change in the new ASM 
GeneratorAdapter breaks casts from short or byte to int).

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

"If you're not annoying somebody, you're not really alive."
-- Margaret Atwood


From: clojure@googlegroups.com  on behalf of Alex 
Miller 
Sent: Wednesday, June 27, 2018 12:52:20 PM
To: Clojure
Subject: [ANN] Clojure 1.10.0-alpha5

Clojure 1.10.0-alpha5 is now available.

1.10.0-alpha5 includes the following changes since 1.10.0-alpha4:

* CLJ-2363 - make Java 8 the 
minimum requirement for Clojure (also bumps embedded ASM to latest) - thanks 
Ghadi Shayban!
* CLJ-2284 - fix invalid bytecode 
generation for static interface method calls in Java 9+ - thanks Ghadi Shayban!
* CLJ-2330 - fix brittle test 
that fails on Java 10 build due to serialization drift
* CLJ-2362 - withMeta() should 
return identity when new meta is identical to prior
* CLJ-1130 - when unable to match 
static method, improve error messages
* CLJ-2089 - sorted colls with 
default comparator don't check that first element is Comparable
* CLJ-2163 - add test for var 
serialization
* Bump dependency version for spec.alpha to latest, 0.2.168 (see 
changes)
* Bump dependency version for core.specs.alpha to latest, 0.2.36 (see 
changes)

NOTE: 1.10.0-alpha5 drops support for Java 6 and 7 and makes Java 8 the minimum 
requirement. Compilation will produce Java 8 level bytecode (which will not run 
on earlier versions of Java). This is the first change in bytecode version 
since Clojure 1.6. We would greatly appreciate it if you tried this release 
with your library or project and provided feedback about errors, performance 
differences (good or bad), compatibility, etc.

When using the `clj` tool and deps.edn, we recommend adding an alias to your 
~/.clojure/deps.edn:

{:aliases
 {:clj/next
  {:override-deps
   {org.clojure/clojure {:mvn/version "1.10.0-alpha5"}

You can then run any of your projects with the latest Clojure dev release by 
activating the alias with `clj`:

  clj -A:clj/next



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

Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Robert Levy
Ironically, concat is one of the few operations in Clojure that actually
very likely to cause you performance headaches that actually will matter.
Concatting is extremely slow.  I think there's a Bagwell functional data
structure (RRB ?) that addresses the performance issues with concat, but to
my knowledge it has not been added to Clojure.

On Wed, Jul 18, 2018 at 8:17 AM Christian Seberino 
wrote:

> Actually I was just kicked out of paradise.  concat always returns a list
> and does NOT return a vector for this (concat [1 2] [3 4]) sadly.
>
> cs
>
> ___
>
> Christian Seberino, Ph.D.
> Phone: (936) 235-1139
> Email: cseber...@gmail.com
> ___
>
>
>
> On Wed, Jul 18, 2018 at 2:16 AM, Didier  wrote:
>
>> It's never a good idea to use the wrong data structure for the job.
>>
>> And thus Clojure takes the stance that it won't make bad ideas easy for
>> you to use. Yet, it will never prevent you from doing anything.
>>
>> If you want to do something bad, you'll need to get your own hands dirty.
>>
>> That's why slow data structure access functions don't exist as standard.
>> That's why data transforms are lazy by default. And why the non lazy
>> variant (transducers) do loop fusion for you. That's why mutability is ugly
>> and requires you to wrap things in extra verbosity. That's why OOP isn't
>> there, and forces you to use the host interop if you want it. That's why
>> there's only recursive loops. Etc.
>>
>> The Clojure standard lib is opinionated. It's not trying to make
>> everything easy and convenient. It's trying to make things simple to reason
>> about, and promote Rich Hickeys opinion of what is a good idea, and what
>> isn't.
>>
>> But, it can afford to be this way, because it made itself a Lisp, meaning
>> it gave you all the power needed to disagree and make your own core, which
>> follows your own opinions of good and bad.[1]
>>
>> Now, I recommend that everyone should have a core library of their own
>> that they keep around for cases like this, where they disagree.
>>
>> And for beginners, I mean, what are you trying to teach them? What
>> problem requires them to add items to the beginning and end of an ordered
>> collection?
>>
>> Anyways, my advice is to teach them concat. It's even nicer then
>> append/prepend. You just give it the arguments where you want them to go.
>>
>> (concat [1] [2 3])
>>
>> (concat [1 2] [3])
>>
>> And it works for any type of ordered collections, even arrays.
>>
>> Also, this blog I think does a great job at teaching all this to a
>> beginner
>> https://medium.com/@greg_63957/conj-cons-concat-oh-my-1398a2981eab
>>
>>
>>
>> [1] Except for reader macros. Rich didn't want you to be able to change
>> the whole program syntax in unconstrained ways. That's probably a good
>> thing to at least keep the foundation universal accross code bases.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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

Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Nathan Marz
If you want to be able to arbitrarily manipulate your data structures, you 
should look at Specter. I recommend reading my introductory blog post on 
it: http://nathanmarz.com/blog/clojures-missing-piece.html The 
`BEFORE-ELEM` and `AFTER-ELEM` navigators are what you use for 
prepending/appending. 

Things get a lot worse in Clojure when dealing with nested/recursive data 
structures. These use cases were the main motivators for developing 
Specter, and the navigation concept naturally ended up solving the more 
basic manipulations like prepend / append / mid-sequence insertion. 


On Wednesday, July 18, 2018 at 11:21:32 AM UTC-4, Gary Trakhman wrote:
>
> Well, actually, concat returns a seq, not a list. For all practical 
> purposes, it looks like a list, but it isn't one.  Practically, the 
> difference is laziness, which is a whole thing on its own. Also the count 
> operation is linear when lists just keep track of their length, and can do 
> it in constant-time.
>
> On Wed, Jul 18, 2018 at 11:17 AM Christian Seberino  > wrote:
>
>> Actually I was just kicked out of paradise.  concat always returns a list 
>> and does NOT return a vector for this (concat [1 2] [3 4]) sadly.
>>
>> cs
>>
>> ___
>>
>> Christian Seberino, Ph.D.
>> Phone: (936) 235-1139
>> Email: cseb...@gmail.com  
>> ___
>>
>>
>>
>> On Wed, Jul 18, 2018 at 2:16 AM, Didier > 
>> wrote:
>>
>>> It's never a good idea to use the wrong data structure for the job.
>>>
>>> And thus Clojure takes the stance that it won't make bad ideas easy for 
>>> you to use. Yet, it will never prevent you from doing anything.
>>>
>>> If you want to do something bad, you'll need to get your own hands dirty.
>>>
>>> That's why slow data structure access functions don't exist as standard. 
>>> That's why data transforms are lazy by default. And why the non lazy 
>>> variant (transducers) do loop fusion for you. That's why mutability is ugly 
>>> and requires you to wrap things in extra verbosity. That's why OOP isn't 
>>> there, and forces you to use the host interop if you want it. That's why 
>>> there's only recursive loops. Etc.
>>>
>>> The Clojure standard lib is opinionated. It's not trying to make 
>>> everything easy and convenient. It's trying to make things simple to reason 
>>> about, and promote Rich Hickeys opinion of what is a good idea, and what 
>>> isn't.
>>>
>>> But, it can afford to be this way, because it made itself a Lisp, 
>>> meaning it gave you all the power needed to disagree and make your own 
>>> core, which follows your own opinions of good and bad.[1]
>>>
>>> Now, I recommend that everyone should have a core library of their own 
>>> that they keep around for cases like this, where they disagree.
>>>
>>> And for beginners, I mean, what are you trying to teach them? What 
>>> problem requires them to add items to the beginning and end of an ordered 
>>> collection?
>>>
>>> Anyways, my advice is to teach them concat. It's even nicer then 
>>> append/prepend. You just give it the arguments where you want them to go.
>>>
>>> (concat [1] [2 3])
>>>
>>> (concat [1 2] [3])
>>>
>>> And it works for any type of ordered collections, even arrays.
>>>
>>> Also, this blog I think does a great job at teaching all this to a 
>>> beginner 
>>> https://medium.com/@greg_63957/conj-cons-concat-oh-my-1398a2981eab
>>>
>>>
>>>
>>> [1] Except for reader macros. Rich didn't want you to be able to change 
>>> the whole program syntax in unconstrained ways. That's probably a good 
>>> thing to at least keep the foundation universal accross code bases.
>>>
>>> -- 
>>> 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 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 

Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Gary Trakhman
Well, actually, concat returns a seq, not a list. For all practical
purposes, it looks like a list, but it isn't one.  Practically, the
difference is laziness, which is a whole thing on its own. Also the count
operation is linear when lists just keep track of their length, and can do
it in constant-time.

On Wed, Jul 18, 2018 at 11:17 AM Christian Seberino 
wrote:

> Actually I was just kicked out of paradise.  concat always returns a list
> and does NOT return a vector for this (concat [1 2] [3 4]) sadly.
>
> cs
>
> ___
>
> Christian Seberino, Ph.D.
> Phone: (936) 235-1139
> Email: cseber...@gmail.com
> ___
>
>
>
> On Wed, Jul 18, 2018 at 2:16 AM, Didier  wrote:
>
>> It's never a good idea to use the wrong data structure for the job.
>>
>> And thus Clojure takes the stance that it won't make bad ideas easy for
>> you to use. Yet, it will never prevent you from doing anything.
>>
>> If you want to do something bad, you'll need to get your own hands dirty.
>>
>> That's why slow data structure access functions don't exist as standard.
>> That's why data transforms are lazy by default. And why the non lazy
>> variant (transducers) do loop fusion for you. That's why mutability is ugly
>> and requires you to wrap things in extra verbosity. That's why OOP isn't
>> there, and forces you to use the host interop if you want it. That's why
>> there's only recursive loops. Etc.
>>
>> The Clojure standard lib is opinionated. It's not trying to make
>> everything easy and convenient. It's trying to make things simple to reason
>> about, and promote Rich Hickeys opinion of what is a good idea, and what
>> isn't.
>>
>> But, it can afford to be this way, because it made itself a Lisp, meaning
>> it gave you all the power needed to disagree and make your own core, which
>> follows your own opinions of good and bad.[1]
>>
>> Now, I recommend that everyone should have a core library of their own
>> that they keep around for cases like this, where they disagree.
>>
>> And for beginners, I mean, what are you trying to teach them? What
>> problem requires them to add items to the beginning and end of an ordered
>> collection?
>>
>> Anyways, my advice is to teach them concat. It's even nicer then
>> append/prepend. You just give it the arguments where you want them to go.
>>
>> (concat [1] [2 3])
>>
>> (concat [1 2] [3])
>>
>> And it works for any type of ordered collections, even arrays.
>>
>> Also, this blog I think does a great job at teaching all this to a
>> beginner
>> https://medium.com/@greg_63957/conj-cons-concat-oh-my-1398a2981eab
>>
>>
>>
>> [1] Except for reader macros. Rich didn't want you to be able to change
>> the whole program syntax in unconstrained ways. That's probably a good
>> thing to at least keep the foundation universal accross code bases.
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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

Re: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Christian Seberino
Actually I was just kicked out of paradise.  concat always returns a list
and does NOT return a vector for this (concat [1 2] [3 4]) sadly.

cs

___

Christian Seberino, Ph.D.
Phone: (936) 235-1139
Email: cseber...@gmail.com
___



On Wed, Jul 18, 2018 at 2:16 AM, Didier  wrote:

> It's never a good idea to use the wrong data structure for the job.
>
> And thus Clojure takes the stance that it won't make bad ideas easy for
> you to use. Yet, it will never prevent you from doing anything.
>
> If you want to do something bad, you'll need to get your own hands dirty.
>
> That's why slow data structure access functions don't exist as standard.
> That's why data transforms are lazy by default. And why the non lazy
> variant (transducers) do loop fusion for you. That's why mutability is ugly
> and requires you to wrap things in extra verbosity. That's why OOP isn't
> there, and forces you to use the host interop if you want it. That's why
> there's only recursive loops. Etc.
>
> The Clojure standard lib is opinionated. It's not trying to make
> everything easy and convenient. It's trying to make things simple to reason
> about, and promote Rich Hickeys opinion of what is a good idea, and what
> isn't.
>
> But, it can afford to be this way, because it made itself a Lisp, meaning
> it gave you all the power needed to disagree and make your own core, which
> follows your own opinions of good and bad.[1]
>
> Now, I recommend that everyone should have a core library of their own
> that they keep around for cases like this, where they disagree.
>
> And for beginners, I mean, what are you trying to teach them? What problem
> requires them to add items to the beginning and end of an ordered
> collection?
>
> Anyways, my advice is to teach them concat. It's even nicer then
> append/prepend. You just give it the arguments where you want them to go.
>
> (concat [1] [2 3])
>
> (concat [1 2] [3])
>
> And it works for any type of ordered collections, even arrays.
>
> Also, this blog I think does a great job at teaching all this to a
> beginner https://medium.com/@greg_63957/conj-cons-concat-oh-my-
> 1398a2981eab
>
>
>
> [1] Except for reader macros. Rich didn't want you to be able to change
> the whole program syntax in unconstrained ways. That's probably a good
> thing to at least keep the foundation universal accross code bases.
>
> --
> 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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Christian Seberino
>
>
> Anyways, my advice is to teach them concat. It's even nicer then
> append/prepend. You just give it the arguments where you want them to go.
>
> (concat [1] [2 3])
>
> (concat [1 2] [3])


Thanks.  This is perfect.  I'm surprised it didn't up earlier in the
conversation.  concat is a single command that allows the addition of not
only
1 but arbitrary numbers of elements to lists and vectors.  Furthermore, it
returns the same type as the initial args.  Seems like the perfect
solution that would make the Lisp gods proud.

-- 
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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Christian Seberino
>  But like others have said, that ship sailed in 2008.
>

Well depends what ship you are talking about.  Using prepend and append
only requires two new function definitions.  That is still easily done in
2018.

-- 
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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Gregg Reynolds
On Tue, Jul 17, 2018 at 3:48 PM, Tomasz Sulej  wrote:

>
>
> W dniu wtorek, 17 lipca 2018 22:44:27 UTC+2 użytkownik Christian Seberino
> napisał:
>>
>>
>> data are functions and vice-versa
>>>
>>
>> What do you mean? e.g. How is the [1 2 3] a "function"?
>>
>>
Also take a look in
https://github.com/clojure/clojure/tree/clojure-1.9.0/src/jvm/clojure/lang
where
you'll see that e.g. maps, sets, and vectors extend AFn which implements
IFn.


user> ([1 2 3] 0)
> 1
> user> ([1 2 3] 2)
> 3
> user> ({:a 1 :b 2} 0)
> nil
> user> ({:a 1 :b 2} :a)
> 1
>

>
>> cs
>>
> --
> 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: OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Gary Trakhman
Concat does the job except for keeping the input collection type.  It will
seq anything you throw at it.

There's a general trade-off here. When I started working in ocaml recently
I was taken aback that the List.map call we used constantly would have to
build the new list backwards in linear time, and then reverse it in linear
time, with some crazy stack expansions as an optimization for smaller
lists. I've said stuff like 'i would be happy to have a map call that
changed type on me sometimes', but honestly I've never had to dig that deep
for performance, and when I do, it's to switch to a more async-incremental
Pipe thing analogous to core.async chans.

On Wed, Jul 18, 2018, 3:16 AM Didier  wrote:

> It's never a good idea to use the wrong data structure for the job.
>
> And thus Clojure takes the stance that it won't make bad ideas easy for
> you to use. Yet, it will never prevent you from doing anything.
>
> If you want to do something bad, you'll need to get your own hands dirty.
>
> That's why slow data structure access functions don't exist as standard.
> That's why data transforms are lazy by default. And why the non lazy
> variant (transducers) do loop fusion for you. That's why mutability is ugly
> and requires you to wrap things in extra verbosity. That's why OOP isn't
> there, and forces you to use the host interop if you want it. That's why
> there's only recursive loops. Etc.
>
> The Clojure standard lib is opinionated. It's not trying to make
> everything easy and convenient. It's trying to make things simple to reason
> about, and promote Rich Hickeys opinion of what is a good idea, and what
> isn't.
>
> But, it can afford to be this way, because it made itself a Lisp, meaning
> it gave you all the power needed to disagree and make your own core, which
> follows your own opinions of good and bad.[1]
>
> Now, I recommend that everyone should have a core library of their own
> that they keep around for cases like this, where they disagree.
>
> And for beginners, I mean, what are you trying to teach them? What problem
> requires them to add items to the beginning and end of an ordered
> collection?
>
> Anyways, my advice is to teach them concat. It's even nicer then
> append/prepend. You just give it the arguments where you want them to go.
>
> (concat [1] [2 3])
>
> (concat [1 2] [3])
>
> And it works for any type of ordered collections, even arrays.
>
> Also, this blog I think does a great job at teaching all this to a
> beginner
> https://medium.com/@greg_63957/conj-cons-concat-oh-my-1398a2981eab
>
>
>
> [1] Except for reader macros. Rich didn't want you to be able to change
> the whole program syntax in unconstrained ways. That's probably a good
> thing to at least keep the foundation universal accross code bases.
>
> --
> 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: concat and mapcat not sufficiently lazy

2018-07-18 Thread Nicola Mometto
Yes, you’re right that neither directly handles `concat`, however CLJ-1583 
improves the behaviour of both your examples and is _necessary_ to fix any 
`apply` related laziness issues

user=>  (first (apply concat (map #(do (println %) [%]) (list 1 2 3 4 5
1
2
3
1
user=> (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
1
2
3
1

While CLJ-1218 in conjunction with CLJ-1583 “fixes” the mapcat example:

user=>  (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
1
1

So to make all your examples as lazy as possible we need a combination of 
CLJ-1218, CLJ-1583 and a `join`-like `concat`




> On 18 Jul 2018, at 09:24, Mark Engelberg  wrote:
> 
> Thanks, I hadn't seen those issues.
> https://dev.clojure.org/jira/browse/CLJ-1218 
>  talks about mapcat, and 
> https://dev.clojure.org/jira/browse/CLJ-1583 
>  talks about apply. Those are 
> aspects of the problem, for sure, but fixing those two issues would not solve 
> the problem with (apply concat ...), I don't think, because another facet of 
> the problem is that concat's args are of the form [x y & zs].
> 
> Gary Fredericks recognizes this problem in the comments for CLJ-1218: "I 
> realized that concat could actually be made lazier without changing its 
> semantics, if it had a single [& args] clause that was then implemented 
> similarly to join above."
> 
> But for the most part, the comments are focused on fixing mapcat by 
> implementing a new function, join, rather than fixing the problem with concat 
> directly.  Seems better to fix concat, if possible.
> 
> I'm truly astonished I haven't gotten bitten by this before.  This is a 
> pattern I use frequently in my code; I guess I just never had deep enough 
> recursion for it to slow things down enough for me to realize what was 
> happening.
> 
> 
> 
> On Wed, Jul 18, 2018 at 12:53 AM, Nicola Mometto  > wrote:
> This behaviour is known and there are a couple of tickets about it :
> 
> https://dev.clojure.org/jira/browse/CLJ-1583 
> 
> https://dev.clojure.org/jira/browse/CLJ-1218 
> 
> 
> On Wed, 18 Jul 2018, 08:28 Mark Engelberg,  > wrote:
> I'm kind of surprised I haven't run across this before, but tonight I was 
> debugging a function that was doing an explosion of computation to return the 
> first value of a lazy sequence, and I was able to reduce the problem down to 
> this example:
> 
> > (first (apply concat (map #(do (println %) [%]) (list 1 2 3 4 5
> 1
> 2
> 3
> 4
> 1
> 
> The last 1 is the return value, but notice that it realized 4 values in order 
> to return the 1.  This has nothing to do with chunked sequences, by the way 
> -- a list is an unchunked sequence.  It appears to be that the way concat is 
> written, it realizes the first two elements, and then another two elements in 
> a recursive call before the lazy-seq kicks in.
> 
> In the function in question, the "apply concat" was part of a recursion, 
> causing that explosion of realizing values (four at each level of the 
> recursion, it would seem) to get at the first element.
> 
> Note that this affects mapcat as well, which relies on concat under the hood:
> > (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
> 1
> 2
> 3
> 4
> 1
> 
> I don't see a quick fix other than writing my own improved concat/mapcat.  Do 
> you?
> 
> -- 
> 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
> 

Re: Complete Web Development Setup Using Clojure CLI Tools

2018-07-18 Thread Tim Goodwin
for additional inspiration, i suggest looking at 
https://github.com/juxt/edge

On Monday, 9 July 2018 17:14:22 UTC+1, Gary Johnson wrote:
>
> Howdy Clojurians,
>
> I recently started developing a new Clojure+Clojurescript web application, 
> and I wanted to see if I could set up my development environment using just 
> the Clojure CLI tools. After a good deal of digging around through 
> tutorials on a number of different websites and a fair amount of 
> experimenting, I've managed to create a very simple (IMHO) configuration 
> that provides me with both development and production mode CLJS->JS 
> compilation, development and production mode ring handlers, and the always 
> delightful FIgwheel development environment all from just the simple 
> "clojure" command. Since I haven't seen this before, I thought I'd share it 
> with all of you in case it helps someone else out there who doesn't need 
> (or want) all of leiningen or boot to develop a simple web app.
>
> Here goes:
>
> Step 1: Create your project structure like so:
>
> ├── cljsbuild.edn
> ├── deps.edn
> ├── figwheel.edn
> ├── resources
> │   └── public
> │   ├── cljs
> │   ├── css
> │   │ ├── style.css
> │   ├── images
> │   └── js
> ├── src
> │   ├── clj
> │   │   └── my_project
> │   │   ├── handler.clj
> │   │   ├── server.clj
> │   │   ├── views.clj
> │   └── cljs
> │   └── my_project
> │   ├── client.cljs
>
> Step 2: Make the deps.edn file (replace :deps and my-project.server 
> namespace as necessary for your project)
>
> {:paths ["src/clj" "resources"]
>
>  :deps {org.clojure/clojure   {:mvn/version "1.9.0"}
> org.clojure/clojurescript {:mvn/version "1.10.312"}
> ring  {:mvn/version "1.7.0-RC1"}
> ring/ring-defaults{:mvn/version "0.3.2"}
> prone {:mvn/version "1.6.0"}
> compojure {:mvn/version "1.6.1"}
> hiccup{:mvn/version "1.0.5"}
> reagent   {:mvn/version "0.8.1"}}
>
>  :aliases {:run{:main-opts ["-m" "my-project.server"]}
>:cljsbuild  {:extra-paths ["src/cljs"]
> :main-opts ["-m" "cljs.main" "-co" "cljsbuild.edn" 
> "-c"]}
>:figwheel   {:extra-deps {org.clojure/tools.nrepl {:mvn/version 
> "0.2.13"}
>  cider/cider-nrepl   {:mvn/version 
> "0.17.0"}
>  com.cemerick/piggieback {:mvn/version 
> "0.2.2"}
>  figwheel-sidecar{:mvn/version 
> "0.5.14"}}
> :main-opts ["-e" 
> "(use,'figwheel-sidecar.repl-api),(start-figwheel!)"]}}}
>
>
> Step 3: Make the cljsbuild.edn file (replace :main for your project)
>
> {:main  "my-project.client"
>  :output-dir"resources/public/cljs"
>  :output-to "resources/public/cljs/app.js"
>  :source-map"resources/public/cljs/app.js.map"
>  :optimizations :advanced
>  :pretty-print  false}
>
> Step 4: Make the figwheel.edn file (replace :ring-handler, :on-jsload, and 
> :main for your project)
>
> {:nrepl-port   7000
>  :nrepl-middleware ["cider.nrepl/cider-middleware"
> "cemerick.piggieback/wrap-cljs-repl"]
>  :server-port  3000
>  :ring-handler my-project.handler/development-app
>  :http-server-root "public"
>  :css-dirs ["resources/public/css"]
>  :builds [{:id   "dev"
>:source-paths ["src/cljs"]
>:figwheel {:on-jsload "my-project.client/mount-root"}
>:compiler {:main  "my-project.client"
>   :output-dir"resources/public/cljs/out"
>   :output-to "resources/public/cljs/app.js"
>   :asset-path"/cljs/out"
>   :source-maptrue
>   :optimizations :none
>   :pretty-print  true}}]}
>
>
> Step 5: Write server.clj
>
> (ns my-project.server
>   (:require [ring.adapter.jetty :refer [run-jetty]]
> [my-project.handler :refer [development-app production-app]])
>   (:gen-class))
>
> (defonce server (atom nil))
>
> (defn start-server! [& [port mode]]
>   (reset! server
>   (run-jetty
>(case mode
>  "dev"  #'development-app
>  "prod" #'production-app
>  #'production-app)
>{:port (if port (Integer/parseInt port) 3000)
> :join? false})))
>
> (defn stop-server! []
>   (when @server
> (.stop @server)
> (reset! server nil)))
>
> (def -main start-server!)
>
>
> Step 6: Write handler.clj
>
> (ns my-project.handler
>   (:require [ring.middleware.defaults :refer [wrap-defaults site-defaults
> ]]
> [ring.middleware.reload :refer [wrap-reload]]
> [prone.middleware :refer [wrap-exceptions]]
> [compojure.core :refer [defroutes GET]]

Re: concat and mapcat not sufficiently lazy

2018-07-18 Thread Mark Engelberg
Thanks, I hadn't seen those issues.
https://dev.clojure.org/jira/browse/CLJ-1218 talks about mapcat, and
https://dev.clojure.org/jira/browse/CLJ-1583 talks about apply. Those are
aspects of the problem, for sure, but fixing those two issues would not
solve the problem with (apply concat ...), I don't think, because another
facet of the problem is that concat's args are of the form [x y & zs].

Gary Fredericks recognizes this problem in the comments for CLJ-1218: "I
realized that concat could actually be made lazier without changing its
semantics, if it had a single [& args] clause that was then implemented
similarly to join above."

But for the most part, the comments are focused on fixing mapcat by
implementing a new function, join, rather than fixing the problem with
concat directly.  Seems better to fix concat, if possible.

I'm truly astonished I haven't gotten bitten by this before.  This is a
pattern I use frequently in my code; I guess I just never had deep enough
recursion for it to slow things down enough for me to realize what was
happening.



On Wed, Jul 18, 2018 at 12:53 AM, Nicola Mometto 
wrote:

> This behaviour is known and there are a couple of tickets about it :
>
> https://dev.clojure.org/jira/browse/CLJ-1583
> https://dev.clojure.org/jira/browse/CLJ-1218
>
> On Wed, 18 Jul 2018, 08:28 Mark Engelberg, 
> wrote:
>
>> I'm kind of surprised I haven't run across this before, but tonight I was
>> debugging a function that was doing an explosion of computation to return
>> the first value of a lazy sequence, and I was able to reduce the problem
>> down to this example:
>>
>> > (first (apply concat (map #(do (println %) [%]) (list 1 2 3 4 5
>> 1
>> 2
>> 3
>> 4
>> 1
>>
>> The last 1 is the return value, but notice that it realized 4 values in
>> order to return the 1.  This has nothing to do with chunked sequences, by
>> the way -- a list is an unchunked sequence.  It appears to be that the way
>> concat is written, it realizes the first two elements, and then another two
>> elements in a recursive call before the lazy-seq kicks in.
>>
>> In the function in question, the "apply concat" was part of a recursion,
>> causing that explosion of realizing values (four at each level of the
>> recursion, it would seem) to get at the first element.
>>
>> Note that this affects mapcat as well, which relies on concat under the
>> hood:
>> > (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
>> 1
>> 2
>> 3
>> 4
>> 1
>>
>> I don't see a quick fix other than writing my own improved
>> concat/mapcat.  Do you?
>>
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clojure@googlegroups.com
>> Note that posts from new members are moderated - please be patient with
>> your first post.
>> To unsubscribe from this group, send email to
>> clojure+unsubscr...@googlegroups.com
>> For more options, visit this group at
>> http://groups.google.com/group/clojure?hl=en
>> ---
>> You received this message because you are subscribed to the Google Groups
>> "Clojure" group.
>> To unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
> --
> You received this message because you are subscribed to the Google
> Groups "Clojure" group.
> To post to this group, send email to clojure@googlegroups.com
> Note that posts from new members are moderated - please be patient with
> your first post.
> To unsubscribe from this group, send email to
> clojure+unsubscr...@googlegroups.com
> For more options, visit this group at
> http://groups.google.com/group/clojure?hl=en
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

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


Re: concat and mapcat not sufficiently lazy

2018-07-18 Thread Nicola Mometto
This behaviour is known and there are a couple of tickets about it :

https://dev.clojure.org/jira/browse/CLJ-1583
https://dev.clojure.org/jira/browse/CLJ-1218

On Wed, 18 Jul 2018, 08:28 Mark Engelberg,  wrote:

> I'm kind of surprised I haven't run across this before, but tonight I was
> debugging a function that was doing an explosion of computation to return
> the first value of a lazy sequence, and I was able to reduce the problem
> down to this example:
>
> > (first (apply concat (map #(do (println %) [%]) (list 1 2 3 4 5
> 1
> 2
> 3
> 4
> 1
>
> The last 1 is the return value, but notice that it realized 4 values in
> order to return the 1.  This has nothing to do with chunked sequences, by
> the way -- a list is an unchunked sequence.  It appears to be that the way
> concat is written, it realizes the first two elements, and then another two
> elements in a recursive call before the lazy-seq kicks in.
>
> In the function in question, the "apply concat" was part of a recursion,
> causing that explosion of realizing values (four at each level of the
> recursion, it would seem) to get at the first element.
>
> Note that this affects mapcat as well, which relies on concat under the
> hood:
> > (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
> 1
> 2
> 3
> 4
> 1
>
> I don't see a quick fix other than writing my own improved concat/mapcat.
> Do you?
>
> --
> 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.


concat and mapcat not sufficiently lazy

2018-07-18 Thread Mark Engelberg
I'm kind of surprised I haven't run across this before, but tonight I was
debugging a function that was doing an explosion of computation to return
the first value of a lazy sequence, and I was able to reduce the problem
down to this example:

> (first (apply concat (map #(do (println %) [%]) (list 1 2 3 4 5
1
2
3
4
1

The last 1 is the return value, but notice that it realized 4 values in
order to return the 1.  This has nothing to do with chunked sequences, by
the way -- a list is an unchunked sequence.  It appears to be that the way
concat is written, it realizes the first two elements, and then another two
elements in a recursive call before the lazy-seq kicks in.

In the function in question, the "apply concat" was part of a recursion,
causing that explosion of realizing values (four at each level of the
recursion, it would seem) to get at the first element.

Note that this affects mapcat as well, which relies on concat under the
hood:
> (first (mapcat #(do (println %) [%]) (list 1 2 3 4 5)))
1
2
3
4
1

I don't see a quick fix other than writing my own improved concat/mapcat.
Do you?

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


OK idea to replace conj and cons with "prepend" and "append" macros that have consistent behavior and return same types as args?

2018-07-18 Thread Didier
It's never a good idea to use the wrong data structure for the job.

And thus Clojure takes the stance that it won't make bad ideas easy for you to 
use. Yet, it will never prevent you from doing anything.

If you want to do something bad, you'll need to get your own hands dirty.

That's why slow data structure access functions don't exist as standard. That's 
why data transforms are lazy by default. And why the non lazy variant 
(transducers) do loop fusion for you. That's why mutability is ugly and 
requires you to wrap things in extra verbosity. That's why OOP isn't there, and 
forces you to use the host interop if you want it. That's why there's only 
recursive loops. Etc.

The Clojure standard lib is opinionated. It's not trying to make everything 
easy and convenient. It's trying to make things simple to reason about, and 
promote Rich Hickeys opinion of what is a good idea, and what isn't.

But, it can afford to be this way, because it made itself a Lisp, meaning it 
gave you all the power needed to disagree and make your own core, which follows 
your own opinions of good and bad.[1]

Now, I recommend that everyone should have a core library of their own that 
they keep around for cases like this, where they disagree.

And for beginners, I mean, what are you trying to teach them? What problem 
requires them to add items to the beginning and end of an ordered collection?

Anyways, my advice is to teach them concat. It's even nicer then 
append/prepend. You just give it the arguments where you want them to go.

(concat [1] [2 3])

(concat [1 2] [3])

And it works for any type of ordered collections, even arrays.

Also, this blog I think does a great job at teaching all this to a beginner 
https://medium.com/@greg_63957/conj-cons-concat-oh-my-1398a2981eab



[1] Except for reader macros. Rich didn't want you to be able to change the 
whole program syntax in unconstrained ways. That's probably a good thing to at 
least keep the foundation universal accross code bases.

-- 
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] scope-capture 0.3.0

2018-07-18 Thread Val Waeselynck
I pushed a bug in 0.3.0 - jump straight to 0.3.1. My bad!

On Tuesday, 17 July 2018 15:18:46 UTC+2, Val Waeselynck wrote:
>
> Just released *scope-capture 
> * 0.3.0, with some new 
> goodies:
>
> - spyqt / brkqt 
> 
>  
> (SPY QuieTly), useful for preventing large outputs from drowning your REPL.
> - (sc.api/calling-from ...) and :sc/called-from 
> :
>  
> only log / record an Execution Point when invoked from some upstream 
> caller. Useful for spy-ing inside generic functions which get called a lot 
> when you trigger execution.
>
> Feedback welcome !
>
> Valentin Waeselynck
>

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