Fork me on GitHub
#cljs-dev
<
2019-11-21
>
lilactown07:11:00

I need a way of notating the return type of a macro for inference purposes

thheller11:11:12

@lilactown macros don't have a return type (usable for inference). the code they generate may have but how you annotate that depends on the code it generates

lilactown15:11:16

the problem I have at the moment is that I’m using type inference within a macro, but the body obviously hasn’t fully expanded yet. so I can’t infer in the case when it’s nested:

(d/div (d/div "foo"))
the first d/div macro will expand, and try and infer the type (d/div "foo") which will come back as any Once it expands, the code it generates is annotated with the correct type

mhuebert12:11:35

(extend-type com.cognitect.transit.types/UUID cljs.core/IUUID)
with *warn-on-infer*, that code results in
Cannot infer target type in expression (. com.cognitect.transit.types/UUID -prototype)
is this a bug? I see a related issue but it is specific to extending Object - https://clojure.atlassian.net/projects/CLJS/issues/CLJS-2862?filter=allopenissues&amp;orderby=priority%20DESC&amp;keyword=extend-type%20infer

dnolen14:11:44

@mhuebert I'm pretty sure there's still a round of issues around warn on infer and deftype/record

dnolen14:11:11

there's a bunch of other things that came up via @roman01la and the plan is to address these in the next release

dnolen14:11:01

@thheller re: goog.module - the docs suggest bundling now instead of individual loads? or does that still work anyway regardless of the recommendation (this would be a serious drawback IMO if not)

dnolen14:11:05

@mhuebert feel free to file that specific bug

4
thheller15:11:18

@dnolen the goog.module stuff just needs pre-processing so that it actually becomes loadable. it can still be loaded using the goog debug loader though. they even have a "transpile" mode that does this on the fly in JS but I haven't used that. in shadow-cljs I just run all the goog code through :whitespace once so it rewrite goog.module to the loadable code

thheller15:11:05

FWIW the rewrites it does fore goog.modules are pretty minimal

goog.loadModule(function(exports) {
  "use strict";
  goog.module("goog.math.Long");
  goog.module.declareLegacyNamespace();
  const asserts = goog.require("goog.asserts");
  const reflect = goog.require("goog.reflect");

thheller15:11:18

basically just wraps it in a function

lilactown15:11:16

the problem I have at the moment is that I’m using type inference within a macro, but the body obviously hasn’t fully expanded yet. so I can’t infer in the case when it’s nested:

(d/div (d/div "foo"))
the first d/div macro will expand, and try and infer the type (d/div "foo") which will come back as any Once it expands, the code it generates is annotated with the correct type

lilactown16:11:36

one more question re: type inference. is there a correct way to notate the RHS in a let-binding? what I'm finding right now is:

(let [foo ^string (bar)]
  (ilk.core/inferred-type foo))
the ^string notation is effectively ignored. however, notating the name foo does seem to work

Roman Liutikov20:11:18

Are you sure it’s not an issue with ilk ? I can’t repro this using analyzer directly

lilactown20:11:59

I am not using ilk for my actual code

lilactown20:11:27

I'll see if I can create a minimal repro and put it on GitHub

lilactown16:11:12

I can turn all of these into JIRA tickets and poke at them in the cljs compiler, if there's not already a solution for them...

dnolen18:11:18

for the above - yeah make a ticket

dnolen18:11:37

re the macro problem - I don't know what you can about that - you have to expand

borkdude22:11:55

@lilactown what about a return type tag on bar?

lilactown22:11:40

haven’t tried it. these are macros that are emitting calls to external JS so it’s a little harder to annotate return types

lilactown22:11:48

specifically, I’m trying to emit something like this:

(useMemo #(str "a" "b"))
and in my macro, annotate the expression with the same type as the function passed into it

lilactown22:11:07

(`useMemo` does some stuff under the hood but essentially will always return the same type as the function passed into it)