Fork me on GitHub
#clojurescript
<
2021-09-18
>
Vlad Kryvokoniev04:09:19

hi, any good libraries to manage env in clojurescript? is it really necessary to have one? any advice would be appreciated!

thheller06:09:23

define "manage env"? in the browser "env" means very different things than in node

Vlad Kryvokoniev11:09:52

like read env from within a clojurescript file

thheller12:09:22

and which target do you use? I mean does it run in the browser or node? do you just want to access the env during compilation to get some token into the code? or do you want actual runtime environment?

Vlad Kryvokoniev12:09:28

It rusn in a browser I need it during compilation

Vlad Kryvokoniev12:09:29

i want to set some secret variables

ikitommi15:09:17

a subtle difference with clj & cljs. Is this a bug or a feature?

;; CLJ
(type ^{:type ::kikka} [])
; => :user/kikka

;; CLJS
(type ^{:type ::kikka} [])
; => cljs.core/PersistentVector

ikitommi15:09:58

also:

;; CLJ
(ns domain)
(defprotocol Kikka)
(type (reify Kikka)) ; => domain$eval9831$reify__9832
(instance? domain.Kikka (reify Kikka)) 
; => true

;; CLJS
(ns domain)
(defprotocol Kikka)
(type (reify Kikka)) ; => domain/t_domain39196
(instance? domain.Kikka (reify Kikka)) 
; => false

ikitommi15:09:01

I’m still trying to get default print methods for reified types, but can’t make it as the creates objects are not of right type (the domain.Kikka in example), so this doesn’t work: https://stackoverflow.com/questions/42916447/adding-a-custom-print-method-for-clojurescript

ikitommi15:09:47

is this something that could be resolved/fixed in cljs itself?

lilactown16:09:32

I think the second example is a function of protocols not being reified, and therefore intentional

lilactown16:09:25

I'm not sure I understand the relationship between printing and "being the right type." Since you're creating the objects via reify, couldn't you add the protocol to the object directly?

lilactown16:09:34

clojurescript doesn't use multimethods for printing, it uses protocols, so the concrete type doesn't matter

lilactown16:09:47

as for type, I could see an argument being made to align it with Clojure, however it is I think called out in the differences page https://clojurescript.org/about/differences#_hinting

lilactown16:09:02

> While `^long` and `^double`—when used on function parameters—are type declarations in Clojure, they are type hints in ClojureScript. > > Type hinting is primarily used to avoid reflection in Clojure. In ClojureScript, the only type hint of significance is the `^boolean` type hint: It is used to avoid checked `if` evaluation (which copes with the fact that, for example, `0` and `""` are false in JavaScript and true in ClojureScript).

lilactown16:09:56

it's unclear if this applies to the circumstance we're talking about, but i would take it as evidence towards this just being another difference between clojure and clojurescript

lilactown16:09:36

in the meantime you could define your own fn which checks metadata, perhaps

lilactown16:09:42

@ikitommi ☝️:skin-tone-2:

ikitommi07:09:44

thanks @U4YGF4NGM! > I think the second example is a function of protocols not being reified, and therefore intentional now sure what you mean, it is refied?

(ns domain)

(defprotocol Kikka (-do [this]))

(def k (reify Kikka (-do [_] "doing")))

(-do k) ; => "doing"
… the difference with Clojure seems that it’s just not an instance of the protocol (class) like in Clojure, which would allow setting things like making all the reified instances also satify a protocol like IPrintWithWriter.
(satisfies? Kikka k) ; => true

(implements? Kikka k) ; => true

(instance? Kikka k) ; => false (this differs from Clojure

ikitommi07:09:47

In my case, I have tens of reified instances, could make all also satify the IPrintWithWriter, but it would be a lot of boilerplate. In Clojure, I can just define it once for all reified instances.

ikitommi08:09:26

also, I think I could implement the IPrintWithWriter for js/Object and read the :type metadata there and dispatch with that - but this is a library (malli) and I don’t think it’s a good idea to have such global things in a library.

lilactown15:09:58

by "reified" i mean literally, there is no concrete object created by defprotocol.

lilactown15:09:13

I guess in testing this isn't totally true, even though this is what's said in the "differences" doc on the clojurescript website. in Clojure defprotocol creates a class, but in CLJS it does not. it creates a function which it only seems to use to do some minor book keeping. it doesn't add it to the prototype inheritance tree and I would expect in a release build it would DCE the function created by defprotocol

lilactown15:09:00

implements? and satisfies? both operate at compile time. you cannot, for instance, pass around a protocol as a value

lilactown15:09:22

is there some reason you're using reify all over the place in your lib, rather than a deftype?

ikitommi06:09:02

I have currently modelled things via reify as the components (schemas) have a three-fold life-cycle (https://github.com/metosin/malli/blob/master/src/malli/core.cljc#L444-L481) 1. creating schema types (line 444) - done once to configure the schema system (“all maps are closed by default”) 2. create schema instances from (line 452) - “the map has keys x & y” 3. creating schema workers, e.g. value transformer (like 468) - “give me a (pure) function to transform values from JSON-domain to EDN for this schema) … using reify is nice here, as I can share and precompute things in the parent closures (in 1 & 2) and they are available for 3. With deftypes, I think it would be a lot more parameter passing around. Not sure if the current design is good, but that’s the way it is today. And - a lot of reify all over the place.

ikitommi06:09:47

and thanks for your time explaining the differences.

Takis_18:09:16

Hello, i am using shadow-cljs to make a node module

Takis_18:09:19

my code works when :target :node-script and it was working also before somedays with :target :npm-module

Takis_18:09:14

now i get cljs$core$ExceptionInfo [Error]: Promise error cause: MongoServerSelectionError: cljs is not defined when i try to use :target :npm-module

Takis_18:09:59

anyone knows what might caused this cljs is not defined ?

lilactown20:09:29

what’s the code?

Takis_20:09:46

i used :node-library instead of :npm-module and it works, now why it didnt work and was working before somedays i dont know

bbrinck23:09:01

Given a line number and a filename, is it possible to get the Clojurescript source at runtime? Basically, I’m wondering if it would be feasible (perhaps with source maps?) to work backwards from an exception to display the relevant source code. Are there any projects that do this already?

bbrinck00:09:38

I’m not looking for detailed code or anything, but I’m curious if this seems feasible given the way CLJS works.

lilactown02:09:40

are you talking about getting correct links in stack traces via source maps, or are you trying to do something programmatically in your app code?

lilactown02:09:49

chrome devtools understands source maps, so you can include them in your bundle to get line numbers and (at dev time) view the code in devtools.

bbrinck02:09:50

This is not fully thought out, but basically I’m trying to reproduce what devtools does at the REPL or in tests. When an errors occurs e.g. at the REPL, I’d like to be able to work backwards from the line number and filename to show the source code that produced the error.

bbrinck02:09:15

So I guess I’m trying to understand if, at the REPL, I can get access to that source map info to display the original source code.

thheller06:09:45

you can do that at the REPL yeah. here is a basic code snippet to map a line back to source https://clojureverse.org/t/server-side-decoding-of-javascript-sourcemaps/1591/3?u=thheller

thheller06:09:25

I wrote a helper for graaljs exceptions doing exactly what you asked since they don't support source maps natively and errors are otherwise unusable

thheller06:09:42

basic thing you could adapt for other platforms

bbrinck23:09:11

@U05224H0W Thank you so much! This is incredibly helpful.