@Gary Johnson, your post is otherwise great, but I think a little confusing
for this point:
> , I would advise you to use the "into" function that I demonstrated at
the beginning of this email if you wish to teach a unified API for
appending and prepending to each of Clojure's four main data structures
while preserving the types of the function's inputs.

Into is essentially just 'reduce conj', so doesn't help for
appending/prepending any more than conj.

Here's a few working modifications to the left sides of your examples:

(into '(1 2) [3])         ;=>  (3 1 2) ; This was incorrect to start with
above
(into [1 2] '(3))           ;=>  [1 2 3]
(into {:a 1 :b 2} [[:c 3]]  ;=>  {:a 1, :b 2, :c 3}

On Fri, Jul 20, 2018 at 11:52 AM Gary Johnson <lambdatro...@gmail.com>
wrote:

> Hi Christian,
>
> You are looking for "into", which is already part of the Clojure standard
> library.
>
> Appending:
>
> (into '(1 2) '(3))         ;=>  (1 2 3)
> (into [1 2] [3])           ;=>  [1 2 3]
> (into {:a 1 :b 2} {:c 3})  ;=>  {:a 1, :b 2, :c 3}
> (into #{:a :b} #{:c})      ;=>  #{:c :b :a}
>
> Prepending:
>
> (into '(1) '(2 3))         ;=>  (1 2 3)
> (into [1] [2 3])           ;=>  [1 2 3]
> (into {:a 1} {:b 2 :c 3})  ;=>  {:a 1, :b 2, :c 3}
> (into #{:a} #{:b :c})      ;=>  #{:c :b :a}
>
> The "into" function pours the contents of the second collection into the
> first collection, returning a collection of the same type as the first
> argument.
>
> That being said, I agree with Alex and James in this rather lengthy
> discussion. Clojure is unique among the Lisps in that it moved beyond
> having linked lists as the only first class data structure.
>
> Prior to Clojure, if you worked in a Lisp like Scheme or Common Lisp, you
> would design your program around the creation, traversal, and manipulation
> of linked lists using higher order functions and explicit recursions. The
> standard library in both languages is heavily focused on these list-related
> operations. After developing the initial version of your program, if you
> found that it was too slow or used too much memory, the accepted practice
> was to profile your application to identify the functions that were getting
> hammered the most and were using up the majority of your computing
> resources. You would then often end up rewriting those function bodies in
> an imperative fashion using loops and mutable data structures (i.e., arrays
> and hashtables). The "wisdom" here was that this would enable you to "first
> make it right, then make it fast". If even further performance was required
> from your program, you might then rewrite part of your program in C, build
> a foreign function interface (FFI) to link the C code into your Lisp
> program, and go from there. These were the Bad Old Days of Lisp(TM).
>
> What was IMHO quite possibly Rich's greatest contribution in the design of
> Clojure to the Lisp world was his decision to make additional data
> structures first class citizens of the language. Most importantly, he did
> so by creating Clojure's vectors, maps, and sets to be immutable,
> persistent, performant, recursively constructed, and representable as data
> literals. This was already a wonderful improvement over previous Lisps, but
> it created a new problem: How could we enjoy the pure delight of
> list-oriented programming that Lisp had always offered us now that the data
> structure space had been fragmented? A famous quote from Alan Perlis is a
> popular gem in the Lisp world, and it goes like so:
>
> "It is better to have 100 functions operate on one data structure than to
> have 10 functions operate on 10 data structures."
>
> Every Lisp had always satisfied this by simply giving programmers only one
> first class data structure to use: the linked list. As I already mentioned,
> the bulk of its standard library would then be built around list
> manipulation functions. Clojure needed a way to preserve this unified style
> of programming while still providing a collection of performant data
> structures for real-world programming. So how did Rich accomplish this?
>
> He created the "sequence abstraction". A sequence in Clojure serves a
> similar role to the linked list of previous Lisps in that it unifies the
> API for interacting with all of Clojure's first class data structures
> (list, vector, map, set). By calling the function "seq" on any data
> structure, you are given a list-like view of that collection that allows
> you to traverse it from beginning to end one element at a time and to add
> new elements to the beginning of it. These operations are called "first",
> "rest", and "cons", and they behave precisely as you would expect them to
> if you were calling them on a linked list.
>
> By using seq throughout the Clojure sequence library (i.e., the set of
> standard library functions responsible for creating, traversing,
> transforming, and manipulating sequences), Clojure is able to have single
> implementations of all of the common Lispy higher order list transformation
> functions. For example, we have "map", "filter", "reduce", "iterate",
> "take", "drop", "repeat", "cycle", and so on. The amazing thing is that
> these can all take any of Clojure's data structures as their inputs. So you
> can call map on a list, vector, map, or set without having to change the
> function signature. Without the sequence abstraction, we could need
> multiple functions for every data structure we wanted to support (e.g.,
> map-list, map-vec, map-hash, map-set, filter-list, filter-vec, filter-hash,
> filter-set). This is precisely the kind of combinatorial explosion of the
> function space the Alan Perlis was warning us about. The tradeoff is that
> each of these higher order functions will then return a new sequence as its
> output. While this prints to the REPL like a list, please note that a
> sequence is not a list (except when it is a sequence on a list ;-D ). It is
> a list-like representation of the contents of any data structure. You can
> check this by calling the "type" function on the output of either "seq" or
> any higher order function (e.g., map, filter, reduce) that calls seq
> internally.
>
> So when you are programming Clojure or teaching it to new programmers (as
> I have done on numerous occasions), it really is important IMHO to take a
> moment to appreciate the history that motivated Rich's design decisions
> around data structures and the sequence abstraction and not to simply write
> it off and treat Clojure as though it were Scheme or Common Lisp made to
> run on the JVM.
>
> In Clojure, the choice of your data structures is central in the design of
> your programs when it comes to performance. However, an equally important
> part of program design is the conceptualization of much of your program as
> a series of sequence transformations composed together so as to reach the
> output you desire from the inputs you are given. To that end, if you wish
> to equip new programmers with the skills to think like a Clojure
> programmer, I would first teach them the four main data structures (list,
> vector, map, set) and the functions to operate on each of them. Next, I
> would teach them the sequence API and demonstrate how these four data
> structures are represented as sequences. This enable everyone to reason in
> a straightforward manner about all of the sequence functions going forward.
> Then, I would teach them how to use higher order functions like map,
> filter, reduce, and range to replace loops and mutation in their program
> logic. After this, I would discuss recursion and function composition as
> the fundamental components of flow control in a functional programming
> language. Finally, I would spend some time going over dynamic vs lexical
> scoping rules, shadowed bindings, namespaces, and the call stack.
>
> This should provide your students with most of the groundwork that they
> need to get going with Clojure programming and to dig deeper into various
> advanced topics like host interop, concurrency primitives, parallel
> programming, spec, pure/impure functions, macros, and so on.
>
> One thing that I would definitely avoid in teaching a new language is to
> alter the syntax of that language on day 1 and teach constructs that are
> neither efficient nor particularly useful in practice. To that end, I would
> advise you to use the "into" function that I demonstrated at the beginning
> of this email if you wish to teach a unified API for appending and
> prepending to each of Clojure's four main data structures while preserving
> the types of the function's inputs.
>
> And with that, I'm going to head back to my day job. Good luck in learning
> Clojure and teaching it to others, and don't hesitate to reach out with
> questions to the Clojure mailing list. Most of the folks on here are
> usually very friendly and intelligent, and I've always found that to be a
> hallmark of this community.
>
> Happy hacking,
>   Gary
>
> --
> 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.

Reply via email to