Fork me on GitHub
#cljs-dev
<
2019-01-08
>
john17:01:35

Printing from functions called by tagged literals is dumping the output in my main.js. I guess that stage is so early in compilation that any printlns end up in the output. Is that too esoteric of a use case to jira?

thheller17:01:54

@john you can print to *err*. *out* is reserved for code generation

john20:01:17

So I got this tagged literal hack working, in order to do conditional requires, depending on if some thing exists in the analyzer's constant-table:

(defn exists? [[extant then? else?]]
  (if (-> env/*compiler* deref :cljs.analyzer/constant-table
        keys str (clojure.string/split #" ") (->> (some #{(str extant)})))
    then?
    else?))

john20:01:49

Then you can do like:

(ns my.core
  #my/exists?
   [clojure.core.protocols/datafy
    (:require [clojure.datafy :as d]
              [cljs.pprint :as pp])
    (:require [cljs.pprint :as pp])])
with this in your tagged_literal.cljc: {my/exists? my.readers/exists?}

john20:01:12

Is anything in this hack likely to be unsupported at some future point?

dnolen21:01:03

hrm I wonder if the latest inference stuff handles cases like this https://groups.google.com/d/msg/clojurescript/s7dg_4m3RyI/qDUN7dGfEAAJ

mfikes21:01:32

Hrm. My take is that #{nil clj-nil} is not definitely known to be a non-number, but we probably don't handle that case correctly and trigger a warning when we shouldn't.

mfikes21:01:08

Easy to repro. I'll file a JIRA.

mfikes22:01:05

Or, hold on, is this because the typecheck knows it might be nil? Hrm.

mfikes22:01:49

We seem to let this by OK: (fn [^{:tag #{clj-nil number}} x] (dec x)) But if you replace number with nil then a warning is emitted.

dnolen22:01:02

@mfikes if you look at the above though shouldn't the and reject clj-nil as a possibilty

dnolen22:01:09

(and ssv-next ...)

mfikes22:01:30

@dnolen Ahh, right, I see what you are saying. We currently have extremely simple predicate-induced inference, that isn't sophisticated enough to "see" that.

mfikes22:01:07

Even a simple extension to what we have: (when (some? x) (dec x), we don't really have a tag to indicate that "this is any value but nil`

mfikes22:01:27

Digging into that email to see if I can at least figure out what changed... 🙂

dnolen22:01:36

@mfikes sure but it does seem like a simple win to know that (if x ...), x must be truthy thus you can at least reject clj-nil from what is inferred

dnolen22:01:06

this is actually a multi-year complaint about the arithmetic inference stuff

dnolen22:01:20

but now with the predicate bits it seems relatively straightforward

mfikes22:01:34

Yeah, more and more is coming into reach 🙂

mfikes22:01:22

For this particular one, it doesn't seem to be the clj-nil that is tripping the typecheck but the nil

mfikes22:01:08

This doesn't trigger a typecheck warning: (fn [^{:tag #{clj-nil number}} x] (dec x)) This does: (fn [^{:tag #{clj-nil nil}} x] (dec x))

dnolen22:01:45

right but again I think both of those should get rejected in a simple true branch

mfikes22:01:15

FWIW, the zprint warning goes away with ClojureScript master. This is because, while 1.10.443 infers the type to be #{clj-nil nil}, master infers it as #{clj-nil any}, which doesn't trigger the warn. This is neither here nor there, with respect to improvements, but alas, it is a fact that the warning goes away for this particular body of code.

mfikes23:01:53

I'm interested in this one; it almost seems trivial given our current setup for predicate-induced inference.