#clojure log - Mar 13 2016

The Joy of Clojure
Main Clojure site
Google Group
IRC
List of all logged dates

1:43 ilevd: Hi, I can't live without Clojure, what can you recommend me?

1:52 burhanloey: Other Lisp?

1:54 Hylang is a lisp too on top of Python, but I haven't try it yet.

1:55 ilevd: Other Lisp?

1:56 Try Pixie https://github.com/pixie-lang/pixie

1:56 burhanloey: Other lisp = Common Lisp, Scheme, Racket etc

1:57 ilevd: Racket looks good, but perfomance...

1:57 burhanloey: Yup, I'm aware of Pixie

3:02 ilevd: It's interesting if anybody uses Hylang in production

3:05 TEttinger: ilevd: what are you asking for recommendations on again?

3:05 like library choices?

3:05 or other clojure-like lisp dialects?

3:06 ilevd: I don't know, I like Clojure but there isn't job on it and I don't know what to programm )

3:17 dysfun: ilevd: quite a few of us here have clojure jobs

3:17 many of us work for ourselves, of course

3:21 ilevd: Cool!

4:40 henke: im currently using this to server index.html (GET "/" {c :context}

4:40 (redirect (str c "/index.html"))) however this puts /index.html on the

4:40 path and i want a path that is only / when serving the index page?

5:48 Empperi: cfleming: any way to tell Cursive to recheck dependencies from project.clj when it's been modified outside of cursive?

5:48 I've been trying out boot as my build tool and have boot auto generate proejct.clj with dependencies for Cursive

5:48 this works fine as long as I've generated the project.clj updates before I launch Idea

5:49 if I do it afterwards I cannot get Cursive to understand the new dependencies

5:49 obviously drives me nuts

5:51 if I quit Idea and reopen it then Cursive understands the new dependencies

5:51 TEttinger: Empperi: ooh ooh ooh!

5:52 I got this fixed yesterday, from cfleming

5:52 view -> tool windows -> Leiningen, there's a refresh button in a blue arrow circle icon

5:52 upper left of the tool window

5:53 Empperi: awesome, thanks!

5:54 TEttinger: someone earlier mentioned boot not working as well as could be, but his workaround was the same as what you're doing with the export to lein

5:54 I think the only problem was .boot files not supported

5:58 Empperi: yeah nothing is understood in those files

5:58 but I can live with that

5:58 as long as my actual code works as expected

5:59 supporting boot as a first class citizen in Cursive is going to be really difficult since the power and flexibility of boot makes it really hard to evaluate for Cursive

6:01 dysfun: but what does it really need to integrate?

6:01 'boot repl' is a default, for example

6:02 cider under the hood just changes which command it runs in a subprocess

6:02 TEttinger: cursive uses cider under the hood? isn't cider an emacs thing?

6:03 dysfun: yes, i'm noting that it was simple for the competition

6:03 TEttinger: ohhhh, I misread

6:03 cfleming: dysfun: Cursive is more complicated than CIDER in this respect.

6:04 It needs to know which dependencies to sync, so they can be attached to the project and indexed.

6:04 That is very difficult in boot.

6:04 Empperi: yeah

6:04 dysfun: is it? (get-env :dependencies) doesn't work in nrepl?

6:05 Empperi: Cursive does not use REPL for code syntax evaluation

6:05 it uses static analysis

6:05 cfleming: That only works if a) you execute your build, and who knows what that will do, and b) you're sure you've executed all code paths in your build.

6:05 I have plans for a much better integration, but it will never be perfect.

6:05 Empperi: part a) is especially true with boot :)

6:06 dysfun: yes, but i tend to agree that a build is a useful place to write code

6:06 cfleming: I'm actually becoming a huge Gradle fan.

6:06 dysfun: i think boot is great for the power it gives you, but i think the api is awful

6:06 cfleming: You can write code, but the important bits are still declarative enough that tooling has a chance to work.

6:06 Empperi: gradle has it's own problems too

6:07 cfleming: Sure, it's a build tool - it's a matter of choosing the one you hate the least

6:07 dysfun: i would expect that it's going to work fine 90% of the time+

6:07 all of my build.boot start off with (set-env! :dependencies ...)

6:07 and i think most other people are the same

6:07 no reason static analysis can't pick that sort of thing up

6:07 Empperi: yeah but nothing forces you to do it like that

6:07 cfleming: dysfun: Sure, and that case is relatively easy to solve statically.

6:07 Empperi: those scenarios are easy to support

6:08 cfleming: But I've heard of people keeping their deps in maps and dynamically loading those maps etc

6:08 But I'm ok with telling those people that they're off the Cursive beaten path and that bets are off.

6:08 dysfun: yeah, i'd do exactly that in your position :)

6:09 Empperi: I'd be happy if Cursive would support a) set-env! based dependencies b) would recognize defined tasks

6:09 plus would understand the code itself meaning it wouldn't try to tell me there is no such thing as set-env! or deftask and so forth

6:09 cfleming: Empperi: Yes, all that is possible and planned.

6:09 Empperi: don't need REPL integration or anything it doesn't already have

6:10 since with boot you pretty much want to start nrepl and connect to that

6:10 you'll lose debugging which sucks but so does life sometimes

6:10 cfleming: Yeah, debugging might be tricky but remote debugging is always an option.

6:10 Empperi: yeah

6:11 dysfun: i'm facing this dilemma at the minute actually for a documentation tool

6:11 a certain amount of static analysis topped up with a certain amount of executing code i think

6:11 (i want to produce clojure and clojurescript docs in one document)

6:11 Empperi: but if I need to make a choice between boot support and macro improvements I'll choose the latter :)

6:11 cfleming: Empperi: BTW better macro solutions are coming down the pipe soon too, I know that's been hurting you.

6:12 Haha snap

6:12 Empperi: you read my mind lol

6:12 ikitommi_ will be happy to hear that too

6:14 cfleming: Yes, no doubt

6:24 dysfun: how have you found building on top of eclipse in practice, then?

6:24 cfleming: dysfun: Me? Cursive is built on top of IntelliJ

6:24 dysfun: oh

6:25 cfleming: CounterClockwise is the Eclipse one.

6:25 dysfun: ah that's right

6:27 cfleming: IntelliJ is actually really nice to build on, but it's enormous and almost totally undocumented.

6:28 I ran cloc over it the other day actually, the community edition is 3.9 million LoC

6:28 dysfun: wow

6:28 cfleming: It takes a while to check out.

6:29 dysfun: haha, longer than webkit?

6:29 cfleming: I've never tried, but I'd bet a beer that it does.

6:29 dysfun: webkit is 5gb

6:29 (the git repo)

6:29 cfleming: That's quite a lot.

6:30 dysfun: yeah. it's the sort of thing where you start to notice git doesn't tell you how much it intends to download

6:30 cfleming: Not sure how to check that size on the community edition, I can't find a simple way to clean the build artifacts.

6:31 dysfun: hah

6:32 cfleming: (there probably is one, but I only have the code for reference, I don't actually build + run it)

6:32 dysfun: oh, git clean -df then

6:32 cfleming: Of course

6:33 du -sh show 4.9 GB

6:33 dysfun: wow, so totally comparable to webkit

6:33 cfleming: Looks like it, yeah.

6:35 https://github.com/JetBrains/intellij-community/graphs/contributors

6:37 Empperi: 168 678 commits :)

6:37 and 32 925 releases

6:37 lol

6:38 cfleming: yole tops out at like 100 commits/week

6:38 Empperi: Jetbrains employee?

6:41 cfleming: Yeah, he was their senior engineer and CTO for a while.

6:41 All those people are JetBrains employees I think.

6:42 Ok, bedtime for me

6:43 Empperi: night

9:50 kwladyka: justin_smith is it possible to use Clojure libraries in Clojure .NET? I guess not. Clojure .NET has additional modules?

9:54 dysfun: kwladyka: anything that taps into underlying java will not be usable on .NET. you will need to find clj/clr code or write your own (or just use the .net objects directly)

9:55 clj/clr is not commonly enough used that people really bother testing against it

9:55 kwladyka: dysfun do you have some experience with Clojure .NET?

9:55 dysfun: about five minutes before it made me want to throw my keyboard at the wall

9:55 but that was some while ago and it may be better now

9:56 kwladyka: what was the problem?

9:56 dysfun: i may have been jesting slightly. i spent a few hours trying to get a game going on it. first with arcadia and then with unity

9:57 i found it all a bit frustrating. the tools just aren't there yet

9:57 clojure + emacs is an extraordinarily rich and powerful tool when configured correctly. clj/clr i don't know if cider even handles it

9:58 and the less said about trying to hack clojure in monodevelop, the better

10:00 the truth is that a heck of a lot of what i love about clojure comes from binding to libraries written in java

10:00 e.g. i use aleph for a webserver. under the hood that's netty. i don't know if there even is an already wrapped webserver in clj/clr

10:03 justin_smith: dysfun: hell, I don't even know if ring works on clj/clr

10:03 dysfun: right, because nobody bothers testing it

10:04 justin_smith: dysfun: and more importantly, it uses java classes

10:04 dysfun: oh, i didn't know that

10:04 i suppose it makes sense

10:04 justin_smith: it implements protocols over OutputStream etc.

10:05 I mean I bet it would be easy to port, but it hasn't been done that I know of

10:05 dysfun: "Updated on 24 Jan"

10:06 (clojure-clr)

10:07 https://github.com/clojure/clojure-clr/pull/8

10:07 if it doesn't even build except on windows, it's not fit for deploying to production

10:08 i can't help but think if that effort had gone into an llvm backend, it might have been worth it

10:10 xnapeak: Hi - I'm calling a constructor inside a Java lib, and the constructor requires casting the value nil to java.util.List<String>. Is there a way to call cast or do type-hinting with generics?

10:10 justin_smith: xnapeak: generics are fictional, but you can definitely pass a java.util.List that is empty

10:10 dysfun: there's no such thing as a generic at runtime. that is java.util.List, not java.util.List<String>

10:11 of course if you put things other than strings in there, you get to keep the pieces

10:12 xnapeak: justin_smith It has to be nil, not empty

10:12 Eg. (nil? (java.util.Vector. [])) returns false

10:12 and just putting in nil without casting returns an IllegalArgumentException

10:12 dysfun: please show a correct java incantation for it

10:14 xnapeak: dysfun I can't find one, but here's the original source code: http://pastebin.com/FY8gYBKt

10:14 I'm trying to set m_Type to STRING

10:14 justin_smith: xnapeak: for that matter, clojure vectors and lists are instances of java.util.List

10:14 xnapeak: dysfun Here's an incantation in Scala: val att3 = new Attribute("att3", null.asInstanceOf[util.ArrayList[String]])

10:14 justin_smith: ,(instance? java.util.List [])

10:14 clojurebot: true

10:16 dysfun: right, i see, you want null

10:16 justin_smith: nil is null though... the trick is the asInstanceOf

10:16 dysfun: yes, i see the problem

10:17 i don't have a good answer though

10:17 justin_smith: xnapeak: scala is weird and you can't even use it from java, do you have working java?

10:17 dysfun: justin_smith: sure you can. some of it.

10:17 justin_smith: xnapeak: if you are trying to call scala from clojure, give up now, not even worth trying

10:18 dysfun: can you imagine if people started using clojure on top of the typesafe platform? hahaha

10:19 xnapeak: justin_smith Oh, I'm not using Scala at all, that was just an example of a call to that constructor I found on GitHub

10:19 dysfun: sorry, i mean "lightbend reactive platform"

10:19 xnapeak: justin_smith I don't have a Java environment set up, I could but that might take a while

10:19 justin_smith: OK - a java example would be much better

10:19 dysfun: xnapeak: lein can compile java

10:19 justin_smith: xnapeak: clojure is a great platform for using java :)

10:19 xnapeak: OK, will try to find one

10:20 dysfun: in fact lein and boot make it super easy to switch your slowest/most hit code to java

10:21 (jmonkeyengine requires you to subclass an abstract class, for example, so you have to write a tiny bit of java if you want to use it)

10:21 xnapeak: justin_smith Okay, here's a Java call: new Attribute("content",(ArrayList<String>)null)

10:22 (That's is not my code, just another example I found on GitHub)

10:25 dysfun: unless justin_smith has an idea, i'm going to suggest you write that bit in java

10:25 (using your clojure build tool to build it for you)

10:27 amalloy: (let [^List foo nil] (Whatever. foo))

10:28 xnapeak: amalloy That works. Thanks!

10:29 (Well, (let [^java.util.ArrayList foo nil] works, but close enough)

10:29 dysfun: amalloy: hrm, i didn't realise type hints could be used to guide method selection

10:29 how does that work?

10:29 amalloy: that is kinda the only thing you can use them for

10:30 select a method at compile time instead of at runtime with reflection

10:30 dysfun: oh yes, of course

10:30 suddenly that makes sense now

10:34 Malnormalulo: Does anyone know of any good implementations of a data structure which is unordered under equality-checks (like a set), but allows duplicate members (like a list)?

10:35 (Also, does anyone know if a structure like that has a common name?)

10:35 dysfun: is it safe to assume that the namespace declaration is the first form in a clojure file if it is not missing?

10:35 Malnormalulo: a 'bag' fits that bill

10:36 Malnormalulo: Aha, bag. Thanks, I'll look for one of those

10:36 dysfun: also known as a multiset

10:36 essentially you can think of it as a map where the key is the item an the value is how many times it occurred

10:36 (and that's not an unreasonable representation)

10:36 Malnormalulo: Yeah and I was thinking of just using a structure like that, but a more direct representation would be convenient

10:37 dysfun: but then you'd want a persistent one and that might take finding

10:37 and also it wouldn't interop nicely with clojure code

10:37 amalloy: dysfun: ns should be first in a well-written program, but i don't think you should assume it actually is

10:38 Malnormalulo: also, I agree with amalloy

10:38 dysfun: the plan was to check the first sexp in the file with tools.namespace

10:39 what would you recommend i do instead?

10:40 amalloy: why?

10:40 clojurebot: why is the ram gone

10:40 dysfun: clojurebot++

10:41 because i'm writing a compiler that uses tools.reader to get clojure syntax for free and i need to know what namespace to read it in so syntax quote works

10:42 amalloy: so what you're reading isn't clojure source files at all, but source files for some other language that happens to use clojure lists/symbols/etc?

10:42 dysfun: yes for this one, no for my back burner clojure-to-machine-code project

10:44 the ideal for that one is to be able to share with clojure and clojurescript in cljc files

10:46 well formedness would be a requirement on that though, so i'm okay with bailing out if the first expression isn't an ns decl

10:55 it also occurs to me that build.boot is not well formed by that rule

11:04 csd_: any suggestions for managing environment vars on heroku? i want to set a secret key but my .lein file doesn't get uploaded when i push to heroku as that would require putting it in my git repo

11:05 i know i can do it using the CLI tool but i'm wondering whether a better solution exists

11:05 justin_smith: csd_: I thought heroku had a command for setting environment vars directly

11:05 csd_: yeah it does through the CLI

11:05 justin_smith: csd_: ideally you would do that, then pick the value up using environ

11:06 csd_: i dont love that because i feel like it hides the var from you

11:06 justin_smith: csd_: it's hiding the var from more than just you, and that's the point

11:06 csd_: fair point

11:16 Empperi: hmm, can't get boot to read project boot.properties

11:16 any hints?

11:16 got the boot.properties in the same directory as my build.boot

11:16 created the base with boot -V > boot.properties

11:16 then edited Clojure 1.8.0 in

11:17 but boot isn't using it

11:19 dysfun: specifically, what line did you change?

11:19 Empperi: BOOT_CLOJURE_VERSION=1.8.0

11:19 and yes, I do know one has to define Clojure dependency to build.boot too

11:20 dysfun: hrm, what's your BOOT_VERSION ?

11:20 Empperi: BOOT_VERSION=2.5.5

11:20 dysfun: can you pastebin the output of boot -V with that properties file in place?

11:21 Empperi: no prob, altough there's nothing special except it says 1.7.0

11:21 https://www.refheap.com/115902

11:22 so it doesn't read the properties file

11:22 dysfun: hrm, are the permissions funny or anything?

11:22 Empperi: nope

11:22 windows however

11:22 dysfun: ohhh

11:23 no clue about boot on windows

11:23 Empperi: there shouldn't be anthing special

11:24 fucking up as simple thing as reading a file from working directory cannot be something they'd do

11:24 dysfun: that's true

11:24 and you're definitely sat in the right directory? :)

11:24 Empperi: yes

11:24 very much so

11:25 dysfun: i'm out of ideas then. You can try #hoplon, that's where the boot guys hang out

11:25 Empperi: hmph

11:25 yeah, guessed so

11:25 :/

11:52 dysfun: found out why it happened

11:52 https://github.com/boot-clj/boot/blob/master/boot/base/src/main/java/boot/App.java#L153

11:53 boot prefers boot.properties first from bootdir() then from projectDir() and then from workdir

11:53 which is imho totally wierd, it should be the other way around

11:53 weird even

11:53 if I went to ~/.boot/ I found boot.properties from there and I modified it and now boot runs with Clojure 1.8.0

11:55 oh right, forget about the prefer part from that. It uses HashMap... *blush*

11:58 dysfun: Empperi: hrm, i agree it seems like the wrong logic

11:58 Empperi: it isn't like that

11:58 check mergeProperties at line 159

11:59 there it iterates the properties files in order boot dir -> project dir -> cwd

11:59 and merges the values together so that last directory should override earlier

11:59 dysfun: ohh

11:59 Empperi: but it also swallows FileNotFoundExceptions

11:59 dysfun: i see

12:00 Empperi: they should add those exceptions into debug logging or something

12:00 now it's super hard to know wtf is going on

12:00 dysfun: er, no, because typically cwd isn't going to return one

12:00 but it's lazy coding

12:00 Empperi: yeah

12:01 I agree

12:01 and to me that Java looks horrid :)

12:01 the style it is written

12:01 not necessarily the quality

12:01 but that's just me

12:03 oh well, I can go forward now since I got it running with Clojure 1.8.0

12:03 dysfun: yes, it's particularly offensive on the eyes

12:03 Empperi: I was considering to clone boot and try to find out what is happening and make a pull request but I really don't want to edit Java code which looks like that

12:03 :)

12:03 dysfun: but i think the boot source code is a good example of why you should use clojure - to not have code that looks like that

12:04 Empperi: well, truth to be told, that is just ugly java

12:04 good thing is that those methods are relatively small and they do only one thing

12:04 but one could do those things much more elegantly

12:04 in java

12:04 dysfun: yes, but one has deadlines :)

12:04 Empperi: :)

12:06 oh well, Now I got cljs-repl to run

12:06 couldn't get it to run with clojure 1.7.0

12:08 any ideas on compound nrepl instances?

12:08 I mean, now I got two nrepls running, one for clojure and one for clojurescript

12:08 both write .nrepl-port which will cause the latter to be there only

12:09 and besides, I don't want to connect to that repl twice unless I really want to do so

12:09 so, it would be great if I could connect to nrepl, it would greet me with prompt like "To access clojure REPL type (clj-repl), to access ClojureScript REPL type (cljs-repl)"

12:09 and I could jump between those two repls as I see fit

12:10 justin_smith: Empperi: you can always ignore the .nrepl-port file and just supply the port explicitly when connecting

12:10 Empperi: justin_smith: yeah, but .nrepl-port is very convenient

12:10 one doesn't have to know what port it is running

12:11 justin_smith: I've found having two repls in emacs nothing but inconvenient

12:11 maybe it's improved since I gave up on repls inside emacs though

12:11 Empperi: well, one needs two with clj+cljs

12:11 one for both

12:11 and I use Cursive

12:11 justin_smith: oh, OK

12:12 Empperi: or well, one doesn't HAVE TO use REPL for either one but... :)

12:13 hmm, it makes me feel like I might have a good candidate for custom boot task with that compound repl thingy

12:16 kwladyka: dysfun from what you saying i can get a conclusion maybe Clojure .NET it is bad idea and should exist?

12:24 *shouldnt

12:24 from other hand maybe it is not ready or .NET has bad community or i don't know :)

12:29 TEttinger: the CoreCLR community has been hyper-responsive in my limited bug reporting

12:29 really good show on some stuff that they fixed (took a while because apparently they don't use windows 7 much)

12:31 I do think that F# being MS-backed and IDE-supported (rather well, too) takes the motivation for using any other multicore/immutable/functional language down

12:31 on the CLR I mean

12:46 kwladyka: TEttinger Did you do something for production in Clojure .NET?

12:48 TEttinger: no, I did look at it enough to see it didn't have a reasonable way to work with multi-dimensional arrays though, which my existing code in C# used heavily

12:48 you can use jagged ones fine, but not rectangular it seems

12:52 * dysfun wonders what a jagged array is

13:00 hyPiRion: dysfun: https://en.wikipedia.org/wiki/Jagged_array

13:00 In short, arrays of arrays, where the inner arrays may be of different lengths

13:00 dysfun: then how on earth if it can handle those can it not handle rectangular ones?

13:03 hyPiRion: damnit i've fallen down a wikipedia hole because of you

13:09 hyPiRion: I guess it depends on how the rectangular arrays are implemented.

13:10 Usually they are just a single block of memory for performance reasons, whereas a jagged one is an array of array pointers

13:14 csd_: any suggestions how you would remove the conditional nesting in this snippet http://pastebin.com/546s0ZQt ? i'm interested in checking out the cats category theory library and using `maybe`. not sure how well that would work because of the db calls though

13:25 TEttinger: hyPiRion: dysfun: they're different types on the CLR.

13:26 .NET and Mono allow you to do "new int[40,20,10];", which helps since they don't have the all-at-once jagged array initializer in Java like "new int[40][20][10];"

13:27 you can still do "new int[40][][];"

13:27 and then assign different or the same lengths to members

13:34 gilch: dysfun: I've been using jMonkey Engine without writing Java so far. What would you need it for?

13:35 dysfun: i don't remember any more. i think it was to do with certain features only being available if you used this abstract class interface

13:38 gilch: clojure can use proxy to make an anonymous subclass of a java class

13:39 It can't access protected members, but you can use reflection for that, or even gen-class if you compile ahead of time

13:39 dysfun: ah yes

13:42 gilch: I think most protected fields in jME that you would care about have public accessor methods anyway.

13:43 dysfun: i didn't play with it much, it was just something i remembered about it from a while ago

14:18 WickedShell: This has to be a stupid question but whats the standard protocol that I need to implement on my records to get meaningful results for when toString or (str ) is called on a record?

14:19 justin_smith: WickedShell: toString method on Object, but really records usually print nicely, deftype on the other hand will need help

14:20 WickedShell: they just keep printing their name and a pointer IE "swiftgcs.utilities.Waypoint@c050c63c"

14:20 justin_smith: then toString is not what is being called, or it isn't created with defrecord

14:21 WickedShell: it's being created with a (str "desc " record-here)

14:22 justin_smith: hmm - maybe I'm wrong about toString - try implementing it eg. (defrecord Foo [] Object (toString [this] ...))

14:22 WickedShell: and its a defrecord, with the actual instance made with (new RecordName field1 field2 etc)

14:22 justin_smith: (defrecord Foo [] Object (toString [this] "this is a foo"))

14:22 ,(defrecord Foo [] Object (toString [this] "this is a foo"))

14:23 clojurebot: sandbox.Foo

14:23 justin_smith: ,(str (new Foo))

14:23 clojurebot: "this is a foo"

14:23 justin_smith: ,(defrecord Foo [] Object (toString [this] (pr-str this)))

14:23 clojurebot: sandbox.Foo

14:23 justin_smith: ,(str (new Foo))

14:23 clojurebot: "#sandbox.Foo{}"

14:24 irctc: hi guys. anybody here?

14:24 justin_smith: always

14:24 irctc: cool

14:25 WickedShell: justin_smith, thanks that looks like exactly the behavior I'm looking for

14:26 justin_smith: awesome

14:26 irctc: I've been looking at clojure on and off over the last couple of months but I've not clue what this does: (def ^:dynamic *re-password* #"^(?=.*\d).{4,8}$")

14:26 actually it's just the ^:dynamic bit that's not clear to me

14:26 justin_smith: it defines a thread-bound var, and the root binding is a regex

14:27 irctc: dynamic vars can carry a different value in each thread

14:27 use them with binding

14:27 ,(doc binding)

14:27 clojurebot: "([bindings & body]); binding => var-symbol init-expr Creates new bindings for the (already-existing) vars, with the supplied initial values, executes the exprs in an implicit do, then re-establishes the bindings that existed before. The new bindings are made in parallel (unlike let); all init-exprs are evaluated before the vars are bound to their new values."

14:28 justin_smith: also, futures inherit dynamic vars from their calling thread

14:28 irctc: @justin_smith. thanks. I think I get it. Not sure why it would be needed in this specific case...

16:24 CaptainLex: So, if I have a function foo

16:24 and a function bar that calls foo

16:24 and I re defn foo in a repl session

16:25 Does bar call the old or the new version of foo?

16:25 justin_smith: CaptainLex: depends how bar was defined - if bar was a defn yes, if defined using eg. comp, perhaps not

16:27 CaptainLex: justin_smith: Yes, I see. I wonder what else is going on here...

16:27 justin_smith: the difference is whether a first class function was used.

16:27 the most common cause of this is that someone runs something like (start-server foo) - where foo is a first class function argument

16:28 that won't see any change in the var #'foo

16:29 CaptainLex: Interesting. That's because when it gets passed, it doesn't care about the identifier anymore? And is there any alternative way to cause this kind of behavior?

16:30 I suppose it would to only /pass/ thin wrapper functions that call the functions you want re-eval?

16:30 justin_smith: CaptainLex: simpler is to pass the var

16:30 if you run (start-server #'foo) it will deref the var each time it uses it, instead of caching the value

16:31 this is because when you call a var, the var looks up its own contents and calls that with the same args

16:31 ,(#'+ 1 2 3)

16:31 clojurebot: 6

16:31 CaptainLex: justin_smith: Whoa, yeah

16:31 That's awesome

16:31 Thanks!

16:32 Also that explains things I've seen in other projects I've worked on

16:32 justin_smith: definitely a cantidate for a faq entry

17:34 duck1123: Does anyone know why I would be getting a Invalid :refer error when compiling cljs in a docker container, but not outside?

18:39 rhg135: I tried to write a blog post about it, justin_smith, but it might not help

18:40 http://www.rhg135.com/posts/2015-08-23-var-or-fn.html

18:44 It seems a very frequent question

18:49 Compiler version perhaps, duck1123

18:50 justin_smith: also I'd compare dependency versions in general, and also make sure build targets have been cleaned since the last change - cljs has bad caching logic sometimes when it tries to incrementally build

19:47 michaelrose: ok dumb question I thought you needed to install templates somehow so figured you had to clone the repo for the template in question and do lein install in that dir which appears to have been utterly uneccesary

19:48 if I understand properly all the lein install actually did was download the proper files to ~/.m2/dir

19:49 justin_smith: michaelrose: right, and it would do that anyway if you just used lein new with the template

19:49 michaelrose: but! that does avoid the problem I have with templates, which is that they are unversioned (and this tends to break internet tutorials, which is a problem)

19:49 michaelrose: so I didn't mess up anything which is good

19:50 justin_smith: heh, sure

19:50 michaelrose: oh so basically manually installing it would ensure I could grab it at a known point

19:50 justin_smith: now that I say that, I wonder if lein wouldn't look for the latest anyway regardless...

19:50 michaelrose: whereas if I had just done lein new name it would grab the latest available

19:51 that should be easy to test

19:55 justin_smith, it does not

19:58 rhg135: that is awesome-ish

Logging service provided by n01se.net