Fork me on GitHub
#cljs-dev
<
2019-02-18
>
mfikes17:02:04

:statement is an odd default as the compiled code for it can be elided if it is known to not produce a side effect. For example:

cljs.user=> (cljs.js/compile-str (cljs.js/empty-state) "1" prn)
{:value ""}
but
cljs.user=> (cljs.js/compile-str (cljs.js/empty-state) "1" "foo" {:context :expr} prn)
{:value "(1)"}
I suspect that, when Antiónio added this docstring clarification, he and I were already quite used to :context :expr, felt comfortable with it being the default, but failed to actually confirm that it is the default.

mfikes17:02:20

(do
   1                ; :statement; can be elided from the generated code
    (prn :hi)       ; :statement; can't be elided as it has a side effect
   3)

john17:02:57

So the elided version of compile-str depends on :statement being the default

john17:02:23

Oh, I misunderstood

mfikes17:02:38

Yeah, evidently all the docstrings indicate :expr is the default, but evidently this is not actually the case.

john17:02:38

The version with less parameters, I mean

mfikes17:02:38

It seems that :statement might be of interest to you in some academic fashion, or if you are building something odd. You almost always want :expr

john17:02:52

Are there instances where you want to call eval or compile-str on a thing but not keep env between invocations? Like, for memory or sandboxing?

mfikes17:02:57

Summary: :expr should be the default, it matches the docstring. We arguably have a defect in that :statement is really the default. Changing the default from :statement to :expr to fix this bug is, strictly speaking, a breaking change. But, pragmatically, speaking, everyone is probably explicitly passing :expr.

thheller17:02:55

you don't really need :expr if you treat things like loading files. :expr is only required if you care about the return value of eval-str

thheller17:02:34

I don't know if :context :expr applies when eval-str ends up loading other files?

john17:02:31

Maybe :expr would leave around a dirty environment for existing code that expects :statement behavior?

mfikes17:02:53

Yeah, that's a good point. If you are only evaluating for side effects, and you know what you are doing, you could use :statement for that.

john17:02:37

Hard to say with out testing I guess

mfikes17:02:54

Yeah, the safest thing to do is to change all the docstrings to reflect the actual default.

mfikes17:02:26

:statement is an unfortunate default in that it doesn't align with the "simpler" use case of just using self-hosted to see what a form evaluates to

john17:02:29

But what if some individual functions, like eval when called directly, opted into :expr behavior? Are there specific fns that'd be more safe to convert?

mfikes17:02:13

I can't really say. I've always used :expr

mfikes17:02:37

The truth is out there. I have no clue what it is 🙂

john17:02:29

Yeah, docstring change is probably safest

mfikes17:02:01

Perhaps to save the future Zane's of the world from bewilderment, the docstring could say something about the default being :statement, which is OK for side-effecting forms, but that you should specify :expr if you need the result of the evaluation.

john17:02:21

Makes sense