cljs-dev 2024-09-23

@alexmiller @fogus for String/new etc. in Clojure does this just create wrapping fn to make it work?

Alex Miller (Clojure team) 2024-09-23T18:52:06.839659Z

in general, yes. When a qualified form is used in a value position, an equivalent fn wrapper is being created. If no param-tags are provided, this generates a multi-arity fn matching each overload of the function. if param-tags are provided, you get a function with only the specified arity and overload via type hints

πŸ‘€ 1
fogus (Clojure Team) 2024-09-23T19:08:41.274739Z

I created an analyzer ticket that talks a little bit more detail about this stuff https://clojure.atlassian.net/jira/software/c/projects/TANAL/issues/TANAL-141?jql=project%20%3D%20%22TANAL%22%20ORDER%20BY%20created%20DESC

πŸ‘€ 1

for this pattern to work generally we still need to distinguish fn vs. properties, thoughts on Foo/-prop && Foo/method ?

There's probably a scenario where "-prop" can also be a "static" field

$ ./node_cli.js -e '(defclass Foo (^:static field -dude "hello") (constructor [_])) (js/console.log Foo/-dude)'
hello
This is in squint, but probably there's something you could come up with in normal CLJS as well

there's a separate issue for that problem, for ClojureScript and or stuff that Google Closure see's I think we can figure this out.

for deftype etc. that'll probably be the first change in this area.

πŸ€” 1

I could see this breaking people's code if they accessed fields of certain libraries with that were written like _foo_bar in JS with -foo-bar in CLJS

they probably shouldn't have done so, but maybe something to consider

You can’t do that with / right now - so what would break?

Maybe a more concrete example would help clarify where you think it would go wrong?

fogus (Clojure Team) 2024-09-23T19:05:44.033979Z

It’s been a long time since I wrote CLJS but do we have the Foo/.-bar to distinguish properties?

@dnolen What do you mean, you can't do that? You can alias any data structure in some JS module in the ns form using the $ notation

but you can't use / randomly

but yeah, ok I see if they're depending on munging

Foo/bar and Foo/.-bar would be neccessary unless compiler information can tell us otherwise.

@fogus doesn't exist yet, but yeah that looks like where we're heading

fogus (Clojure Team) 2024-09-23T20:01:28.256769Z

Foo/.-bar looks instancey but is there a difference between properties on an instance and a prototype?

Sorry now that I'm looking over it again - I think we should separate the property thing to side

@borkdude rolling back, yeah there isn't actually a problem there because $ leads a to a namespace, which doesn't really conflict w/ "classes"

Foo/new etc. is only going to work on things you :refered etc. anyway

I think the tension here is only only with the Classname/staticMethod pattern because Clojure knows whether it's a property or method

@dnolen why is this restricted to :refer ? In clojure 1.12 you can do this too:

user=> java.lang.String/new
#object[user$invoke__String_new__134 0x18324f97 "user$invoke__String_new__134@18324f97"]
For JS globals, there is a proposal / open issue to support this in CLJS:
(:require ["js$React" :as react])
if I remember correctly even globals would be affected by this since you can alias them and not just reach them via js/ .

react is a namespace, so there's no need need for this to work - the global bit not so important

goog.foo.Bar can work for the obvious reasons

react was just an example, not important for the general case

but anything that like that isn't a problem

js/foo/bar is not going to be allowed.

fogus (Clojure Team) 2024-09-23T20:14:05.306599Z

In Clojure you can do (:require [foo.bar :as Baz]) and then run into conflict if there's a class member and var referenced by Baz/quux

js/foo/bar isn't allowed, I know, this is why I brought up js$ which is a feature discussed not so long ago

and there I believe you will have this ambiguity again

have to step away, but more feedback appreciated, will probably write something up so can have more structured feedback that's not trapped in Slack

anyway, perhaps I'm too focused on edge cases

no edge cases are good

js$ right, worth pondering.

An somewhat related question - would e.g. (String/.toLowerCase s) (or js/String, unclear to me at this point) be essentially turned into (.toLowerCase s) or into (String.prototype.toLowerCase.call s)?

probably the former since more efficient

πŸ‘ 1

New /-enabled possibilities for prototype shenanigans. :)