jscl-project / jscl

A Lisp-to-JavaScript compiler bootstrapped from Common Lisp

Home Page:https://jscl-project.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Converting array of strings from JS to Lisp

davazp opened this issue · comments

Currently, JS strings are converted to Lisp strings.

However, JS arrays are preserved as Lisp "storage vectors".

This results in some bad conversions though, as if you convert ["foo"] you will have a storage vector of "js-object". And you would have to convert it manually to a string.

I am not sure what we should do here.

It is convenient, though inefficient, to convert values while doing FFI. But for deeply nested structures is quite expensive. And even worse, it won't work for user-defined values as we can't know what to convert.

Should we then remove all conversion from the FFI and let the callee do them explicitly?

It is long over due to design and specify how FFI should behave!

commented

My opinion - is to do nothing.

Reason Is that at this moment not one case is visible where it is required. Obviously everyone solves these problems for himself.

Is enough for most cases: js-to-lisp lisp-to-js

one big ;)

commented

Hmmm

CL-USER> (setq vv #(0 0 0 0))
#(0 0 0 0)
CL-USER> (oget vv  (string 0))
0
CL-USER> (setf (oget vv "0") 99)
99
CL-USER> vv
#(99 0 0 0)
CL-USER> (setf #j:lvv vv)
#(99 0 0 0)
CL-USER> (oget #j:lvv "0")
99
>lvv[0]
99
>var v = new Array( "aa", "bb" ,"cc")
undefined
CL-USER> (oget #j:v "0")
"aa"
CL-USER> (setq jar (jscl::make-new #j:Array "aa" "bb" "cc"))
#("aa" "bb" "cc")
CL-USER> (aref jar 0)
"aa"
CL-USER> (oge jar "0")
ERROR: Function 'OGE' undefined
CL-USER> (oget jar "0")
"aa"
CL-USER> (setf #j:Jar jar)
#("aa" "bb" "cc")
CL-USER> (oget #j:Jar "0")
"aa"

I found this issue trying to do:

(subseq #j:process:argv 2)

To get the arguments the jscl node cli. This results in a vector but the strings aren't converted.

commented

About the #j:process ... when working with it, you know what you do and know why.

Get implicit conversions from FFI ? hmm

How to convert from js null, and how to return it to the right place in js?

In general, making a coerce it is nice idea, until you start costs estimate

commented
CL-USER> (mapcar (lambda (x) (jscl::js-to-lisp x)) 
...                                        (jscl::vector-to-list (subseq #j:process:argv 2)))
( "--enable-features=WebComponentsV0Enabled" "--disable-features=SpareRendererForSitePerProcess"   "--node-integration" "--no-sandbox" "--no-zygote" "--enable-remote-module" "--background-color=#fff" "--device-scale-factor=1.1041666269302368" "--num-raster-threads=4" "--enable-main-frame-before-activation" "--renderer-client-id=5" "--no-v8-untrusted-code-mitigations" "--mojo-platform-channel-handle=2368" "/prefetch:1")
CL-USER> 

Something like this.

And js:null is a real evil

I was more leaning toward the side of no conversion at all. Not even strings.

So every time you deal with JS you always get a "js object". Except for the cases where the Lisp and JS representation matches. (numbers, storage vectors..).

But for instance, JS strings and booleans would be "js objects".

Then, many standard functions won't work with JS objects. I guess we can define a primitive-string type that is a subtype of string in Lisp so string and sequence functions could work with JS, but for booleans you would need to convert it when needed or use something like (eq obj #j:true).

I think this sounds more predictable (and efficient) than those mixed 1-level conversion only.

commented

All is correct. I agree.

var True = true
CL-USER> (eql t #j:True)
T
CL-USER> (and t #j:True)
T

Per conta

js>var Ba = new Array (true, true, false)
undefined
js>var True = true

CL-USER> (eql  #j:true)
NIL
CL-USER> (eql  #j:True)
T
CL-USER> #j:Ba
#(#<JS-OBJECT true> #<JS-OBJECT true> #<JS-OBJECT false>)
;;; Need conversion
CL-USER> (mapcar (lambda (x) (jscl::js-to-lisp x)) (jscl::vector-to-list #j:Ba))
(T T NIL)