Using https://github.com/cognitect/transit-js with webpack and getting this at runtime
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
wasn't getting any error until it tries to actually parse data
https://clojurescript.org/news/2021-04-06-release#_noteworthy_breaking_changes
so, their build is broken?
@emccue I made a mention of this now in #cljs-dev
@emccue Seems like goog.isArray
is only used by the printing function. Are you [implicitly] calling toString
on the read value?
I am explicitly calling toString
(val.status == 'success') ? <Text> {val.data.toString()} </Text> ...
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
@emccue 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
I'm not using clojurescript
i just am using the npm dep, which says it has no dependencies
oh, hmm. then use an older version of closure explicitly
closure isn't in the dependencies
so pick an older released build from them?
I have no idea how this works, but perhaps ask in #clojurescript
Works if I downgrade to 0.8.861 from 0.8.867
so confidence in library has gone from an 8 to around a 3
FWIW their issues on GitHub are open - you can create an issue there, it might get better traction.
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?
I've never had to use .
on its own, but it could be convenient in constructing readable macros
for anything else we have regular method calls and member access
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.
@emccue Check #cljs-dev for more info
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?
Perhaps because defining anonymous functions using fn
is more general, and #()
would get even more confusing when nested than not nested?
I am guessing -- I did not define the language.
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.
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->
.
#()
is a reader macro built into the reader.
->>
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.
Basically, nesting #()
is highly likely to generate edge cases that the reader/compiler isn’t going to have a good way to distinguish between.
@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.
regular macros and "reader macros" are implemented very differently, and Clojure does not allow you to define your own reader macros.
without changing your copy of the Clojure reader source code, that is, which almost no one does.
(fn [%] (foo (fn [%] (inc %)) %))
<- works tho
Wouldn't it be simple to have the innermost %
always bind to the 'tightest' #()
, and let users use fn
if they want something else?
(-> (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.
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.
It would not be difficult to change the Clojure reader to enable the behavior you describe. That isn't the way it is now.
@wombawomba I think a decent guess is, “it’s confusing, and rarely necessary.”
Yeah that makes sense. I wonder if there could be historical precedence though? How do other lisps deal with these sorts of anonymous lambdas?
Note: I am not saying "Never ask such questions." I am simply trying to tell you the best kinds of answers you can expect.
Confusing because, by definition, it means you have multiple implicit contexts with unnamed parameters floating around.
i don't know of any other lisps that have a reader for lambdas like clojure does
Common Lisp and Scheme both have something similar to Clojure fn
, which nest.
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.
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 🙂
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
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.
You’re only looking at one side of the tradeoff.
The question isn’t just, “is this confusing vs simple.”
The question is also: What do you get for allowing something?
And the answer here happens to be: Virtually nothing.
You get to type a little less in one specific (and rare) scenario.
And (like Sean said), it’s a scenario you arguably don’t want to be in in the first place.
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.
Arguably users might find having just (fn [])
be less confusing
Still, fair point
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.
How to destructure inner :app properties to keys? Something like, but working
(let [{:app/keys [useragent] :app} {:app {:app/useragent {}}]
You need an extra pair of {}
around your destructured value:
(let [{{:app/keys [useragent]} :app} {:app {:app/useragent {}}}]
useragent)
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
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
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)
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 😉
medley is by far my favorite of the "should have been in core" function libraries
i think of medley as lovely and thoughtful functions that the core of the language makes easy to write and include
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")
Ran 1 tests containing 3785 assertions.
1 failures, 0 errors.
=> {:test 1, :pass 3784, :fail 1, :error 0, :type :summary}
@surf-kid24 Is your is
assertion inside a loop perhaps?
no, that would be an easy explanation 🙂
are you running your tests like (clojure.test/run-all-tests)
?
That would show multiple tests.
no, using a single namespace via clojure.test/run-tests
Can you share the code, or a simplified version of it?
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
(doto (is ...) (println 'test))
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.
thanks, I'll check this
I have a suspicion that I have accidentally used "is" somewhere else
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.
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
#() 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?
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.
It’s not a question of, “is this sensical/consistent/good/bad?”
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.“)