squint-cljs / squint

Light-weight ClojureScript dialect
https://squint-cljs.github.io/squint
645 stars 39 forks source link

Squint remove ":" for keyword value #516

Closed kangaroolab closed 5 months ago

kangaroolab commented 5 months ago

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 commented 5 months ago

Keywords are just strings in squint, this is a design decision. In cherry there are real keywords though

https://www.michielborkent.nl https://www.eetvoorjeleven.nu

On Sun, 28 Apr 2024 at 07:09, kangaroolab @.***> wrote:

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

— Reply to this email directly, view it on GitHub https://github.com/squint-cljs/squint/issues/516, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACFSBTOC5KZIPIUFMG2DH3Y7SAAZAVCNFSM6AAAAABG4VTFIWVHI2DSMVQWIX3LMV43ASLTON2WKOZSGI3DOMZUGU2TSMI . You are receiving this because you are subscribed to this thread.Message ID: @.***>

kangaroolab commented 5 months ago

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:

borkdude commented 5 months ago

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

kangaroolab commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

Actually I fixed it already now in https://github.com/babashka/scittle/issues/77 - I'll publish a new scittle version

borkdude commented 5 months ago

https://github.com/babashka/scittle/releases/tag/v0.6.17

borkdude commented 5 months ago

Here is a scittle example with a webworker:

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

kangaroolab commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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