Clojurians
#clojure
<
2016-03-08
>

This page is not created by, affiliated with, or supported by Slack Technologies, Inc.

jtackett01:03:52

Anyone know how to get the clojure webdrive to press enter?

roberto02:03:43

submit should work

cddr04:03:08

I have a macro that mostly just expands into a def. When I try to require the namespace and use the defined var, it works with lein run, but not when it is inside an uberjar. Can anyone explain this behavior?

hiredman04:03:49

are you aot compiling the uberjar?

hiredman04:03:13

(and what do you mean by works? in what way does it not work?)

cddr04:03:21

I was trying to find a way to avoid aot compilation

hiredman04:03:56

but are you aot compiling for your uberjar?

cddr04:03:36

Yes. Turns out I am

cddr04:03:40

:profiles {:uberjar {:aot :all}}

hiredman04:03:48

if I had to guess, I would say you are aot compiling for your uberjar, and your macro is def'ing directly instead of expanding in to code that defs

hiredman04:03:46

so the def happens when the macro is expanded, which happens before compilation, which, well, when running aot compiled code, compilation has already happened, so the macro is never expanded / run

cddr04:03:18

Right. That sounds like what's happening

cddr04:03:16

The code calling this tries to resolve the symbol that would be defined by the expansion

hiredman04:03:48

is the namespace loaded before you resolve?

cddr04:03:29

I was thinking about making this just a function anyway so I think I should probably just go ahead and do that

hiredman04:03:07

I don't see anything immediately wrong with that macro there

cddr04:03:58

Hm, maybe it's something else then. Thanks for the note about when the code gets expanded. I was a bit fuzzy on that

cddr04:03:41

Ah, if I try to resolve the var as opposed to just the quoted unqualified symbol, it works as expected

cddr04:03:34

Or rather, I don't need to resolve anything. I can just use the var directly

chancerussell04:03:44

So, maybe this is going to sound crazy

chancerussell04:03:25

I’m writing a clojure.test test to demonstrate that a function doesn’t throw a stack overflow when operating on a deeply nested tree

chancerussell04:03:45

The function definitely works as expected by itself

chancerussell04:03:07

But throws a stack overflow error when being evaluated in a test

chancerussell04:03:45

The logic from the function also works fine when “inlined" into the test

chancerussell04:03:24

Anyone know of any behaviors where clojure.test could cause an intermediate lazy-seq in a function to be realized when it otherwise wouldn’t be?

bijoy05:03:36

@jonahbenton: Thank you, I'll check that option

reefersleep06:03:24

When does it make sense to use comment rather than ;;? I can't see the purpose. Except perhaps for making comments a part of the AST and thus more malleable. :confused:

echristopherson06:03:19

commenting out a whole form

reefersleep06:03:47

Good point :simple_smile:

reefersleep06:03:49

I'm trying to comment inside a function - is there a best practice for this?

reefersleep06:03:57

Can you even do it?

reefersleep06:03:09

Not as the docstring, but in the function body.

seancorfield06:03:41

(comment ...) evaluates and gives you nil as I recall, whereas ;; this comment is just a "pure comment"

seancorfield06:03:26

And the convention in Clojure is ;; to comment out a whole line but ; to append a comment to the end of a line.

reefersleep06:03:38

@seancorfield: That's what I read in the docs. I'm having trouble using either within a deftest that I want to explain a bit :simple_smile:

seancorfield06:03:08

Can you http://refheap.com the code that doesn't work so we can see what's up?

reefersleep06:03:31

The comments are perhaps redundant and silly, but now that they don't work, I want to know why

reefersleep06:03:23

I get a stackoverflowerror when running the tests using lein quickie

reefersleep06:03:43

And I've run the tests, but in a different way, before

reefersleep06:03:51

let me just try this way without the comments

reefersleep06:03:37

Still get the error

seancorfield06:03:54

Yeah, if you're not getting a syntax error, then the comments are fine.

reefersleep06:03:03

I guess so :simple_smile:

seancorfield06:03:20

So I suspect your nth-generation is faulty.

reefersleep06:03:45

That is curious, because I've run the same tests using is

reefersleep06:03:54

with no error

reefersleep06:03:50

Inside of nth-generation, I use nth on a lazy seq - I wonder if that gets messed up when using are

seancorfield06:03:21

Try removing the names from those two anonymous functions at the end...

seancorfield06:03:39

Or change them to something other than a and b...

reefersleep06:03:25

Here is a paste of working isinvocations:

reefersleep06:03:45

Let me try with different anonymous functions :simple_smile:

seancorfield06:03:11

Your is version doesn't test functions, BTW.

seancorfield06:03:12

You have the function test commented out

seancorfield06:03:38

But you don't need the a and b names inside the (fn ...) forms

reefersleep06:03:59

changing the names of the anonymous functions to something else caused an error in that exact test, but other tests to g ogreen

reefersleep06:03:06

I see what you mean, doh :simple_smile:

seancorfield06:03:36

Like I say tho' I think that's the issue: the a and b in the are test are being treated as the named arguments a and b in the are substitution...

seancorfield06:03:23

Sounds like you have your solution now? :simple_smile:

reefersleep06:03:50

Well, almost I think

reefersleep06:03:04

I just tried iswith the functions, works well, no problem

reefersleep06:03:19

Let me try without function names and are

seancorfield06:03:08

(I'm out for the night so good luck!)

reefersleep06:03:48

Hah, I'm just about to get on the train to get to work (early!)

reefersleep06:03:53

Thank you for your help!

reefersleep07:03:18

Hmm, having a bit of trouble following that

reefersleep07:03:55

Ah, I think I get it. I guess each fn invocation creates a new function instance... Maybe?

reefersleep07:03:24

The conversion of functions to weird #<> names really confuses me.

seancorfield07:03:30

Functions compile to Java classes. Anonymous functions get generated names. Because are is a macro expansion, you get multiple "textual" instances of each function so your fn will become multiple (different) classes.

reefersleep07:03:36

But it seems like I end up with [(fn [] (+ 1 2)] when calling nth-generation as specified in the test.

reefersleep07:03:10

So does that mess up equality?

reefersleep07:03:14

Or are they still equal?

seancorfield07:03:41

Each macro-expanded anonymous function will compile to a different class.

seancorfield07:03:12

So your three a functions will become three different classes.

reefersleep07:03:40

Does that mean that calling = on them will return false?

seancorfield07:03:03

They're different classes so they cannot be equal.

reefersleep07:03:34

So functions are not really values? Or maybe my understanding of values is wrong.

seancorfield07:03:00

How would you expect two functions to be checked for "equality"?

trancehime07:03:09

Something's really weird...

reefersleep07:03:48

I dont' know ¯\(ツ)

trancehime07:03:47

The object receive the unicode text fine, but it's saved to the database as ??? instead of ななし ...

trancehime07:03:03

Which is weird, because I don't get this issue testing locally, only on wildfly deployment

reefersleep07:03:24

But textually, I can see with my eyes that 1 = 1 and (fn [] (+ 1 2) = (fn [] (+ 1 2).

seancorfield07:03:05

What about (fn [] (+ 2 1))?

smw07:03:51

or (fn [] ( + 1 2))

seancorfield07:03:57

Bottom line: each anonymous function is considered unique (not equal to any other).

reefersleep07:03:09

:simple_smile: I see your point.

seancorfield07:03:44

And because are is a macro and substitutes one of your functions three times, it will produce three unique values.

seancorfield07:03:05

They would all evaluate to the same result but they are not equal.

seancorfield07:03:37

Named functions defined with defn will compile to specific named classes (not generated names) so you could compare those for equality. I am on my iPhone so I don't have a REPL to verify that.

cddr07:03:09

Haha, love the cljs-lambda docs: "Afterward, the resulting ARN is written into the project file, due to accumulating doubts around your ability to perform remedial tasks."

reefersleep07:03:13

But does that mean that anonymous functions are not values in the sense that 1 or "Hello" or [1 2 3 4] are?

reefersleep07:03:39

@seancorfield: I have already repl-tested nth-generation using references to defn'ed functions, and this seemed to have the intended result. Though I didn not compare for equality. Will have to give it a go.

reefersleep07:03:56

Great success!

seancorfield07:03:43

Not all values can be compared for equality. Values of different types -- different classes -- will not compare equal (caveat: certain conversions are applied).

reefersleep07:03:58

So the tests run with areand references to defn'ed functions. Thank you for you help, @seancorfield!

reefersleep07:03:38

I guess that is where my understanding of values breaks down. (The understanding I got from "Are we there yet")

seancorfield07:03:14

But, yes, functions are values. But that doesn't mean all operators will apply.

seancorfield07:03:42

You can't order functions for example.

reefersleep07:03:55

I get what you are saying :simple_smile:

reefersleep07:03:03

And that is why we like data first, right?

reefersleep07:03:15

Because it's much more malleable.

seancorfield07:03:26

Data Good :smile_cat:

reefersleep07:03:33

So good :smile:

cddr07:03:47

Functions can be malleable too. Just in a different way

seancorfield07:03:19

Midnight here. Back in eight hours or so!

reefersleep07:03:37

But not as (depending on your qualification of malleability, I guess), right, @cddr ?

reefersleep07:03:57

9 in the morning and my Java work resumes. Thank you!

cddr08:03:26

Sure. There are more ways to combine "data" values like maps, vectors etc than there are ways to combine functions

trancehime08:03:57

oh my god this is NOT happening

trancehime08:03:19

file upload breaks in wildfly because i guess it handles uploads differently from tomcat!!!

trancehime08:03:27

Ughhh I am an IDIOT! Why didn't I check this earlier!!

trancehime09:03:22

OK... WTF? I had talked to the person who has control over the fileserver to include directories I asked for... Now file upload works on Wildfly. WTF

trancehime09:03:30

I'm not complaining, but thank god for dodging a bullet.

tomoram11:03:26

Hi, I’m having some issues with clojure.tools.namespace.repl/refresh - for some reason it’s started complaining that it can’t find my namespaces when I run (refresh). Initially in the repl everything works fine and I can run my code, but when I run (refresh) I then get errors about namespaces not found. Anyone got any ideas? Many thanks!

rauh11:03:29

@tomoram: I had this just 2 days ago. It's somewhere up there in slack's logs.

rauh11:03:29

Inspect the state in the private var refresh-tracker and see how its getting picked up

rauh11:03:01

Then remove that dir with ctnr/set-refresh-dir

rauh11:03:43

Or it may be as easy as clearing target and/or resources from old compilations stuff.

tomoram11:03:40

@rauh: Thanks for your suggestions. I’m fairly new to clojure.tools.namespace.repl so I’m not really sure what’s going on under the hood but that’s a great place to start

rauh11:03:45

@tomoram: Just do a (deref #'ctnr/refresh-tracker) and search for the offending namespace. I just pasted it into vim and did a simple search.

tomoram11:03:17

@rauh: removing target seems to have solved the namespace issue but now it’s getting upset with a speclj symbol…at least it’s progress :wink:

lmergen13:03:41

ok, so, this is an interesting challenge.. i was to convert a "nice" map into a more overhead array, i think it's kind of like an unzip or something... to illustrate, i have a map like this:

{:name "Joe Awesome"
 :email ""}
and want to convert it to an array that looks like this:
[{:key "name",
  :value "Joe Awesome"}
 {:key "email"
  :value ""}]

lmergen13:03:01

what kind of transformation function should i be using for this?

lmergen13:03:43

as in, i'm aware of all the different traversal/map/etc functions... just want to know what the idiomatic approach to this would be

lmergen13:03:50

hmmm, probably should first convert it to a sequence with seq, and then map it

cky13:03:40

(into [] (map (fn [[k v]] {:key k :value v}) {:name “Joe Awesome” :email “"}))

cky13:03:54

Can’t vouch for idiomaticness since I’m new to Clojure myself, but.

stuartsierra13:03:29

@tomoram: Most problems with tools.namespace like this are caused by either 1) stale AOT-compiled files on the class path; or 2) files whose ns declaration does not match their path/name. Do lein clean and restart the REPL will resolve (1).

stuartsierra13:03:49

Tools.namespace refresh does not work if anything in the project is AOT-compiled.

tomoram13:03:53

@stuartsierra: Great, thanks for the info. It’s working again now as expected (although a bit of an issue with speclj stubs but that’s a different issue) but it great to get a better understanding of what is going on. Thanks for your replies!

stuartsierra13:03:09

You're welcome.

roberto13:03:52

is there any place I can read about AOT? It always confuses me. Some tools don’t work well with AOT, but then when I build an uberjar (with lein) it fails to do so if AOT is disabled.

stuartsierra14:03:31

Ahead of time (AOT) compilation is only useful if you are delivering an application (not a library). It really only has two practical benefits: 1) a real main method which can be invoked from the java command line; 2) slightly faster startup time.

roberto14:03:13

cool, that explains a lot. So I only need to enable AOT for core in most cases.

roberto14:03:21

where core has a -main

stuartsierra14:03:54

Yes, and you should only enable AOT compilation for production (e.g. uberjar) builds. Never for development.

roberto14:03:49

Thank you. This is very helpful.

stuartsierra14:03:03

You're welcome.

noisesmith15:03:59

my preferred way to have aot is essentially

(ns my.shell (:gen-class))

(defn -main [& args]
   (require 'my.real.ns)
   (apply (resolve 'my.real.ns/-main) args))

noisesmith15:03:29

this way only one harmless / mostly useless namespace is compiled, jsvc knows how to launch that ns, and it pulls in the rest without them needing compilation

roberto20:03:44

anyone here familiar with hara?

donaldball21:03:50

A little bit, yeah

virmundi21:03:48

does anyone one know how to put a vector of 32 ints into an environment variable so environ can access it?

solicode21:03:53

@virmundi: Well, environment variables can only hold string values. So some form of conversion is going to be necessary. You could store it in a bunch of different ways, but I might just go with EDN

virmundi21:03:21

sounds good. I wondered if this was built in

solicode21:03:47

Ah, right. I don’t think there’s anything built in. I remember doing something similar when I used environ

shaun-mahood23:03:54

@virmundi: If you're just starting with environ, it might be worth looking at https://github.com/tolitius/cprop instead - looks like it was built for that type of use case