Fork me on GitHub
#beginners
<
2018-10-26
>
Charlot00:10:11

Throwable works just fine. Thank you

Charlot01:10:17

(deref ('sessions (ns-interns 'clojure.tools.nrepl.middleware.session)))
is erroring now...

Charlot01:10:03

but I was able to proceed with pretty much identical code earlier, and I have the logs to compare to

hiredman01:10:08

because you haven't loaded the namespace

Charlot01:10:00

Just checked that, and it does not seem to be the issue. The logs have me requiring it, and requiring it in the present code still gives me the same error

Charlot01:10:11

StackOverflowError   java.util.regex.Pattern$Branch.match (Pattern.java:4722)

andy.fingerhut01:10:59

Google searching for that finds this result, which might be related to the problem you are having: https://stackoverflow.com/questions/7509905/java-lang-stackoverflowerror-while-using-a-regex-to-parse-big-strings

andy.fingerhut01:10:21

I have never seen java.util.regex.Pattern match do a StackOverflowError, but seems possible with some kinds of regex patterns and long strings.

andy.fingerhut01:10:00

Do you have the rest of the stack trace available? Putting it in a gist or other public place other than pasting it in Slack would be best if long

andy.fingerhut01:10:14

If there is some open source Clojure code somewhere with a regex causing the issue, I might be able to reproduce it and see if there is a replacement that handles more use cases.

andy.fingerhut01:10:08

Wow, that is buried pretty deep in Clojure's printing code itself, it seems, and the regex is internal to Java's implementation of its format method.

andy.fingerhut01:10:08

Were you trying to print a Java object with reference cycles, maybe?

Charlot01:10:24

well... it's not ideal, but if I don't let it escape to the screen, then it would work

Charlot01:10:32

will be fun to develop this.

andy.fingerhut01:10:42

That stack trace has the same repeating set of about 10 calls for many repetitions

andy.fingerhut01:10:36

Are you typing this expression at a REPL, which then tries to print the return value? (deref ('sessions (ns-interns 'clojure.tools.nrepl.middleware.session)))

andy.fingerhut01:10:57

If you don't need to have it printed, you could wrap that in a (def temp1 ...) and it won't get printed.

Charlot01:10:20

indeed. I'm working at a repl because I need to dig into this deeply. It's a deeply nested whatever it is...

andy.fingerhut01:10:38

There are Clojure objects that have cycles in references between their parts, or between them, and namespaces and Vars could be among them. I've run across such infinite loops when debugging Eastwood a couple of years ago, so the details are a bit fuzzy, but I did create some custom printing code to avoid printing the parts that led to infinite loops.

andy.fingerhut01:10:01

Protocol objects seemed to have been an issue. Any defprotocol's in that namespace?

Charlot01:10:08

I have managed to get down past whatever has these loops

Charlot01:10:26

I would imagine so, the name space is all present namespaces

andy.fingerhut01:10:41

I'm just tossing out possibilities that this reminds me of. My thoughts may be not the actual issue.

andy.fingerhut01:10:41

Which version of Clojure, by the way? Might help me match up line numbers in the stack trace.

Charlot01:10:26

this was in1.8.0 thanks for the reminder

Charlot01:10:22

https://pastebin.com/cGefEqgB here is the error under 1.9.0

andy.fingerhut02:10:36

I don't see how this is anything but some kind of cyclic structure that you shouldn't be trying to print out in its entirety.

Charlot02:10:50

Then no big deal, and thank you

andy.fingerhut02:10:09

You can assign its value to a Var in a REPL, then examine pieces of it carefully without printing it all out.

Charlot02:10:33

I have managed to avoid printing the unprintable, and thank you for pointing out that was the prime issue

Charlot02:10:42

I hope I did not sound short?

andy.fingerhut02:10:49

e.g. (keys (some-expression-evaluating-to-a-map)) follows by (:interesting-key (some-expression-evaluating-to-a-map)) It can be painstaking that way, I know, but the only alternative I know is to create a custom printing function that breaks the cycle somehow, e.g. use pprint with *print-level* set to a small number like 5 to start with.

andy.fingerhut02:10:02

no, no worries.

andy.fingerhut02:10:42

We are definitely beyond what I would consider the problems that most beginners would have, though 🙂

Charlot02:10:20

I'm at an annoying place where I have questions that don't fit well. Because they can be either really dumb or really deep.

Charlot02:10:37

Last time I asked in the general chat, I was told I should ask in here

Charlot02:10:42

so here I am

Charlot02:10:16

I might have another interesting question in another moment... if this seems to be what I think it is

Charlot02:10:34

So I have a map, that has vars as keys

Charlot02:10:08

{#'clojure.core/*unchecked-math* false, #<Var: --unnamed--> #object[clojure.lang.DynamicClassLoader 0x44220b8d "clojure.lang.DynamicClassLoader@44220b8d"], #'clojure.core/*compile-path* "/home/unwary/Clojure/projects/scratch/target/classes", #<Var: --unnamed--> nil, #'clojure.core/*3 :meep, #'clojure.core/*out* #object[java.io.PrintWriter 0x18c3bb51 "java.io.PrintWriter@18c3bb51"] ....

Charlot02:10:24

How does one create a key to lookup in this map?

andy.fingerhut02:10:21

You should be able to type them as they print

andy.fingerhut02:10:45

If you have stored the map in a Var named my-map, then (my-map #'clojure.core/*unchecked-math*) should do it.

andy.fingerhut02:10:26

If you cause the result of that to be printed, and it is the value that has a cycle in it, then you'll be sad again.

andy.fingerhut02:10:59

Out of curiosity, what is your overall goal where you have entered into this debug session?

Charlot02:10:57

I am working on extracting full error objects, in order to be parsed into a beginner friendly format

Charlot02:10:08

this function will be placed in an nrepl middleware

dpsutton03:10:26

No chance you're using rebel read line by any chance? I've seen a stack overflow from that before. I think hired man diagnosed it

Charlot03:10:14

not seen that. Will check it out

TeMPOraL04:10:19

@joelsanchez RE that calling and fun vs #'fun, thanks! that's what I was asking for

TeMPOraL04:10:31

ironically, the syntax is almost exact opposite to Common Lisp

Michael Fiano06:10:48

@temporal.pl In CL, #' is a reader macro for (function ...). It's not the opposite. In Clojure, that expands to (var ...). Symbols are not vars. Infact symbols are just names and do not contain a function or namespace property as they do in CL.

Azzurite08:10:36

Why does this code not catch the exception thrown?

(try
  (gen/sample (s/gen (s/and int? #(= % 12345))))
  (catch Exception e
    (prn "Caught exception")))
; -> ExceptionInfo Couldn't satisfy such-that predicate after 100 tries.  clojure.core/ex-info (core.clj:4739)

Azzurite08:10:15

using clojure.spec & test.check

val_waeselynck09:10:16

@azzurite may gen/sample returns a lazy sequence?

Azzurite09:10:20

yep, with doall it works. Thanks!

agigao12:10:56

Hi Clojurians, it has been a while since the last time I posted here. So, I'm trying to parse XML the first time in Clojure. I'm using parse-str from clojure.data.xml package.

agigao12:10:24

Eventually got this kind of structure:

#xml/element{:tag :S1_A_ALERTS_Output,
             :content [#xml/element{:tag :Body,
                                    :content [#xml/element{:tag :RecordNR,
                                                           :attrs {:CB_SpecialCode "_",
                                                                   :SystemDecision "AP",
                                                                   :Result_Block "0",
                                                                   :PAffiliates " ",

agigao12:10:14

And I want to get :content > :content > :tag RecordNR data

agigao12:10:01

(type xml-tree)
=> clojure.data.xml.node.Element

agigao12:10:37

(-> xml-tree
    (:content)
    (type))
=> clojure.lang.LazySeq

hendore12:10:36

I feel so lost. I really want to be productive with cljs but getting started has been hard. The language itself is not the problem but the tooling. What is the simplest way to take some cljs and compile it into js without lein, boot, figwheel etc? I feel I need to understand that before those tools will make any sense.

hendore13:10:48

@chokheli Ofcourse 🙂 What I ended up with is a lot of output (before doing an optimised build for production)

hendore13:10:07

Other “to javascript” languages I’ve used will output a single javascript bundle, I’m not to familiar with what’s been built here, I guess I just create an html document and add the main.js script, right?

hendore13:10:28

I think I have it now. I included main.js to my html document and it does indeed run as expected. So right now my flow (the simplest and not developer friendly but understandable) is to run clj --main cljs.main --compile hello.core then hit refresh in the browser. Now I need to understand the purpose of the --repl flag from the docs

hendore13:10:53

When compiling with advanced optimizations, the main.js output is the result, this is my application that I would add to cdn to be served, all other output are just artefacts that are not required to run my app?

XORshift14:10:13

I would like to pass all the args passed to a function to a macro within that function but have not been able to figure out how to do that. Is it possible? Assume the function arg list is [& args], I would like to pass those along to the macro which also takes the same arg list [& args].

andy.fingerhut14:10:03

macros take forms as inputs, and return forms. You can pass the form args to the macro, but the macro runs at compile time, so at that time will have no way to know how many items args contains. The macro can return a form that contains args in whatever way you write it to.

manutter5114:10:14

@samer what’s the context of your question? Maybe there’s a way to do what you want without a macro?

XORshift14:10:31

I am working with Clojurescript developing Lambda. I am trying to include the Timbre logging library which contains macros for logging by level such as info, warn, error, etc. I would also like to include context in my log statements. Timbre has a macro with-context for that purpose. I would like to write my own functions to wrap the calls to the log macros so it will include the context as well. The context is stored in an atom. My current goal to to write my own function like info that makes the call to include the boilerplate to add context to the log messages. This way my log statements are more readable and I would not need to duplicate the boilerplate.

manutter5114:10:27

It looks like timbre already has a configuration option for that (`:context` under the :fn key for an appender), is that enough to give you what you want?

XORshift14:10:44

I have written my own output-fn which accesses context when provided. Not sure if that is what you meant.

manutter5114:10:12

I’m referring to the example-config under the Configuration heading here: https://github.com/ptaoussanis/timbre

XORshift14:10:47

For example I can write a simple log statement:

(info "some log message")
and add context:
(with-context
	{:this "foo" :that "bar" :the-other "baz"}
	(info "some log message"))
The context will be set at the beginning of the Lambda request and won't change for the duration of the request. I will store that in an atom and could replace the above with:
(with-context
	@my-context
	(info "some log message"))
However I would really like to put all of that behind a function so my calls look like the first example:
(info "some log message")
I imgined it would look smething liek this
(defn info [& args]
	(with-context
		@my-context
		(info args)))
I guess in the end I can just write all my log statements like the third example. I just thought there must be some way around this duplication but I do not have enough fu to see it.

XORshift15:10:13

@manutter51 Yes I am using :context key in my custom appender to access the context when provided.

XORshift15:10:59

Well not custom appender just my own output-fn of the existing console-appender.

manutter5115:10:17

Ok, I’m bringing myself up to speed on timber and saw that, just wanted to mention it in case it was useful

manutter5115:10:37

by the way, there’s a dedicated #timbre channel, you might try asking your question there.

manutter5115:10:54

On the other hand, I actually kind of like your third example if you write it like this:

(defn info [msg & extra-info]
  (timbre/with-context
    @my-context
    (timbre/info msg {:context *context* :extra-info extra-info})))

manutter5115:10:16

Not sure if timbre will handle that map the way you like but you could always use pr-str or something.

XORshift15:10:54

Yeah, this is where things start getting complicated and I feel I may need to compromise on what features I support. I can do this:

(info "this" "that" "the-other")
which will output
"this that the-other"
Behind the scenes Timbre will str up all the things. If you use the other info macro named infof you can do this:
(infof "this %s %s" "that" "the-other")
which will output
"this that the-other"
My output-fn needs to support both of these. In addition my output-fn is writing the message when a formatter is used as a single log line and when no formatter is used writing one log line per argument provided. The purpose of my output-fn is to output JSON rather than a string. I can write this:
(info {:this "foo" :that "bar"})
and the output using my output-fn would be
{"this":"foo","that":"bar"}
However, you are giving me an idea. I could be more specific in my info function when thinking about my real uses cases rather than trying to support all the ways Timbre could be used, especially the ways I would not use it.

grierson15:10:09

I'm trying to use lein :injections [(require '[clojure.repl :refer :all])] but when I start REPL I get an error saying unable to resolve symbol.

grierson15:10:22

But if I require in repl it works.

Braden Shepherdson19:10:30

getting a baffling failure. (let [[a b] (foo)]) fails because I can't apply nth to a long. (let [x (foo)] (prn x)) shows that x is a vector.

andy.fingerhut19:10:02

Maybe try some extra debug steps like this? (let [tmp (foo), _ (println "(type foo)=" (type foo)), [a b] tmp] ...)

manutter5119:10:07

Maybe you need a lein clean or equivalent?

andy.fingerhut19:10:18

Is it possible foo sometimes returns a vector, other times a number?

manutter5119:10:24

Is this Clojure or CLJS?

Braden Shepherdson19:10:06

Clojure. foo is (defn foo [] [(bar) (baz)]), with the vector at the top. I'll try a clean.

Braden Shepherdson19:10:20

no change with a clean.

manutter5119:10:14

I’d try andy.fingerhut’s suggestion then

Braden Shepherdson19:10:22

applying debugging in that style, I get a correct printout of the whole vector. (type tmp) is clojure.lang.PersistentVector as expected, and I can even (prn (nth tmp 1)) and get the value I expected!

Braden Shepherdson19:10:39

but then after printing, trying to bind [a b] tmp fails with the same error.

andy.fingerhut19:10:22

you're messing with us, right? 🙂

andy.fingerhut19:10:31

Just kidding. I believe you, I just can't imagine yet what is happening.

Braden Shepherdson19:10:02

I think I found it, and it's a lame reason. there's another, similar destructuring farther down in the same let block, and it's the one that's wrong.

andy.fingerhut19:10:21

that makes more sense

Braden Shepherdson19:10:21

the line number pointed at the start of the let, I guess. not a satisfying answer, but an answer.

Braden Shepherdson19:10:42

in related news, I have too many let bindings in this function.

andy.fingerhut19:10:27

It would be nice if the line number were closer to the cause of the problem, but I suspect that given the macro expansion used by let loop etc. with destructuring, it isn't easy to track the original source line numbers.

asilverman23:10:11

Hi there clojurians, I am looking for some help regarding the use of clojure.spec.alpha. Basically I would like to verify that a map of key-value pairs i receive as an argument is a sub set of a well defined group. For example let the group of valid keys be :key1 :key2. I would like my spec to conform if I get a map with en empty amount of keys, or with either :key1 exclusively or :key2 exclusively or both :key1 and :key2 exclusively. I’m confused about how to specify this

seancorfield23:10:21

@ariel.silverman That sounds like you just want s/keys with all the keys being optional (`:opt-un` or :opt)?

asilverman23:10:05

@seancorfield not really, basically want my API endpoint to fail when given an unknown query parameter, so that the consumer of the API understands what happened with a descriptive error.

seancorfield23:10:22

Closed specs are discouraged.

asilverman23:10:26

The reason is that query parameters are case sensitive, lets say I want to support a query parameter called id, then my api ignores Id and ID and iD