This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-05-15
Channels
- # announcements (2)
- # aws (52)
- # beginners (326)
- # cider (24)
- # clara (7)
- # clj-kondo (14)
- # cljs-dev (175)
- # clojure (183)
- # clojure-ecuador (2)
- # clojure-europe (4)
- # clojure-italy (11)
- # clojure-nl (1)
- # clojure-norway (1)
- # clojure-spec (5)
- # clojure-sweden (5)
- # clojure-uk (103)
- # clojurescript (49)
- # cursive (29)
- # data-science (9)
- # datascript (17)
- # datomic (23)
- # emacs (6)
- # events (4)
- # fulcro (19)
- # graalvm (8)
- # graphql (2)
- # hoplon (36)
- # jobs (1)
- # jobs-discuss (92)
- # juxt (3)
- # luminus (10)
- # off-topic (4)
- # pedestal (8)
- # planck (1)
- # re-frame (59)
- # reagent (1)
- # reitit (22)
- # rewrite-clj (8)
- # ring-swagger (3)
- # shadow-cljs (101)
- # spacemacs (15)
- # tools-deps (36)
- # vim (68)
^ +1 to that. It's pleasantly surprising how cheap short-living garbage is on modern VMs.
Why some of the functions defined this way?
(def
^{:arglists '([x])
:doc "Return true if x is a String"
:added "1.0"
:static true}
string? (fn ^:static string? [x] (instance? String x)))
i'm not sure if this one in particular is due to this but you might be seeing workarounds to the bootstrap problem. If defn
hasn't been defined yet then you can't use that form. And i imagine that defn
uses string?
so this must come before that
This is a bit algorithmic-specific rather than Clojure-specific but I'm new to functional/clojure and that's making this extra difficult.
I'm trying to create a seq of all combinations of sublists of a list.
So [1 2 3]
becomes [ [[1] [2] [3]], [[1] [2 3]], [[1 2] [3]], [[1 2 3]] ]
Are you looking for a library that has a function that does that, or are you looking to write a function yourself?
@ericihli https://github.com/clojure/math.combinatorics/blob/master/src/main/clojure/clojure/math/combinatorics.cljc
Idan, I'm curious how it's done. If there's a library, that's enough I could read the implementation and get a little bit of an understanding.
Ivan, I looked at the combinatorics library and couldn't find the answer there. It's not quite subsets because order and position matters. For example, I can't have [1 3]
or [2 1]
in my result set from [1 2 3]
input.
Maybe partitions would be a better choice for you than?
From the combinatorics GitHub page:
=> (combo/partitions [1 1 2])
(([1 1 2])
([1 1] [2])
([1 2] [1])
([1] [1] [2]))
That's totally it! Thanks! I even freaking saw function in there about 2 hours ago and it didn't register that it was what I was looking for and I spent the next two hours trying to figure it out.
Ah I think I know what happened. I scanned the list of functions in combinatorics, I saw "partition" and thought that might be it, so I googled "clojure partition" and saw https://clojuredocs.org/clojure.core/partition and that's totally not it.
Bah. No. Even that's not quite right.
(combo/partitions [1 2 3])
(([1 2 3]) ([1 2] [3]) ([1 3] [2]) ([1] [2 3]) ([1] [2] [3]))
I can't have ([1 3] [2])
in there. I can just filter out any flattened sublist that isn't in the correct order.@ericihli permutations creates a lazy sequence of calls to iter-perm
function in one or another way
well, i was a bit wrong here, authors redirect us to a book
Most of these algorithms are derived from algorithms found in Knuth's wonderful Art of Computer Programming books (specifically, the volume 4 fascicles), which present fast, iterative solutions to these common combinatorial problems. Unfortunately, these iterative versions are somewhat inscrutable. If you want to better understand these algorithms, the Knuth books are the place to start.
Hi all. How to require spec defined in another file (namespace) with
(s/def ::my-string string?)
?This seems to work:
(s/valid? ::hs/my-string word)
where hs
is the alias I gave to the spec namespace. Is this the way I shoud refer to spec def in another namespace?Nope, that’s good
TL;DR - Need help with deploying a shadow-cljs project to heroku. Would anyone be able to answer some questions about deployment to heroku? I have a test project here: https://github.com/andreortiz82/middlemancljs I’m trying to deploy it to heroku but I’m not sure what the incantations are. * What build packs do I need? Ruby, Node, Java - all of them? * What should the Procfile contain? * Who the heck sent me down this wacky path in the first place?! 👉 this guy @bobnadler (only slightly kidding 😉 ) If anyone has the time to assist (or sync on a zoom call) - that would be great!
Not sure. I guess you need Java to be able to build it (since cljs/shadow uses Google Closure compiler written in Java) and Node to run it. You could ask in #shadow-cljs, perhaps.
Where should we ask jdk questions? I've been trying out adoptopenjdk
with openjdk 11. I am also exploring graalvm so installed the community edition and put that in my path. Now (on linux debian) whichever export statement I have last in my .profile
turns into my default jdk. If graalvm path is last then my java -version
is java 8 graalvm with no mention of adoptopenjdk. vice versa with java 11 if i have adoptopenjdk last. How does this affect my clojure software development? Are these two going to coincide peacefully or will my various projects be all screwed up depending on which one I used to start a project or run a project? Sorry if this is too convoluted.
ok cool. I think I will just keep adoptopenjdk 11 as my default and try to bring graalvm to the forefront whenever I want to explore creating a native binary. Which is different than the "native image" thing you just mentioned right? I was thinking the whole benefit of clojure folks trying graalvm was to compile to native binaries.
Has anyone here had a good experience with the http://purelyfunctional.tv service? I think I am going to drop for the membership but just want to hear a testimonial to put my mind at ease first
I've personally have had a great experience with it. Eric is super responsive too and always willing to help out. It helped me to understand some hard concepts like reduce
, destructuring
, for
, etc. I haven't got through much yet but I'm liking what I've seen so far.
Thanks! I think it will be a worthwhile investment. Good to hear that it seems to be well curated
Yeah I think he has a good feel for how to present the material in an understandable way. The clojure community is super supportive and there are great resources but I think it's hard to put yourself back in the beginner's mind or even intermediate mindset and explain things in simpler terms. I think he finds that balance.
Sometimes I get some great help here but it's like a mile above my head. I haven't felt that with his tutorials

I also think that one is pretty solid - definitely the best one for beginners. Also largest and still growing - unlike (sadly) https://lambdaisland.com/
anyone got a minute to assist with cider nrepl issues ?
What's the issue? I'm not at my machine but I think usually the issues are related to versioning
i'm using nrepl 0.6.0 and cider/cider-nrepl "0.22.0.beta1"
which seem to be the latest
my emacs cider is 0.22.0snapshot
which seems to be most recent versions of everything
i'm trying to embed a repl , build and run an uberjar, and connect to it
the connection from emacs happens (with cider-connect-clj)
and it doesn't complain about version mismatch or anything
but the clj app throws a bunch of exceptions
i launched the repl server like this:
(:require [nrepl.server :as nrepl-server]
[cider.nrepl :as cider])
(nrepl-server/start-server :port 7888 :handler cider/cider-nrepl-handler)
but it can't find namespaces , hangs on eval buffer, throws exceptions like this:
ERROR: Unhandled REPL handler exception processing message {:op complete, :ns user, :symbol co, :context :same, :session 6e561eda-b8f2-400d-b1c6-67485763e6d5, :id 10}
java.lang.NullPointerException
any thoughts ?
can you share more of the stacktrace?
the only unusual thing i'm doing is including compiled classes for grpc stuff
ERROR: Unhandled REPL handler exception processing message {:op out-subscribe, :session 4c15cf3a-fd34-4464-9c70-8c07c8367587, :id 5}
java.lang.NullPointerException
at clojure.core$deref_future.invokeStatic(core.clj:2300)
at clojure.core$deref.invokeStatic(core.clj:2320)
at clojure.core$deref.invoke(core.clj:2306)
at cider.nrepl$wrap_out$fn__10724.invoke(nrepl.clj:290)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at cider.nrepl$wrap_enlighten$fn__10686.invoke(nrepl.clj:162)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at cider.nrepl$wrap_refresh$fn__10736.invoke(nrepl.clj:336)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at cider.nrepl$wrap_tracker$fn__10772.invoke(nrepl.clj:437)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at nrepl.middleware.session$session$fn__10452.invoke(session.clj:272)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at nrepl.middleware.print$wrap_print$fn__10259.invoke(print.clj:234)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at cider.nrepl$wrap_slurp$fn__10654.invoke(nrepl.clj:94)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at nrepl.server$handle_STAR_.invokeStatic(server.clj:18)
at nrepl.server$handle_STAR_.invoke(server.clj:15)
at nrepl.server$handle$fn__10483.invoke(server.clj:27)
at clojure.core$binding_conveyor_fn$fn__5739.invoke(core.clj:2030)
at clojure.lang.AFn.call(AFn.java:18)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
ERROR: Unhandled REPL handler exception processing message {:nrepl.middleware.print/stream? 1, :nrepl.middleware.print/print cider.nrepl.pprint/pprint, :nrepl.middleware.print/quota 1048576, :nrepl.middleware.print/options {:right-margin 70}, :op init-debugger, :session 4c15cf3a-fd34-4464-9c70-8c07c8367587, :id 6}
java.lang.NullPointerException
at clojure.core$deref_future.invokeStatic(core.clj:2300)
at clojure.core$deref.invokeStatic(core.clj:2320)
at clojure.core$deref.invoke(core.clj:2306)
at cider.nrepl$wrap_debug$fn__10680.invoke(nrepl.clj:136)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at cider.nrepl$wrap_inspect$fn__10706.invoke(nrepl.clj:199)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at cider.nrepl$wrap_trace$fn__10766.invoke(nrepl.clj:419)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at cider.nrepl$wrap_macroexpand$fn__10712.invoke(nrepl.clj:243)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at cider.nrepl$wrap_spec$fn__10748.invoke(nrepl.clj:374)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at nrepl.middleware.load_file$wrap_load_file$fn__10366.invoke(load_file.clj:81)
at nrepl.middleware$wrap_conj_descriptor$fn__10059.invoke(middleware.clj:16)
at cider.nrepl$wrap_content_type$fn__10648.invoke(nrepl.clj:82)
it goes on for days like that, i can post it all if that'd help
do you ever get to a java.lang.ClassNotFoundException
?
checking
nope, all null pointer exceptions
gotcha - I was seeing if this was a nrepl
-related issue that was fixed relatively recently with a new snapshot release, but it seems like that's not the case here. unfortunately I don't know enough to help further!
no worries, thanks for giving it a try :thumbsup:
i can fall back to my old workflow - just the classpath stuff with grpc/proto has me recompiling and it kills the repl workflow
so I’m trying to re-create your error, and I when I use cider-nrepl
0.21.1, it works fine
i only started having trouble when i wanted to embed the repl in the jar and connect that way, instead of cider-jack-in
what if you build uberjar and launch embedded repl server ?
let me give it a try with 0.21.1 also
do you know how to force emacs to use older version of cider?
WARNING: CIDER 0.22.0-snapshot requires cider-nrepl 0.22.0-beta1, but you're currently using cider\
|-nrepl 0.21.1. The version mismatch might break some functionality!
same exceptions and behavior (frozen repl) , regardless
How can I run single .clj file without Leiningen?
I tried java -cp clojure.jar clojure.main test-code.clj
but got an error: "Error: Could not find or load main class clojure.main"
I tried to find clojure.jar (and even clojure*.jar) on my machine and there is none.
I installed Clojure with Leiningen (downloaded lein.sh from official site and followed the docs)
for lein, I believe you can do lein run -m clojure.main test-code.clj
lein uses the Maven dependency cache in ~/.m2/repository and so the main clojure jar will be buried in that cache, along with any other dependencies you use.
the main clojure jar has two dependencies as well, so it's slightly more complicated to use it directly
would clojure /path/to/file.clj
not work? Am I mistaken?
you may be interested in the clj
tool as well
@mitchell_clojure it can work if Clojure is installed with standard package manager
clj is a dependency downloader, classpath constructor, and wrapper around clojure.main
i think you can use boot and shebang notation to kick off a clojure file but the clojure.jar still needs to load
like
#!/usr/bin/env boot
(defn -main ....)
then chmod +x it
Ok, I did sudo apt install clojure
which gave me clojure
binary and it's version 1.9. Now I can do clojure my-code.clj
I'm not sure what that clojure
script you're getting is
can you do clojure -Sverbose
?
if that works, then that's cool. if it doesn't, then that's some non-official script being included with the distribution.
also, since you mentioned startup time; if you don't need jvm ecosystem, you may be interested in cljs/node alternative planck for scripting
actually to correct myself planck doesn't depend on node
Right, Planck uses JavaScriptCore, Lumo uses V8, but effectively is a special build of Node
@gr.evocatus If you're up for listening to a podcast, https://vijaykiran.com/2019/04/defn-48-david-miller/ has the best recent overview of everything you might want to know about it before using it
ClojureCLR is basically up to date with the jvm version (David Miller was working on 1.10.0 compatibility)
Looks like there are enough differences between JVM and JS to be extremely careful while prototyping on Planck/Lumo. Even numbers are represented differently (JS doesn't have actual Long Integers)
somewhere there is an incomplete and always growing list of differences between clojure and clojurescript
Does anyone have tips for profiling slow leiningen start up times? I am on a fresh machine, running same java version and lein version as rest of my team, yet start up times are almost double than theirs.
I had to set a large timeout in my profiles.clj to load the same project, otherwise it times out
the first thing to do is to examine the differences between your setup and other people on the team's setup
configuration from sources that don't often get checked in, like a user.clj or profiles.clj, are likely contenders
Hm yeah I did compare profiles.clj
i wonder if maybe it's a network issue with our private maven repo
there is a known performance issue with the latest version of the jdk that has a drastic perf impact if you are using a user.clj file
{:user
{:repl-options {:timeout 120000}}}
in my profiles.cljwhat's your java -version
and do you have a user.clj file?
fetching deps happens after loading right? I do not have a user.clj, using java 1.8.0_202 and lein 2.9.1
java 1.8.0_202 is the first Java 8 build with the issue (also 11.0.2, 12)
but if you don't have a user.clj file, this is probably not the issue.
lein runs two jvms, one for lein one for your project, the repl client runs in the lein jvm and the server runs in the project jvm
ahhh okay
so that indicates the project jvm is slow to start, which sounds like you have a user.clj somewhere
don't think i have a user.clj, i never created one
but let me verify
there's definitely bloat
but not sure why my machine would take more than twice as long to start up
there is a user.clj
in the module itself
checked with (
per @ghadi I think that solves it
sorry the project directory
project/project.clj, project/env/dev/user.clj
whoops
we are working on a dodge around this issue for 1.10.1
excellent, thanks everyone for the help
(soon to be beta3)
Is it possible to use something like pattern matching in multimethods (or build a new multimethod implementation around pattern matching)? I'd like to do something like the following:
(defmatchmulti mm [a b] [a b])
(defmatchmethod mm [1 2] [a b] :a1)
(defmatchmethod mm [_ 2] [a b] :a2)
(defmatchmethod mm [1 _] [a b] :a3)
(defmatchmethod mm :default [a b] :a4)
(mm 1 2) ;; => :a1
(mm 3 2) ;; => :a2
(mm 12 104) ;; => :a4
I looked at core.match, but I'm not sure there's any way for me to build a set of patterns dynamically.
(edited for syntax, added function bindings)I'm working on implementing something that translates underscores to ::no-match
and does the comparison at runtime, but it seems a bit brute-forcey
Here's what I came up with:
(defn create-match-multi
[dispatch]
(let [m-atom (atom {})
matches?
(fn [d-value target]
(and
(not= target :default)
(all (mapv #(or (= %2 ::skip) (= %1 %2)) d-value target))))]
(with-meta
(fn [& args]
(let [d-value (apply dispatch args)
m @m-atom
m-pairs (seq m)
n-pairs (count m-pairs)]
(apply
(loop [idx 0]
(let [m-pair (nth m-pairs idx)]
(cond
(matches? d-value (first m-pair)) (second m-pair)
(< idx (dec n-pairs)) (recur (inc idx))
(contains? m :default) (:default m)
:else (throw (js/Error. (str "Failed to dispatch " args))))))
args)))
{:methods m-atom})))
(defn add-match-method
[mm pattern f]
(swap! (:methods (meta mm)) assoc pattern f))
(defmacro defmatchmulti
[sym bindings & body]
`(def ~sym (create-match-multi (fn ~bindings ~@body))))
(defmacro defmatchmethod [mm pattern bindings & body]
(let [pattern (if-not (= pattern :default)
(mapv #(if (= % '_) ::skip %) pattern)
pattern)]
`(add-match-method ~mm ~pattern (fn ~bindings ~@body))))
This seems to work fine, but again, doesn't use any fancy pattern matching algorithm, it just iterates through the maps's keys.
Clojure Gurus! I yesterday asked how to convert this:
[{:pgid {:S "1"}, :pgname {:S "Books-local-aws"}} {:pgid {:S "2"}, :pgname {:S "Movies-local-aws"}}]
to this:
{"1" "Books-local-aws", "2" "Movies-local-aws"}
I was asking whether there is some solution that doesn't use recur or reduce.
I got two answers:
Solution 1 (my original solution elaborated a bit with Clojure gurus):
(reduce
(fn
[mymap item]
(assoc mymap
(-> item :pgid :S) (-> item :pgname :S)))
{}
items)
and:
Solution 2:
(->> items
(map (juxt (comp :S :pgid) (comp :S :pgname)))
(into {}))
Do real Clojure gurus favor to find a solution based on the standard library (e.g. using map + juxt as in solution 2) or are solutions 1 and 2 equally good?The first I find easier to read, but the second is cooler (I didn’t know juxt
!). I like to go with the code that is the “least surprising” so that would be 1.
That said, wrap your implementation in a function, add a docstring, write a test, and they are equal from a usage perspective 🙂
... and is there some way to "reverse-engineer" some expressions like
(juxt (comp :S :pgid) (comp :S :pgname))
to see what kind of function gets created? It took me some time and mental effort to really understand what was happening there. 🙂@kari.marttila in my experience, reading the doc strings for juxt
, comp
, partial
, and apply
, then translating as many functions as I can into "point free" style as I can with repl experimentation
the idea with point-free is that you eliminate variable names from the code, and those functions in particular allow a specific style of point-free code when used together
and after enough experimentation and forced examples, it gets easier to recognize cases where they will simplify your code
(and along with that, it gets easier to recognize the point free idioms when reading code)
also, learning about lambda calculus might help if you like higher math, or are fond of that style of reasoning
Ok. Thanks. Practice, practice, practice.
Work hard Kari!
haha, and take time in a hammock every now and then 🙂!
All work and no play makes Kari a dull boy. 
What's hammock?
Hammock = a bed made of canvas or rope mesh suspended from two supports by cords at both ends. ?
right, Rich Hickey coined the term "Hammock Driven Development" - his talk about it is good
All right! I'm gonna watch it this night!
my sloppy version is take the time to daydream and think about the implications and look for connections and simpler versions of things before writing too much code
It's a bit funny. I remember reading that term every once in a while in this site (and others) - I always thought that you were referring to Hammond (electric piano) (- I'm not native English speaker). I always thought that it means something like "Enough coding, I go play piano". 🙂
haha, that interpretation actually makes sense even
Yep. I only now bothered to check the word in the dictionary. Never assume anything - always check the dictionary. 🙂
Actually my English teacher at school told us to start reading English novels - and not to use dictionary - "Try to figure out the meaning of a new word from the context". So, I wasn't sure of the word and I somehow must have used the context and interpreted the meaning to refer to electric piano (which I mixed : hammock - hammond).
I think a mixture of "make good guesses from context and see how far you get" and "look up the real definitions of things you think you know" will get you really far in most subjects :D
I have learned a lot about clojure (and programming in general) by intentionally researching things I supposedly know already
In university, I learned a lot from Compiler Construction. I had learned Java in my first year, but didn’t quite understand it until I had to make a compiler targetting java byte code
Point being, sometimes you think you understand something, but there is often so much more below
BTW. These video recommendations are really good. Every time someone recommends a Clojure related video I send an email to myself to remind me to watch the video (my inbox - a kind of task list). E.g. Stuart Halloway's REPL Driven Development was astonishing. I also started to write my REPL stuff in a file instead of REPL editor. I already have a bunch of various expression experiments in my scratch file. All these expressions would have disappeared like tears in rain if I had used REPL editor - now they are eternally in my scratch file for me to browse them through later time to see if I have done something similar in the past.
you can also make watch lists on YT
There is a big list of talks here: https://github.com/tallesl/Rich-Hickey-fanclub
Great! Another email sent to me!
@kari.marttila I usually accompany reading the docstrings with exercising the expressions with simplest possible examples.
user> ((juxt inc dec) 1)
[2 0]
From there it’s easier to jump to
user> (map (juxt inc dec) [1 2 3])
([2 0] [3 1] [4 2])
…and finally
user> (into {} (map (juxt inc dec) [1 2 3]))
{2 0, 3 1, 4 2}
for juxt, I find it's helpful to think of it as opposed to map - map applies the same function to many pieces of data. juxt applies many functions to the same data. (with the difference that juxt returns a function rather than doing the work itsefl)
Good point that juxt can apply any amount of functions
user> ((juxt inc dec str -) 1)
[2 0 "1" -1]
Here is a handy usage of juxt
in a higher order function that I keep in my utility belt:
(defn index-by
([idx-fn coll]
(index-by idx-fn identity coll))
([idx-fn value-fn coll]
(into {} (map (juxt idx-fn value-fn)) coll)))
I use it often when I have a vector of entities and I want to have a map of ID’s to the entities for easy access:
(def ms [{:id 1 :name "kissa"} {:id 2 :name "koira"}])
user> (index-by :id ms)
{1 {:id 1, :name "kissa"}, 2 {:id 2, :name "koira"}}
3-arity version let’s you manipulate the values as well
user> (index-by :id :name ms)
{1 "kissa", 2 "koira"}
And with some comp
magic you can achieve more complex manipulation of keys and values
user> (index-by (comp str :id) (comp string/upper-case :name) ms)
{"1" "KISSA", "2" "KOIRA"}
…and so on. Super powerful!(defn index-by
([keyf coll]
(index-by keyf identity coll))
([keyf valf coll]
(reduce (fn [m v]
(let [k (keyf v)]
(if (find m k)
(throw (ex-info "Duplicate key" {:k k}))
(assoc m k (valf v)))))
{}
coll))
([keyf valf mergef coll]
(reduce (fn [m v]
(let [k (keyf v)]
(if-let [entry (find m k)]
(assoc m k (mergef (val entry) (valf v)))
(assoc m k (valf v)))))
{}
coll)))
I'm following these instructions : https://clojurescript.org/guides/quick-start to get a repl running in a browser. Everything seems to work except that I don't get a repl prompt in the browser window. Does anyone have any thoughts on what might be going wrong or how to diagnose the problem?
I didn't think that was supposed to have a repl in the browser itself - usually a cljs repl is in a terminal and talks to the browser over a socket
> After a couple of seconds you will see Hello world! print at the terminal and you will be given a REPL prompt. Try evaluating some expressions like the following: to me, that means "enter these things into the terminal"
I do see the "Hello world!" printout but no prompt at the terminal either. When I type into the terminal I get no repsonse.
I would be happy with a repl in either the browser or the terminal.
The message in the browser window says "This page hosts your REPL and application evaluation environment. " which gave me the impression that the REPL would appear on the page but I don't really care one way or the other.
The "developer console" built into the browser is like a JS repl, but it's not usually the repl we're talking about when talking about clojure repls. We'll usually be referring to the terminal repl (or one connected from your IDE)
But if you follow the quick-start guide, you should have gotten a prompt at the terminal repl
no prompt at the terminal repl.
just a "Hello World!" message
and a browser window popped up as the instructions said would happen.
does it say the clojurescript version, right under the "Hello world!" message in the terminal?
no, nothing.
The "hello world!" message prints again if I refresh the browser window.
Did you remember to pass the flag to enable the repl at the end? clj --main cljs.main --compile hello-world.core --repl
no messages in the browser console.
here's what I see in the terminal:
Hi. I have two vectors: 1. - [ [Z1 X1 C1] [Z2 X2 C2], .....[Zn Xn Cn] ] 2. - [ [Q1] [X1] [W1] [Q2] [X2] [W2] [Qm] [Xm] [Wm] ] m != n The names Z X C .... are fields with some type (type in domain, not in programming - all of theme are strings) I want to combine those two vectors into one if they match pattern that field X in first vector is the same a field X in the second vector. I'm looking for a hint how to do it not for a solution. Do any one know how to do it in Clojure?
( I think slack didn't like what I typed in )
/repos/gitnc/hello-world$ clj --main cljs.main --compile hello-world.core --repl Hello world! Hello world!
@davecompton7 That's strange :thinking_face:
In OO language (or just not Clojure) I will make two loops (O(n2)) compare values and merge theme...
Is there any kind of error log or something along those lines that I can look at?
you could check the javascript console, that should be somewhere in the browser UI depending on which one you are using
I'm a little at a loss for where to go from here.
Well, the ordering of things don't appear to be guaranteed actually, so I'm not sure if you'll want to start with merge-with there
@john (mege-with function_which_check_condition vector1 vector2) - will it be something like this?
@davecompton7 Have you tried starting fresh from another folder entirely?
you mean another directory in the filesystem ?
@davecompton7 yeah, just to make sure it's a fresh development environment
@john What do you mean by aligned? They are always on the same indexes in both files.
So then, you should be able to partition the second vector by 3, and then feed both into merge-with
I made vectors from csv file.
I have not tried that yet. I will. I did try deleting the "out" folder that clj created in my "hello-world" folder and then starting again but that didn't help. I'll try starting fresh from a new folder now and let you know if that makes a difference.
@john Thank you I will try to play with (merge-with ...)
@davecompton7 there's also a ./.cpcache
folder that you can clear out too
@john As a result I want to get [[Z1 X1 C1 Qx Wx] [Z2 X2 C2 Qy Wy] ....]
@john The X is just an email address, and in one vector I have some data an in another I have another part of data related with the first vector by email value.
@tomek423 clojure.set/project
isn't the exact thing you want, but I think it would do most of your work for you if you shape your data into what it can use
started over completely from scratch and it made no difference.
@davecompton7 you may have some local environment issues. I gotta run though!
@noisesmith I just looked at the examples of clojure.set/project
and they are based on hashMap. Will it work on vectors?
sorry - I was thinking clojure.set/index
but I typed project instead by mistake
but you still likely need to do some data transformations to make it work (I think it wants sets of maps)
thank you for giving it some thought. Does anyone else have any thoughts on what the problem might be ( or how to diagnose it ).
I just tried the instructions in a fresh directory on a Mac and here's the output
(! 667)-> clj --main cljs.main --compile hello-world.core --repl
Downloading: org/clojure/clojurescript/1.10.516/clojurescript-1.10.516.pom from
Downloading: org/clojure/clojurescript/1.10.516/clojurescript-1.10.516.jar from
ClojureScript 1.10.516
cljs.user=>
but it took a long time between the Downloading messages and the blank line, version, and prompt appearing.And I just waited, before trying to reload the page.
And you don't get the prompt etc until after the browser has opened and the page has rendered (showing the "Welcome to the ClojureScript browser REPL." page)... and then it takes a while before the prompt appears.
In particular note that you shouldn't get Hello World! in the terminal until after you reload the browser -- and you shouldn't reload the browser until after you get the prompt.
What O/S are you on and what browser are you using by default? Do you have non-default security settings on the browser that might be preventing the connection to Clojure/ClojureScript?
I'm running in a docker container that is based on Ubuntu 16.04. The OS on my computer is also Ubuntu 16.04.
And the browser...?
The brower that I'm using is chromium.
I have not changed anything as far as security settings go. At least not intentionally.
here's what I see in the terminal including starting from a fresh start with a new hello-world directory:
(bear with me... struggling with copy/paste into slack )
I've waited 20 minutes for now for the repl prompt. No reloading of the browser but I do see a single "Hello World!"
OK, I think this might be a timing issue. If you're getting Hello World! before you get a prompt then I suspect something in the initial ClojureScript setup isn't happening before your compiled hello_world.cljs file is run and so you are not getting the ClojureScript connection and therefore no connected REPL.
Can you try this natively on your Linux machine, outside Docker?
I tried it. I'm getting some kind of java (?) error: https://pastebin.com/XPtLxD8K
(this kind of problem is why I usually try to isolate my development environment using docker or a vm )
figured it out ( or at least a workaround ). If I start the browser before running the clj command then clj connects to the running browser and I get a repl in the terminal.
What does java -version
show? That error is a class file version mismatch.
Ah, that does sound like a timing issue then!
Clojure/ClojureScript requires JDK 8+ now -- which is probably your problem trying to run it locally.
dave@peach:~/repos/gitnc/hello-world$ java --version Unrecognized option: --version Error: Could not create the Java Virtual Machine. Error: A fatal exception has occurred. Program will exit.
Sorry, java -version
-- one -
I always forget that java
isn't like other *nix commands 🙂
dave@peach:~/repos/gitnc/hello-world$ java -version Error occurred during initialization of VM java.lang.Error: Properties init: Could not determine current working directory. at java.lang.System.initProperties(Native Method) at java.lang.System.initializeSystemClass(System.java:1119)
Sounds like you're trying to run the command in a directory you deleted in another window...
maybe.
1 min
java -version java version "1.7.0_67" Java(TM) SE Runtime Environment (build 1.7.0_67-b01) Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode) dave@peach:~/repos/gitnc/hw3$
and yes, it looks like the wrong java
but at this point it appears to be working under docker so I'm not too worried about getting it to work on my "real" computer.
in fact, can you tell me how to remove the clojure that I just installed ?
Ask in #tools-deps -- I'm not sure what the official process is for uninstalling clojure
/`clj` since I've never needed to do it.
I suspect it's a manual process of deleting things from certain folders but I've no idea where it even puts stuff on Ubuntu.
ok. Thanks for your help. Your "timing" comment got me on the right track.
The downside to using Docker 🙂
Really, the "how to diagnose it" is the more important part of my question.
why is intellij the size of wisconsin?
like "boy, is that delicious?"
Is there a succinct and idiomatic way of pulling static java methods into a clojure namespace as functions. Tried the following
(def int2hex (partial Integer/toHexString))
Unable to find static field: toHexString in class java.lang.Integer
@kbosompem I don’t think partial
works with static Java methods. you might have to use #(Integer/toHexString %)
@kbosompem idiomatic way is to use it directly
memfn usually introduces reflection fyi
that's an interesting question. I'm not sure its actually a macro. Fun to go spelunking why this is the case. Its thinking its a field and rightly not finding it
It’s not a macro, it’s the . special form
Which works with both fields and methods and will report as a field error if not found
Well, in the sense that (Integer/toHexString ...)
expands to (. Integer toHexString …)
. But the expanded form also can’t be partial
ed, so… as @alexmiller: no static import — invoke directly or wrap in a lambda.
It is possible to macro the creation of anonymous functions for multiple static methods in one step
Back in old contrib, Stuart Sierra had some stuff for this
I see the code in Compiler.java
which creates StaticMethodExpr
, InstanceMethodExpr
, StaticFieldExpr
, or InstanceFieldExpr
. Where does the rewriting happen to the special form .
. Is that in the reader?
that's what i was seeing already but it seems to already be in (. Integer toHexString)
form there
at compile time, when bytecode is being generated, so after reading but before evaluation i guess
it's read by the reader as a list invoking a symbol
the compiler is the one that handles it
technically, I think it's in the analyzer part of the compiler where it decides what kind of symbol it is, like in analyzeSymbol
that figures out if it's a var, static call, class, etc
Is there an idiomatic/built in way to perform an instance?
with multiple possible classes? In this case I am checking if an exception I have been handed is one of several different possible classes
nothing but the obvious
Java has syntax for that now, but we haven't done anything in Clojure to handle it
typically you'd make multiple catch blocks for each option
maybe a possible future extension to echo Java there
In this case it's outside of a catch (dealing with exceptions coming in from a clj-http.client
async call)
@robertfrederickwarner supers
returns a set, and you can easily check if various classes are in it
eg. check set/intersection to do multiple matches in one direction, set/contains in the other direction
have to be careful with that stuff though - classes are not constants, they are classloader dependent
Is there any way to find out what namespace is requiring the current one? My use case is I have a namespace (a) that registers a bunch of multimethod handlers that come from namespace (b), but doesn't really export anything. I want to make sure those handlers get registered whatever the calling context, so I'm re-exporting the multimethod from (a). I'd like to enforce the convention that that multimethod is only imported from (a), not from (b). If there's a better way to do this, feel free to suggest it 🙂