Clojure sequences and Lab 2


(ns examples)
(use 'clojure.repl) ; to be able to look at function source code

;; Clojure documentation:
(println [
;          (source map)
;         (doc map)
;          (meta map)
;          (dir clojure.repl)
])


;;; Clojure sequences and operations on them (Ch. 4)
;;; Start learning about laziness and efficiency 

;;; Two main things: 
;; Clojure is translated into Java bytecode 
;; (Just about) everything in clojure is a sequence


;; Lists and vectors are sequences we already know 
;; Other Clojure collections (sequences): maps, sets 
;; Lazy sequences
;; Java seq-able elements: Java collections, arrays, strings,
;; Other things: I/O streams, regular expression matches.
;; And more!

(println [
          (class '(1 2 3)) "\n"
          (class [1 2 3])  "\n"
          (class (rest [1 2 3])) "\n"
          (class (rest '(1 2 3)))
])


;; Operations applicable to all sequences: cons, first, rest

;; more general operations: conj
(println [
          (conj [6 7] 8)
          (conj [6 7] 8 9)
          (conj '(6 7) 8) ; Note the difference in order!!!
          (conj '(6 7) 8 9)
          (nth [4 5 6 7 8] 1)
          (nth [4 5 6 7 8] 3)
          ;(nth [4 5 6 7 8] 10)
          (["hi" "there" "friend"] 2) ;; applying a vector??
])

;; Lab 2 Problem 2:
;; 1. explore a function "into" (it works on any two collections)
;; use the documentation, then show its work on lists and vectors
;; 2. explore a function "subvec" that gives a subvector. 
;; what happens when you pass one parameter to it? Explain clearly,
;; give examples. 

(println [
          :name ; a keyword. Often used for indexing. 
])

;; maps: pairs, the first element is treated as a key, the 
;; second one as a value
(def phone-book {:Sam "589-9999" :Chris "585-1234"})
 
(println phone-book)

(println [
          (phone-book :Sam)
          (:Sam phone-book)
          (keys phone-book)
          (vals phone-book)  
          (contains? phone-book :Sam)
          (contains? phone-book :Kim)
])

;; Lab 2 Problem 3:
;; figure out how to add a new person and phone number to the 
;; phone book and how to change a phone number for an existing person.
;; Keep in mind that collections are immutable so you will get
;; a new phone book rather than modify an existing one
;; Hint: Ch. 4 of the textbook may be helpful

;; Lazy sequences.

(println [
          "Class of range: \n"
          (class (range 1 30 2)) 
          "\nDoc for range function\n"
          (meta range)
])


(println [
          (nth (range 1 100000000 4) 16) "\n"
          (nth (range) 5) "\n" ;; Taking the 5-th element of an inifnite sequence
          (doall (range 1 20 4)) "\n" ;; forcing a lazy sequence
          (nth (doall (range 1 10000000 4)) 16) ;; note the execution time!
])

;; Lab 2 Problem 4:
;; Study functions map, filter, rest, concat. Check if they return 
;; lazy sequences. Take two functions that return lazy sequences and
;; create a sequence of that would've taken a very long time (or would've 
;; caused a heap overflow) it weren't lazy, but is fast and memory efficient 
;; because of lazy sequences. Note: a composition of lazy functions is lazy, 
;; use ranges as a strating point.  


(println [
          ;; regular expressions pattern-matching 
          ;; find all words that start with an a.
          ;; recall that \b is a word boundary and \w is a word character 
          (re-seq #"\ba[\w]*\b" "apples and anacondas and bears are fun") ; the result is a list           
])

;; construct a pattern that uses a variable

(def letter \a) 
(def patt (str "\\b" letter "[\\w]*\\b")) ;; creating a pattern with a variable
                         ;; since we need to pass it to a Java method,
                         ;; we need \\ instead of \

(println [
          patt
          (re-seq (. java.util.regex.Pattern compile patt) "apples and anacondas and bears are fun")    
])

;; Lab 2, Problem 5. 
;; This is somewhat involved so start early and build it incrementally
;; Some important elements are given above.

;; Write a function count-words-start that, given a letter of 
;; the alphabet and a string, counts the number of words in the string 
;; that start with that character. 

;; Write a function count-words-end that, given a letter of 
;; the alphabet and a string, counts the number of words in the string 
;; that end with that character. 

;; Write a function count-words-middle that, given a letter of 
;; the alphabet and a string, counts the number of words in the string 
;; that have that character somewher in the middle (i.e. in a position other
;; than the first and the last one). 

;; Make a string that has a sufficiently long text (100 words minimum,
;; more is better). You may just copy-paste it from any online source.
;; This will serve as your data. Apply .toLowerCase to it so that 
;; you don't have to worry about the difference between upper- and lower-case
;; letters (see p. 30). 

;; Create a map indexed by the letters of the alphabet that has the 
;; counts of words starting with each letter in the given string. 
;; To do this, use a string or other structure that stores
;; the 26 letters of the alphabet and iterate over it. 
;; Then do the same for count-words-end and count-words-middle.

;; Use pre-defined functions or write your own to find the most
;; and the least frequent starting, ending, and middle letters. 

;; Clarification: the map may or may not include letters that 
;; don't appear at all (as zeros)
;; The least frequent letter shoudl not include zeros.
;; If there are ties, any letter can be returned. 


UMM CSci 4409