This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-20
Channels
- # beginners (106)
- # boot (25)
- # cider (2)
- # cljs-dev (100)
- # cljsjs (1)
- # cljsrn (8)
- # clojure (90)
- # clojure-brasil (1)
- # clojure-dev (7)
- # clojure-greece (2)
- # clojure-italy (4)
- # clojure-madison (1)
- # clojure-russia (15)
- # clojure-serbia (15)
- # clojure-spec (13)
- # clojure-uk (32)
- # clojurescript (88)
- # cursive (19)
- # datascript (13)
- # datomic (32)
- # defnpodcast (1)
- # dirac (43)
- # euroclojure (1)
- # graphql (5)
- # hoplon (11)
- # immutant (1)
- # jobs (6)
- # lein-figwheel (2)
- # liberator (2)
- # luminus (14)
- # lumo (22)
- # off-topic (12)
- # om (9)
- # onyx (49)
- # parinfer (45)
- # precept (4)
- # protorepl (2)
- # reagent (14)
- # ring-swagger (3)
- # sql (1)
- # test-check (58)
- # timbre (3)
- # untangled (86)
I was pondering how we can improve the ^:const
description in the “differences” page (https://clojurescript.org/about/differences#_special_forms) for when the next release comes out. It currently has
* `:const` metadata in ClojureScript disallows re-def and supports case. In Clojure `:const` allows re-def but value inlined at use site.
Here is a draft of potential new copy:
* `:const` metadata:
- disallows re-def in ClojureScript, while re-def is allowed in Clojure
- supports inlining of static literal values in ClojureScript, while only primitives are inlined in Clojure
- allows `case` test constants which are symbols resolving to `^:const` Vars to instead represent their values in ClojurScript, while such tests constants are symbols in Clojure
I found this relevant to Clojure: https://github.com/clojure/clojure/blob/f572a60262852af68cdb561784a517143a5847cf/changes.md#215-const-defsSweet: Test output is now appearing in the CI builds (where it was being swallowed previously): https://travis-ci.org/mfikes/clojurescript/builds/244743749
also the disallowing redef is only about compiling files - not a REPL thing - so not a big deal for users
OK. So perhaps there will be no essential difference between ClojureScript and Clojure with respect to inlining. (That line could be removed)
the important semantic distinction is that Clojure will eval the const initializer at compile time
user=> (def ^:const a (do (println "foo") [1]))
foo
#'user/a
user=> (defn x [] a)
#'user/x
Here is an example that made me think that arbitrary EDN might not be inlined in Clojure:
user=> (def ^:const x [1])
#'user/x
user=> (identical? x x)
true
@dnolen right, under AOT any def
is evalauted twice, once during compilation and once during load, again, not specific to const
so yeah, there is an evaluation difference between clj and cljs but saying that clj does it at compile time is incorrect
So, it sounds like the only thing really worth mentioning on the “differences” page is the case
behavior.
difference is essentially: clj will inline evaluated values, cljs will just inline unevaluated literals. both require the inlined value to be a valid EDN literal
Ahh, right. This is alluded to in https://github.com/clojure/clojure/blob/f572a60262852af68cdb561784a517143a5847cf/changes.md#215-const-defs
e.g.
user=> (def ^:const bar (Object.))
#'user/bar
user=> (defn foo [] (bar))
CompilerException java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: java.lang.Object@3d71d552, compiling:(NO_SOURCE_PATH:3:1)
@bronsa one problem is that what we just discussed is surprisingly subtle and easy to be confused about
* `:const` metadata:
- supports inlining of static EDN values in ClojureScript, while evaluated values are inlined in Clojure
- allows `case` test constants which are symbols resolving to `^:const` Vars to be inlined with their values in ClojureScript, while such tests constants are symbols in Clojure
^ this is my revised proposed languageand based on what I did for ^:const
(an early aggressive and not quite right commit) there’s too much incorrect stuff already in the wild
as in people didn’t understand how it was supposed to work and did the wrong thing in existing code
“people didn’t understand how it was supposed to work” including me for the last who knows how many years
I think we should say that ^:const
will inline compile-time static EDN values and leave it at that
This simpler language just focuses on ClojureScript:
* `:const` metadata:
- will cause inlining of compile-time static EDN values
- causes `case` test constants which are symbols resolving to `^:const` Vars to be inlined with their values
Best I can tell from the exception, these write handlers should be one-arg functions, not two-arg method impls: https://github.com/clojure/clojurescript/blob/293b7ddb7c26d525e8fe33c0cf1707cee52c6f8b/src/main/clojure/cljs/analyzer.cljc#L87-L94
For https://dev.clojure.org/jira/browse/CLJS-2110, I’ve posed a question for clarification in #test-check
@dnolen Summary is it appears there was unintentional breakage. Perhaps that means for ClojureScript is that either it could move to 0.10.0-alpha2
if one is produced in time, or we could revert my change that moved it to 0.10.0-alpha1
if a ClojureScript release becomes imminent.
@favila, thanks is that :clj
only? perhaps that’s why we messed this up - pretty sure sig is different for transit-clj / transit-cljs