Fork me on GitHub
#clojure
<
2017-10-17
>
xtreak2907:10:30

Is there a way to get basic autocompletion without nrepl using just rlwrap java -cp ~/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar:src clojure.main . Any lightweight jars I can load to get the feature instead using lein repl ?

jumar07:10:14

@xtreak29 I'm afraid there's no easy way. At least no one I'm aware of. I use lein repl (mostly with Cider) most of the time and pure clojure repl only very occasionally

xtreak2908:10:00

I too use Cider and Emacs. However since I am from Python background I got used to starting and closing REPL instantly to start from a clean scratch of the state and deps. Sure I can connect to the REPL using the port but I was just curious about some other lightweight workflow.

jumar08:10:12

why is lein-repl a problem in the first place?

jumar08:10:34

If you want to get rid of dependencies from your profiles.clj, you can use lein with-profile base repl

jumar08:10:22

(sorry I thought that but that's probably not how this works - need to dig a bit deeper...)

jumar08:10:21

so yes and no: I still have a couple of dependencies defined in :repl profile in ~/.lein/profiles.clj and these are loaded. However, the :user profile should be ignored.

boldaslove15608:10:46

Is datomic.client is just an async counterpart of datomic.api ?

xtreak2909:10:03

@jumar I don't see it much of a problem except that I was thinking if I was missing some lightweight REPL. Thanks for the info about deps and profiles.

jumar11:10:17

Where is the automatic import of "java.lang." classes handled in clojure?

jumar11:10:16

I'm just wondering why StackWalker class cannot be found but java.lang.StackWalker can:

user=> (StackWalker/getInstance)
CompilerException java.lang.RuntimeException: No such namespace: StackWalker, compiling:(NO_SOURCE_PATH:1:1)
user=> (java.lang.StackWalker/getInstance)
#object[java.lang.StackWalker 0x28cb9120 "java.lang.StackWalker@28cb9120"]

jumar11:10:31

Note: StackWalker was added in Java 9

reborg11:10:48

You can still fully qualify that to work: java.lang.StackWalker

reborg11:10:47

(you saw that already)

Ertugrul Cetin12:10:44

Hey Guys, I’ve open sourced Clojurecademy 🎉🎉🎉 https://github.com/clojurecademy/clojurecademy

qqq13:10:53

is there a way to tell java "just use all the resources on the machine; it's all yours" ?

yury.solovyov13:10:10

just run java troll

qqq13:10:44

java -Xms -Xmx specifies memory usage

qqq13:10:53

it appears to take all processors by default

qqq13:10:05

boot is hanging on: Retrieving scala-xml_2.11-1.0.4.jar from https://repo1.maven.org/maven2/ (633k)

qqq13:10:13

which is weird, as I have a 24 core machine with 96 GB of RAM

qqq13:10:39

how long can processing scala-xml.jar take? [I'm calling a scala lib from clojure, so it's apparently pulling in the entire scala compiler chain]

yury.solovyov13:10:25

well, anyway getting 0.5mb file should not take long on most networks

qqq13:10:48

so I nuked ~/.m2 ; then I ran boot, and boot has spent 9 minutes pullingin all the jar dependencies so far

qqq13:10:09

it's pulled in much larger ones with no problem:

k)
Retrieving scala-library-2.11.8.jar from  (5610k)
Retrieving scala-reflect-2.11.8.jar from  (4467k)
Retrieving log4j-1.2.17.jar from  (478k)
Retrieving slf4j-api-1.7.5.jar from  (25k)
Retrieving slf4j-log4j12-1.7.7.jar from  (9k)
Retrieving args4j-2.0.29.jar from  (83k)
Retrieving scala-parser-combinators_2.11-1.0.4.jar from  (414k)
Retrieving scala-compiler-2.11.8.jar from  (15124k)
Retrieving scala-xml_2.11-1.0.4.jar from  (633k)


qqq13:10:19

so I think it has something to do with processing whatever scala-xml.jar contains ?

qqq13:10:27

[ I have no idea and am guessing ]

ghadi14:10:44

https://clojurians.slack.com/archives/C03S1KBA2/p1508226390000134 I use a bare non-lein non-boot REPL. To be honest I haven't missed autocomplete as much as I thought I would

1128614:10:42

hi, I'm trying to use clojure to create a Burp extension, basically a jar with a java class burp.BurpExtender that implements some interface

1128614:10:52

however, when it clojure calls the init method, it throws a notfound exception for clojure/core.clj

qqq14:10:59

for atom, is there a function for "set value of atom to FOO, and return old value" ?

1128614:10:02

there is also another class that defines a main function and that runs fine when called with java -jar X

1128615:10:33

the jar is an uberjar created with lein

1128615:10:40

not sure how to debug this issue

qqq15:10:37

@metametadata: awesome! I get to delete

(defn swapr! [atm f]
  (let [ans (atom nil)]
    (swap! atm
           (fn [old]
             (swap! ans (fn [_] old))
             (f old)))
    @ans))

qqq15:10:52

I don't know what swap-vals! is implemented, but I suspect it's much more elegant.

tbaldridge16:10:03

Probably a good idea, that code has a bug anyways 😛

tbaldridge16:10:20

oh wait...maybe not, I didn't notice the double swap

tbaldridge16:10:59

But yeah, read up on https://clojuredocs.org/clojure.core/compare-and-set! it'd make that function a lot cleaner.

tbaldridge16:10:45

bleh need the ! at the end of that url, just google for comapre-and-set!

qqq22:10:25

@U07TDTQNL: iirc, months ago, we had this same discussion over this same problem; I'd like to think my complaints made an epsilon push towards this being implemented 🙂

dealy15:10:04

I have a function with an overloaded parameter say (defn f1 [foo bar-dt] ...) where bar-dt can be either a clj.DateTime or a java.util.Date. So I have an if statement in the function which converts the Date to a clj.DateTime. Switching on a type like this feels wrong (oop leftovers I guess). And a multimethod is too heavyweight for this kind of thing IMHO. Is there some better way to handle this type of overloading?

jcf15:10:59

@dealy you can use a protocol. Something like:

(defprotocol ILikeDates
  (f1 [this foo]))

(extend-protocol
  clj.DateTime
  (f1 [this foo] this)
  java.util.Date
  (f1 [this foo] (.toCljDate this)))

donaldball15:10:32

You could also piggypack on the new Inst protocol

byron-woodfork16:10:28

Are there any Twitch streamers out there that broadcast them working on Clojure related things? Channel links?

madstap20:10:50

That's the idea with #mob-programming although not necessarily via twitch. It's been kinda quiet lately, but we did get a couple sessions going about two weeks back. (Using twitch and teamspeak)

ccann18:10:51

can someone tell me how to read a clojure source file without evaluating it? I just want to parse it as clojure data structures and manipulate those.

ccann18:10:43

since edn is a subset of clojure, do I have to use read? read seems to want to validate that the symbols in the file I’m reading are resolvable (which they aren’t) EDIT: read is not validating symbols, I was incorrect

ghadi18:10:29

you can also use the org.clojure/tools.reader project, which gives you a few more knobs @ccann

ccann18:10:45

you’re the best, thanks!

josh.freckleton19:10:21

I have some name spaces that I'd like to extract (along with tests and dependencies) into their own repo my env is cider and emacs are there any tools in there to make this quick'n'painless?

josh.freckleton20:10:51

checking it out now thanks

borkdude20:10:17

in clojure, when I have a function like (let [a [1 2 3]] (fn [x] (contains? (set a) x)), will the function create the set at every invocation, or is this optimized?

noisesmith20:10:12

I don’t think it can be - since clojure doesn’t exiplicitly track side effects so can’t prove set isn’t doing something useful on each run

dpsutton20:10:36

would the jvm jit do something like that after a while? my fundamental jvm knowledge is lacking

dpsutton20:10:50

i'm assuming you're talking about the clojure compiler

noisesmith20:10:06

I almost suggested changing set to println to see if it gets optimized, but I think we both know what it would do 😄

ghadi20:10:09

it's hard to say re: JVM JIT. But [1 2 3] is created only once by clojure 🙂

ghadi20:10:26

collections that only have constants are hoisted

noisesmith20:10:36

right, the easy workaround there is to move the set call into the let block (but of course real code might be trickier)

dpsutton20:10:04

so even if it was (fn [x] (let [a [1 2 3]] (contains (set a) x))? I assumed it would only be made once because of the closure

ghadi20:10:20

it being what?

noisesmith20:10:47

@dpsutton but clojure doesn’t know that set is without side effects as far as I know

noisesmith20:10:09

if it would break if that was a println call, I don’t think clojure can automatically hoist it

dpsutton20:10:22

"collections that only have constants are hoisted". his example had the collection defined outside the fn body so it was already hoisted. I was asking if it was defined inside of the function body would it still only be created once

ghadi20:10:30

constant expressions are generally hoisted and created once statically, whether the expression is scalar or a collection

ghadi20:10:42

the (set foo) is not a constant expression

ghadi20:10:57

it's an invocation, even if it's to a pure function

tanzoniteblack20:10:32

Way to prove this:

(let [a (transient [1 2 3])
      my-fn (fn [x] (contains? (set (persistent! a)) x))]
  (println (my-fn 5))
  (conj! a 5)
  (println (my-fn 5)))
The 2nd my-fn throws an error
IllegalAccessError Transient used after persistent! call  clojure.lang.PersistentVector$TransientVector.ensureEditable (PersistentVector.java:548)

tanzoniteblack20:10:06

(there's probably a better way to prove that the (set (persistent! ...)) runs, and it's not apples to apples, but it kind of proves the point)

noisesmith20:10:53

yeah, that looks like empirical proof that the optimization doesn’t happen, (though you are right @dpsutton that a clever compiler probably could do that)

tanzoniteblack20:10:18

and if it were a clever compiler, it would realize not to do it in the case there's a known side effect, like what I introduced there....

noisesmith20:10:21

then again, set is a var, so to be fully consistent we can’t make assumptions about its redefinition without opting in…

noisesmith20:10:00

it would be dumb to redefine clojure.core/set at runtime, but the language says its allowed

ghadi20:10:17

@tanzoniteblack aside: make sure you use the result of (conj!...)

tanzoniteblack20:10:38

in this case, we don't really need to. conj!, while returning the original coll, also works just as a side effect.

(let [coll (transient [])]
                      (run! #(conj! coll %) (range 5))
                      (persistent! coll))
;; [0 1 2 3 4]

tanzoniteblack20:10:12

i.e. don't use transients in your code unless you know what you're doing and really need to 🙂

ghadi20:10:58

you're missing the point

ghadi20:10:43

conj! is not valid if you call it on the same collection over and over. and your simple example will not reveal the bug I'm referring to. need to call conj! on the result of calling conj!

tanzoniteblack21:10:19

I think you might be confusing conj and conj! ? Or, if I'm wrong on that, can you please provide an example where the bug you're talking to comes into play?

ghadi21:10:58

you are wrong -- they both work the same way

ghadi21:10:17

there is an open ticket to clarify the docstring

ghadi21:10:41

it's a misconception that conj! bashes in place, sometimes it returns a new container

ghadi21:10:05

it just appears to works on small collections

tanzoniteblack21:10:58

cool, thanks. I do seem to have had that wrong

ghadi21:10:54

n.p. -- i forget where exactly the change happens, it's not at 32 elements because I just tried that

ghadi21:10:09

but you have to reduce conj! instead of run! conj!

dominicm20:10:21

Curious thought: What is a good use-case for metadata?

borkdude20:10:57

ok, so I should be conscious about defining sets outside my functions then

tbaldridge20:10:05

@borkdude the Clojure compile does very few optimizations, I see this as somewhat of a good thing. It's easier to predict performance when there's fewer optimizations, but this set example is one I've seen quite a few times.

tbaldridge20:10:38

(contains? (set a)) is going to be slow-ish depending on the size of a. But for smaller sets, it may not matter

tbaldridge20:10:04

And performance wise, there's little difference between (filter #{a b} coll) and (filter #(or (= % a) (= % b)) coll)

borkdude20:10:09

haha, I was frowned upon once when I used that idiom of set contains in Scala, because I didn’t want to type my || expressions out, was so used to doing this in Clojure

ghadi21:10:15

constant collection ~= are only filled with literals (numbers, keywords, ...)

ghadi21:10:19

clojure also lifts regex literals -- only compiles them once

qqq23:10:04

clojure has double? why is there no long? how do I test if a number is a long ?

qqq23:10:34

how do I test is a number is a java long ? (some java functions want java ints, and I need to coerce longs to ints)

tbaldridge23:10:43

@qqq can always check the class: (instance? Long x)

noisesmith23:10:08

@qqq I was under the impression that when clojure sees that a method takes int, it accepts a long and implicitly converts - is that not working?

bronsa23:10:52

that is correct @noisesmith, unless the method also has a long overload and he explicitely wants the int one

noisesmith23:10:11

ahh, that would be a gotcha

noisesmith23:10:15

but also a rare case

noisesmith23:10:31

but even then you wouldn’t need to check for longs, you can explicitly call int