Fork me on GitHub
#clojure
<
2017-02-24
>
Drew Verlee00:02:43

Anyone want to recommend a CS related book or blog post i read on the plane tomorrow?

curlyfry06:02:18

Any subjects in particular that you're looking for? If you want Clojure-related Clojure Applied and The Joy of Clojure are great. The Pragmatic Programmer and The Effective Engineer are cool if you want something more general (perhaps more related to working in the software industry than pure CS).

josh_tackett02:02:12

Getting this error: java.lang.IllegalArgumentException: Body may not be null with this request:

(client/post <url>
             {:body "test"
              :multipart [{:name "distributor_id" :content 1419}
                          {:name "scenario" :content "fair_pricing"}
                          {:name "file" :content ( "/Users/josh/Desktop/rd/bronx-download2017-02-24T01-59-25-321Z.csv")}]}
             )
with this lib: https://github.com/dakrone/clj-http

hiredman04:02:11

what version? that looks very similar to this issue https://github.com/dakrone/clj-http/issues/287, which my read is it was the result of having :content be something that it doesn't know how to handle, in this case a number instead of a string

bradford05:02:51

btw Enlive is super awesome and is making my life better

xsyn06:02:31

@bozhidar I finally started using the cider-debugger, and now I can’t think about not using it. Thank you

placeboza08:02:27

Still can't get ntlmauth to work with JTDS for MS SQL 😞 ... "SSO Failed: Native SSPI library not loaded". Tried every possible solution on the net.

tjtolton08:02:53

Can anyone tell me how to get the pid of the job lein run spawns?

tjtolton08:02:15

I'm trying to use lein to spin up a server, then run some postman tests against it, then spin it down.

istvan08:02:59

tjtolton somthing like -> (-> (java.lang.management.ManagementFactory/getRuntimeMXBean) (.getName))

tjtolton08:02:27

ah, sorry, should have mentioned. I meant I wanted to get the pid in a bash script

istvan08:02:47

that is even easier

istvan08:02:48

i think $! is the pid of the previously spawned process

tjtolton08:02:08

It is, however, that's the pid of the lein process

tjtolton08:02:28

lein has a process, and then it spawns your actual java process separately

istvan08:02:35

so you need to combine the code than

istvan08:02:42

write the pid to a pid file

istvan08:02:49

from within clojure

istvan08:02:55

and use it in the shell script

tjtolton08:02:18

hmm Wanted to be able to do it without modifying the clojure source code

pesterhazy08:02:57

Lein trampoline

tjtolton08:02:23

ahh interesting

tjtolton08:02:29

niiiiiice, thanks @pesterhazy

placeboza08:02:31

ja, pretty interesting

tomaas09:02:19

why cant i read json in server side from :body? getting object instead

pesterhazy09:02:16

you need to (slurp body)

placeboza11:02:45

Anybody here today that's familiar with using windows ntlm auth for sql server with jTDS?

placeboza11:02:34

nvm. after huge amounts of wasted time, finally got it right. Need to be very careful of x86 vs x64 of your java version (NOT your machine), and ensure ntlmauth.dll goes into all your jre and jdk "bin" and "jre/bin" folders

placeboza11:02:30

Now it's a new error 😞

tianshu12:02:27

Is there a good library for simple web crawler?

tianshu12:02:57

something like enlive but with more selectors support, e.g. xpath.

baptiste-from-paris12:02:09

hello guys, core.async issue here ^^ Does anyone ever seen this =>

(when-let [[v c] (a/alts!! [input-channel timeout])]
     ...))
I got this error =>
No implementation of method: :take! of protocol: #'clojure.core.async.impl.protocols/ReadPort found for class: clojure.core.async$timeout

baptiste-from-paris12:02:52

everything is not in a go block but when I put it in a go block it’s working..

manutter5112:02:02

@doglooksgood If I were going to build a web crawler I’d do a search for “clojure selenium” and use some of the webdriver stuff.

manutter5112:02:48

I used clj-webdriver back in the day, but it looks like that is no longer maintained.

tianshu12:02:24

my demand is pretty simple, I don't need to handle AJAX request. just need a parser to parse html string to struct(maybe hiccup), and a selector to extract the content that I want.

tianshu12:02:03

I'll take a look

tianshu13:02:30

This is what I want! thanks! @manutter51

manutter5113:02:52

Awesome :thumbsup:

placeboza13:02:24

OMG. I'm cursed with jTDS and SQL Server. I believe I found my problem ... a known bug in jTDS for SQL Server and SSL connections 😞 : https://sourceforge.net/p/jtds/patches/129/

placeboza13:02:40

why is this so hard

placeboza13:02:57

Im new to JVM, and I'm beginning to dislike using it

placeboza13:02:37

Switched to MS SQL JDBC ... worked first time :S . FYI, followed these instructions: https://micahasmith.github.io/2014/11/18/clojure-mssql-sql-azure/

placeboza13:02:19

only difference is the version and jar name

placeboza13:02:47

and putting the sqlauth dll into my java app path

placeboza13:02:02

but the error made that clear

pesterhazy13:02:55

Usually JDBC is rock solid

placeboza13:02:27

it's the windows auth with jTDS that let me down

placeboza13:02:39

the rest seemed good

pesterhazy13:02:06

Can anyone recommend a simple project template for a server app? It should tick the following boxes - HTTP server - some sort of routing - easy reloading/restarting of the system, either manually through the REPL or automatically, when files change

pesterhazy16:02:53

ah yes! 🙂

pesterhazy13:02:28

it could use component or mount but I'm not tied to either

danielgrosse13:02:02

How can I flatten the list in this vector? [[:a {}] '([:a {}] [:b {}]) [:c {}]]

pesterhazy13:02:42

@danielgrosse what should be the output?

mccraigmccraig13:02:47

i've used yada & bidi and been very happy with them @pesterhazy - they are all wrapped up in https://github.com/juxt/edge

pesterhazy14:02:16

I'm a fan of bidi so I should check out those other 4-letter words

danielgrosse14:02:50

@pesterhazy I now used (vec (apply concat [[:a {}] '([:a {}] [:b {}]) [:c {}]]))

danielgrosse14:02:38

Oh. not the right output

danielgrosse14:02:05

It should be [[:a {}] [:a {}] [:b {}] [:c {}]]

pesterhazy14:02:29

@ddeaguiar good point on pedestal, I always forget that one

pesterhazy14:02:23

@danielgrosse you'll probably have to write your own selective flatten fn

mpenet14:02:04

@danielglauser if you need speed and don't care about laziness (I guess you don't, hence the vec) you can use this:

mpenet14:02:20

it's at least 3x faster on a stupid repl based bench

nathanmarz14:02:56

@danielgrosse with specter it's just (transform (srange 1 2) first [[:a {}] '([:a {}] [:b {}]) [:c {}]])

placeboza14:02:27

edge looks pretty awesome

joshjones15:02:55

@baptiste-from-paris your issue is that you did not actually create a timeout channel. you are trying to take from the timeout function. so, you need to say:

(when-let [[v c] (a/alts!! [input-channel (timeout 1000)])] ....

placeboza15:02:10

Don't understand why korma's defentity macro doesn't accept e.g. (defentity (symbol "mytable") (table "mytable"))

placeboza15:02:27

I get PersistentList cannot be cast to clojure.lang.Named

placeboza15:02:08

defentity uses ~ on that first arg

placeboza15:02:15

I'd think that'd be happy then

placeboza15:02:25

defentity looks like this:

placeboza15:02:27

(defmacro defentity "Define an entity representing a table in the database, applying any modifications in the body." [ent & body] `(let [e# (-> (create-entity ~(name ent)) ~@body)] (def ~ent e#)))

moxaj15:02:50

@placeboza you call name on (symbol "mytable"), that won't work

moxaj15:02:57

it has to be a compile-time symbol

placeboza15:02:07

oh of course ..

placeboza15:02:11

looking at wrong bit

placeboza15:02:26

thanks, that makes sense.. now how do I work around it 😞

moxaj15:02:30

also, the def expression wouldn't work either

placeboza15:02:55

I think the def would work, cos of ~

placeboza15:02:31

sorry I need to start quoting symbols properly in here

moxaj15:02:59

nope, it'd still macroexpand to a list, not a symbol

placeboza15:02:24

so short of using read-string (yuck)... Im a bit poked

placeboza15:02:43

unless I redefine my own macro that is similar to defentity, maybe

placeboza15:02:15

ok, I rewrote the macro into a new version of my own, this works:

placeboza15:02:36

.. reposted below..

placeboza15:02:49

sorry I dunno how to block code here.. let me google that

moxaj15:02:55

triple backticks

placeboza15:02:31

Repaste:

(defmacro def-korma-entity-by-name
  "Define an entity representing a table in the database, applying any modifications in the body."
  [ent-name & body]
  `(let [e# (-> (create-entity ~ent-name)
                ~@body)]
     (intern *ns* (symbol ~ent-name) e#)))

(doseq [t tables]
  (def-korma-entity-by-name (:name t) (database rbe) (table (str (:schema t) "." (:name t)))))

joshjones15:02:04

you can also edit posts -- ... when you hover over your message and choose to edit, or up arrow for most recent message

placeboza15:02:15

still learning clojure, but I assume you can't macro a macro definition

baptiste-from-paris15:02:29

@joshjones thx I’ve seen my mistake, I really need sleep ^^

moxaj15:02:34

@placeboza what do you mean by that?

moxaj15:02:44

expand to a new macro definition?

placeboza15:02:35

well, the macro's code, not the expansion

placeboza15:02:04

Im sure you can use a macro on an existing macro's expansion , but guessing you can't modify what the macro does with another macro

placeboza15:02:45

Of course , this is crazy talk and would make the coding gods strike me down because it's horrible to do

moxaj16:02:17

yes, macros are outer -> inner, if that's what you mean

placeboza16:02:25

yup, I think I understand 🙂

placeboza16:02:58

actually, while I'm putting in intern *ns*, it's an opportunity to keep all these dynamically created symbols in a separate namespace instead of *ns*

placeboza16:02:19

not sure I like that the korma entities are symbol definitions

placeboza16:02:30

feels like globals to me

placeboza16:02:13

I can see why, but feels wrong somehow

placeboza16:02:24

but who am I to question... I'm still a noob 🙂

donaldball17:02:13

placeboza: FWIW there are many clojurists who share your reservation about korma’s use of vars.

donaldball17:02:38

My sense is that most clojurists using sql prefer hugsql or honeysql to korma these days

placeboza17:02:28

Tx @U04V4HWQ4 good to know im not alone :)

placeboza17:02:04

Going to look into those alternatives

nwjsmith17:02:36

Could a Clojurians admin help me recover a friend’s account?

byron-woodfork17:02:27

Anyone have any passion open source projects they're working on (in Clojure)?

pandeiro17:02:02

is there any official documentation on how to extend say a Java collection type to ISeq or other protocols? ie, which methods must be implemented?

hiredman17:02:16

ISeq is an interface

hiredman17:02:46

https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Seqable.java is a much easier target (assuming you can easily generate a seq over whatever)

pandeiro17:02:25

hiredman: so answer is that the source code is the documentation?

risto17:02:50

is there something for clojure that lets you do static analysis of code? something like a super-linter?

risto17:02:06

for example, be able to find instances in the code that doesn't follow a particular convention would be an example

seancorfield17:02:28

@risto check out Eastwood… there’s another one too, name escapes me right now...

risto17:02:13

is there anything like that for clojurescript?

seancorfield17:02:35

No idea whether it works with cljs — check the docs.

seancorfield17:02:47

The other one is called kibit, I just remembered.

risto17:02:07

yeah it says it doesn't support clojurescript

risto17:02:32

ah nice! kibit works with clojurescript 🙂

jstew18:02:19

@risto If you're using boot, there is always boot-check https://github.com/tolitius/boot-check

pre20:02:36

Could an experienced clojure/lisp engineer recommend good sources for thinking in recursion? I’ve been professionally coding in clojure for four years (ten more in jvm/js), and though I’m now in an immutable mindset, I still struggle to solve problems with recursion.

pre20:02:46

I have that on my shelf 🙂

pre20:02:45

I’d like to try out the examples in Clojure (though it lacks TCO) to focus on refactoring existing code and libraries. Reading Scheme and SICP takes me an abstraction away from the tools.

pre20:02:59

Thanks for the references.

jr20:02:51

I'd recommend those SICP video lectures because they will force you to think in terms of substitution instead of iteration

jr20:02:32

which is helpful for understanding recursive procedures

pre20:02:54

Interesting. Do you think it’s possible to implement the examples in Clojure, along the way?

jr20:02:00

the language is moot

jiri.knesl20:02:09

from my experience, one doesn't need recursion very often in Clojure

joshjones20:02:35

@pri - you said you've been doing it for a while, but do you use it every day?

pre20:02:16

@joshjones writing clojure?

jiri.knesl20:02:17

once you have powerful HOFs, with combination with comp, partial, the need for recursion is scarce

pre20:02:22

I’ve written a few recursive functions with mutable data inside (transient/persistent!) to do some transformations on large records. But thinking in recursion doesn’t come naturally to me—immutability does.

joshjones20:02:12

@pri This is possibly an obvious and dumb suggestion -- but when solving problems recursively, you really have generally two cases -- the case for termination, which you hit once, and the case for recursion, which happens every other time. If you can clearly identify the terminating case, it often becomes easier to think through the problem.

pre20:02:51

That sounds good, but do you think outside of processing lazy seqs (that supposedly abstracted away recursion), thinking in raw recursions is an advantage?

jr20:02:50

substitution is the advantage

jr20:02:04

(loop [i 0]
  (if (< i 5)
   (recur (inc i))
   i)

jr20:02:20

becomes

(inc (inc (inc (inc 0))))

dpsutton20:02:10

ha i was reading that thinking it did nothing

pre20:02:11

I’m going to keep that word in mind: “substitution”, like a meme.

pre20:02:11

Is it possible, for instance, to “rewrite most functions in my library” with just primitives in recursion—whatever that means.

jr20:02:14

substitution is important because it is easier to reason about than iteration. Stacks represent the total # of steps a procedure has to perform to complete

joshjones20:02:46

@jr, you're not saying that your loop code block is evaluated that way, correct?

pre20:02:32

Yes, stacks are great to represent steps in a process.

jr20:02:36

you can substitute that recursive procedure with those steps though

joshjones20:02:39

ok just making sure it was clear that the evaluation of the loop is not done that way

joshjones21:02:09

yes, familiar, but not how loop works here, just clarifying

joshjones21:02:55

@pri you said: "do you think outside of processing lazy seqs (that supposedly abstracted away recursion), thinking in raw recursions is an advantage?" An advantage over thinking iteratively? Well, for clojure, I think so. To me it's another case of declarative vs imperative; a recursive solution almost defines the solution in terms of the problem itself, and looping defines specifically how to do it.

joshjones21:02:38

At the instruction level it all goes back to jumps, pushes and pops anyway, but that's another story

pre21:02:00

But Clojure’s lazy sequences allowed us to forget about recursion, and I often wonder what I’m “missing” as I haven’t seen a wide adoption of recursive problem solving. Do you have a problem to share, along with a before/after codesize to demonstrate its advantage?

hiredman21:02:54

lazy seqs are a recursive process laid out on the heap instead of on the stack

istvan21:02:38

hey guys, could somebody shed some light on this code? i cannot grasp it:

(def everything (-> (run hello)
                  (assoc :path "/howdy")
                  (->> (run howdy))
                  (merge {:path "/" :port 8081})
                  (->> (run hola))))

joshjones21:02:39

@pri I don't have a sample problem with several solutions to demonstrate approaches, on hand -- but in a language which provides only one primitive for looping (that I know of -- is there another?), the loop special form (which is identical to recursion, except that it enforces a tail call so it's stack friendly), problems are solved everywhere with recursion, especially under the hood. Now, that may be abstracted away and therefore you may not have to use recursion yourself that much, so only you can judge whether it should be a priority or not for your programming 🙂

jr21:02:40

user=> (clojure.pprint/pprint (clojure.walk/macroexpand-all code))
(run
 hola
 (merge
  (run howdy (assoc (run hello) :path "/howdy"))
  {:path "/", :port 8081}))

hiredman21:02:02

loop/recur technically provide iteration, recursion with a bounded stack, for just plain recursion you can just call a function

joshjones21:02:19

@istvan combining thread first and last is usually better done with as-> , in that case you'd probably find it easier to read

jr21:02:19

@istvan that code is much more understandable without threading 😉

hiredman21:02:30

the terminology is confusing because tail recursion (loop/recur) can be optimized to very efficient iteration, which is good, so people often conflate tail recursion with recursion

istvan21:02:43

jr yes i totally agree 🙂

istvan21:02:53

coming from here ^

istvan21:02:14

joshjones thanks, i am trying to rewrite it to be human readable

hiredman21:02:07

(fn f [] (f)) is a recursive function, which will run out of stack space. (fn f [] (recur)) is recursive too, but also iterative, so it won't run out of stack space and will just loop forever

pre21:02:14

Thinking in recursion has come after working in core.async for a year. But outside of core.async, I don’t often write loop-recurs. @hiredman how would one implement a lazy seq on a stack?

hiredman21:02:56

well just take something that creates a lazy seq and do it without the laziness, which would just be a list

istvan21:02:13

priyatam funny you talk about recursion, just yesterday i had to solve a problem where recursion (even do without using recur and loop) helped a lot

istvan21:02:52

it is not needed a lot but there are situations when recursion is invaluable

hiredman21:02:50

recursion and iteration are classifications in the zoology of processes, not really tied to particular constructs in a programming language

joshjones22:02:53

@hiredman Yes, but iteration requires constructs in a language that recursion does not

istvan22:02:16

i am not sure if i could live without recursion though

pre22:02:56

@istvan could you expand on that?

hiredman22:02:25

@joshjones that is not always the case

joshjones22:02:59

Well, how else do you loop without a goto?

istvan22:02:19

priyatam sure, this is the example from yesterday, i get messages with nested data structures like {:user_name "joe" :address {:city "SF" :state "Cali" }}

istvan22:02:43

i need to flatten out these messages with arbitrary level is nesting

hiredman22:02:54

goto is a detail of the target language, the source language may not have an implicit iteration construct, but still create iterative processes depending on how it is mapped to the target language

istvan22:02:22

i wrote a simple recursive call that walks in the hashmap and when finds a subhash calls itself with the subhash

istvan22:02:51

(i know there are tools like zip, walk etc. this is a special situation i needed to implement something myself)

hiredman22:02:31

for example scheme doesn't have any kind of explicit iteration construct, if I recall, so programs that result in an iterative process look the same as programs that are recursive

hiredman22:02:10

so iteration is a special optimization of some programs

joshjones22:02:00

I thought we were talking about the point of view of the programmer, who's writing in one language. From his/her perspective, it doesn't matter how it's translated into something else

hiredman22:02:49

that is my point basically, iteration and recursion are properties of the execution of programs, not static properties, so it does matter

joshjones22:02:00

So if I'm writing scheme, and it has no explicit iteration construct, how do I solve a problem using iteration, and not recursion?

hiredman22:02:01

you have to know that the compiler can optimize code that would result in a recursive process when it has the right shape in to a iterative process

joshjones22:02:44

So you're saying that because the compiler converts a recursive process into an iterative process (which they all do), ... that affects me how, as I'm writing the program? Or maybe I'm missing you

pre22:02:46

@hiredman what is the shape of such a recursive process?

hiredman22:02:30

sicp and that video of the lecture from a sicp class I linked both describe the shape of recursive and iterative processes

istvan22:02:59

yeah, all kinds of recursive processes

hiredman22:02:12

an iterative process is constant space, a recursive one is bound by the input in some way

istvan22:02:17

i like the visual from the SICP book

joshjones22:02:27

I think I understand what you're saying -- and I agree, but it's a fact that some languages provide syntactic "helpers" to iterate. That's all I'm saying

istvan22:02:28

it helped me a lot to grasp on recursion

istvan22:02:41

like clojure iterate? 🙂

istvan22:02:51

best fibonacci implementation ever

istvan22:02:23

(def fib-seq-iterate
  (map first (iterate 
               (fn [[a b]] [b (+ a b)]) [0 1])))

joshjones22:02:49

yeah i have this, a lazy-seq version, lying around

(def fibs ((fn fib [a b]
             (lazy-seq (cons a (fib b (+' a b))))) 0 1))

istvan22:02:57

priyatam btw. how come this recursion questions came up?

hiredman22:02:26

http://agl.cs.unm.edu/~williams/cs491/three-imp.pdf is neat paper, it includes compiling scheme for a very different execution environment, some kind of graph reduction machine

joshjones22:02:47

@hiredman gotta run, thanks for the discussion, was enjoyable! 🙂

pre22:02:33

@istvan I’ve worked in core.async for a while and got used to recursion, but unable to think recursively for the rest of my code. Looking for more inspiration to think recursively in other areas.

bsunter22:02:20

@pri i've been looking through this book "how to design programs" and it has a pretty good discussion of recursion and exercises http://www.htdp.org/2003-09-26/Book/curriculum-Z-H-32.html

paulocuneo22:02:25

Hi everyone, nice to meet so many clojurians!

paulocuneo22:02:17

@pri may i suggest writting the toposort algorithm in strict tail recursive fashion(i.e. using recur in every tail)

pre22:02:34

@paulocuneo algorithms don’t excite me, but I'll try, thanks