Fork me on GitHub
#beginners
<
2018-06-14
>
dylanrdrake01:06:37

What is the best method to wrap a reagent/render to make sure the element is loaded and not get the "Target container is not a DOM element" exception?

lee.justin.m01:06:52

@dylanrdrake what are you trying to do? i’m not sure i follow

dylanrdrake01:06:21

trying to render a component right when the page loads. I'm getting a "target container is not a DOM element" exception. I think the render is being evaled before the page is done loading @lee.justin.m

lee.justin.m02:06:48

so you typically do something like

(defn mount-root []
  (reagent/render [#'react-dnd-component]
    (.getElementById js/document "app")))
and then you stick a script tag below the <div id="app"></div>

dylanrdrake02:06:41

aaahhhhh got it. thanks @lee.justin.m

dylanrdrake04:06:49

when receiving an edn string in the body of the response from the server, what is the recommended way to read that edn into a reagent/atom? cljs.reader/read-string?

kwcharllie37906:06:01

Is there way to watch inner key of the atom? I mean I know that I can watch primitives, but what if I want to watch the :name key in { :name ‘Karol’ } map.

kwcharllie37906:06:27

I want to simulate the store.

lady3janepl08:06:46

can you (declare) a name that you will later define via (defn-) in the same namespace (will it still result in a non-public definition)?

dl08:06:31

hey guys

dl08:06:57

should one learn another lisp like scheme, racket or common lisp before learning clojure?

gklijs05:06:46

Clojure was my first lisp, goes fine.

carr0t09:06:53

Actually, that's a lie. I did Scheme back in college. But that was about 16 years ago and I didn't remember any of it when I started doing Clojure. Also I am no convinced such outdated knowledge would have helped anyway 😉

curlyfry09:06:23

@dl I didn't and don't see any particular reason to!

curlyfry09:06:42

@kwcharllie379 I don't think there's such a function in core.

curlyfry09:06:32

But you could write your own:

curlyfry09:06:29

(defn add-key-watch [reference watch-key map-key on-map-key-change]
  (add-watch reference watch-key
             (fn [_ _ old-map new-map]
               (let [old-value (old-map map-key)
                     new-value (new-map map-key)]
                 (when (not= old-value new-value)
                   (on-map-key-change old-value new-value))))))

;; Usage
(def a (atom {:foo 5
              :bar 10}))

(add-key-watch a :my-watch-id :foo (fn [old-value new-value]
                                       (prn "old: " old-value
                                            "new: " new-value)))

;; Repl example
(swap! a update :foo inc)
"old: " 5 "new: " 6
=> {:wat 10, :foo 6}
(swap! a identity)
=> {:wat 10, :foo 6} ;; No print since the value for :foo didn't change

kwcharllie37910:06:40

@ Thank you so much 🙂

duminda09:06:25

I'm having trouble with post endpoint in compojure:

(defapi mgmt-routes
  {:swagger {:ui "/swagger-mgmt-ui"
             :spec "/swagger-mgmt.json"
             :data {:info {:version "1.0.0"
                           :title "Sample API"
                           :description "Sample Services"}}}
;;
  (context "/api/mgmt" []
    :middleware [wrap-session-auth]
    :auth-rules admin?

    (POST "/create_user" req
      :summary "Creates a user with the given username and password."
      (ok
        (println (slurp (:body req)))))))
When sent a request from swagger ui like this:
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/octet-stream' -d '{ \ 
   "username": "test_2", \ 
   "password": "secret" \ 
 }' ''
There's no body received. Been stuck here for about two hours now. Can you point me in the right direction?

ikitommi09:06:44

you should declare you body, something like:

ikitommi09:06:35

(POST "/create_user" []
  :summary "Creates a user with the given username and password."
  :body [body {:username s/Str, :passwod s/Str]
  (ok body))

ikitommi09:06:07

the request :body is parsed automatically and the parsed body is found under :body-params.

ikitommi09:06:33

so, this would work also:

(POST "/create_user" req
      :summary "Creates a user with the given username and password."
      (ok
        (println (:body-params req))

ikitommi09:06:43

hope this helps, ping @

duminda09:06:39

@: Thanks, however, I came to this after trying the body schema. For example,

(POST "/create_user" req
      :summary "Creates a user with the given username and password."
      :body [body {:username schema/Str :password schema/Str}]
      (ok
        (println body)))))
Will result in an error:
2018-06-14 17:51:03,516 [XNIO-2 task-23] INFO  compojure.api.exception - Request validation failed: [email protected] 
clojure.lang.ExceptionInfo: Request validation failed: [email protected]
	at clojure.core$ex_info.invokeStatic(core.clj:4739) ~[clojure-1.9.0.jar:na]
	at clojure.core$ex_info.invoke(core.clj:4739) ~[clojure-1.9.0.jar:na]
	at compojure.api.coerce$coerce_BANG_.invokeStatic(coerce.clj:61) ~[na:na]
	at compojure.api.coerce$coerce_BANG_.invoke(coerce.clj:53) ~[na:na]
	at water.routes.services$fn__61132$fn__61133.invoke(services.clj:270) ~[na:na]
	at compojure.core$wrap_response$fn__30542.invoke(core.clj:158) ~[na:na]
	at compojure.core$wrap_route_middleware$fn__30526.invoke(core.clj:128) ~[na:na]
	at compojure.core$wrap_route_info$fn__30531.invoke(core.clj:137) ~[na:na]
	at compojure.core$wrap_route_matches$fn__30535.invoke(core.clj:146) ~[na:na]
	at compojure.api.routes.Route.invoke(routes.clj:74) [na:na]
	at compojure.core$routing$fn__30550.invoke(core.clj:185) [na:na]
	at clojure.core$some.invokeStatic(core.clj:2693) [clojure-1.9.0.jar:na]
	at clojure.core$some.invoke(core.clj:2684) [clojure-1.9.0.jar:na]
	at compojure.core$routing.invokeStatic(core.clj:185) [na:na]
	at compojure.core$routing.doInvoke(core.clj:182) [na:na]

duminda09:06:34

My handler:

(mount/defstate app
  :start
  (do
    (start-router!)
    (middleware/wrap-base
      (routes
        (-> #'home-routes
            (wrap-routes middleware/wrap-csrf)
            (wrap-routes middleware/wrap-formats)
            (wrap-authentication auth-backend))
        (-> #'service-routes
            (wrap-authentication auth-backend))
        (-> #'mgmt-routes
            (wrap-authentication auth-backend)
            wrap-params)
        #'websock-routes
        #'auth-routes
        (route/not-found
           (:body
             (error-page {:status 404
                          :title "page not found"})))))))

ikitommi09:06:21

Hmm.. is there a response body with schma error as json?

ikitommi09:06:35

clojure.lang.ExceptionInfo: Request validation failed: [email protected]

ikitommi10:06:06

is changed in some later version to include the human readable error instead of object pointer

duminda10:06:49

The response body is quite long, here's the beginning:

<!DOCTYPE html>
<html><head><meta charset="utf-8"></meta><title></title><link rel="stylesheet" href="/prone/1645105518/prone.css"></link></head><body><div id="ui-root"></div><input type="hidden" id="script-replacement-string" value="DQ59MP"></input><script type="text/json" id="prone-data">{:title nil, :location "/api/mgmt/create_user", :error {:message nil, :type "java.lang.NullPointerException", :class-name "NullPointerException", :frames [{:file-name "exception.clj", :line-number 58, :class-path-url "compojure/api/exception.clj", :loaded-from "compojure-api-1.1.12", :method-name "request-parsing-handler", :package "compojure.api.exception", :lang :clj, :id 0, :source {:code "(ns compojure.api.exception\n  (:require [ring.util.http-response :as response]\n            [clojure.walk :as walk]\n            [compojure.api.impl.logging :as logging]\n            [schema.utils :as su])\n  (:import [schema.utils ValidationError NamedError]\n           [com.fasterxml.jackson.core JsonParseException]\n           [org.yaml.snakeyaml.parser ParserException]))\n\n;;\n;; Default exception handlers\n;;\n\n(defn safe-handler\n  \"Writes :error to log with the exception message & stacktrace.\n\n  Error response only contains class of the Exception so that it won't accidentally\n  expose secret details.\"\n  [^Exception e data req]\n  (logging/log! :error e (.getMessage e))\n  (response/internal-server-error {:type \"unknown-exception\"\n...

duminda10:06:27

These error messages and clojure stacktraces are killing me.

ikitommi10:06:19

something strange in the overall configuration, as by default, c-api gives you readable schema errors by default.

ikitommi10:06:51

if you can push you code somewhee, I can try to figure out what is happening there. Have you used the swagger-ui to test the endpoints?

duminda10:06:31

@ : Thanks for the help. I’m away from desk now, but when I get time, I will try to create a minimal example with the problem. (I can’t post my code as-is because it’s work-related). Perhaps in trying to create a minimal example, I will figure out the problem myself. Thanks for the guidance again.

jumar12:06:32

Probably not important, but you are returning nil (the result of println) as a the response body.

saara.m.pakarinen12:06:40

Hi everyone, I'm very new to Clojure and ClojureScript. I was wondering if there was a good tutorial for learning javascript interop with clojurescript. Especially using external libraries with interop would be appreciated. Thanks in advance. :)

saara.m.pakarinen15:06:35

Hi, thanks for the link. It wasn't really what I was looking for. I have a javascript code using a javascript library but I haven't been able to make it work in clojurescript. There's an interop for javascript which means that I can call javascript library functions in a clojurescript code and mix them up. I haven't been able to find anything very useful on the subject. I was wondering if anyone here might be able to help. :)

saara.m.pakarinen15:06:48

In other words I'd like to use the javascript library in clojurescript. Just like I'm able to call Java in Clojure. :)

lee.justin.m15:06:54

@ there probably should be a tutorial, but I don’t know of one. the good news is that once you actually have a javascript library loaded (which is the hard part), the actual interop is pretty straightforward. if you read up on ., .-, #js, clj->js, and js->clj, you pretty much know what’s going on.

lee.justin.m15:06:17

if you are having trouble, feel free to ask questions here and i’m sure we can get you going

saara.m.pakarinen05:06:14

Thanks very much 🙂 I'll post some code here if I get really stuck.

dylanrdrake13:06:52

I'm building an SPA with Clojurescript (Reagent) for the frontend, Clojure on the backend and edn over the wire. My server is responding to ajax calls with edn strings in the body of the response. What is the recommended way to read that edn into a reagent/atom? cljs.reader/read-string?

lee.justin.m16:06:08

@dylanrdrake I don’t know (I just use json), but from hanging out here, I think most people use transit as a wire protocol when they want to be more clojurey rather than edn. I could be wrong though.

dylanrdrake16:06:30

yeah I'm trying to use all Clojure throughout the application just for the sake of doing it and learning. I eventually even want to try out Datomic for the db and leverage it's unique take on time. Thanks, I'll look into transit.

mhadaily14:06:02

Sorry If I am asking a trivial question, we are using immutant which apparently under the hood is using undertow as a web server. I could manage to enbale http/2 which seems like

(mount/defstate ^{:on-reload :noop}
                http-server
                :start
                (http/start
                  (-> env
                      (assoc :handler (handler/app))
                      (update :http2 true)
                      (update :io-threads #(or % (* 2 (.availableProcessors (Runtime/getRuntime)))))
                      (update :port #(or (-> env :options :port) %))))
                :stop
                (http/stop http-server))
however, I am struggling to enable compression for my content such as Gzip or deflate. Does anybody have an experience with it and know how I can do that ? BTW, I have searched and it seems I cannot find a good documents regarding this in Clojure. Any advice is highly appreciated.

erp1214:06:40

After a few months of trying to better utilize deftype to define new data structures, there is one thing I am consistently getting tripped up on. Let's say I know which Clojure core functions I would like to use to manipulate the data structure purely based on a semantic understanding of the existing Clojure functions. How do I know what prototcol/interface/objects to implement in the deftype?

lee.justin.m16:06:15

@ if you know the name of the protocol, you can hop into the repl and look at the source for the protocol. e.g.:

cljs.user=> (source ILookup)
(defprotocol ILookup
  "Protocol for looking up a value in a data structure."
  (-lookup [o k] [o k not-found]
    "Use k to look up a value in o. If not-found is supplied and k is not
     a valid value that can be used for look up, not-found is returned."))

erp1216:06:09

@lee.justin.m Thanks thats a handy tip. I was more asking about how to determine which of the clojure.lang interfaces are appropriate to implement for a given data structure. For example, if I know what behavior I want to see when I call (nth ds 5), where ds is my new data structure, how do I know what interface to implement to achieve that.

lee.justin.m16:06:36

@ oh well same trick. look for implements? conditionals

lee.justin.m16:06:44

in the source of the function

lee.justin.m16:06:04

my favorite feature of the language is that you can just dive into the source. if you have a good editor you can just do it straight from there

lee.justin.m16:06:12

it would be interesting if there was a more programmatic way to see what protocols a method belongs to (i’m not even sure if that’s the proper way to phrase it) but i don’t know of one

erp1216:06:29

Your suggestion of looking for implements? sounds exactly like what I wanted, but I might be missing something. I just tried it for nth and got this:

=> (source nth)
(defn nth
  "Returns the value at the index. get returns nil if index out of
  bounds, nth throws an exception unless not-found is supplied.  nth
  also works for strings, Java arrays, regex Matchers and Lists, and,
  in O(n) time, for sequences."
  {:inline (fn  [c i & nf] `(. clojure.lang.RT (nth ~c ~i [email protected])))
   :inline-arities #{2 3}
   :added "1.0"}
  ([coll index] (. clojure.lang.RT (nth coll index)))
  ([coll index not-found] (. clojure.lang.RT (nth coll index not-found))))
But I see no mention of implements?. I know from trial and error that I should be looking for something like clojure.lang.Indexed.

lee.justin.m16:06:25

weird the source in clojurescrip is totally different and contains this:

(implements? IIndexed coll)
      (-nth ^not-native coll n)

lee.justin.m16:06:54

I wonder if my trick is cljs specific

erp1216:06:48

ah ok. Thats too bad, thanks anyway though!

lee.justin.m16:06:22

this is probably worth asking in #clojure because I think whats going on is that some of the lower level functions are falling back to a java protocol. hence the clojure.lang.RT. I think that the “protocol” stuff is a wrapper around java interfaces

lee.justin.m16:06:38

so there’s probably a way there.

noisesmith16:06:14

clojure interfaces / protocols are very granular but you can see them with supers

(ins)user=> (supers (class []))
#{clojure.lang.IPersistentVector clojure.lang.IObj clojure.lang.IPersistentStack java.util.RandomAccess clojure.lang.IKVReduce clojure.lang.Associative clojure.lang.Seqable clojure.lang.IMeta clojure.lang.Indexed clojure.lang.IReduce java.lang.Iterable clojure.lang.ILookup clojure.lang.IEditableCollection clojure.lang.APersistentVector java.util.List clojure.lang.IReduceInit clojure.lang.IHashEq java.lang.Object java.util.Collection clojure.lang.Counted clojure.lang.IFn clojure.lang.AFn clojure.lang.Reversible java.util.concurrent.Callable java.lang.Comparable clojure.lang.Sequential java.lang.Runnable clojure.lang.IPersistentCollection java.io.Serializable}
(ins)user=> (supers (class ()))
#{clojure.lang.IPersistentList clojure.lang.IObj clojure.lang.IPersistentStack clojure.lang.ISeq clojure.lang.Seqable clojure.lang.IMeta java.lang.Iterable java.util.List clojure.lang.IHashEq java.lang.Object clojure.lang.Obj java.util.Collection clojure.lang.Counted clojure.lang.Sequential clojure.lang.IPersistentCollection java.io.Serializable}

noisesmith16:06:59

to nitpick, java has no protocols, only interfaces, and most of clojure.core uses interfaces

lee.justin.m16:06:48

so how do you tell what interfaces/protocols a function like nth implements (or reifies or whatever the right word is)

erp1216:06:13

@ Thanks! supers get's me part of the way there, but its about the source for the PersistentVector etc.

noisesmith16:06:58

@lee.justin.m if you follow the functions nth calls down the call stack, eventually you get to interface methods

noisesmith16:06:50

@ that source is all in clojure.core and it follows a typical java project structure, it can be helpful to use a java editor on the clojure.core source or at least get a nice tree navigator plugin for github

erp1216:06:46

@ So if we look at the implementation of nth here: ([coll index] (. clojure.lang.RT (nth coll index))) where would I look next to eventually end up on something that tells me clojure.lang.Indexed?

noisesmith16:06:27

src/jvm/clojure/lang/RT.java, which will define an nth method

noisesmith16:06:39

so either Indexed or something nthFrom (defined right after that) accepts

noisesmith16:06:03

definitely go with Indexed

lee.justin.m16:06:27

interesting! thanks @ that was illuminating (for me at least)

noisesmith16:06:14

there can be a mental block to going and reading the java, but it's not as bad as you might fear, and actually quite sane and simple for a java codebase for the most part

erp1216:06:32

Ah gothca! That is awesome, thanks! So it looks like RT.java is going to hold the answers for this kind of thing. I checked (source %) for conj, get, nth, and count and they all basically just call a function in RT.java

erp1216:06:58

Probably a total noob question here but.... what does RT stand for?

noisesmith16:06:17

right - there's other interesting classes in that same clojure/lang directory but RT has a lot of the interesting stuff

erp1216:06:45

Ah of course. Thank you so much. You saved me a bunch of time.

noisesmith16:06:45

it's the code clojure needs to actually run (not just compilation stuff)

orestis14:06:06

Does anyone have a good story for SublimeText 3? SublimeREPL is the only thing that claims it’s working but it’s lein only, and even in this case I couldn’t make it work.

scott.archer15:06:57

Any suggestions on clojure editors? I’ve tried several and keep bumping into rough edges.

scott.archer15:06:17

I liked Nightcode, but I couldn’t get it to work with Clojure 1.9

dpsutton15:06:13

Recent survey results said half are in emacs and cider. I think cursive is the most polished and it's Rock solid. I like cider and emacs though

scott.archer15:06:14

Maybe that was light table. I don’t recall. I’m using atom now, which is pretty decent.

scott.archer15:06:46

I tried cursive and just didn’t like it. I need to try emacs I guess. I used it 20 years ago.

orestis15:06:20

Atom and VSCode are getting some attention, yes. Spacemacs is a nice default Emacs setup that’s gotten popular with Vim people.

scott.archer15:06:52

Are most devs using Linux / Mac? I’m on windows and that may be why I’m hitting some of these rough edges.

orestis15:06:40

Yes, that’s common in Windows, apparently. Are you using WSL?

dpsutton15:06:48

There's a thread on clojure verse about Windows specific stuff. Consensus was that it was really good with a few workarounds

scott.archer15:06:35

Also I wasn’t aware of Clojure verse, thanks!

scott.archer15:06:23

Windows Subsystem for Linux?

jeremy64215:06:08

I use windows and I use Spacemacs (coming from a heavy vim background).

jeremy64215:06:28

For Java I use IntellIJ and thought about picking up Cursive at some point but never made the plunge.

kyselyradek15:06:11

How can you guys deal with Emacs? 😄

kyselyradek15:06:39

I feel like its capabilities to navigate to project are so bad

lee.justin.m16:06:36

i used emacs for 10 years and i’m never going back 🙂 i miss atom in many ways but cursive is just too solid not to use. plus @cfleming is a great guy and hangs around here and i like supporting him

seancorfield16:06:12

@radekdymacz (and @scott.archer and others) If you want to try a curated Emacs package setup, take a look at Prelude -- maintained by the same guy who leads CIDER etc. It adds much better command completion, project navigation, and so on. I tried a number of curated Emacs setups but that seemed about the best (for Clojure development).

seancorfield16:06:50

That said, after using Emacs 20+ years ago, then coming back to it for about two years while doing Clojure, I switched to Atom/ProtoREPL and have been happy with that.

seancorfield16:06:23

Emacs takes a huge amount of work to get used to -- but most people who get anywhere close to mastery will never go back to other editors.

dpsutton16:06:06

i've been on prelude my entire emacs career.

dpsutton16:06:14

i like that all my environments look and act the same. editing clojure, scheme, go, random bash files, text files, log files, they all behave the way i'm used to

dpsutton16:06:44

for some, that would also include email, calendar, organization, irc, rss, and on and on. for a particular tool it may not ever be the best. for a set of tools it's proven quite nice for me

erp1216:06:44

All that matters to me re editor is that I can disable parainfer/paraedit and Atom's modular packages gave me that and I already used it for other languages.

kyselyradek16:06:48

Thanks for pointing me to this. I’ll definitely try it. So far I’m used to NeoVim (because regular Vim doesn’t support asynchronous plugins) but am still looking at Emacs since I started learning Clojure

kyselyradek16:06:59

Side question: do you run Emacs standalone or inside terminal?

dpsutton16:06:38

although there's #editors if there are more questions, discussions i guess

noisesmith16:06:34

btw emacs doesn't do multi-threading like nvim

noisesmith16:06:59

but it has a much richer ecosystem of code, and a much nicer extension language for coding in

troglotit16:06:30

Everyone who’s coming from (neo)vim to emacs should check spacemacs (#spacemacs) - I switched from vim, although I had only few months experience back then

dpsutton16:06:05

emacs just dipped its toe into multithreading with the 26 release. but it is far from pervasive

noisesmith16:06:56

I switched to vim (then nvim) from emacs

noisesmith16:06:37

I used emacs with evil mode but I got tired of long editor start up, freezes for long lines our repl output in a buffer, and crashes from bad elisp code

dpsutton16:06:42

yeah the long lines are just turrible

dpsutton16:06:12

also, i was writing some elisp code the other day that used (let ((comment-start ... and it broke emacs because that's a global variable and elisp is a dynamic lisp

noisesmith16:06:07

yeah, when doing hardcore elisp hacking I find I need to have one emacs open for editing the final code, and a second (started with emacs -q ideally) for testing the code

noisesmith16:06:24

nothing worse than a bug in your code killing the editor you use to fix the bug

dpsutton16:06:53

Yeah. And working now doesn't guarantee it'll work up when up restart. That's always a pain

noisesmith16:06:23

the -q flag does help there - starting without any of your other libs loaded

dpsutton16:06:17

Oh I mean like closures that are hanging around or variables you defined and then changed and old state is laying around

lee.justin.m17:06:42

is there an into for more than two collections?

dfcarpenter18:06:08

Does core.async utilize all the cpu cores like golang or elixir?

noisesmith18:06:16

@lee.justin.m you can kind of get that via the cat transducer (into coll cat [c1 c2 ... cn])

noisesmith18:06:06

@dfcarpenter on the jvm where multiprocessing exists, yes

jeremy64218:06:00

@kyselyradek I came from just vim vim and setting up a ton of dotfiles myself. Emacs took a couple days to figure out but once I figured a few commands in Spacemacs, the rest came naturally for project handling and window navigation. Document editing for me is just vim so it really just expanded vims capabilities.

scott.archer18:06:56

I’m trying to read a list of files in a directory using clojure and then get the absolute path. How do I go from what I believe is a Java array of File objects to a vector of strings containing the absolute path of each file?

jeremy64218:06:12

Versus a real IDE, I only use spacemacs for Clojure. I use VSCode for JS, IntelliJ for Java... I'm pretty IDE agnostic but Spacemacs has been pretty easy to use and gets me into the groove of using shortcuts for navigation instead of clicking everything with my mouse.

scott.archer18:06:17

When I try to map .getAbsolutePath across the array it doesn’t recognize .getAbsolutePath.

noisesmith18:06:32

@scott.archer methods are not first class, so can't be passed as arguments on the jvm, you can create a lambda with a a method call in it, functions are first class as they are objects

scott.archer18:06:36

I’d also like to filter the array by .isDirectory

noisesmith18:06:52

#(.getAbsolutePath %)

noisesmith18:06:18

same process with isDirectory

scott.archer18:06:01

Awesome thanks!

scott.archer18:06:21

So since it can’t reference the function, you define a function that calls that method on whatever is passed in.

scott.archer18:06:32

And that’s what you can pass to map, etc.

scott.archer18:06:41

It seems to be working.

noisesmith18:06:10

it can reference functions- instances of clojure.lang.IFn

noisesmith18:06:19

it can't reference methods (behaviors of classes)

noisesmith18:06:29

this is why there's two different words for these things

scott.archer18:06:32

I think I understand.

scott.archer18:06:13

Map takes a function as a parameter, .getName isn’t a function, but you can define one on the fly that calls the .getName method on it’s input and returns that.

noisesmith18:06:15

there are objects that reify and describe methods in reflection packages but those aren't really methods either - they describe methods

noisesmith18:06:58

@scott.archer that's correct - I nitpick on function vs. method because the distinction is an important one to understand

scott.archer18:06:00

I get it now, thanks for the help, I would have been stumped on that one for a while.

dylanrdrake18:06:49

I have a web app that is kind of a hybrid SPA. The home, login and create-new-user pages are all separate routes until the user logs in. Then they are served the SPA. I'm trying to get figwheel configured but when i run lein figwheel then navigate to localhost:3449 in my browser i am presented with this: Figwheel server: Resource not found I don't have any .html files in my app. Everything is generated via hiccup. How do you config figwheel to work with my client app that is behind some other routes? Edit: never mind. I think I figured it out. I was mounting the app component incorrectly.

bj19:06:25

Is this an idiomatic way to ensure that all entries in a list are the same?

(every? (partial = (first coll)) (rest coll))

alexmiller19:06:28

you can (apply = coll)

porkostomus21:06:10

In Clojure I can fetch the HTML contents of a URL with (slurp "https://www.whatever.com"). How would I do it in ClojureScript?

porkostomus21:06:04

and as a follow-up question (I'm new here), how do you type code snippets in these threads?

noisesmith21:06:11

use three backtick on each side for multi-line, and one backtick on each side for individual items

noisesmith21:06:51

I don't know how to easily quote the three-backtick, but you likely get the idea

porkostomus21:06:43

thanks,

I figured it was something like that

dl21:06:18

do you think I should learn racket or scheme or common lisp before clojure?

noisesmith21:06:36

racket is well optimized for new learners

noisesmith21:06:02

but clojure is a reasonable first lisp if you can ignore the weird stuff at first

noisesmith21:06:23

(weird stuff being the jvm integration, which is less important when first learning)

dl21:06:37

ok interesting

dl21:06:46

I have bought the getting clojure book

dl21:06:48

and started working on it

porkostomus21:06:42

I came to Clojure from Scheme which I learned because of SICP. But I see less purpose in going the other direction. Just go right to Clojure!

dl21:06:48

but somewhere I read that racket or scheme were cleaner lisps

dl21:06:14

and other people say: learning racket to learn clojure easier is like learning french to learn spanish easier

dl21:06:23

so I didnt really know who to listen to lol

dl21:06:10

there is the SICP book for clojure already: http://www.sicpdistilled.com/

porkostomus21:06:34

holy crap! I was thinking of making that same thing, guess I'm too late

dl21:06:18

yeah it is just my fear of missing out that keeps me looking if the grass is greener when learning another lisp first lol

scott.archer21:06:43

Ok another question. I’m trying to use shell/sh to execute a command, but I want to build the argument list as a vector and pass it to sh.

scott.archer21:06:54

Is there a way to do that?

noisesmith21:06:32

that's easier to do with ProcessBuilder / Process I think, but not hard

scott.archer21:06:49

Ok, so I should look at process builder instead of sh

noisesmith21:06:06

wait - just use apply

noisesmith21:06:40

user=> (apply clojure.java.shell/sh "ls" ["-l" ".."])
{:exit 0, :out "total 722808\ndrwxr-xr-x   3 justin.smith ..."}

noisesmith21:06:13

apply takes any number of args before a coll to unpack as args

scott.archer21:06:33

That’s quite useful ha.