This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-08-06
Channels
- # aleph (1)
- # beginners (180)
- # calva (16)
- # cider (29)
- # clj-kondo (47)
- # cljsrn (5)
- # clojure (40)
- # clojure-dev (39)
- # clojure-europe (1)
- # clojure-italy (25)
- # clojure-nl (9)
- # clojure-russia (1)
- # clojure-spec (8)
- # clojure-uk (83)
- # clojurescript (54)
- # core-async (2)
- # datomic (20)
- # defnpodcast (7)
- # figwheel (6)
- # fulcro (6)
- # jobs (5)
- # joker (4)
- # kaocha (4)
- # luminus (4)
- # off-topic (8)
- # onyx (6)
- # pathom (14)
- # re-frame (28)
- # reagent (30)
- # remote-jobs (2)
- # shadow-cljs (88)
- # spacemacs (2)
- # specter (17)
- # sql (25)
- # tools-deps (78)
- # xtdb (1)
- # yada (2)
clojure compiler error message almost never point me to the real issue, the only useful info just the line number, and the runtime exception even worst, most of the time just throw a null pointer exception, any practical workflow you guys are using when developing clojure project?
some of the common ones are weird at first but make sense when you learn them "* cannot be cast to ifn" -> you put something in parens that isn't a function you can call "end of form during reading" - > missing a closing paren
in fact the compiler messages contain a lot of interesting data that regular runtime errors don' t with newer versions (but it's in a relatively raw form that doesn't make a lot of sense to a newcomer)
@godwin.ko First off, I'd recommend you try Clojure 1.10.1 so you get the most up-to-date error reporting (it was improved a lot in 1.10). Also, not all of the tooling out there supports the changes in 1.10 around error reporting so you can still get a lot of "noise" from tooling, unless you're using the CLI / deps.edn
stuff.
Second, as @noisesmith says, the errors provide exactly the information you need, once you get used to a few specific "mappings" you need to do in your head.
If you are getting NPEs, you are probably trying to perform numeric or string operations on things that are nil
, or you're trying to call a symbol/expression whose value is nil
. Getting used to idiomatic nil-punning will help here (I almost never get NPEs these days but I did when I started out).
Hi, I am trying to call a function inside a let statement, but it is saying "unable to resolve symbol in this context"
(defn addd [arg]
(let [
arg (some-func arg)
]
(println "arg is " arg)
arg
))
That indentation / layout is non-idiomatic and very hard to read.
(defn addd [arg]
(let [arg (some-func arg)]
(println "arg is " arg)
arg))
@gagan.chohan I assume some-func
is the symbol it says it cannot resolve here?
Where is some-func
defined?
Where in the same file?
Clojure requires that symbols are defined (or at least declared) before their first use.
So the (defn some-func ...)
needs to come before the (defn addd ...)
yes - in fact the clojure compiler doesn't really care much about files per se
Clojure is compiled one form at a time, not one file at a time.
it reads forms in order, they can come from various places
the nice thing about this is the repl works exactly like any other scenario
the order of definitions matters, nothing is available before it's declared or defined
because likely in the repl you defined the function first
do the same thing in the file
thx @noisesmith & @seancorfield for pointing me some directions π:skin-tone-2:
Hello everybody! I just started my journey on the clojure world and was wondering if someone could recommend some good resource to follow. I just finished this https://github.com/functional-koans/clojure-koans and found it really cool, anything interactive like that would be really appreciated
Within the repl, is there a way to load all of my project's namespaces in, say starting from my "core.clj" and getting it to pull in everything that it depends upon, so that I have access to the "dependent" namespaces?
hey @U11EL3P9U , I just looked at the description of https://github.com/clojure/tools.namespace . Perhaps it can help you.
I usually create a user
namespace, add it as a source-path in development, and set the repl to start in that namespace (using :repl-options
> :init-ns
in leiningen, for example). Then I require all my namespaces in there so it's all ready to go when the repl starts. I realise this isn't exactly what you were asking (tools.namespace is the answer), but it is how i achieve the same thing on a day-to-day basis.
@U11EL3P9U Now that I'm reading your question again, what @U053032QC says makes more sense if you just want to have all you need in the repl like the most common namespaces / functions. I do the same. You can see an example where I make the cli
alias and all public functions in core
available in the repl for quick usage https://github.com/jivagoalves/codebreaker/blob/master/dev/user.clj#L4-L5
There's also a helper fn to run the tests https://github.com/jivagoalves/codebreaker/blob/master/dev/user.clj#L7-L12
if it applies to you, in emacs using cider, open the core.clj buffer and do the keypress c-c c-k
NB require is already recursive: if a namespace requires another namespace, require already loads both
hello guys, I recently started using clojure (is awesome so far!). Iβm creating a simple compojure application. The whole code is visible here: https://github.com/bakku/clj-rest-web-app Iβm currently trying to have a session that stores the currently logged in user ID. Iβve configured the ring-session middleware to use a cookie store, however after restarting my server the session is somehow refreshed as if it is actually not using any cookie store. The important bits are probably: - Here I am configuring the cookie-store: https://github.com/bakku/clj-rest-web-app/blob/master/src/clj_rest_web_app/core.clj#L24 - Here I am setting the session after a successful login: https://github.com/bakku/clj-rest-web-app/blob/master/src/clj_rest_web_app/controllers/sessions.clj#L6 - Iβm running the application in docker, here I am setting the cookie secret: https://github.com/bakku/clj-rest-web-app/blob/master/docker-compose.yml#L15 Does anybody have some idea what might be the problem?
@christian.paling by default Ring uses an in-memory session store. you can change it to store data in a cookie or something persistent like Redis, see https://github.com/ring-clojure/ring/wiki/Sessions#session-stores
I got it to work ! I was using the site-defaults
from ring which already wrapped my routes using the session middleware but the site-defaults
are using the in-memory session. I had to update the session configuration of the site-defaults
according to my needs to get it to work π
Hi all! I am trying to use Reagent with react-beautiful-dnd
and I run into an error when trying to convert one of the datastructures they pass to me for usage (`provider` - a parameter to the react child function) from a js value to a cljs value with (js->clj provider :keywordize-keys true)
. The reason seems to be that the datastructure contains javascript symbols.
A simple reproduction is to type in the cljs repl: (str (js/Symbol "foo"))
which leads to the same error.
Is there a (simple) way around this error - a way with which clojurescript can deal with the javascript symbol?
I found I can extend the writer protocol to understand js symbols - I wonder though why this is not part of the clojurescript implementation
@alpox you can use String
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#String_conversion
symbols intentionally aren't "stringy"
@noisesmith thanks for pointing that out. My issue is that the string conversion is done implicitly by js->clj
somewhere deep in the datastructure though - not something that is under my control.
js->clj
is kind of a sloppy tool - if you use the transit
library it allows arbitrary functions to handle data types as you like, and it also performs much better
A solution I found is to:
(extend-protocol IPrintWithWriter
js/Symbol
(-pr-writer [sym writer _]
(-write writer (str "\"" (.toString sym) "\""))))
But I'm not sure if extending the protocol generally for symbols is a good idea@noisesmith Ah I heard a lot about transit but didn't yet check it out. May be the time π Thanks, I'll look into it!
@noisesmith I'm a bit confused about what I see about transit. I see that it can read/write from/to strings for the purpose of data-transport. What I fail to see is how transit applies to the transformation of js values to clojurescript values. Is the general way to go to marshal js values to a string and then read it into cljs? This seems like one step too much
"failed: Error during WebSocket handshake: Unexpected response code: 200"
puzzling
it's expecting 101
but i'm not sure why it's connecting too quick too early
oh sorry to just hijack your convo
@alpox you know about cljs reader right?
i was thinking cljs-reader / read-string, but what are you trying to do ? (what's your end-goal )
I just want to transform a javascript datastructure (deep) to a cljs datastructure. The pickle: Somewhere in the datastructure, there is a javascript Symbol which js->clj
cannot handle
@alpox had something to attend to at $JOB
@noisesmith no problem π
I agree that transit isn't for your precise problem, but it does a common task: a deep walk of a structure to turn it into "simple" values
where clearly a js Symbol isn't simple
> Note that js->clj is not optimized for speed and the transit.cljs library is recommended for parsing large amounts of JSON data. https://cljs.github.io/api/cljs.core/js-GTclj
also you can simply copy/paste the function on that page, and add a clause for Symbol
(if only js->clj was built on a multimethod or protocol you could extend it...)
oh! you could extend IEncodeClojure
(extend-protocol IPrintWithWriter
js/Symbol
(-pr-writer [sym writer _]
(-write writer (str "\"" (.toString sym) "\""))))
@alpox by extend I mean make it understand a new input without editing the code
it doesn't use IPrintWithWriter though?
it does use IEncodeClojure
OK - via the else clause I guess
encoding of result failed TypeError: Cannot convert a Symbol value to a string
at Array.join (<anonymous>)
at Function.cljs$core$IFn$_invoke$arity$1 (core.cljs:2963)
at Object.cljs$core$pr_writer_impl [as pr_writer_impl] (core.cljs:10174)
at cljs$core$pr_writer (core.cljs:10183)
at core.cljs:10306
at Object.cljs$core$pr_sequential_writer [as pr_sequential_writer] (core.cljs:10037)
at Object.cljs$core$print_prefix_map [as print_prefix_map] (core.cljs:10303)
at Object.cljs$core$print_map [as print_map] (core.cljs:10315)
at Object.cljs$core$IPrintWithWriter$_pr_writer$arity$3 (core.cljs:10390)
at Object.cljs$core$_pr_writer [as _pr_writer] (core.cljs:763)
I still think extending IEcondeClojure is more directly addressing the need
Ok thanks, I'll see how its used - i'm still kinda new to all this so it may take me a while to figure it out π
Oh that was actually straight forward. Thanks a lot @noisesmith! This solution seems to fit well π
awesome
(extend-protocol IEncodeClojure
js/Symbol
(-js->clj [sym options]
(str "\"" (.toString sym) "\"")))
that looks right to me (though the MDN page seemed to suggest using the String
constructor instead)
way 2 go team
hey check out my simple clojurescript website http://www.nonforum.com and give me feedbacks pls
You know that there's a line in the Sente starter package that has a line to assign the channel socket randomly as EITHER ajax or websockt
50/50 chance
that shit was ruining my life until about an hour ago
why does my site render approximately half the time
i was doing stats on it last night ROFL "okay 2/8 times it just doesn't render the page and gets a weird websocket error"
πππ
know every line of the libraries you bring in
(when not inconvenient and mission critical)
Peace y'all have a great day Wisdom Bless
that's the wrong syntax
it's a constructor
>The "safer" String(sym) conversion works like a call to Symbol.prototype.toString() with symbols, but note that new String(sym) will throw.
it's (String. sym)
oh...
never mind, looks like toString is actually working for you
guys, I want some help with project.clj of leiningen... I want to have many folders under src but only open repl for each one subfolder by profile and generate a jar file with this profile only
like, src/a src/b
(defproject backend "0.1.1"
:dependencies [[org.clojure/clojure "1.10.1"]
[org.clojure/data.xml "0.2.0-alpha6"]]
:plugins [[lein-environ "1.1.0"]]
:resource-paths ["resources"]
:source-paths ["src"]
:profiles {:a {:main backend.a.core
:source-paths ["src/a"]
:resource-paths ["resources/a"]
:aot [backend.a.core]
:pedestal {:server-ns "backend.a.core"}}})
but this aot is giving me error to initiate the repl
lein with-profile a update-in :dependencies conj \[nrepl\ \"0.6.0\"\] -- repl
Error encountered performing task 'update-in' with profile(s): 'a'
some tip about this?
I am not sure about this, but I suspect it might be a bad idea to have two source paths where one is a prefix of the other in your project, like "src"
and "src/a"
are in your example.
If you have a source file named "src/a/foo.clj"
for example, it could be found if you require namespace a.foo
, but also foo
I have not used update-in
with Leiningen before, so am not helpful there. I have successfully used lein with-profile +a ...
commands before to add a profile, but am not familiar with Leiningen's capabilities without the +
there.
There is a #leiningen channel that you may get more answers from.
Anyone have any clue why I'm getting
Unexpected error macroexpanding s/def
[...]
Caused by: java.lang.AssertionError: Assert failed: (map? env)
for the offending snippet:
(s/def ::generated-date #(instance? Date %))
maybe you have to import Date ?
what's s an alias for?
is there a way to step through the execution of something? line-by-line, the way ruby has binding.pry
or python had pdb
lines aren't really a meaningful thing to the compiler, but you can use a debugger to step through the method calls that the clojure compiler emits, and a good editor can follow along in your source - intellij/cursive and emacs/cider have this set up
the big gotcha is for it to be useful you usually need to turn off locals clearing, which causes memory problems that don't exist in normally compiled code
sure, lines aren't meaningful to the compiler, but java can still have breakpoints and step-wise execution
I'm just saying the steps aren't lines, they are method calls, which mostly map to forms but not quite
and when you run into things like laziness, I'm not sure how accurate the mapping will be
you can do it with cursive
it often "steps" multiple times per line (once per expression)
naturally
cool, i'll look into that
I find it useful with working with interop as you can step through a mix of clojure and java
I think the emacs cider debugger also has this, but the ergonomics are probably a little different, and not sure if it works with java
yeah, that makes sense. thanks!
Can you use case with keywords? Or do you have to use a multimethod?
case works with keywords, the difference is that if it's a multimethod third party code can add a new condition without changing the upstream code
gotcha π
case doesn't work for things that don't have a read syntax, but of course keywords have a read syntax
@iagwanderson I can't vouch for this lib, but it looks like it has the right pieces to attempt what you want https://github.com/mjul/docjure
I'm currently using this library, but seems not to do lazy-load (line-by-line) of a xlsx file
isn't that what row-seq
is for?
https://github.com/mjul/docjure/blob/master/src/dk/ative/docjure/spreadsheet.clj#L156
as long as you don't hold the head, of course
unless there's something that holds onto the memory on the underlying lib I guess but one would hope they support streaming properly
if you have an example or minimal repro I can help check for a stray head reference that prevents the laziness from minimizing memory usage
simplest example, if you are not familiar: if you have (def rows (row-seq ...))
the entire realized seq is held in memory, because the def holds the head
I did an example with a 100k xlsx file and memory did not went up or event the cpu process
(defn row-size [row]
(println (.getRowNum row)))
(->> (xlsx/load-workbook filename)
(xlsx/select-sheet "Plan1")
xlsx/row-seq
(map row-size))
OK, so the issue is likely somewhere in your code holding onto the head
(in your real code, not this example, of course)
I was already trying to use this library in Java: https://github.com/monitorjbl/excel-streaming-reader