Fork me on GitHub
#clojure
<
2015-11-16
>
mbertheau03:11:29

@binduwavell: maybe you want spacemacs.

roelof07:11:07

@spei: thanks, I understand what you mean

roelof09:11:37

Can I programm in clojure on windows or can I better use a cloud enviroment so I can use Linux ?

ian09:11:10

@roelof: of course you can program on windows.

roelof10:11:14

#ian I know enough languages which are not right to do in Windows. Is lighttable then a good ide and can I have a lint and a format function too

ian10:11:15

lighttable is a good option for getting started.

roelof10:11:16

oke , then I will try to make my first steps with clojure using light table and the brave book

ian10:11:23

you can also use intellij or emacs or vim or atom or whatever you want.

robert-stuttaford10:11:44

http://braveclojure.com also has really good info on using emacs

roelof10:11:07

Thanks all

shwx8411:11:03

Hi, I am trying to figure out how to use () to reference a resource in a dependency. I see the an optional argument is a class loader. Is there a way to create a classloader from symbol foo where foo is my dependency name?

dm311:11:30

@shwx84: your dependencies will appear on the classpath once you start the repl/properly packaged app. io/resource will pick up anything on the classpath. If you want to fetch a dependency dynamically, you can take a look at https://github.com/pallet/alembic

dm311:11:06

according to http://clojure.org/java_interop: > All arguments are passed to Clojure fns as objects, so there's no point to putting non-array primitive type hints on fn args. Instead, use the let technique shown to place args in primitive locals if they need to participate in primitive arithmetic in the body. is this still true?

mbertheau11:11:35

Any documentation for specter that I have overlooked? I struggle to understand if-path and cond-path. And how is (s/transform [(s/if-path [:a :b] :a :b)] inc {:a {:b 2}}) = {:a "{:b 2}1"}?

mbertheau11:11:04

What I'm trying to do is apply the transform only if the given path exists. I don't know of a similar function in clojure, which is why I wrote a contains-in, which I check before calling update-in. However these functions don't handle lists, and specter does so beautifully.

shwx8411:11:46

@dm3: aha, thanks! have gotten it to work now, had an error in my code

kardan12:11:29

I’m trying to insert a bigInt to a postgrest bigint column using Yesql. But get "Can't infer the SQL type to use for an instance of clojure.lang.BigInt. Use setObject() with an explicit Types value to specify the type to use.” I tried using 🆔:bigint , 🆔:integer and other stuff but can’t get it to work. Did also see https://github.com/krisajenkins/yesql/issues/59 but not really sure what to do really. Any tips?

mhjort12:11:18

@kardan I think you have to use extend-protocol with jdbc/ISQLValue

mhjort12:11:48

Here's an example for converting Clojure maps to JSON fields http://hiim.tv/clojure/2014/05/15/clojure-postgres-json/

kardan13:11:25

@mhjort: ah, will look into that- thanks (sorry, kids pulled me from the computer, hence the lag)

tolitius13:11:02

@oliv: here is an example: https://github.com/tolitius/mount/blob/master/doc/uberjar.md#creating-reloadable-uberjarable-app here find-orders and add-order are DB calls from within compojure routes, and they are simply :required

roelof13:11:22

No one who has succeed in making clojure work on codeenvy ?

roberto13:11:19

most people use Cursive, Emacs or Vim.

roelof13:11:26

oke, so no much people code in the cloud . Not handy when you make something as a team I think

ian13:11:12

hm, I don't think many teams use those cloud programming platforms, do they? everyone just uses DVCS.

roelof13:11:36

I do not know. and what is DVCS ?

ian13:11:08

git , for example.

ian13:11:01

distributed version control system

jstew13:11:51

Every large team I've ever been on has used git (or in the past other version control systems).

lambeta13:11:52

anyone knows how to run all down methods with leingen in drift, seems not supported

nilbus13:11:49

IMO cloud dev environments are a good fit for people with Chromebooks (or windows?) that can’t set up a good environment locally. Not being able to work offline or with poor wifi would be terrible.

roelof14:11:09

oke, I work with Windows but I can set up a good enviroment on my own box. I work now with LightTable, lein

roelof14:11:56

why do add_hundred give a error message here : http://lpaste.net/145376

roelof14:11:59

I see this error message : clojure.lang.Compiler$CompilerException: java.lang.RuntimeException: Unable to resolve symbol: add_hundred in this context, compiling:(C:\Users\rwobb\Documents\programming-exercises\do_things\src\do_things\core.clj:10:1)

darnok14:11:54

it must be something with converting dashes to underscores during compilation

akabander14:11:56

The style guid would tell you to name the function add-hundred (dash not underscore).

akabander14:11:47

darnok may be on the right path, there's some mapping between underscores and dashes when it comes to modules/namespaces and file names. Not sure how deep that goes.

darnok14:11:25

It works in REPL . I'll check if it doesn't work when you load and compile source file.

roelof14:11:39

I work with Lighttable and I see the error when I only select this line (add_hundred 😎

darnok14:11:44

It works too when I put your function to source file and load it with (load-file).

ian14:11:10

I would assume it's something with your lighttable setup

roelof14:11:11

I do not know. IM a beginner who like to learn clojure

ian14:11:01

are you using the instarepl?

roelof14:11:01

I installed light table and pointed it to my project so the directory is being used

roberto14:11:33

ah, looks like LightTable can’t recognize that as clojure code.

roberto14:11:41

it looks like a configuration issue

roberto14:11:24

you need to configure the instarepl

roberto14:11:31

the docs show you how to do that

roelof14:11:52

oke, thanks

roelof14:11:13

Wierd, when I also select the function then it works fine

ian14:11:33

unfortunately, from memory, light table can be hard to work with sometimes.

ian14:11:46

however that was awhile ago so I don't know anymore.

akabander14:11:20

I have a question about lazy seq's... I feel like I must be missing something obvious. I'd like to "store" a lazy seq in a map, like this (merge mymap { :generations (iterate next-generation cells)})

akabander14:11:40

But the merge seems to trigger the evaluation of the seq, which is a... problem.

lvh14:11:33

akabander: why is that a problem?

lvh14:11:44

oh, wait

lvh14:11:47

I see what you mean

lvh14:11:20

akabander: that’s interesting; it doesn’t seem like merge should care

lvh14:11:58

since it just writes over old values… does it matter if mymap has :generations in it already?

lvh14:11:07

akabander: what does assoc do?

roberto15:11:26

it looks like merge uses reduce1 internally, which would evaluate the lazy seq. https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L895

roberto15:11:15

why not use assoc instead?

roelof15:11:22

anyone here who is using light table as his/her IDE. I wonder if it is possible to use eastwood in Light table ?

roberto15:11:54

I don’t see why that wouldn’t be possible

roberto15:11:00

eastwood isn’t tied to an editor

roelof15:11:05

nope, but according to the readme, I have to do lein eastwood but Light table has no terminal where I can put it

roberto15:11:18

use the command line to run it

akabander15:11:29

Roberto -- thanks for the suggestion, I will try it out

akabander15:11:38

(Sorry was in a scrum meeting)

roberto15:11:55

no worries, I’m not even sure I’m right. It is what I understood from the source code.

roelof15:11:15

@roberto: does Light Table have a command line ?? I do not think so

roberto15:11:30

it doesn’t matter if it doesn't

roberto15:11:39

you can bring up the command prompt in windows

roberto15:11:41

and run it form there

roberto15:11:16

I’m always interacting with the command line (to start figwheel, start a repl, start a docker container, etc)

roelof15:11:32

oke, that way

akabander15:11:50

Yeah I use the lein repl frequently, just to sanity check. The cursive REPL is great, but maybe too helpful sometimes.

roberto15:11:31

yeah, I’m not too familiar with LightTable, maybe they have a plugin similar to cider in Emacs that allows you to start a repl inside emacs.

roberto15:11:00

but since you are just beginning, I would just focus on keeping things simple so I can learn the language

roberto15:11:36

I only started using cider once I felt comfortable with clojure

roelof15:11:37

oke, maybe I schould not use a ide but work with repl. Last question : How can I load a source file in repl ?

roberto15:11:07

I would not go to that extreme

roberto15:11:12

I would still use LightTable

akabander15:11:19

Assoc worked, thanks roberto! It's a little dangerous on the REPL, because if you try to print the resulting map it tries to eval the infinite seq... But it's a start!

roberto15:11:20

and evaluate from there

roberto15:11:33

also, Eastwood is a little advanced, I wouldn’t use it when starting

roberto15:11:41

it doesn’t really bring anything to the table for beginners.

roberto15:11:06

it is good to use when you are building a project and are comfortable with the language

roberto15:11:24

but when you are beginning, it is ok to not use it.

roelof15:11:26

oke, im just curious if i done the exercises the right way

casperc15:11:18

So I am wondering, is it considered a bad idea to make a protocol like this: (defprotocol ICompare (< [this other]) (> [this other]) (<= [this other]) (>= [this other])) (extend-protocol ICompare java.lang.Comparable (< [this other] (neg? (compare this other))) (> [this other] (pos? (compare this other))) (<= [this other] (or (= this other) (neg? (compare this other)))) (>= [this other] (or (= this other) (pos? (compare this other)))))

casperc15:11:19

I mean it gives a lot of warnings, but it works: Warning: protocol #'microservice.cassandra/ICompare is overwriting function < Warning: protocol #'microservice.cassandra/ICompare is overwriting function > Warning: protocol #'microservice.cassandra/ICompare is overwriting function <= Warning: protocol #'microservice.cassandra/ICompare is overwriting function >= WARNING: < already refers to: #'clojure.core/< in namespace: microservice.cassandra, being replaced by: #'microservice.cassandra/< WARNING: <= already refers to: #'clojure.core/<= in namespace: microservice.cassandra, being replaced by: #'microservice.cassandra/<= WARNING: >= already refers to: #'clojure.core/>= in namespace: microservice.cassandra, being replaced by: #'microservice.cassandra/>= WARNING: > already refers to: #'clojure.core/> in namespace: microservice.cassandra, being replaced by: #'microservice.cassandra/>

casperc15:11:36

This way i can compare java.util.Dates and everything else that is comparable. I am just wondering if there is a better way to do it. Or a way to get rid of the warnings.

mccraigmccraig15:11:54

@casperc: http://clojuredocs.org/clojure.core/refer-clojure will get rid of the warnings . i would choose something else for the fn names though - i would find re-using < etc confusing

roelof15:11:11

What did I do wrong here ; http://lpaste.net/145384. I see the output : #{(2 2 3 3)} where I was expecting to see #{(2 3 )} ?

casperc15:11:54

@mccraigmccraig: ah cool, thanks. I’ll see if I can find some better names.

roberto15:11:12

@roelof hash-set isn’t expecting a list

roberto15:11:18

it treats the list as one single item

roberto15:11:34

(hash-set 1 1 2 2) would work

roberto15:11:49

but what your function is doing is (hash-set [1 1 2 2])

roelof15:11:41

@roberto: oke, back to the book (brave) . I try to solve this one : http://lpaste.net/145385

jeff.terrell15:11:17

@roelof: You can use apply for that. (apply hash-set [1 1 2 2]) is equivalent to (hash-set 1 1 2 2).

roelof15:11:19

oke, if I change hash-set to set the numbers are right but reversed : #{3 2}

akabander15:11:37

Sets are unordered

roberto15:11:56

@roelof: you might be using the wrong function, hint hint, there is a set function

roelof15:11:27

@roberto: see my remark just before akabander did

roberto15:11:41

sets are unordered

roberto15:11:50

so #{3 2} is the same as #{2 3}

roelof16:11:05

I mean this one : oke, if I change hash-set to set the numbers are right but reversed : #{3 2}

roberto16:11:13

yeah, it doesn’t matter

roberto16:11:16

order doesn’t matter in a set

roelof16:11:33

what is better : set or apply hash-set ?

roelof16:11:44

they both give the same answer

roberto16:11:44

it depends on what you are trying to do

akabander16:11:44

(= #{:a :b} #{:b :a}) => true

roelof16:11:45

oke, at this moment trying to solve the exercise

roelof16:11:02

and trying to learn clojure the right way

roberto16:11:42

you can do it with both, one will be a little harder than the other. It is a good exercise to also try it with hash-set

roberto16:11:54

might lead you to discover more clojure goodies

jeff.terrell16:11:08

I would prefer set over apply hash-set. I was only mentioning apply hash-set to point out what apply does. simple_smile

jstew16:11:01

apply is a good thing to know as a beginner.

roelof16:11:18

oke, in the first chapter apply is not explained

lvh16:11:30

(into #{} coll) too

roelof16:11:42

then this are my solutions (http://lpaste.net/145386) to the exercises on this page : http://www.braveclojure.com/do-things/

roelof16:11:25

I hope I done a good job. Exercise 5 and 6 I skipped , I think I have to learn more about clojure to solve those two

roelof16:11:49

no remarks , Then I can goto the next chapter simple_smile

roelof16:11:54

a question for the future. Is it possible to make a web app without a framework ?

jeff.terrell16:11:19

Heck yes it is. Many Clojurians prefer to do it that way, to avoid the cognitive load of an entire framework.

eraserhd16:11:08

@roelof: It depends on what you mean by “framework”. I find ring itself super convenient.

akabander16:11:40

Also depends on what you mean by app... :^)

eraserhd16:11:42

It’s not heavy at all. Literally, though, it’s a framework - it calls you instead of you calling it.

roelof16:11:39

A framework for me is for example Rails, Django

roelof16:11:03

and by app I mean something like for example a ecommerce store

jstew17:11:05

Luminus is the closest thing we have to a framework

jstew17:11:27

But it's not a framework, it's just an opinionated set of libraries that are convenient for web apps.

mocker17:11:33

Luminus also has a lot of great documentation.

roelof17:11:17

oke, and is there a example for authentication and something like roles. So I can make it work that some people may upload new products and other not. Or guest may look but for buying something you have a account ?

jstew17:11:18

There are a few authentication libraries to choose from. I think that luminus uses buddy. Af far as authorization goes, I don't know. You may have to roll your own. Clojure doesn't have anything like, say, devise, (for Rails).

roelof17:11:08

oke, thanks

roelof17:11:25

First thing first learn clojure

roberto17:11:06

Friend has some good docs on doing oauth too : https://github.com/ddellacosta/friend-oauth2/wiki

roberto17:11:20

with working examples included

mj_langford17:11:53

@roelof It’s a breath of fresh air compared to the “framework norm” languages like ruby/python/php/javascript. You can understand everything you’re using as you add things piece by piece

roelof17:11:07

@mj_langford: you mean working with luminus

mj_langford17:11:22

I mean not needing to work with something like luminus

mj_langford17:11:47

You can start with “here is ring, let me manually assemble some text to return based on the URI passed in”

mj_langford17:11:02

and then add a templating library to do templating…then when you’re ready, a routing library

mj_langford17:11:16

You don’t get 234098 components you don’t understand or need sitting around

roelof17:11:34

oke, are the tutorials or books that I can use to learn to make web apps that way

roberto17:11:42

no, all you need to know is how to use clojure.

roberto17:11:45

that is the beauty

mj_langford17:11:57

http://purlyfunctional.tv sells a course that goes through the layering process

roberto17:11:10

very simple concepts, with no magic

mj_langford17:11:15

certainly not mandatory, but it was a very quick way for me to learn

roberto17:11:41

yeah, that is a good course on the basics

mj_langford17:11:02

the web course was really helpful understanding what ring/compojure/hiccup, etc were all doing

mj_langford17:11:26

I don’t come from a webdev background, and don’t do it most of the time at work, was pretty good at covering the whole topic’s bottom level

roelof17:11:05

LIke I said in a pm I now use the brave book to learn to basics of clojure

roberto17:11:59

that book is a little outdated

roberto17:11:13

the author is updating it

roberto17:11:32

it uses some libraries which are no longer maintained

yogthos18:11:38

@roberto the beta is scheduled for Jan 13th simple_smile

roelof18:11:24

oke, I hope I have then finished the brave book simple_smile

roelof18:11:05

hmm, I have a file suspects in the root of my project but as soon as I do this: (def filename "suspects.csv") and then (slurp filename) I get a message that the file is not found. Where do I have to put the file then. Light Table is now driving me grazy

jstew18:11:06

@roelof: you have to specify the full path to the file, I think.

roberto18:11:44

does the file exist?

roelof18:11:50

yes , I see it in the file explorer of Windows

roberto18:11:10

are you using lein?

jstew18:11:18

One thing you can try doing is putting it in resources, and using this: https://clojuredocs.org/clojure.java.io/resource

mj_langford18:11:42

the root of your project is the right place

mj_langford18:11:15

do you have a repl going?

roelof18:11:16

im using lein and I put the file in the root of the project

roelof18:11:49

@mj_langford: Light table has no repl just a instarepl

mj_langford18:11:09

I’m Not great with the development on windows story, but I’m assuming you can go “lein repl” in a terminal in the root directory of your project, outside of lighttable

roelof18:11:05

I can do that I think , moment

mj_langford18:11:41

(System/getProperty "user.dir") gives you the current working directory

mj_langford18:11:17

try it in the repl of that project, could illuminate what is going on if something is going strangely

eraserhd18:11:38

It’s really interesting to see Rich Hickey using metadata in clojure.zip to make “objects” out of vectors by attaching “methods”.

eraserhd18:11:55

Feels kind of weird.

roelof18:11:33

@mj_langford: I see this output and it looks fine to me : C:\\Users\\rwobb\\Documents\\programming-exercises\\core_functions"

mj_langford18:11:39

what happens then when you (slurp (str (System/getProperty "user.dir”) “/suspects.csv”))

roelof18:11:55

also the same output

mj_langford18:11:41

don’t know what to tell you then, looks like you don’t have a file called suspects.csv in that folder. Perhaps you mispelled it, or have it in the wrong place. sorry I couldn’t be more helpful

roelof18:11:16

I have found it. the file on the disk had .cvs instead of .csv

roelof18:11:29

stupid mistake. Sorry for the confusion

jstew18:11:01

It happens. Especially when there's the cognitive load of learning a new language.

roelof18:11:07

Can someone help me with this one : http://lpaste.net/145389

roelof18:11:22

I just copied the code from the brave site

mj_langford18:11:58

You have a carriage return in your CSV file perhaps?

mj_langford18:11:11

windows has /r/n at the end of lines

mj_langford18:11:19

unix has /n at the end of lines

mj_langford18:11:23

this is because you’re on windows

mj_langford18:11:03

there are two ways to fix this, you can change line 27 to split on the string “\r\n” or you can use a more sophisticated str->int function

roelof18:11:49

your are right, Windows has put /r after each line 😞 ["Edward Cullen" "10\r"]

mj_langford18:11:57

instead if (clojure.string/split string #"\n")

mj_langford18:11:31

I think this is something @nonrecursive should consider fixing in the book/site. Many professional programmers work on mac or linux now, and little things like this slip through

roelof19:11:09

not fun. Now I see this error : clojure.lang.ExceptionInfo: EOF while reading, starting at line 41 and column 1 :: {:type :reader-exception, :line 41, :column 32}

roelof19:11:58

I think I will change to a cloud ide where I can use Linux

mj_langford19:11:23

Moving over to #C053AK3F9 to answer about the EOF error

swizzard21:11:37

@alex.nixon: do you care about the end result?

alex.nixon21:11:53

nope, only the side effects

alex.nixon21:11:54

something akin to (run! f (sequence xf vs))

swizzard21:11:09

i think you should be able to do something like (doall (map f (xf vs)))

swizzard21:11:32

but you’ll have to rewrite xf

alex.nixon21:11:04

I think what you're getting at there is the same as (sequence xf vs)

alex.nixon21:11:25

I was hoping to avoid building a lazy list

alex.nixon21:11:58

I think I might argue that run! should have an arity which takes a transducer

swizzard21:11:17

i mean, from what i understand, transducers shouldn’t really be combined with side effects

noonian21:11:07

transduce will do it right? So you could make a run-xf! or something on top of that so it doesn’t feel awkward?

noonian21:11:51

basically the same as if it was built-in to run!

alex.nixon21:11:44

noonian: yeah I can write that

alex.nixon21:11:06

swizzard: I'm not sure I feel the same about that, particularly given they're heavily involved in core.async which is built on side effects

swizzard21:11:26

fair enough! i don’t honestly know that much about transducers simple_smile

alex.nixon21:11:11

np, thanks for offering your thoughts anyway

pshk4r21:11:53

noob question: how to define a function that returns a function in let? as for now, I do straightforward ... (let [coercer ((coerce/coercer User coerce/string-coercion-matcher)))] ... but it feels wrong

pshk4r21:11:36

or it is not?

noonian21:11:08

the snippet looks wrong, let requires an even number of forms in the binding vector for one thing

pshk4r21:11:01

sorry, I copied it wrong. now it's updated.

mj_langford21:11:27

or you mean one more level?

arthur21:11:28

Always be suspicious of you are two opening (( in a row

arthur21:11:11

Let-fn is a decent option for this as well

noonian21:11:24

((coerce/coercer User coerce/string-coercion-matcher))) is taking whatever coerce/coercer returns (presumably a function) and calling that function with no arguments binding the result to coercer.

noonian21:11:08

but whether or not that is correct depends on the implementation of coerce/coercer so I’m not sure if that’s what you want

noonian21:11:29

Ah, so I think coercer is from the schema lib, and according to the readme the fn returned by coercer expects some data to coerce. So you probably just want (let [coerce (coerce/coercer User coerce/string-coercion-matcher)] …).

pshk4r21:11:25

Thanks guys! Especially @noonian simple_smile Yes, the function comes from schema and I've got a bit confused about binding it to a symbol.