Fork me on GitHub
#clojure
<
2016-11-21
>
misha01:11:00

@hwk: apply is way nicer

fellshard01:11:29

"Don't reach for macros when a function will do."

didibus03:11:40

I've noticed core.reducers map does not let you map over multiple collections. How would you achieve this then: (r/map + (range 100) (range 100)) ?

Alex Miller (Clojure team)04:11:40

Well there's no benefit of doing one op over 100 elements with reducers anyways

Alex Miller (Clojure team)04:11:17

You'd have to map vec over the inputs to combine them before the reducer op

didibus04:11:10

@alexmiller Thanks, I was just using as an example. Is this inherently a limitation of the way reducers work, if so, can you explain that a little?

hwk04:11:46

@misha, @fellshard : it's not a macro -- it's just quasiquoting and splicing, there's no defmacro anywhere

fellshard05:11:08

Hmm, I guess it's a reader macro, isn't it

spacepluk07:11:49

is there any way to see the generated code of a prismatic/schema validator?

gfredericks13:11:29

@spacepluk do you know for sure that it even generates code?

spacepluk13:11:50

hmm, you're right

spacepluk13:11:00

it's probably just a bunch of closures

Alex Miller (Clojure team)14:11:57

@didibus reducers don’t currently support it. they ultimately end up grouping the source collection into segments, and running reduce on them (then a combine function on those results). Being reduce-based (like transducers), the story for iterating over multiple coll sources is limited. Transducers do have an impl of this but it’s not really used.

hwk15:11:18

I now about compojure.route.file and compojure.route.resources . How can I say "I want localhost:9009/dogecoin" to map to "<PROJECT_DIR>/foobar" ? route/resources seems only good for mapping localhost:9009/ to resources/public

roelofw16:11:28

(defn fibtill [n]  (take n (map first (iterate ( fn[ [a b] ] ( + b  (+ a b))) [0 1])))) 
but now this error message : IllegalArgumentException Don't know how to create ISeq from: java.lang.Long clojure.lang.RT.seqFrom (RT.java:542)

colin.yates16:11:31

@roelofw I think your inner fn signature needs to be [a b] not [[a b]]. It isn’t passed a sequence, it is passed a Long (e.g. 0 and then 1).

colin.yates16:11:13

@roelofw (also note that it is idiomatic to have a space between the ‘n’ and the ‘[’ but I assume that was a cut/paste error)

roelofw16:11:41

When I do that , I see another error message :

ArityException Wrong number of args (1) passed to: runner/fibtill/fn--1885  clojure.lang.AFn.throwArity (AFn.java:429) `ArityException Wrong number of args (1) passed to: runner/fibtill/fn--1885  clojure.lang.AFn.throwArity (AFn.java:429) 

colin.yates16:11:07

yes, that inner fn will only be called with one argument, first 0 and then 1

colin.yates16:11:32

https://clojuredocs.org/clojure.core/iterate states iterate calls an fn that accepts a single argument

colin.yates16:11:24

oh I see, I said you needed it to be [a b] - doh - not enough coffee 🙂

roelofw16:11:54

When I do

(defn fibtill [n]  (take n (map first (iterate ( fn [ [a b] ] ( + b  (+ a b))) [0 1]))))   
I see now this error :
CompilerException java.lang.RuntimeException: Unable to resolve symbol:   in this context, compiling:(C:\Users\rwobb\AppData\Local\Temp\form-init3477763366039765302.clj:1:1)  

colin.yates16:11:18

yes, your inner fn is provided with, and can only accept ‘a'

colin.yates16:11:39

if you want ‘a’ to be 0 and ‘b’ to be 1 in your example then you probably want to pass a sequence of vectors

colin.yates16:11:49

e.g. (defn...... [[0 1]])

roelofw16:11:00

also when I do fn [a b] I see this error :

CompilerException java.lang.RuntimeException: Unable to resolve symbol:   in this context, compiling:(C:\Users\rwobb\AppData\Local\Temp\form-init3477763366039765302.clj:1:1) 

roelofw16:11:00

@colin.yates I did that but then I get the first error and that is what I want that a = 0 and b = 1 on the first time

roelofw16:11:02

and on the next turn a and b needs to be the latest two numbers of the seq

roelofw16:11:31

I try to make a seq which contains n numbers, where n is given by the user

dpsutton16:11:21

roelofw, have you read the docstring of iterate?

dpsutton16:11:32

i think that might give you a hint

colin.yates16:11:56

@roelofw - let me play at the repl

mpenet16:11:02

the problem is in the return value of the anonymous fn

dpsutton16:11:18

iterate is gonna keep calling the function on what the function returns

mpenet16:11:24

should be something like

(take 10 (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1])))

dpsutton16:11:53

basically, your function needs to be "closed" in that what it takes in it returns something similar, as you are gonna call your function on that again

mpenet16:11:07

first step is to understand the early steps I guess, decompose what the iterate call does without the map first and go from there

colin.yates16:11:29

@roelofw I’ve been leading you up the garden path - I misread the '(’ :-). (def fib (map first (iterate (fn [[a b]] [b (+ a b)]) [0 1]))) is what you want

mpenet16:11:30

(take n (iterate ...))) ..

colin.yates16:11:54

so because your iterate fn takes a sequence it must return a sequence

colin.yates16:11:10

you aren’t doing that, you are returning a single number (+ b (+ a b)).

colin.yates16:11:26

so the second invocation is passed a single number

roelofw16:11:42

I think that was missing I had to make the calculate the part into a [] and make two numbers

colin.yates16:11:30

I’m not ashamed to admit that after 4 or so years writing Clojure full time this is the first time I have had cause to look at iterate 😉

dpsutton16:11:40

> Returns a lazy sequence of x, (f x), (f (f x)) etc. f must be free of side-effects So reading this immediately i know that the output of f must "look like" (have the same type) as its input

dpsutton16:11:59

neat function

roelofw16:11:46

@colin.yates how do you make the fib numbers then

roelofw16:11:17

I was thinking immediatly on the function

dpsutton16:11:29

your function is correct

colin.yates16:11:03

the iterate is return a sequence of vectors (e.g. [[0 1] [1 2] [2 3] [3 4]] - NOT the real fib numbers obviously), so mapping first turns that into [0 1 2 3]

roelofw16:11:57

oke, learned that also

roelofw16:11:31

I learn a lot about clojure by doing the 4clojure challlenges. More then doing the clojure koans

colin.yates16:11:00

getting familiar with passing around and destructuring maps and sequences is a huge part of it I find.

roelofw16:11:03

and I have to learn a lot more

colin.yates16:11:12

(checkout clojure.type or Prismatic’s schema)

roelofw16:11:33

@colin.yates is this a remark for me ?

colin.yates16:11:54

yep. I found describing the structures I am expecting and exporting save my bacon a huge amount of times

roelofw16:11:33

oke, I found a little bit about Prismatic schema when reading about validating on web apps

colin.yates16:11:41

@roelofw I don’t know what has happened to my fingers and brain today - I mean clojure.spec - sigh.

roelofw16:11:11

I hope the day is not too long for you @colin.yates

roelofw16:11:25

Clojure.spec I did not have read about

roelofw16:11:55

@colin.yates I read the spec guide and it looks very interrested

roelofw16:11:17

also I hope to dig into partial and apply . I use now a lot '( fn [x] ..... ) ' and saw that some people write the same with partial , comp and apply

roelofw16:11:41

Enough to learn the next few weeks/months

colin.yates16:11:50

@roelofw yep, they make for some really elegant code. Also get comfortable with the threading operators (-> and —>)

colin.yates16:11:13

slightly less used is juxt but when you need it, it is great 🙂.

colin.yates16:11:21

right, I had better go and continue breaking my app

roelofw16:11:43

and I go to have dinner with my daugther

roelofw16:11:04

@colin.yates what app are you making if I may know

colin.yates16:11:20

@roelofw it is commercial software unfortunately.

vitvakatu16:11:09

Hello everybody. I need to add some lib (in jar file) to my classpath for android project. Unfortunately, placing jar to new 'resources' folder and adding :resource-paths in project.clj doesn't help

roelofw16:11:42

oke, and you use clojure as development language ? @colin.yates ?

colin.yates16:11:42

I do, both for the back and front end. I have been experimenting with Elm a bit as well.

vitvakatu16:11:04

Actually, I have a problem with Jsoup library on android. The error message is "IllegalStateException Could not read resource entities-xhtml.properties. Make sure you copy resources for org.jsoup.nodes.Entities org.jsoup.nodes.Entities.load (Entities.java:289)". It happens when I invoke Jsoup/connect. I now, that the problem is, that my apk doesn't have entities-xhtml.properties (this file is inside jsoup.jar)

vitvakatu16:11:31

So, I need to include jsoup.jar to my apk (or not the whole jar, just one file)

roelofw16:11:44

and do you use something like luminus or do you use seperate libraries ? @colin.yates ?

colin.yates16:11:59

@roelofw I wanted to learn the guts of it so I started with Compojure and ring and built everything up from there. If you are using it on both back and front then I highly recommend you look at the EDN infrastructure. So much quicker than JSON.

dpsutton17:11:40

I'm creating a zip file from a folder on disk. I'm currently using this form to return the zip file, but it saves it to disk which is completely uneccessary

dpsutton17:11:19

can anyone point me in a direction to just stream the zip file without committing it to disk?

dpsutton17:11:04

also, running into issues of where the folder "generated" is on my local vs the deployed site

dpsutton17:11:32

in dev, its resources/generated/ but in the war file its just generated

roelofw17:11:34

@colin.yates thanks and go back to work before the boss gets angry

stain17:11:35

@dpsutton you need to have a new thread that writes to the ZipOutputStream and use a PipedOutputStream, then you can return the other end and avoid filling memory.

colin.yates17:11:01

@roelofw - that’s one of the benefits of being the chief techie 😉

stain17:11:03

there's some management to do in case the client drops the connection and you don't get to write all of the zip file, in which case you should kill the thread

dpsutton17:11:42

this is simple internal tool so "happy path" only is acceptable

dpsutton17:11:04

and the new thread is to prevent blocking the web server?

roelofw17:11:05

@colin.yates then you do not have a problem. I hope when I learned a lot I also can be a proffesional clojure programmer but at this moment no clojure jobs in the Netherlands

dpsutton17:11:37

@stain how would i compose the streams?

dpsutton17:11:15

(ZipOutputStream. (PipedOutputStream. ))

stain17:11:37

(sorry.. too used to MarkDown in Gitter)

dpsutton17:11:56

and the piped input stream can be returned in a ring handler in the :body?

dpsutton17:11:05

or is there another step of stream conversion

stain17:11:08

no, I think that's the whole idea.. so you would do like :body (piped-input-stream (fn [ostream] (ZipOutputStream. ostream) ; your stuff

dpsutton17:11:10

I very much understand the motivation behind ztellman/byte-stream

dpsutton17:11:35

that should be enough for me to start poking and proding

dpsutton17:11:38

thank you very much

stain17:11:45

that function would then run in a future that writes into the inner PipedOutputStream while ring gets the corresponding PipedInputStream

colin.yates17:11:46

@dpsutton - you could do a lot worse than consume everything that guy has written 🙂

dpsutton17:11:02

yeah looking at the piped-input-stream looks like its right up my alley

dpsutton17:11:10

are you talking about zach?

dpsutton17:11:23

I was lucky enough to hang out with him in Seattle for clojure/west

dpsutton17:11:36

incredibly nice and gracious with is time. i've also read quite a bit of his code

dpsutton17:11:45

he's a fascinating guy and fantastic coder

roelofw17:11:15

pff , clojure is hard. Why is my function call not right, I see this error message :

java.lang.Long cannot be cast to clojure.lang.IFn, 
on this code :
(ns exercises.core)

(defn my-max
  "Finding the max of a seq without using max"
  [s]
  (reduce (fn [acc n ] (if (n > acc) n acc  )) 0 s)

)

(my-max ( 1 2 3)) 

roelofw17:11:33

The error message points to the function call

colin.yates17:11:29

(1 2 3) is a function calling form, where the reader will call the first argument providing the remaining arguments. You need [1 2 3]

dpsutton17:11:43

or '(1 2 3)

colin.yates17:11:47

or '(1 2 3) if you want a literal list

dpsutton17:11:54

we have to pretend like clojure is still a lisp

colin.yates17:11:59

ah - @dpsutton beat me to it 🙂

roelofw17:11:28

Then I see the same error when doing run in Cursive

roelofw17:11:37

I thought about that solution

rauh17:11:59

(n > acc) is unlispy 🙂

roelofw17:11:41

That was the one

roelofw18:11:30

another 4clojure problem solved 🙂

fellshard18:11:55

The 4clojure problem set is pretty fun 😄

fellshard18:11:17

And the golf is actually competent and ignores whitespace, whoo

roelofw18:11:34

chips, I have to change my code, I thought I had read a seq but it is a number of inputs:(

roelofw18:11:54

simple solution found

borkdude19:11:43

I have a question about transducers: > The resulting sequence elements are incrementally computed. These sequences will consume input incrementally as needed and fully realize intermediate operations. This behavior differs > from the equivalent operations on lazy sequences. Why is that different from lazy sequences?

borkdude19:11:23

And what is the benefit over using lazy sequences operators

bfabry19:11:01

the tl;dr: is that they're much faster

borkdude19:11:39

I thought one benefit of transducers was that they fuse intermediate operations

dpsutton19:11:58

here's a talk by rich hickey about their motivation and some implementation

dpsutton19:11:39

undoubtedly there's a shorter answer to your question but the talk is a good one if you have the 45 minutes at some time in the future

borkdude19:11:15

I’ve seen the talk

borkdude19:11:37

I’m just confused by the ‘fully realize intermediate operations’ part

ghadi19:11:04

i think you're conflating transducers themselves vs transducers in the lazy-sequence context

ghadi19:11:37

if you had: (sequence cat [(range 10) (range 10) (range 10)]), when you try to take an element at a time, the cat transducer might will pump all 10 items from one of the ranges all at once

ghadi19:11:39

if you had (mapcat identity [(range 10) (range 10) (range 10)]) and took an item, the mapcat would only take the minimum amount necessary from the ranges

ghadi19:11:57

they're both lazy, but the mapcat one is lazier

ghadi19:11:00

things based on reduce are generally push-model (push all these elements through the reduction), things based on lazy-seqs are pull-model

borkdude19:11:16

that makes sense

genec19:11:06

hi, i'm new to clojure, any suggestions other than emacs for a windows editor with repl?

genec19:11:32

was thinking sublime as i've used it with ocaml

dpsutton19:11:08

cursive seems to be popular

jcsims19:11:37

light table is pretty similar to sublime text, I’d think @genec

jcsims19:11:53

and you can ping @sbauer if you find bugs

genec19:11:17

@jcsims thanks, i was looking at nightcode and had not heard of lighttable

dpsutton19:11:33

but i'll put out the opinion that emacs is well worth learning and is a lovely clojure environment. but don't let anyone bully you into learning it, and there will be quite a bit of time to pick it up

genec19:11:00

@dpsutton i may setup emacs, i tried to get it running for ocaml on windows and was a nightmare. worked fine on linux though

dpsutton19:11:19

yeah i'm not sure how setup path and other things on windows

dpsutton19:11:36

but i run it for work and clojure on windows and its not terrible but i much prefer my fedora box at home

colin.yates19:11:41

another emacs fan but a huge +1 for Cursive - it runs on IntelliJ which is excellent. If I was looking for the lowest barrier to entry that is the route I would go

dpsutton19:11:11

we use Jetbrains software in .NET, the resharper package. Nothing but high praise for their engineering

genec19:11:35

thanks for the info, I'll look at intellij/cursive as well

cfleming20:11:45

@genec If you have any Cursive related questions, ping me in #cursive and I’ll see what I can do.

genec20:11:11

@cfleming thanks, does cursive work with the intellij community edition

cfleming20:11:45

Yes, it does. You can get a free non-commercial licence for Cursive for playing around.

genec20:11:08

@cfleming @colin.yates thanks for the info, intellij/Cursive looks like the simplest way to get setup. I'm looking to move some of my work from FSharp to Clojure but don't want to get bogged down in the Clojure setup just yet.

cfleming20:11:59

@genec Cool, if you’re used to an IDE Cursive is probably the lowest-friction starting point. You can always switch to emacs later if you decide you want to.

roelofw20:11:38

@genec I use cursive and I love it. I did all the clojure koans and some 4clojure problems

genec20:11:37

great, I just need something to setup a project with a repl for now

roelofw20:11:26

Can both be easily done with cursive

roelofw20:11:25

anyone who can point me to a good compojure tutorial so I can start learning to make web apps.

tdantas21:11:43

I read so many times, avoid use global states on the example below, I'm using cassandra as global can you enumarate why this is so bad ?

(defn create
    [receipt]
    (cassandra/insert receipt))

tdantas21:11:23

why should I pass the cassandra connection as argument ?

Alex Miller (Clojure team)22:11:01

what if you had two cassandra instances to talk to?

hugesandwich22:11:40

Anyone have recommendations for the best way to architect long-running Clojure threads and scale them out in a way that is not brittle? I could achieve what I want via actors (Akka), but I'd rather stick to Clojure, core.async, and use channels and go-blocks if possible. Essentially looking for something to scale out threads with a bunch of go-blocks running inside, and then kill/restart/etc them as needed. Currently doing some of this via stream processing, but for various reasons there are a lot of drawbacks I don't want for a part of my use-case.

bfabry22:11:45

component + core.async have worked well for us

hugesandwich22:11:46

I use component with core.async, but this doesn't solve scaling things out across machines in any way.

hugesandwich22:11:32

Looking more for Akka but with core.async. I'm pretty certain nothing like this exists, but asking just in case.

bfabry22:11:54

sorry I didn't realise you wanted distributed

hugesandwich22:11:35

Really I just need to know things like if the thread is alive/dead, kill the threads on remote machines, etc. I can do this manually and it works, but is very brittle and feels like a reinvention of things that exist but have years of work in them.

bfabry22:11:57

onyx purports to be distributed processing for clojure, but I've not used it. I don't think the CSP model (core.async's model) is appropriate for distributed processing personally

hugesandwich22:11:02

So perhaps the answer might be something more general JVM related that can be used easily from Clojure. I'm able to do what I'm doing a lot easier with core.async than actors, which is one reason I don't just use Akka. For instance I don't want the sender/receiver coupling.

hugesandwich22:11:37

I'm using Onyx which is what I was referring to with stream processing. There are some drawbacks for my use case in that I'd end up with a lot to do micro-managing jobs, order is an issue even with windowing, and a few other things.

hugesandwich22:11:34

I use stream processing for a lot of things, but this part of my use-case is exactly what I need to move out of stream processing as there's a bit of use-case mismatch.

bfabry22:11:39

dunno sorry. I've done distributed processing as streams/mapreduce, and I've done CSP on single machines. I've not seen anything like distributed CSP

hugesandwich22:11:11

Thanks. Nor have I really. Some rumblings inside the Golang space about exactly that. So I'm left with being overly clever in my stream processing and having to remove some functionality, or transitioning some code to use actors and Scala. Anyway, I think part of the problem is by nature core.async is flexible and not tied to distributed implementations like actors typically are, but it would be nice to have something one day.

tdantas22:11:24

good point @alexmiller . but on my real usecase I don't have

tdantas22:11:57

regarding tests, I could mock the global database and avoid hit the real db

tdantas22:11:50

what really bother me is change my function signature to receive the connection or a map with all my deps

Alex Miller (Clojure team)22:11:18

@oliv in my experience, many systems grow to have more than one of something in the fullness of time. The other major problem with globals is that those functions are hiding their true dependencies. I would far rather know about my dependencies than have one fewer parameter.

Alex Miller (Clojure team)22:11:13

you can still easily mock your db either way so that’s not a differentiator

tdantas22:11:37

yeah , agree

Bryan22:11:50

Hey everyone, looking for some help here. Been banging my head against the wall for a couple hours now, lol

(defrecord TestRecord [^Double field-1
                       ^String field-2
                       ^BigInteger field-3
                       ^BigInteger field-4])
(def v ["123.45" "I am a String!" "1234567890" ""])
How do I cast the data in v to the type-hinted types in TestRecord? Obviously this is just a mockup, but I'm reading in from a tsv.

bfabry22:11:56

I don't think you can, that information is gone at runtime

tdantas22:11:57

> The other major problem with globals is that those functions are hiding their true dependencies good point. I see the hiding as a good thing. ( maybe too much oo bias ? )

Alex Miller (Clojure team)22:11:26

@oliv as Rich has said, “encapsulation is folly” :)

tdantas22:11:44

lol, yeah ! I saw that ! love it

Alex Miller (Clojure team)22:11:50

@mystickphoenix it’s a hack, but you could use read-string

Bryan22:11:05

At this point, I'd probably be okay with a hack, lol

Alex Miller (Clojure team)22:11:15

read-string will read each string into Clojure data

Alex Miller (Clojure team)22:11:43

if you (map read-string v) you’re pretty close

Alex Miller (Clojure team)22:11:23

but really, you probably want something that a) models the expected type of each field and b) applies a type-specific conversion

Alex Miller (Clojure team)22:11:39

using things like Double/parseDouble etc

Bryan22:11:41

Agreed, I was hoping that records could do that, but it seems like they can't

Alex Miller (Clojure team)22:11:52

nope, they’re just containers

Alex Miller (Clojure team)22:11:04

those type hints aren’t even used by the record

Alex Miller (Clojure team)22:11:12

the fields will all be type Object

Alex Miller (Clojure team)22:11:27

they would be used if you inlined methods into the defrecord to resolve java interop

Bryan22:11:01

Ah, okay. That makes more sense. Great, thanks @alexmiller, at least I have a direction to go in now. Appreciate the help!

hwk23:11:26

how do I write something out (fast) so I can read it back via edn/read or edn/read-string ?

hugesandwich23:11:47

@mystickphoenix Not sure what your larger goal is, but if you just want maps with some type safety, what about using something like Schema (if you aren't familiar with it)? Coercisions + validation might be useful for you here. There are some other libs that deal with transforming data from untyped sources with some conversions and into types, especially from CSVs, but I can't think of the names off the top of my head. https://github.com/plumatic/schema