clojure-miami

[Miami Clojure] Tonight: Introduction to ClojureScript Part 2 @ Orange Republic!
2015-12-10T00:02:32.000011Z

i’ll do my best to answer questions it# /cc @christianromney @adrianm

2015-12-10T00:02:41.000012Z

(although i don’t know cljs

2015-12-10T00:02:44.000013Z

)

christianromney 2015-12-10T00:04:45.000014Z

thanks @bryce much of your clojure knowledge will apply anyway

2015-12-10T00:05:28.000015Z

(lol)

2015-12-10T00:08:53.000019Z

allo

christianromney 2015-12-10T00:08:58.000020Z

a reading from the Gospel of Hickey 😛

christianromney 2015-12-10T00:09:23.000021Z

he meant compiles down to javascript

christianromney 2015-12-10T00:10:08.000022Z

don’t worry if you don’t know what all this means right now

christianromney 2015-12-10T00:10:17.000023Z

you will eventually

christianromney 2015-12-10T00:12:33.000024Z

or you do, but not in the beginner docs

christianromney 2015-12-10T00:17:54.000026Z

https://xkcd.com/297/

2015-12-10T00:19:11.000028Z

the mandatory nesting is great

2015-12-10T00:19:23.000029Z

been schooling fools about sql order-of-operations for a week now

2015-12-10T00:19:34.000030Z

(in SQL, AND and OR aren’t equivalent)

christianromney 2015-12-10T00:19:50.000031Z

not having to memorize precedence rules is nice

christianromney 2015-12-10T00:20:01.000032Z

* has precedence over + in js, ruby

christianromney 2015-12-10T00:20:31.000033Z

2 + 3 * 4 is 14 not 20

2015-12-10T00:20:41.000034Z

just use parens anyways, make your code reviewers not hate you for making ‘em look up precedence rules

christianromney 2015-12-10T00:20:50.000035Z

hehe true

2015-12-10T00:21:38.000037Z

(defn my_band "cool doc string" [band] (println "my favorite band is" band))

2015-12-10T00:21:59.000038Z

(defn FUNCTION_NAME DOC_STRING ARRAY_OF_ARG_NAMES FUNCTION_BODY)

2015-12-10T00:22:30.000039Z

guessing that’s a macro around some kind of cleverness to quote stuff appropriately and transform the arg names into a let-statement

2015-12-10T00:23:25.000040Z

ah, vector, not array

2015-12-10T00:23:52.000041Z

cljs.user=> (type [])
cljs.core/PersistentVector
cljs.user=> (type "asdf")
#object[String "function String() {
    [native code]
}”]

christianromney 2015-12-10T00:26:08.000043Z

btw gang, don’t stress if you’re not yet feeling it…there’s a lab coming up to try things in your shiny new REPLs

christianromney 2015-12-10T00:26:19.000044Z

hang in there!

lostlucidity 2015-12-10T00:27:03.000046Z

On the previous slide how does the function know what "band" is if "my_band" is the argument?

2015-12-10T00:27:26.000047Z

neat, if you put your codes in a, say, band.cljs file you can run ‘em with planck band.cljs

christianromney 2015-12-10T00:27:28.000048Z

@lostlucidity: good question, let me attempt to recreate here

christianromney 2015-12-10T00:28:05.000049Z

((fn [band] (println “My favorite band is “ band) “Rodrigo y Gabriela”)

christianromney 2015-12-10T00:28:19.000050Z

let’s break this down

christianromney 2015-12-10T00:28:38.000051Z

(fn [band] (println “My favorite band is” band)

christianromney 2015-12-10T00:28:59.000053Z

this part creates an anonymous (or un-named) function

christianromney 2015-12-10T00:29:19.000054Z

nevermind the JS equiv

christianromney 2015-12-10T00:29:36.000056Z

this just makes a function

christianromney 2015-12-10T00:29:41.000057Z

but it doesn’t call or invoke it

christianromney 2015-12-10T00:30:12.000058Z

but if you somehow managed to call this function (we’ll cover that in a sec)

christianromney 2015-12-10T00:30:23.000059Z

you would pass it one argument

christianromney 2015-12-10T00:30:41.000060Z

you know it accepts a single arg by looking at the argument list enclosed in square brackets

christianromney 2015-12-10T00:30:45.000061Z

in this case [band]

christianromney 2015-12-10T00:30:59.000062Z

this is just the name we give the argument we are passed

christianromney 2015-12-10T00:31:08.000063Z

so we can use it later inside the print statement

christianromney 2015-12-10T00:31:13.000064Z

(println “Hello” band)

christianromney 2015-12-10T00:31:21.000065Z

the band in the println

christianromney 2015-12-10T00:31:28.000066Z

is the same band we’re given above

christianromney 2015-12-10T00:32:03.000067Z

to call a function we place it inside parentheses

christianromney 2015-12-10T00:33:23.000069Z

(FUNCTION-TO-CALL argument1 argument2 … argument3)

christianromney 2015-12-10T00:35:13.000070Z

i think the slide in question might have had a typo

christianromney 2015-12-10T00:35:42.000071Z

quick poll: plz feel free to be candid….

christianromney 2015-12-10T00:35:44.000072Z

too fast?

christianromney 2015-12-10T00:35:47.000073Z

just right?

christianromney 2015-12-10T00:35:49.000074Z

too slow?

christianromney 2015-12-10T00:36:07.000075Z

i think we’re going kind of fast, but it could just be my biases 😄

lostlucidity 2015-12-10T00:38:37.000076Z

" java.lang.ArrayIndexOutOfBoundsException: 5" this returned on def duos. That okay?

christianromney 2015-12-10T00:38:48.000077Z

lemme see

lostlucidity 2015-12-10T00:38:48.000078Z

Thank you, Christian?

christianromney 2015-12-10T00:38:53.000079Z

no sweat!

christianromney 2015-12-10T00:39:22.000080Z

(def duos {:rodrigo :gabriela :ren :stimpy})

christianromney 2015-12-10T00:39:26.000081Z

try that

christianromney 2015-12-10T00:39:33.000082Z

equivalent ruby:

christianromney 2015-12-10T00:39:55.000083Z

duos = {:rodrigo => :gabriela, :ren => :stimpy}

2015-12-10T00:40:11.000084Z

(def fruit  {:red “apple” :blue “blueberry”})
(fruit :red)
=> “apple”

christianromney 2015-12-10T00:40:13.000085Z

if the commas help you, feel free to add them

christianromney 2015-12-10T00:40:19.000086Z

yay!

christianromney 2015-12-10T00:40:36.000087Z

(def duos {:rodrigo :gabriela, :ren :stimpy}) ;; with commas

lostlucidity 2015-12-10T00:40:37.000088Z

java.lang.Exception: Unable to resolve symbol: def in this context (NO_SOURCE_FILE:0)

lostlucidity 2015-12-10T00:40:44.000089Z

java.lang.Exception: Unable to resolve symbol: def in this context (NO_SOURCE_FILE:0)

2015-12-10T00:40:58.000090Z

make sure to run def as a function (def …)

christianromney 2015-12-10T00:42:19.000091Z

lists are special

christianromney 2015-12-10T00:42:29.000092Z

you MUST type single quote first

christianromney 2015-12-10T00:42:36.000093Z

when you are using a list to hold data

christianromney 2015-12-10T00:42:40.000094Z

like this

christianromney 2015-12-10T00:42:45.000095Z

’(1 2 3)

christianromney 2015-12-10T00:42:54.000096Z

why?

lostlucidity 2015-12-10T00:45:18.000097Z

(:fee :fi :fo :fum) java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :fee (NO_SOURCE_FILE:0)

2015-12-10T00:45:26.000098Z

without the single quote it’s gonna call the 1 function with arguments 2 and 3

christianromney 2015-12-10T00:45:47.000101Z

yessir

lostlucidity 2015-12-10T00:45:53.000102Z

Cool, thanks.

christianromney 2015-12-10T00:46:00.000103Z

remember

christianromney 2015-12-10T00:46:19.000104Z

in Clojure (or any lisp)

christianromney 2015-12-10T00:46:25.000105Z

when you see open parens

christianromney 2015-12-10T00:46:40.000106Z

it’s a function call

christianromney 2015-12-10T00:46:53.000107Z

(FUNCTION-TO-CALL arg1 arg2 …)

christianromney 2015-12-10T00:47:03.000108Z

the single quote

christianromney 2015-12-10T00:47:05.000109Z

tells Clojure

christianromney 2015-12-10T00:47:13.000110Z

dude, don’t call this like a function

christianromney 2015-12-10T00:47:17.000111Z

treat it as DATA

christianromney 2015-12-10T00:47:28.000112Z

incidentally

christianromney 2015-12-10T00:47:29.000113Z

christianromney 2015-12-10T00:47:41.000115Z

is just a shortcut for typing

christianromney 2015-12-10T00:47:48.000116Z

(quote (1 2 3))

christianromney 2015-12-10T00:47:54.000117Z

try that in your repl!

2015-12-10T00:48:34.000118Z

cljs.user=> '(+ 1 2 3)
(+ 1 2 3)
cljs.user=> ~'(+ 1 2 3)
undefined is not an object (evaluating 'cljs.core.unquote.call')

cljs.user=> `'(+ 1 2 3)
(quote (+ 1 2 3))

2015-12-10T00:48:37.000119Z

how do i unquote?

2015-12-10T00:48:41.000120Z

or eval

christianromney 2015-12-10T00:49:24.000121Z

backtick

christianromney 2015-12-10T00:49:27.000122Z

is syntax-quote

lostlucidity 2015-12-10T00:49:33.000123Z

So vectors are treated as functions?

christianromney 2015-12-10T00:49:34.000124Z

(we won’t cover that yet)

christianromney 2015-12-10T00:49:45.000125Z

nope vectors are like arrays

christianromney 2015-12-10T00:50:01.000126Z

[1 2 3] ;; vector

christianromney 2015-12-10T00:50:09.000127Z

(1 2 3) ;; list

christianromney 2015-12-10T00:50:32.000129Z

the difference between vectors and lists (why you want one instead of the other) will be covered later

christianromney 2015-12-10T00:50:43.000130Z

i’ll make sure we spend a few minutes talking about that

lostlucidity 2015-12-10T00:51:13.000131Z

Okay, so the tick is needed because paranthesis?

christianromney 2015-12-10T00:51:14.000132Z

@bryce unquote will be (within the context of syntax-quote) ~

lostlucidity 2015-12-10T00:51:19.000133Z

For lists.

christianromney 2015-12-10T00:51:19.000134Z

yes

christianromney 2015-12-10T00:51:21.000135Z

correct

christianromney 2015-12-10T00:51:35.000136Z

to tell clojure “this is not intended to be a function call"

christianromney 2015-12-10T00:52:47.000137Z

@bryce for unquote you could do this (this example is totally contrived btw)

christianromney 2015-12-10T00:54:45.000139Z

we’ll cover unquote, backtick and macros in general in part 4 of 4

christianromney 2015-12-10T00:54:47.000140Z

😄

christianromney 2015-12-10T00:54:52.000141Z

you’re way ahead

christianromney 2015-12-10T00:54:56.000142Z

hehe

christianromney 2015-12-10T00:56:09.000143Z

so to review

christianromney 2015-12-10T00:56:20.000144Z

we have 4 main collection types

christianromney 2015-12-10T00:56:38.000145Z

lists, vectors, maps, sets

christianromney 2015-12-10T00:56:54.000146Z

'(1 2 3) ;; list

christianromney 2015-12-10T00:56:57.000147Z

[1 2 3] ;; vector

christianromney 2015-12-10T00:57:30.000149Z

{:fn “Mickey” :ln “Mouse”} ;; maps

christianromney 2015-12-10T00:57:54.000150Z

#{0 1 2 3 5 8 13} ;; sets

christianromney 2015-12-10T00:58:44.000151Z

module in Ruby

christianromney 2015-12-10T01:04:19.000158Z

Anyone have any questions???

christianromney 2015-12-10T01:05:57.000159Z

this part is kinda advanced

christianromney 2015-12-10T01:06:03.000160Z

destructuring

christianromney 2015-12-10T01:06:16.000161Z

the code on the slide is a bit hard to see

christianromney 2015-12-10T01:06:23.000162Z

here’s a similar example

2015-12-10T01:06:27.000163Z

the :as key signals the rest of the map?

christianromney 2015-12-10T01:06:35.000164Z

did we cover let already?

2015-12-10T01:06:40.000165Z

yup

christianromney 2015-12-10T01:06:44.000166Z

ok good

christianromney 2015-12-10T01:06:56.000167Z

:as lets you give a name to the entire map

christianromney 2015-12-10T01:07:02.000168Z

so here come some examples

christianromney 2015-12-10T01:07:18.000169Z

(let [x 1 y 2] (+ x y) ;; => 2)

2015-12-10T01:07:43.000170Z

an un-found destructure turns into nil

christianromney 2015-12-10T01:08:34.000171Z

(let [nums [1 2] [a b] nums] (+ a b)) ;; => 3

christianromney 2015-12-10T01:09:17.000173Z

(def me {:fn “Chris” :ln “Romney”})

christianromney 2015-12-10T01:09:55.000174Z

(let [{:keys [fn ln] :as user} me] user) ;;=> {:fn “Chris” :ln “Romney”}

christianromney 2015-12-10T01:10:15.000175Z

(let [{:keys [fn ln] :as user} me] fn) ;;=> “Chris”

christianromney 2015-12-10T01:11:03.000179Z

sorry i went too fast

christianromney 2015-12-10T01:11:07.000180Z

examples corrected

lostlucidity 2015-12-10T01:11:33.000181Z

Why do :as when the map has a name already?

christianromney 2015-12-10T01:11:42.000182Z

good question

christianromney 2015-12-10T01:11:49.000183Z

it may not always already have a name

christianromney 2015-12-10T01:11:56.000184Z

depending on where/how you use it

christianromney 2015-12-10T01:12:01.000185Z

so here’s one example

lostlucidity 2015-12-10T01:12:03.000186Z

okay.

lostlucidity 2015-12-10T01:14:56.000188Z

Got it!.. probably

lostlucidity 2015-12-10T01:14:58.000189Z

Thanks.

christianromney 2015-12-10T01:15:18.000190Z

this is a lot of material being covered very quickly

christianromney 2015-12-10T01:15:24.000191Z

feel free to ask in this channel

christianromney 2015-12-10T01:15:26.000192Z

anytime

christianromney 2015-12-10T01:15:31.000193Z

I’m always here

christianromney 2015-12-10T01:16:00.000194Z

one thing I want to tell everyone: don’t be discouraged if some of this takes a while to really sink in

christianromney 2015-12-10T01:16:06.000195Z

it’s A LOT of material

christianromney 2015-12-10T01:16:13.000196Z

being covered very quickly

2015-12-10T01:16:34.000197Z

cond vs. case: is the only difference the syntax for the default option?

christianromney 2015-12-10T01:17:14.000198Z

case does a literal match against a value

2015-12-10T01:17:26.000199Z

ahhh, and cond checks for truthiness?

christianromney 2015-12-10T01:17:29.000200Z

correct

christianromney 2015-12-10T01:18:10.000201Z

there’s also condp

christianromney 2015-12-10T01:18:19.000202Z

which is somewhere in between 😄

2015-12-10T01:18:26.000203Z

get romantic with your clojure~

2015-12-10T01:18:36.000204Z

could you explain that? case vs cond

2015-12-10T01:18:55.000205Z

jorda0mega: let me write some code

2015-12-10T01:20:50.000206Z

(cond
test expr
test expr)

2015-12-10T01:21:03.000207Z

cond evaluates each test and if it’s true, evaluates the expression

2015-12-10T01:21:24.000208Z

(case some-value
comparison expr
comparison expr)

2015-12-10T01:22:00.000210Z

case requires that you pass in some value, it evaluates comparisons, and if that comparison equals some-value, evaluates the expression

2015-12-10T01:22:12.000211Z

gotcha

2015-12-10T01:22:16.000212Z

(condp some-function some-value
test expr
test expr)

2015-12-10T01:22:22.000213Z

condp is halfway between ‘em

2015-12-10T01:22:46.000214Z

it evaluates some-value, takes that value down each test, evaluates (some-function some-value test)

2015-12-10T01:22:52.000215Z

if that comes true, it evaluates the expression

2015-12-10T01:23:08.000216Z

cool cool

2015-12-10T01:23:09.000217Z

thanks

2015-12-10T01:29:39.000218Z

(defn band_evaluator
  "fart"
  [band_name]
  (case (get band_quality (-> band_name
                              .toLowerCase
                              keyword))
    :great (println "you like" band_name "and have taste")
    :okay (println "i agree," band_name "is okay!")
    (println ":middle_finger::skin-tone-6::santa::skin-tone-6:your opinion of" band_name "is WRONG :middle_finger::skin-tone-6::santa::skin-tone-6:")
    ))

(defn cond_evaluator
  "fart"
  [band_name]
  (let [quality (get
                  band_quality
                  (-> band_name
                      .toLowerCase
                      keyword))]
  (cond
    (= quality :great)
    (println "you like" band_name "and have taste")
    (= quality :okay)
    (println "i agree," band_name "is okay!")
    :else
    (println ":middle_finger::skin-tone-6::santa::skin-tone-6:your opinion of" band_name "is WRONG :middle_finger::skin-tone-6::santa::skin-tone-6:")
    )))

(defn condp_evaluator
  "fart"
  [band_name]
  (condp = (get band_quality (-> band_name
                              .toLowerCase
                              keyword))
    :great (println "you like" band_name "and have taste")
    :okay (println "i agree," band_name "is okay!")
    (println ":middle_finger::skin-tone-6::santa::skin-tone-6:your opinion of" band_name "is WRONG :middle_finger::skin-tone-6::santa::skin-tone-6:")
    ))

2015-12-10T01:29:42.000219Z

lol

2015-12-10T01:29:56.000220Z

this is how cond, case, and condp differ

2015-12-10T01:30:05.000221Z

and you can see my middle finger santas get really mangled too

2015-12-10T01:30:15.000222Z

haha

julian 2015-12-10T15:44:27.000224Z

Great intro last night! Here are some more resources:

julian 2015-12-10T15:44:30.000225Z

Clojure for the Brave and True http://www.braveclojure.com/ ClojureTV https://www.youtube.com/user/ClojureTV ClojureScript for Skeptics - Derek Slager https://youtu.be/Y2jQe8DFzUM?list=PLZdCLR02grLrl5ie970A24kvti21hGiOf Om Next - David Nolen https://youtu.be/MDZpSIngwm4?list=PLZdCLR02grLrl5ie970A24kvti21hGiOf

2015-12-10T16:01:16.000227Z

Thank you!

2015-12-10T17:34:07.000228Z

Hey guys! Just wanted to thank everyone for coming out. You were a great audience. I’m going to be sharing my slides with the group shortly. @julian Thank you for sharing those resources. I’ll be adding to that list as well.

christianromney 2015-12-10T20:56:22.000229Z

Om Next will be easier to digest from this https://awkay.github.io/om-tutorial/#!/