Assigning best case scenarios


#1

I’ve learned so far that there are (at least) three ways to assign/bind/map a value to a name:

  • def ex: (def greatest-wrapper "6ixRap")

  • map ex: {:last-name "Ever" :first-name "Greatest"}

  • let ex: (let [boss-witch "Nik of the North"] boss-witch)

But when do I use which? I’m thinking use def when I want to simply define a constant; map if I have a sizeable list of values to pair with keywords; and let is best to use if I want to assign a function to something. I’m looking for a rule of thumb here.

Make any sense? All advice/corrections appreciated.

p.s. did i use the right category? should I have used the “Clojure” category instead?


#2

Ok what I’m realizing now is that let is a special form that expects you to do something with the binding right after. Like it’s an in-place bind and destructure routine, all in the same scope.
A map or def are just simple bindings, whereas let is bind+.

Am I making sense?


#3

As you mention, let introduces a new scope within which your bindings (and every binding within a higher scope) are available to you. Though let doesn’t actually care if you do anything with the symbols you declare/bind. def introduces what is effectively a global name, although you may have to refer to it by it’s fully qualified name (e.g. name.space.your/deffed-symbol). Maps are similar to namespaces in a sense. Once you have a reference to it, you can dig in and see everything it contains.

If you want to be a completist, fn and with-bindings also allow you to introduce new bindings, defn is just shorthand for (def foo (fn [] ...)). There may be others, but those are all that I know of. Does that answer your question?


#4

Thanks @dogenpunk, I think I get the differences now. I guess let is kind of like a private class in the OO universe :slight_smile: I know fn and defn, but with-bindings is new to me. The options can be a bit dizzying, but I’ll get the hang of which to use when.


#5

Yeah, I guess you could draw a parallel between let and an inner-class. There are a number of different ways to bind a value to a name in Clojure. I guess the way I think of these is, maps are for data or keeping related things together in a structure I can easily pass around. def is for top-level constructs in a namespace that I may need to access from another namespace. let is then for convenience and readability inside of a function/scope. It lets me name intermediate values for clarity and ease of use. That help?


#6

Thank you, @dogenpunk, that is a nice, simple way for me to hold the differences/use cases in my head :slight_smile:


#7

Cool. :slight_smile: