Fork me on GitHub
#beginners
<
2018-08-17
>
sooheon00:08:08

The http://figwheel.org tutorial/docs are the best I’ve read for getting started with webdev in clojure--thank you @bhauman!

Michael Stokley06:08:11

i'm trying to unit test a function that calls (comp resolve symbol) on a string that may or may not resolve to a symbol in the enclosing namespace

Michael Stokley06:08:56

i'm not sure how to provide a bound symbol that the function can resolve

Michael Stokley06:08:19

i tried just passing in bound symbols as arguments to the function, but that doesn't work

Michael Stokley06:08:18

oh, looks like resolve optionally accepts a namespace

sundarj06:08:01

@michael740 there's ns-resolve for when you want to pass a namespace to resolve from

sundarj06:08:17

though personally, instead of using resolve or ns-resolve, i would have the function take a map from symbols to values as an explicit argument

sundarj06:08:01

you can also get a random symbol from your namespace by doing something like (rand-nth (seq (ns-map *ns*))) or (rand-nth (seq (ns-interns *ns*)))

Michael Stokley06:08:00

originally i wanted to use resolve because i was trying to write code that would treat json data as code, and execute it

Michael Stokley06:08:25

like, what if json could be a dsl?

Michael Stokley06:08:49

could a macro transform "{\"operator\" [\"operand1\" \"operand2\"]}" into (operator operand1 operand2)?

Michael Stokley06:08:46

so far, i'm just doing it with functions. first i transform the map into a list, then i resolve the strings

sundarj06:08:39

yeah, macros are only for transforming Clojure code into different Clojure code, so functions are the way to do it

sundarj06:08:44

instead of resolveing the strings in the function, you can have the function take a map from string to operator

sundarj06:08:25

replicating the resolve behaviour (if you want that), is then just passing in the (ns-map *ns*) map

sundarj06:08:59

well, that has symbols as keys

sundarj06:08:35

if you only want to be able to resolve things from the current namespace, then you can use (ns-interns *ns*) instead

kennytilton07:08:29

@olekss.janis The REPL sometimes distorts what is going on, in this case by insisting on displaying (the P in REPL) the value produced by E. You entered a DO, which returns the value returned by the last form, namely the value returned by (p2). So the REPL itself is triggering the evaluation of the lazy sequence. For fun, try

(do (println "l1") (p1) (println "l2") (p2) 42)

kennytilton07:08:52

Even if (p2) is the last form, it will not necessarily execute.

(let [j (do (println "l1")
            (p1) (println "l2")
            (p2))]
  42)

mfikes16:08:01

I haven’t read all of the backlog, but this doesn’t seem right. do actually “does” when needed, following the spirit of its name. ClojureScript optimizes by eliding some non-side-effecting non-last expressions in a do (and perhaps Clojure does as well).

kennytilton07:08:41

Lazy sequences are quite the gotcha for folks not accustomed to them, and sometimes even us. This is one of those deals where one is always double-checking oneself. The best rule of thumb is to use doseq for side-effects, and to think twice if one finds oneself coding doseq nested under any lazy generator.

quadron12:08:36

How do I edit the leiningen app template to update the clojure version to 1.9.0 in the project.clj file?

quadron12:08:23

"lein new app new-project" still generates a "project.clj" with clojure 1.8.0

quadron13:08:53

i alread have 2.8.1

quadron13:08:07

besides, it is a template thing

Patrick Hildreth14:08:51

edit your ~/.lein/profiles.clj this is the default profile lein initially builds to

Patrick Hildreth14:08:59

also its worth noting leiningen is still using clojure 1.8

quadron14:08:58

I need to know where the app template is stored

quadron14:08:18

chainging leiningen configuration does not affect the app template

bhauman13:08:46

@sooheon glad you liked the tutorial!!

mg15:08:55

@veix.q5 no, they do different things. byte-streams handles type conversion. gloss handles binary format deserialization.

quadron15:08:47

@michael.gaare hmmm, since gloss is archived, I was wondering if some other lib has deprecated it?!

mg16:08:29

Not sure, I think he just decided to stop working on it maybe

bj18:08:06

What is the conventional meaning around surrounding or prefixing vars with asterisks (*)?

hiredman18:08:12

dynamic var

hiredman18:08:27

something that may be rebound using binding

kennytilton19:08:44

@bj Here is a little on dynamic vars: https://clojure.org/reference/vars In Lisp we call tem special variables, and some refer to the asterisks as earmuffs.

kennytilton19:08:21

Dynamic vars are insanely useful when needed (often by library code) where a suite of functions will expect to be operating in some context or other and we do not want to be forever passing around this extra “context” variable. Former Mac QuickDraw programmers will un-fondly remember juggling the global grafPort.

mfikes21:08:06

One thing that may help avoid confusion with earmuffs (at lest for ClojureScript devs) is that this Clojure warning will appear in the next ClojureScript release:

cljs.user=> (def *foo* 3)
WARNING: *foo* not declared dynamic and thus is not dynamically rebindable, but its name suggests otherwise. Please either indicate ^:dynamic *foo* or change the name at line 1 <cljs repl>

Chase22:08:32

so I've been loving this (doc f) capability in the REPL. Can I get something like that for java things? like a quick example from a tutorial used (Integer. str) which is pretty self explanatory but am I going to be coming across more java stuff like that and if so how do I look up the docs?

Chase22:08:55

well i assume that was java. maybe it's a clojure thing too but (doc Integer.) didn't return anything

lilactown22:08:56

yeah that’s correct, (<Object name>.) is syntax for constructing a new Java object in Clojure

lilactown22:08:29

unfortunately I don’t believe Clojure gives a defined way of obtaining docs of Java code

lilactown22:08:09

Java does not really have a language-level way of associating docstrings with a class or method

lilactown22:08:00

what you can do is: 1. Open a browser and Google the class name (kinda sucks) 2. Use an editor that can go-to the definition site, like Cursive (maybe Emacs does this too?)

Chase22:08:01

ok, cool. i'll explore my spacemacs stuff and ask on that channel if i can't find anything. i think it will have something because it does autocomplete the java stuff so it's recognizing it somehow.

Chase22:08:51

yeah it seems cider has a way to send me straight to the relevant javadoc. cool stuff!

Chase22:08:19

now whether i can do anything with that big ole doc page remains to be seen. hahaha. i'm sure it builds up with experience though

Chase22:08:06

if I do find some cool capability with a java method or something can i assume i will be able to use that within my clojure functions?

lilactown22:08:47

yep, that’s one of the beautiful things about Clojure - we have access to all of Java as well 🙂

lilactown22:08:09

it’s not always great to use Java APIs though… they are usually built in a way that is very mutable and object-oriented

Chase22:08:46

makes sense. thanks

andy.fingerhut22:08:11

@chase-lambert Try this in a REPL: (require '[clojure.java.javadoc :as jd]) followed by (jd/javadoc Integer)

andy.fingerhut22:08:29

When I do that, it opens a browser to the Java doc page for class Integer

Chase22:08:16

yup, that worked too, sends me to the same place the cider-doc link goes to.

Chase22:08:58

quick namespace question. if you called clojure.java.javadoc :as jd why do i still need to write (jd/javadoc ...) instead of just (jd ...)

Chase22:08:05

does every namespace specific call need the / ala (foo/bar ...) so it knows i'm calling a namespace? not sure if i'm using these words correctly.

andy.fingerhut22:08:52

@chase-lambert In a REPL, it is probably more common to want to avoid typing namespaces, and also to avoid typing "namespace aliases", which is what the "jd" is called in my example. You could instead do (use 'clojure.java.javadoc) followed by (javadoc Integer).

andy.fingerhut22:08:25

The namespace clojure.java.javadoc might have many functions, constants, etc. in it other than javadoc.

dpsutton22:08:30

clojure.java.javadoc is a namespace. it contains a function named javadoc

Chase23:08:21

ahh. so i'm basically saying (clojure.java.javadoc/javadoc ...)?

andy.fingerhut23:08:52

yes, which you can get explicitly if you change my example to (require 'clojure.java.javadoc) followed by (clojure.java.javadoc/javadoc Integer).

andy.fingerhut23:08:33

In code saved in a file, it is very common to create and use short namespace aliases, like the "jd" in my first example. At the REPL, it is common to use either those, or use to avoid them completely, as long as the names of things in the namespace you are use-ing do not collide with your names. It is fairly uncommon to use the use variant in code saved in a file, because then it can be difficult when reading the code to determine which namespace different names originally came from.

Chase23:08:01

gotcha. good stuff