Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Squint remove ":" for keyword value #516

Closed
kangaroolab opened this issue Apr 28, 2024 · 16 comments
Closed

Squint remove ":" for keyword value #516

kangaroolab opened this issue Apr 28, 2024 · 16 comments

Comments

@kangaroolab
Copy link

version

[ Please specify which version of squint you're using. You can find this in package.json under "squint-cljs"
latest version 0.6.95

problem

[ Please provide a short and to the point description of the problem ]
for (:a {:a :b}), Squint parse and return as: squint_core.pr_str(squint_core.get(({ "a": "b" }), "a"));, where ":" is removed from the keyword value

repro

[ Please provide a minimal and complete reproduction of the problem, preferably something which can be run with Node.js without dependencies. ]
see above

expected behavior

[ What is the behavior you expected to see from squint? ]
should keep ":" for keyword value and return ":b". this works fine with scittle

@borkdude
Copy link
Member

borkdude commented Apr 28, 2024 via email

@kangaroolab
Copy link
Author

kangaroolab commented Apr 29, 2024

Thanks for your feedback. Very helpful.

I am trying to put together a browser only env where I can edit and run Clojure code in browser with some Clojure core modules like core/string/set etc. Better if I could use web worker to compile and executive Clojure code. A few options I tried:

  • Scittle: I love it but the only problem is it refers to DOM. is there an option to build it without DOM reference? It comes quite neat as a way to run Clojure code in browser without the need of using cljs or shadow-cljs to compile offline
  • Squint: it is not as rich as Scittle and not 100% Clojure way (e.g. above)...understanding it uses some native JS structure vs Clojure
  • Cherry: I haven't tried it yet in browser as it seems more NPM focused. does it support name space like Scittle does?...would love your thought

@borkdude
Copy link
Member

What is your use case for scittle without running it in a browser? I think I could make that DOM stuff optional

@kangaroolab
Copy link
Author

kangaroolab commented Apr 29, 2024

it is running in browser but I am trying to make it run in web worker (a separate thread).

here is the use case (what I am trying to put up):
a browser based self-contained offline development env where I can quickly edit clojure code in browser (via contenteditable), run/test the code (using Scittle as the REPL), and some preliminary dependency support (currently thru script tag to load additional clj/cljs). I do have VScode setup for some heavy lifting work but this comes handy if I just need to quickly prototype something that I can do everything just in browser without jumping around cross different apps/windows etc.

right now, I have this up/running with Scittle as part of html page. I am hoping to see if there is option to move Scittle into a web worker where the REPL will happen while keeping the html page for user interaction only.

hope this clarifies. to remove DOM reference in Scittle, is it just to remove eval_script_tag from the core?

@borkdude
Copy link
Member

I think the function itself doesn't really hurt since you can refer to undefined stuff in JS functions, but there is an event which calls that function here:

https://github.com/babashka/scittle/blob/fcc1d1b843f2e45ea3d96e6220182cda5e8542dd/src/scittle/core.cljs#L116

You can opt out of that behavior by calling this function:

https://github.com/babashka/scittle/blob/fcc1d1b843f2e45ea3d96e6220182cda5e8542dd/src/scittle/core.cljs#L109

@kangaroolab
Copy link
Author

kangaroolab commented Apr 30, 2024

thanks...

should I remove following from core.cljs?

(js/document.addEventListener
"DOMContentLoaded"
(fn [] (when-not @auto-load-disabled? (eval-script-tags))), false)

it (the compiled js) will be parsed/invoked during import (in web worker) even if I can disable auto-eval.

what should be the edn to compile scittle? or package.json works even if it is for NPM.

sorry I asked question about scittle here...please advise if I should post this under scittle on github.

thanks again for offering scittle. it works like a charm and I love it.

@borkdude
Copy link
Member

should I remove following from core.cljs?

JavaScript doesn't care about that. E.g.:

$ node
Welcome to Node.js v20.6.1.
Type ".help" for more information.
> function foo() { document.querySelector("dude") }
undefined

As long as you don't call foo() you won't have an error.

But in scittle's case js/document is used on the top level so this is where the problem is. Now, I could make this optional, and check if js/document even exists and then only use it when it exists. Feel free to post an issue about that.

For now you can work around it like this:

Define a fake document:

document = {addEventListener: () => {}}

When I then load scittle in Node.js, it works:

Object.assign(globalThis, require("scittle/dist/scittle.js"));
> scittle.core.eval_string("(+ 1 2 3)")
6

@borkdude
Copy link
Member

Actually I fixed it already now in babashka/scittle#77 - I'll publish a new scittle version

@borkdude
Copy link
Member

@borkdude
Copy link
Member

Here is a scittle example with a webworker:

https://jsfiddle.net/borkdude/3nmxhwju

@kangaroolab
Copy link
Author

kangaroolab commented May 1, 2024

thanks...but I tried your web worker example in jsfiddle but it doesn't seem working.

to test it quickly with import, I tried following in html:

<html>
<head></head>
<body>
<h1>new scittle</h1>
<script type="module">
import * as module from 'https://cdn.jsdelivr.net/npm/scittle@0.6.17/dist/scittle.js';
const result = module.core.eval_string("(+ 2 3)");
console.log(result);
</script>
</body>
</html>

It shows error Uncaught TypeError: Cannot read properties of undefined (reading 'eval_string'). If I tried the same with squint, it works fine. Is scittle compiled as module or what are part of the exports?

@borkdude
Copy link
Member

borkdude commented May 1, 2024

See the docs here:

https://babashka.org/scittle/

You just use a normal script tag without module.

I used import() in the webworker just as a way to load scittle, but it isn't actually an ESM module

@borkdude
Copy link
Member

borkdude commented May 1, 2024

Also, if you don't know what the exports are you can just do this:

console.log(module)

and then find out how it's structured.

@kangaroolab
Copy link
Author

kangaroolab commented May 1, 2024

here is the comparison between squint and scittle:

<script type="module">
import * as module from 'https://cdn.jsdelivr.net/npm/scittle@0.6.17/dist/scittle.js';
console.log(module);
import * as squintCljs from "https://cdn.jsdelivr.net/npm/squint-cljs@0.6.95/lib/compiler.js";
console.log(squintCljs);
</script>

and the results are below:
Module {Symbol(Symbol.toStringTag): 'Module'}
Symbol(Symbol.toStringTag): "Module"

Module {…}
$APP: (...)
$jscomp: (...)
compileString: (...)
compileStringEx: (...)
shadow$provide: (...)
Symbol(Symbol.toStringTag): "Module"
get $APP: ƒ ()
set $APP: ƒ ()
get $jscomp: ƒ ()
set $jscomp: ƒ ()
get compileString: ƒ ()
set compileString: ƒ ()
get compileStringEx: ƒ ()
set compileStringEx: ƒ ()
get shadow$provide: ƒ ()
set shadow$provide: ƒ ()

here is the code to start web worker (I used script tag above with type = "module" to test the module out before I put the code in web worker accordingly), which requires import module vs common JS. note: classic doesn't work with web worker as the worker will need to import other javascript module

function startWorker() {
  if(typeof(Worker) !== "undefined") {
    if(typeof(w) == "undefined") {
      w = new Worker("/example/sci_workers.js", {type: "module"});
    }
    w.onmessage = function(event) {
      console.log(event);
      document.getElementById("result").innerHTML = event.data;
    };
  } else {
    document.getElementById("result").innerHTML = "Sorry, your browser does not support Web Workers...";
  }
}

it didn't seem there are exports with scittle

@borkdude
Copy link
Member

borkdude commented May 1, 2024

As I already said, don't use scittle itself as a module in a script tag, but this does work:

<html>
  <script type="module">
    import * as _ from 'https://cdn.jsdelivr.net/npm/scittle@0.6.17/dist/scittle.js';
    console.log(scittle.core.eval_string("(+ 1 2 3)"));
  </script>
</html>

The scittle variable is created as a global variable when loading scittle. It is NOT an ES6 module itself.

@kangaroolab
Copy link
Author

it works now both in browser and web worker....thanks a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants