clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
ozzloy 2020-09-08T06:04:43.339900Z

i'm following this: https://www.learn-clojurescript.com/section-2/lesson-14-performing-io/ . under "Handling Events", when i try point 2, (gevents/listen input gevents/EventType.KEYUP update-target), i get WARNING: Use of undeclared Var goog.events/EventType at line 2 <cljs repl>

rpkarlsson 2020-09-08T09:02:50.342700Z

Testing in a repl led me to:

goog.events/EventType.KEYUP
;; => nil

goog.events.EventType.KEYUP
;; => "keyup"

(.-KEYUP goog.events.EventType)
;; => "keyup"
It looks to me like bad interop syntax in the course example but I'm unsure as I dont do that much JS interop. I would expect anything after / to be a function not an attribute lookup.

rpkarlsson 2020-09-08T09:08:32.343Z

Scratch that. Actually running it gives me the same results as the course.

(require '[goog.events :as gevents])
 gevents/EventType.KEYUP
;; => "keyup"

ozzloy 2020-09-08T06:06:27.340800Z

and this https://google.github.io/closure-library/api/goog.events.EventType.html seems to be saying that goog.events.EventType.KEYUP exists

ozzloy 2020-09-08T06:09:39.342200Z

however, if i replace gevents/EventType.KEYUP with "keyup", things work as expected. what's wrong with gevents/EventType.KEYUP?

thheller 2020-09-08T09:51:42.345200Z

it mostly allows the code to be minified more. ie. when closure minifies goog.events.EventType.KEYUP it turns into aB or so which is much shorter than "keyup" in the final release build. doesn't really matter much but thats the reason I believe.

Andreas S. 2020-09-08T09:43:00.344800Z

Hello everyone! I'm just trying to follow the steps here: https://clojurescript.org/guides/quick-start , but i'm on windows and I get an error if I try a PRODUCTION build, normal build works OK, but on Production build I get this:

Andreas S. 2020-09-08T09:43:03.345Z

Exception in thread "main" java.nio.file.InvalidPathException: Illegal char <:> at index 2: /C:/Users/ascheinert/Downloads/cljs_hw/out/cljs/core.js
        at java.base/sun.nio.fs.WindowsPathParser.normalize(WindowsPathParser.java:182)
        at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:153)
        at java.base/sun.nio.fs.WindowsPathParser.parse(WindowsPathParser.java:77)
        at java.base/sun.nio.fs.WindowsPath.parse(WindowsPath.java:92)
        at java.base/sun.nio.fs.WindowsFileSystem.getPath(WindowsFileSystem.java:229)
        at com.google.javascript.jscomp.SourceMapResolver.getRelativePath(SourceMapResolver.java:102)
        at com.google.javascript.jscomp.SourceMapResolver.extractSourceMap(SourceMapResolver.java:63)
        at com.google.javascript.jscomp.JsAst.parse(JsAst.java:168)
        at com.google.javascript.jscomp.JsAst.getAstRoot(JsAst.java:55)
        at com.google.javascript.jscomp.CompilerInput.getAstRoot(CompilerInput.java:133)
        at com.google.javascript.jscomp.Compiler.parseInputs(Compiler.java:1720)
        at com.google.javascript.jscomp.Compiler.parseForCompilationInternal(Compiler.java:939)
        at com.google.javascript.jscomp.Compiler.lambda$parseForCompilation$4(Compiler.java:922)
        at com.google.javascript.jscomp.CompilerExecutor$2.call(CompilerExecutor.java:102)
        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:835)

takis_ 2020-09-08T11:17:33.346500Z

Hello : ) I want to convert 1 clojure function to 1 "standalone" javascript function. I want to use this function inside mongoDB,that only allows 1 function without extra dependencies. Is it possible to do it with Clojurescript? If its not possible any alternative way?

borkdude 2020-09-08T11:18:41.347300Z

@takis_ You can export the function and compile it with CLJS. A very hacky way is this (from planck):

cljs.user=> (defn foo [x] (inc 1))
#'cljs.user/foo
cljs.user=> (str foo)
"function cljs$user$foo(x){\nreturn ((1) + (1));\n}"

takis_ 2020-09-08T11:19:26.347800Z

all the code needed will be inside that function?

borkdude 2020-09-08T11:19:47.348500Z

no, probably not. thus you will need to compile it with CLJS properly

borkdude 2020-09-08T11:20:14.349300Z

Use ^:export to make it available in the compiled output

takis_ 2020-09-08T11:20:35.349900Z

i am new with clojurescript,the times that i compliled it,it produces many large javascript files

borkdude 2020-09-08T11:20:54.350300Z

@takis_ You'll have to use advanced compilation, so it cuts away everything that's not used

borkdude 2020-09-08T11:21:12.350800Z

and then you can paste that JS into mongo (hopefully)

takis_ 2020-09-08T11:21:26.351100Z

ok but still it will be possible,to convert all in 1 standalone function?

borkdude 2020-09-08T11:22:22.352Z

JS is very flexible so I'm pretty sure you could make it into just one function.

borkdude 2020-09-08T11:22:27.352200Z

using closures

takis_ 2020-09-08T11:22:47.352600Z

ok thank you , i am new , i will try it : )

takis_ 2020-09-08T11:24:21.353700Z

If someone experienced in clojurescript can convert this function to 1 "standalone" javascript function, it will be helpful, of how he did it

(defn mygroupby [v k]
  (reduce (fn [grouped-array doc]
            (let [cur-key (str (get doc k))]
              (if (contains? grouped-array cur-key)
                (update grouped-array cur-key conj doc)
                (assoc grouped-array cur-key [doc])))) 
          {}
          v))

borkdude 2020-09-08T11:28:27.354600Z

@takis_ put your file in a src folder, add ^:export to it, like:

(ns my.cljs)

(defn ^:export mygroupby [v k]
  (reduce (fn [grouped-array doc]
            (let [cur-key (str (get doc k))]
              (if (contains? grouped-array cur-key)
                (update grouped-array cur-key conj doc)
                (assoc grouped-array cur-key [doc]))))
          {}
          v))
Then compile with:
$ clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.597"}}}' -m cljs.main -O advanced -c my.cljs
Find the compiled asset in out/main.js

borkdude 2020-09-08T11:29:09.355Z

Looking at the output size this will probably make you write this function in JS instead, but that's up to you :)

takis_ 2020-09-08T11:29:48.355400Z

thank you πŸ™‚ we will see

Milan Munzar 2020-09-08T11:30:38.355900Z

Hey, πŸ™‚ It seems to me that there is some problem with name resolution in defrecord when defining method named delete . In the following code it fails with a type error saying that delete is not a function. However when I rename it to del or something else it works as expected. Also I am able to call it like ((:delete foo)). Does anyone knows what is going on? Thx πŸ™‚

(defn make
  [ddb-client]
  (map->DBClient {:get    #(-> ddb-client .get .promise)
                  :put    #(-> ddb-client .put .promise)
                  :query  #(-> ddb-client .query .promise)
                  :delete #(-> ddb-client .delete .promise)}))

(def foo (make client))
(.delete foo)

borkdude 2020-09-08T11:30:55.356200Z

@takis_ :

> require('./out/main')
{ my: { cljs: { mygroupby: [Function: Ee] } } }
This is in node

takis_ 2020-09-08T11:33:32.356500Z

ok thank you i am trying it now

borkdude 2020-09-08T11:35:21.356900Z

Maybe -t node also helps in some regard, not sure if it's relevant here

takis_ 2020-09-08T12:30:48.359500Z

@borkdude i still try to run it,but i cant

takis_ 2020-09-08T12:31:04.359800Z

1)created a folder jsgen 2)created a folder jsgen/src 3)put my.cljs inside jsgen/src 4)cd jsgen 5)clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}' -m cljs.main -O advanced -c my.cljs Execution error (FileNotFoundException) at http://java.io.FileInputStream/open0 (FileInputStream.java:-2).-Sdeps (No such file or directory) Full report at: /tmp/clojure-11667070442944232008.edn

borkdude 2020-09-08T12:31:22.360100Z

@takis_ it should be my/cljs.cljs

borkdude 2020-09-08T12:31:51.360400Z

so the dir structure is jsgen > src > my

thheller 2020-09-08T12:37:18.360600Z

most likely https://clojure.atlassian.net/browse/CLJS-871 since delete is also a reserved word

πŸ‘ 1
takis_ 2020-09-08T12:39:07.361100Z

1)created a folder jsgen 2)created a folder jsgen/src/my 3)put my.cljs inside jsgen/src/my 4)cd jsgen 5)clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}' -m cljs.main -O advanced -c my.cljs Execution error (FileNotFoundException) at http://java.io.FileInputStream/open0 (FileInputStream.java:-2). -Sdeps (No such file or directory) Full report at: /tmp/clojure-6401545215020083189.edn

takis_ 2020-09-08T12:39:26.361500Z

i dont know why i cant run it, i should install anything else first?

takis_ 2020-09-08T12:39:48.361800Z

the my.cljs is the file you sended me above

2020-09-08T12:41:34.362400Z

"-Sdeps (no such file or directory)" - I bet your "clojure" isn't the one that uses deps.edn

2020-09-08T12:41:39.362600Z

check out which clojure

2020-09-08T12:42:17.363300Z

it's saying that it wants to open -Sdeps as a file, which probably means someone's old useless bundling of clojure

takis_ 2020-09-08T12:50:49.363500Z

clojure Clojure 1.10.1 user=> exit

takis_ 2020-09-08T12:51:08.363800Z

it says 1.10.1

takis_ 2020-09-08T12:51:59.364100Z

how to install a clojure that can use deps.edn

2020-09-08T12:53:54.365400Z

deps.edn isn't a version of clojure, what I'm saying is there are CLI tools called "clojure" that don't use deps.edn, the which tool will help you figure out what actually runs if you run clojure at the command line

2020-09-08T12:54:23.365900Z

eg. debian has a "clojure" that just runs java and loads the clojure library and runs clojure.main

2020-09-08T12:54:47.366200Z

which isn't what most people would want these days

2020-09-08T12:56:44.366700Z

here's me verifying that my "clojure" knows what Sdeps means

$ grep Sdeps $(which clojure)
    -Sdeps)
	 -Sdeps EDN     Deps data to use as the last deps file to be merged

takis_ 2020-09-08T13:15:46.367300Z

i done it thank you, i installed clojure using brew

takis_ 2020-09-08T13:15:58.367600Z

but now i get different error

takis_ 2020-09-08T13:16:00.367900Z

clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}' -m cljs.main -O advanced -c my.cljs Execution error (AssertionError) at cljs.closure/build (closure.clj:3098). Assert failed: No file for namespace my.cljs exists uri Full report at: /tmp/clojure-17078041070905694243.edn

2020-09-08T13:19:58.368800Z

if the ns is my.cljs you need to have src/my/cljs.cljs

2020-09-08T13:20:15.369Z

cljs is a weird name for an ns btw

takis_ 2020-09-08T13:26:07.369500Z

it worked,but now i see so many files and directories

dpsutton 2020-09-08T13:29:15.371Z

If you read the get started article it should go over all this. If you create an advanced optimizations build you will have only a single file as output

takis_ 2020-09-08T13:36:20.372300Z

i just runned clojure -Sdeps '{:deps {org.clojure/clojurescript {:mvn/version "1.10.741"}}}' -m cljs.main -O advanced -c my.cljs

takis_ 2020-09-08T13:37:03.373100Z

in the past i created one simple clojurescript hello world , for node.js

takis_ 2020-09-08T13:37:47.373600Z

do you have a link of what to read to produce 1 single file as output?

dpsutton 2020-09-08T13:39:04.375800Z

Your steps above with advanced should have produced a single output. Probably you have some remnants from past compilation hanging around. Delete the output directory and run it again and I suspect you will be fine. Alternatively give a new output location and you should see the single generated file I suspect

takis_ 2020-09-08T13:41:46.376300Z

i see those,i deleted the out,and re-run the clojure -Sdeps .......

takis_ 2020-09-08T13:44:28.376800Z

the main.js is that 1 single file?

takis_ 2020-09-08T13:50:58.377400Z

it is its working πŸ™‚

takis_ 2020-09-08T13:51:56.378300Z

thank you for your patience , you helped me alot, dpsutton ,noisesmith , borkdude πŸ™‚

πŸ‘ 1
dpsutton 2020-09-08T13:53:12.378900Z

good luck! one question, did you need a single file or a single function?

dpsutton 2020-09-08T13:53:55.379300Z

it might be impossible to have everything self-contained in a single function.

borkdude 2020-09-08T13:55:48.379800Z

I guess you can wrap that entire "namespace" object in a closure

borkdude 2020-09-08T13:56:11.380Z

but honestly I don't know why you would want that

takis_ 2020-09-08T14:05:26.380700Z

i need a single function,and able to call it with it arguments

takis_ 2020-09-08T14:05:55.381400Z

but still 1 file is big step

borkdude 2020-09-08T14:06:19.381900Z

@takis_ you can do const { my } = require("./out/main"); which will give you my.cljs.yourfunction as the one function

borkdude 2020-09-08T14:07:35.382100Z

$ node
Welcome to Node.js v14.5.0.
Type ".help" for more information.
> const { my } = require("./out/main");
undefined
> my.cljs.mygroupby
[Function: Ee]

takis_ 2020-09-08T14:17:06.382900Z

perfect πŸ™‚ thats exactly what i need it , thank you alot i was thinking that no way i can clean all those code

takis_ 2020-09-08T14:17:18.383300Z

i have 1 fucntion now callable from js

ozzloy 2020-09-08T20:32:16.390900Z

weird, i'm getting this at the cljs repl: cljs.user> gevents/EventType WARNING: Use of undeclared Var goog.events/EventType at line 1 <cljs repl> #js{:INPUT "input", :SUSPEND "suspend"

ozzloy 2020-09-08T20:32:41.391300Z

it says goog.events/EventType is undeclared, but also prints out a js object

ozzloy 2020-09-08T20:32:48.391500Z

i've truncated the output

ozzloy 2020-09-08T20:33:36.391900Z

what is going on here? cljs.user> (goog.object/get gevents/EventType (clj->js :KEYUP)) WARNING: Use of undeclared Var goog.events/EventType at line 1 <cljs repl> "keyup"

ozzloy 2020-09-08T20:46:36.392300Z

it says the var is undeclared, but also gives the expected answer

phronmophobic 2020-09-08T20:50:20.392700Z

how are you requiring gevents?

ozzloy 2020-09-08T20:51:34.392900Z

yes

ozzloy 2020-09-08T20:51:46.393200Z

(require '[goog.events :as gevents])

ozzloy 2020-09-08T20:52:05.393400Z

gives no error, returns nil

ozzloy 2020-09-08T20:53:36.393700Z

@smith.adriane thanks for looking

phronmophobic 2020-09-08T20:54:33.393800Z

i'm trying to see if I see the same issue, but I just updated my OS and nothing is working atm Β―\(ツ)/Β―

ozzloy 2020-09-08T20:55:10.394Z

o bummer

ozzloy 2020-09-08T21:11:57.394800Z

figured out a fix, still not sure what's going on, but this works: (require '[goog.events.EventType :refer [KEYUP] :rename {KEYUP keyup}])

ozzloy 2020-09-08T21:15:57.397200Z

the difference is between (require '[goog.events] ...), versus (require '[goog.events.EventType] ...) but i'm not sure how that would "work" and give a warning.

phronmophobic 2020-09-08T21:20:54.397700Z

it probably works without optimizations, but might not work under advanced compilation

lilactown 2020-09-08T21:22:25.398400Z

I wonder if EventType is one of those classes that needs to be imported

1
lilactown 2020-09-08T21:22:37.398700Z

On mobile otherwise I would check

2020-09-08T23:30:45.403900Z

I understand how an atom interacts on top of the jvm (multithreaded compare and swap) but on the browser what role does it play? I imagine conceptually it could be used with web workers

lilactown 2020-09-08T23:40:37.405100Z

an atom is pretty much just an object with a state property that gets changed on swap! / reset! , and calls watchers on update

lilactown 2020-09-08T23:43:20.406Z

I don’t think the atom API could be used with web workers because it’s expected that reset! and swap! will block until the value is updated, but that’s impossible to do in a JS environment + web workers

πŸ‘ 1
lilactown 2020-09-08T23:46:58.407Z

that would be a classic example of https://blog.izs.me/2013/08/designing-apis-for-asynchrony