Fork me on GitHub
#clojure
<
2021-04-19
>
emccue13:04:43

Using https://github.com/cognitect/transit-js with webpack and getting this at runtime

emccue13:04:46

TypeError: goog.isArray is not a function. (In 'goog.isArray(a)', 'goog.isArray' is undefined)

This error is located at:
    in App (created by ExpoRoot)
    in ExpoRoot (at renderApplication.js:45)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:106)
    in DevAppContainer (at AppContainer.js:121)
    in RCTView (at View.js:34)
    in View (at AppContainer.js:132)
    in AppContainer (at renderApplication.js:39)
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:104:6 in reportException
at node_modules/react-native/Libraries/Core/ExceptionsManager.js:171:19 in handleException
at node_modules/react-native/Libraries/Core/ReactFiberErrorDialog.js:43:2 in showErrorDialog

emccue13:04:40

so, their build is broken?

borkdude13:04:07

@U3JH98J4R I made a mention of this now in #cljs-dev

p-himik13:04:03

@U3JH98J4R Seems like goog.isArray is only used by the printing function. Are you [implicitly] calling toString on the read value?

emccue13:04:21

I am explicitly calling toString

emccue13:04:52

(val.status == 'success') ? <Text> {val.data.toString()} </Text> ...

p-himik13:04:20

Four ways to fix it in your build: 1. Wait till it's fixed in transit-js 2. Use an older version of ClojureScript 3. Patch the goog object (might be finicky in the release build) 4. Roll out your own implementation of toString

borkdude13:04:27

@U3JH98J4R a workaround for now would be to downgrade CLJS to the previous release, file an issue at transit-js. wait for them to bump it to the newest closure and then upgrade again

emccue13:04:32

I'm not using clojurescript

emccue13:04:53

i just am using the npm dep, which says it has no dependencies

borkdude13:04:04

oh, hmm. then use an older version of closure explicitly

emccue13:04:17

closure isn't in the dependencies

emccue13:04:26

so pick an older released build from them?

borkdude13:04:21

I have no idea how this works, but perhaps ask in #clojurescript

emccue13:04:23

Works if I downgrade to 0.8.861 from 0.8.867

emccue13:04:50

so confidence in library has gone from an 8 to around a 3

p-himik13:04:04

FWIW their issues on GitHub are open - you can create an issue there, it might get better traction.

borkdude16:04:33

@U3JH98J4R Check #cljs-dev for more info

emccue13:04:43

wasn't getting any error until it tries to actually parse data

Xarlyle015:04:18

Are there any strong opinions on the dot special form for Java interop? I'm using Java interop for my current project and have a feeling that the dot special form somewhat obscures what I'm doing, so I haven't used it, but I wanted to see if there are any opinions about it. When would it be better to use the dot special form for working with Java classes?

noisesmith15:04:16

I've never had to use . on its own, but it could be convenient in constructing readable macros

noisesmith15:04:33

for anything else we have regular method calls and member access

nilern16:04:36

I think most people prefer the (.foo bar) version. But it makes sense to have just one special form . in the end and there is a very long Lisp tradition behind that flow.

wombawomba17:04:14

Why precisely aren't nested #()s allowed? Having bindings shadow other bindings seems to be deemed okay in every other situation. Is there another reason?

andy.fingerhut17:04:20

Perhaps because defining anonymous functions using fn is more general, and #() would get even more confusing when nested than not nested?

andy.fingerhut17:04:27

I am guessing -- I did not define the language.

wombawomba17:04:59

Yeah I guess it could be something like that, but then that seems inconsistent with e.g. allowing nested ->>/`->` when there's the more general and less confusing as->.

andy.fingerhut17:04:16

#() is a reader macro built into the reader.

andy.fingerhut17:04:39

->> and -> are macros that anyone could define if they did not exist in the language, and the Clojure compiler never tries to prevent you from nesting macro calls.

seancorfield17:04:38

@wombawomba as-> is not a “more general” threading macro: it is intended to be used in specific cases inside -> pipelines for expressions that require the value to be passed into a slot other than the first or the last.

👍 2
andy.fingerhut17:04:41

regular macros and "reader macros" are implemented very differently, and Clojure does not allow you to define your own reader macros.

andy.fingerhut17:04:57

without changing your copy of the Clojure reader source code, that is, which almost no one does.

seancorfield17:04:05

(-> (something) (as-> v (do-stuff :to v :with 13)) (something-else)) is the intended usage. as-> is expected to be very rare in real world code.

nilern19:04:58

Reader macros run in the parser, so a nestable #() would make the grammar context sensitive. This is generally avoided as it makes tooling more difficult to build.

nilern19:04:15

But I think the real reason is that #() is mostly meant to be used as a generalized (and faster) partial like cut in Scheme and _ in Scala

manutter5117:04:57

Consider #(foo #(inc %) %). If foo applies an anonymous fn to a collection, you might want the outer % to be a collection and the inner % to be one item from the collection, but if foo works like an if, you might want both %’s to be the same value.

☝️ 2
manutter5117:04:33

Basically, nesting #() is highly likely to generate edge cases that the reader/compiler isn’t going to have a good way to distinguish between.

potetm17:04:20

(fn [%] (foo (fn [%] (inc %)) %)) <- works tho

wombawomba17:04:25

Wouldn't it be simple to have the innermost % always bind to the 'tightest' #(), and let users use fn if they want something else?

andy.fingerhut17:04:35

When you ask "why is it this way?", part of the full answer is "what was Rich Hickey thinking when he designed it with this restrction?". You might find someone who knows the full answer because they heard Rich Hickey answer that specific question, or found an answer he wrote in the Clojure Google group to link to, but other than that, the best we can do is guess.

✔️ 2
andy.fingerhut17:04:02

It would not be difficult to change the Clojure reader to enable the behavior you describe. That isn't the way it is now.

potetm17:04:16

@wombawomba I think a decent guess is, “it’s confusing, and rarely necessary.”

wombawomba17:04:46

Yeah that makes sense. I wonder if there could be historical precedence though? How do other lisps deal with these sorts of anonymous lambdas?

andy.fingerhut17:04:55

Note: I am not saying "Never ask such questions." I am simply trying to tell you the best kinds of answers you can expect.

potetm17:04:16

Confusing because, by definition, it means you have multiple implicit contexts with unnamed parameters floating around.

Noah Bogart17:04:27

i don't know of any other lisps that have a reader for lambdas like clojure does

andy.fingerhut17:04:37

Common Lisp and Scheme both have something similar to Clojure fn, which nest.

wombawomba17:04:46

The main reason I ask is that disallowing things just because it might be confusing for users seems to run contrary to the Lisp tendency to make things as simple as possible.

potetm17:04:27

You’re only looking at one side of the tradeoff.

potetm17:04:03

The question isn’t just, “is this confusing vs simple.”

potetm17:04:16

The question is also: What do you get for allowing something?

potetm17:04:25

And the answer here happens to be: Virtually nothing.

potetm17:04:47

You get to type a little less in one specific (and rare) scenario.

potetm17:04:09

And (like Sean said), it’s a scenario you arguably don’t want to be in in the first place.

potetm17:04:15

So, the scenarios are: 1. You have to write a recursive parser for #() and users might find it confusing. 2. Don’t allow it. Users might still find it confusing. No other downsides.

wombawomba17:04:11

Arguably users might find having just (fn []) be less confusing

wombawomba17:04:38

Still, fair point

andy.fingerhut17:04:38

You can write perfectly fine Clojure programs that never use the #() syntax. It still helps to know it if you run across it in other people's code.

Linus Ericsson20:04:14

#() has ordered arguments as well, and I can see that an expression like #(something #(something %1 %2) %2 :a :b) quickly could become inconsistent. Which argument is the inner %2 refering to?

potetm20:04:59

This is the same argument someone else made earlier. The semantics aren’t actually ambiguous. They would always apply to the inner-most scope. This is the same way regular function shadowing works.

potetm20:04:43

It’s not a question of, “is this sensical/consistent/good/bad?”

potetm20:04:53

No one here appears to know the real answer, but a fair assumption is, “It’s not worth it.” (Which isn’t the same as, “This example would be inconsistent.“)

seancorfield17:04:18

Given that the general guidance for #() is that anonymous functions should be very simple expressions and you should use a named function for anything complex, I would say “nested function uses” would fall outside “very simple expressions” in the first place 🙂

☝️ 2
wombawomba17:04:27

Perhaps the answer is that other Lisps just don't have this thing in the first place, because it's simpler to just have one way to define functions

andy.fingerhut17:04:44

I do not recall anything quite like #() in Common Lisp or Scheme, although Common Lisp lets you define your own reader macros (which Clojure does not support, by design choice) which might let you define something like #() yourself.

Karol Wójcik17:04:28

How to destructure inner :app properties to keys? Something like, but working

(let [{:app/keys [useragent] :app} {:app {:app/useragent {}}] 

Lennart Buit18:04:31

You need an extra pair of {} around your destructured value:

(let [{{:app/keys [useragent]} :app} {:app {:app/useragent {}}}]
  useragent)

dpsutton18:04:41

i think simple things that have multiple "correct" behaviors are generally avoided for inclusion for clojure core. Deep merge, nested literals like this, and other similar problems. They all have different implementations with solutions that make tradeoffs that all make sense, and so there's no natural one that is better for inclusion. Also, since they don't add a huge benefit they are quite easy to not add to the language

👍 2
yuhan18:04:08

One surprising example I found early on was dissoc-in which seems like such a natural thing to have in the core family of functions - apparently because there's an ambiguity of whether to keep empty maps around if their last key has been dissoc'ed

Wesley Matson18:04:02

https://github.com/weavejester/medley - I find myself often including this library because it has made reasonable decisions on many of those situations (and the documentation states any relevant assumptions http://weavejester.github.io/medley/medley.core.html#var-dissoc-in)

🎉 2
Lennart Buit18:04:52

Haha yeah, medley is quite useful. Also as a reality check: what I’m trying to do, is it so common that it is offered in medley 😉

Noah Bogart18:04:10

medley is by far my favorite of the "should have been in core" function libraries

2
dpsutton18:04:48

i think of medley as lovely and thoughtful functions that the core of the language makes easy to write and include

SK19:04:27

hi! I'm running a test using clojure.test, but get a lot of assertions reported.. any guess how can this happen? (in my deftest, there is a single "is")

SK19:04:34

Ran 1 tests containing 3785 assertions.
1 failures, 0 errors.
=> {:test 1, :pass 3784, :fail 1, :error 0, :type :summary}

seancorfield19:04:07

@surf-kid24 Is your is assertion inside a loop perhaps?

SK19:04:40

no, that would be an easy explanation 🙂

dpsutton19:04:14

are you running your tests like (clojure.test/run-all-tests)?

seancorfield19:04:32

That would show multiple tests.

SK19:04:39

no, using a single namespace via clojure.test/run-tests

seancorfield19:04:58

Can you share the code, or a simplified version of it?

SK19:04:19

I cannot see anything obvious that would result in this.. I'm just wondering where I could add some logging or a breakpoint or similar

seancorfield19:04:09

(doto (is ...) (println 'test))

seancorfield19:04:54

If that prints just one test line, then you have other assertions being run. If it prints 3,785 test lines, then your is assertion is being run thousands of times.

SK19:04:33

thanks, I'll check this

SK19:04:12

I have a suspicion that I have accidentally used "is" somewhere else