Fork me on GitHub
#beginners
<
2022-08-19
>
Ben Lieberman03:08:12

I'm using Cider to try to connect to a running Figwheel REPL. But when I use the cider-connect-cljs command in Emacs and then pick localhost port 9500, it doesn't matter whether I select Figwheel or Figwheel main (though I'm assuming only one of those is the right one), nREPL closes the connection immediately

seancorfield04:08:07

Port 9500 sounds like maybe what your web app is running on for HTTP, not your REPL?

seancorfield04:08:03

The address you go to in a browser (e.g., ) is not the same host/port the REPL is running on.

seancorfield04:08:32

Are you following a particular tutorial @U03QBKTVA0N?

Ben Lieberman04:08:20

no I just am using the Figwheel template to work on a website of my own

Ben Lieberman04:08:38

I did check out the tutorial though, and I got that REPL working okay

Ben Lieberman04:08:46

I checked out netstat hoping that might let me suss out the port but I think I missed it if it told me anything useful and I assume there's a more practical way to do things

Ben Lieberman04:08:33

mhm that's the one

Ben Lieberman04:08:46

I did the lein version to start it up

seancorfield04:08:07

OK, so lein fig:build -- and it shows the browser/HTTP URL is http://localhost:9500 but that is not the REPL port.

Ben Lieberman04:08:47

is there a more straightforward option for connecting to running REPLs than Cider? I am not married to it, it just came up when I started checking out Clojure. It seems to work fine with clj REPLs but I was also having some weird issues with shadow-cljs and Cider

seancorfield04:08:53

I no longer use Emacs but I can't find how to connect to a running cljs REPL, only how to start one from the editor: https://figwheel.org/docs/emacs.html

Ben Lieberman04:08:36

yeah I was browsing that page earlier, didn't see anything immediately obvious

Ben Lieberman04:08:11

I could switch to VSCode, I do use it regularly, I just found Calva a bit intimidating at first

Ben Lieberman04:08:20

but I'm sure it would be okay now

seancorfield04:08:23

The Figwheel docs seem to suggest that you need Piggieback in your deps for this.

seancorfield04:08:26

(I don't currently do any cljs so I'm rapidly running out of suggestions at this point 🙂 )

Ben Lieberman04:08:10

I'll give Piggyback a go. Thanks for your help!

seancorfield04:08:27

I get the impression the normal workflow is just to save files and have Figwheel auto-compile and hot-reload the resulting JS... maybe?

seancorfield04:08:56

But I think Piggieback is the "magic" that actually gives you a cljs REPL connection from your editor somewow.

Ben Lieberman04:08:23

yeah maybe I'm thinking about this wrong anyway and I suppose in terms of just validating pure Clojure logic I can run a regular clj REPL

Ben Lieberman04:08:35

and then for actual JS and HTML changes use the FIgwheel hot loading thing

Ben Lieberman04:08:19

aha, I have fooled myself once more...it seems that what I really needed was cider-jack-in-cljs and not cider-connect-cljs

seancorfield04:08:24

jack-in will cause Emacs/CIDER to start the REPL up for you -- it won't use the one you already had running.

seancorfield04:08:20

At some point in my future, I will come back to cljs dev and build an actual production app. We built a p.o.c. back in 2013/14 with Om and then with Reagent but gave up on cljs because the tooling was so fragile and clunky. I looked at it again last year with re-frame and figwheel-main and it looked promising but I was using Atom/Chlorine then and a Socket REPL I started myself so it was a modified version of what the Figwheel docs show. I've switched to VS Code/Calva now and I believe it only has an integration with Shadow-cljs but I haven't dug deep into that yet.

Ben Lieberman04:08:30

yes I think where I went astray was to start the REPL in another terminal and then try to connect, when apparently starting the REPL in Cider works just fine. Not sure why I didn't try that from the start

Ben Lieberman04:08:08

I'd say my JS and Clojure skills are about equal so my sense of which is better for what is essentially nonexistent. I just like writing Clojure more

seancorfield04:08:30

I am awful with JS (and I hate the language and most of its ecosystem)... but after a decade of Clojure I'm going with the server-side stuff... but I'm a beginner with ClojureScript with the tooling...

Ben Lieberman05:08:04

yeah JS does a lot of things wrong from what I can tell, and if I'm gonna have to go without types I'm gonna want the Clojure no types version. TypeScript feels like too little too late

seancorfield05:08:25

FWIW, I just recreated my test project with +deps to get deps.edn and CLI support and now VS Code can jack-in just fine and hot reloading works as does direct evaluation from the editor into the (cljs) REPL.

👀 1
seancorfield05:08:06

Ah, and now I have two REPLs: a Clojure REPL for the backend and a ClojureScript REPL for the front end -- all very slick!

Aron10:08:06

Cross posting for higher visibility. 🙂 Any comment here or there would be greatly appreciated.

quan xing11:08:59

I'm use jdbc/execute update data in map , close datasource pool after map show SQLException error message:

(let [conn (db/ds)
        sql-list sql-vecs]
    (map (fn [sql]
           (prn "SQL->" sql)
           (let [affect-row (jdbc/execute! conn sql)]
             (assoc sql :affect-row affect-row))) sql-list)
    (.close (jdbc/get-datasource conn)))

=> ; Execution error (SQLException) at com.zaxxer.hikari.HikariDataSource/getConnection (HikariDataSource.java:96).
; HikariDataSource HikariDataSource (HikariPool-41) has been closed.
why it's execute sql after .close . the map not run stop? my database conn with jdbc/with-logging

rolt12:08:46

map is lazy, is will only execute the function when you consume the sequence. Have a look at mapv, run!, doall

quan xing13:08:50

ok. thanks, I'll try it.

quan xing14:08:00

How can I compare two map equals? Should I sort first and than eq?

def sortedmap-a  (into (sorted-map) map-a)
def sortedmap-b (into (sorted-map) map-b)
def same? (= sortedmap-a sortedmap-b)
is there a better way?

Alex Miller (Clojure team)14:08:10

just (= map-a map-b) does what you want

Alex Miller (Clojure team)14:08:10

maps are equal if they have the same key set and the values for those keys are equal (sorting is not relevant)

quan xing14:08:12

m1 {:a 1 :c 2} m2 {:a1 :c2} how can i get m1-m2 or m2-m1 = {:c 2} I hope get two map different element use clojure.set/difference ?

(->> (clojure.set/difference (set m1) (set m2))
                           (into {}))

Erick Bodine16:08:55

Seeing strange ClassCastException with tools.cli

(base) ➜  cljgen clj -X cljgen/-main -p 81
before run-cmd
Execution error (ClassCastException) at clojure.tools.cli/tokenize-args (cli.cljc:34).
class clojure.lang.PersistentArrayMap cannot be cast to class java.lang.CharSequence (clojure.lang.PersistentArrayMap is in unname
d module of loader 'app'; java.lang.CharSequence is in module java.base of loader 'bootstrap')

Full report at:
/var/folders/y8/qdbsc97n4d76l_2m9px751300000gp/T/clojure-1788712896876580086.edn
tools.cli - 1.0.206 clj --version Clojure CLI version 1.11.1.1155 java --version openjdk 18.0.2 2022-07-19 OpenJDK Runtime Environment Homebrew (build 18.0.2+0) OpenJDK 64-Bit Server VM Homebrew (build 18.0.2+0, mixed mode, sharing) The code is dead simple
(def cli-options
  [["-p" "--port PORT" "Port Number"
    :default 8]
   ["-h" "--help"]])

(def -main
  [& args]
  (parse-opts args cli-options))

hiredman16:08:08

You should prn args

hiredman16:08:45

-X passes a map, not a seq of strings

Erick Bodine16:08:23

changed to using -M and now i get a FileNotFoundException?? clj -M cljgen/-main -p 81

dpsutton16:08:25

do you have a file named cljgen.clj on your classpath?

Erick Bodine17:08:20

not that I am aware of …

dpsutton17:08:13

then clj -M some-namespace has no hope of succeeding

dpsutton17:08:19

things are found on the classpath. So clj -M foo will look for a file called foo.clj on the classpath and run its -main function (don’t specify cljgen/-main). If it cannot locate a file on the classpath that you told it to run, it will error with a FileNotFoundException

Erick Bodine17:08:14

excuse my naiveté but then why does clj -X cljgen/-main w/out any options succeed?

dpsutton17:08:37

cljgen clj -X cljgen/-main -p 81
before run-cmd
Execution error (ClassCastException) at clojure.tools.cli/tokenize-args (cli.cljc:34).
class clojure.lang.PersistentArrayMap cannot be cast to class java.lang.CharSequence (clojure.lang.PersistentArrayMap is in unname
d module of loader 'app'; java.lang.CharSequence is in module java.base of loader 'bootstrap')

Full report at:
/var/folders/y8/qdbsc97n4d76l_2m9px751300000gp/T/clojure-1788712896876580086.edn
i wasn’t aware that it had succeeded

Erick Bodine17:08:26

clj -X cljgen/-main succeeds clj -X cljgen/-main -p 8 fails with the ClassCastException

dpsutton17:08:32

can you try clj -M -m cljgen -p 8?

dpsutton17:08:04

The difference is that -X you specify the function you want to run and that function should take a single map as an argument. With -M you specify the namespace and it will run a function called -main in that namespace

dpsutton17:08:48

so when you specified clj -M cljgen/-main it’s possible it was looking for a cljgen/-main.clj (and it wanted to run a -main function in that file) rather than looking for cljgen.clj on your classpath

Erick Bodine17:08:07

i did not see the -m in “Deps and CLI Reference” guid

dpsutton17:08:43

if you omit it i think you’ll get a warning that it’s necessary but it will still work

Erick Bodine17:08:26

fails with “No such file or directory” if that is missing. Thanks!

Ted Ciafardini17:08:59

is there a core function that will turn a symbol: authentication/find-user into a quoted symbol: 'authentication/find-user

hiredman17:08:28

'foo is short hand for (quote foo)

hiredman17:08:22

meaning when the reader reads ' it produces a list of two elements, the first element is the symbol quote and the second element is whatever the result of whatever the readers after the ' is

hiredman17:08:45

what do you think a quoted symbol will do for you?

Ted Ciafardini17:08:37

quote doesn’t seem to be working as I’m storing functions as strings initially….

;;THE GOAL:
  ;turn
  (def s "blog_components_01/first-entry")
  ; =>
  (def qs 'blog_components_01/first-entry)
  ;THEN
  (resolve 'blog_components_01/first-entry)

hiredman17:08:44

you just want a symbol

hiredman17:08:57

resolve doesn't take a "quoted symbol"

hiredman17:08:00

it takes a symbol

Ted Ciafardini17:08:06

in cljs repl: (resolve 'blog_components_01/first-entry) works well, but calling symbol does not work- it wants a “quoted symbol”

hiredman17:08:21

ah, cljs is different

hiredman17:08:51

it is unlikely you will get want you want going down that path

dpsutton17:08:59

there is no resolve in cljs

hiredman17:08:26

there is, but it is a macro someone added for use in the cljs repl

Ted Ciafardini17:08:35

maybe I should ask this in cljs channel oops

hiredman17:08:15

and then because clojue's resolve is a function, so you might call it with a quoted symbol, someone made the cljs macro require a literal quoted symbol

Ted Ciafardini18:08:01

Maybe the solution is a macro that turns a symbol into a quoted symbol

dpsutton18:08:13

The solution is you will need to maintain a lookup from whatever input to values you need

👍 1
thanks2 1
Ted Ciafardini18:08:20

or maybe it's as easy as cljs.user=> (symbol "'flip/flipper")

hiredman18:08:55

the thing is, cljs is much less of a reified runtime than clojure, so doing stuff in cljs that relies on a refied runtime (dynamically finding values of symbols, etc) doesn't work great,

vlad_poh18:08:01

any recommendation for a nice sized re-frame app to study

seancorfield18:08:45

subscribing since I'm interested in the answer to this too! I'm just starting to dabble with cljs (again!)...

👍 2
hiredman18:08:38

I have https://gist.github.com/hiredman/c6868603eb9bf3620f2b89acfaef623e which is a single file little app that scrapes package delivery information, sticks it in a database and then displays it in a pretty simple little table ui. I don't know that it is good, but I like to point to it because it is a re-frame app without any of the (from my point of view) large tooling stack that people seem to typically use

hiredman18:08:45

the backend and frontend are defined in the same cljc file, and when you load the clojure namespace, it queues up compiling the same file as clojurescript to get the javascript for the frontend

seancorfield18:08:57

I don't see re-frame mentioned in that gist?

seancorfield18:08:27

I see a little bit of Reagent being used.

hiredman18:08:25

oh, I apologize, I get all the re* named stuff mixed up

JohnJ21:08:27

I like how "hardcore" this is 😉

JohnJ21:08:58

Trying something similar but with Jetty (no ring)

JohnJ21:08:32

but just for practicing interop/java, definitely not a good example(but fun) for a beginner unless you want to scare them away

jkxyz09:08:45

I wrote a little (unfinished) XMPP client with video chat capabilities using re-frame a few years ago. It's using some older idioms but I was proud at the time that it's very re-framey. It contains https://github.com/jkxyz/ct-chat/blob/master/src/cljs/ct/xmpp/effects.cljs and sending stanzas which you might find interesting - I still use it as reference when I need to do something similarly stateful with effects. Also some potentially useful approaches to encapsulating events, subscriptions and UI, by https://github.com/jkxyz/ct-chat/blob/master/src/cljs/ct/chat/messages/events.cljs. I can't guarantee it all still works, especially the mediasoup stuff. https://github.com/jkxyz/ct-chat

👍 1
Chase17:08:48

https://github.com/jacekschae/conduit This might be a good one for you to check out. It's a re-frame version of the RealWorld app

👍 1