Fork me on GitHub
#clojure
<
2018-01-04
>
Mateus Quaresma01:01:28

Hello everyone, I'm just starting to learn clojure and I'd like to ask if anyone is doing some kind of work on mathematics, like optimisation or even calculus. It's hard to find mathematically inclined C.Scientists...

rymndhng01:01:34

anyone have experience with any oauth1 client libraries? i.e what did you like or dislike

bobo02:01:29

@rymndhng why not OAuth2?

rymndhng02:01:50

@bobo i’m integrating with some legacy APIs

bobo02:01:26

RFC is better for you to understand the protocol. https://tools.ietf.org/html/rfc6749

rymndhng02:01:31

thanks for the link, though it's for OAuth2, I found an OAuth1 ref, thanks.

grzm08:01:54

Any admin for the https://dev.clojure.org JIRA instance here? Looks like it's getting spammed. https://dev.clojure.org/jira/secure/ViewProfile.jspa?name=jennyhannb

lambder11:01:35

Hi Folks, any idea how can I automatically have (reset) run on file changes? e.g. how to configure file watch so it resets the duct or stuart sierra system for me?

pyr13:01:30

I'm implementing a service against 3rd-party XML parsers which are strict and require elements to be output this way:

pyr13:01:59

<SomeTag xmlns="http://foo/"><SomeContent>Bar</SomeContent>/</SomeTag>

pyr13:01:41

While moving from data.xml 0.0.8 to 0.2.0-alpha5 it seems it's no longer possible, or am I doing something wrong?

pyr13:01:08

Using qname or alias-uri I'm able to output xmlns:a= attributes, not a plain xmlns= one

pyr13:01:04

wondering if anyone else ran into this

pyr13:01:53

(if anyone has an alternative xml library to recommend, I'm also all ears)

borkdude14:01:31

is there something like this in clojure? (cond (foo x) {:type :foo :value (foo x)} (bar x) {:type :bar (bar x)}) where (foo x) can be bound to a name? Kind of like (let [f (foo x), b (bar x)] (cond f {:type :foo :value f} ...))

dpsutton14:01:49

no problem. i like that one

tomaas16:01:25

Hi, I'd like to know which the correct way to implement something like. This snippet works in the begining for some time, but then, after random time, at/every does not call its callback . I've tried to debug put prints, try/catch blocks. I have this handler.clj deployed in heroku. Thanks in advance

hiredman16:01:21

doesn't heroku stop apps after some amount of time?

schmee16:01:49

reposting my question from #off-topic: does anyone know any good resources about Java 8 streams and Java Spliterators, and if/when/how they can be used in Clojure?

jeff.terrell16:01:45

Yeah, @tomaas, are you on the free tier in Heroku? If so, the dyno running your app might just be asleep. If you load the page (causing the dyno to boot up), does the callback start happening again?

tomaas16:01:11

no it does not, cause @data is not nil (just returns outdated @data value). I have free version, but the apps's client-side (cljs) makes a long polling to that route every 5 min, so it never goes to sleep (as least heroku states that sleeping mode starts after 30 min of no requests).

dpsutton16:01:32

i thought i remembered horuku limiting the free tier to 18 hours a day?

dpsutton16:01:44

is that a thing? i'm probably misremembering

tomaas17:01:47

Accounts are given a base of 550 hours each month in which your Free dynos can run. In addition to these base hours, accounts which verify with a credit card will receive an additional 450 hours to the monthly Free dyno quota.

tomaas17:01:19

heroku ps -a <app name> says that I have 94% of my free dynos hours

tomaas17:01:28

this is so weird

hiredman17:01:01

if it stops working, what makes it start working again?

hiredman17:01:30

(calling clojure.core/read-string on user input is usually a bad idea, use clojure.edn/read-string)

tomaas17:01:05

ok, thanks. Redeploying it again or restarting all dynos from heroku interface

hiredman17:01:16

when you say you tried to put debug prints and try catch blocks, what does that mean? what did you do and what was the result?

tomaas17:01:04

just tried to put the at/every's callback's expression into try/catch block

hiredman17:01:16

what do you mean by that?

hiredman17:01:12

(try #(...) (catch ...)) or #(try ... (catch ...))? what exception types were you catching?

hiredman17:01:43

you are making a string of the exception information but not doing anything with it

tomaas17:01:11

sorry, I had a print for that

hiredman17:01:25

how does printing work on heroku?

hiredman17:01:35

try replacing Exception with Throwable

tomaas17:01:51

ok, heroku prints everything you prn to the console logs

hiredman17:01:40

if you replace the user of at/every with (future (while true ... (Thread/sleep (* 60 1000 5)))) what happens?

tomaas17:01:54

thanks @hiredman, didn't try this way, maybe then it's that libs stuff. I deployed the future snippet version, so let's see if it does not stop after a period of time 🙂

PB18:01:19

It's been a while since I've had the chance to build something new. I'm building out a new api, does anyone have any preferences for liberator / pedestal server / anything else?

seancorfield18:01:39

@petr I prefer to keep things simple with just Ring / Compojure (I haven't used compojure-api but that is probably still "simple"-ish).

PB18:01:46

Maybe I'm being stilly. I just like the way pedestal server works with middleware. I like how the interceptor layer is done

ordnungswidrig18:01:15

pedestal and liberator work together well, btw.

luskwater18:01:17

Once I saw it, I liked the interceptor way as well.

PB18:01:46

I guess i could use liberator for the routing

ordnungswidrig18:01:52

liberator creates a ring handler, in the end wich you can mount with pedestal and still attach interceptors…

ordnungswidrig18:01:04

@petr, no liberator doesn’t do routing.

PB18:01:35

@seancorfield may have the correct approach though

PB18:01:10

Oops, yes sorry. tonguetied

dominicm18:01:41

Using a multi method as a point for e.g. Choosing an action to take in response to an event doesn't seem to work with dependency injection. The caller always ends up needing to know about the stateful methods, in order to let them query the appropriate services, with the correct api keys, etc.

PB18:01:36

Duct just looks like a generator?

pfeodrippe18:01:54

You take the configuration out of the code and put it in a data structure, letting your focus on your code, it's opinionated, but it's well designed for APIs. Made by the same creator of compojure https://github.com/weavejester

pfeodrippe18:01:14

It has some batteries included

pfeodrippe18:01:27

It can be used at the place of Component from Stuart Sierra

PB18:01:17

Hmm. I'll check it out. Thanks

pfeodrippe18:01:58

o/ any hard time using it, PM or mention me, I have some test code that can be shared using duct, you're welcome

rymndhng18:01:37

I'm trying to make my comojure handler functions reloadable, I notice that when I use the routing DSL as follows, the var handler-a, handler-b, handler-c are derefed to the function and when I re-define handler-a, my changes don't take effect

(route/route handler-a handler-b handler-c)
However, if I write this using vars, the code is reloadable.
(route/route #'handler-a #'handler-b #'handler-c)
Are there performance impacts of using vars instead of functions?

noisesmith18:01:09

it's an extra pointer lookup

rymndhng18:01:42

right, how costly is it to deref a var constantly?

noisesmith18:01:21

it's just a pointer lookup and a method call

noisesmith18:01:26

there's literally nothing else

noisesmith18:01:04

also to be clear, when you have (defn foo [] (bar x)) it does the same lookup on bar

noisesmith18:01:16

this is already happening everywhere in your code, repeatedly, ubiquitously even

rymndhng18:01:50

gotcha, thanks! i think I was caught offguard why compojure's route doesn't have the same indirection -- i probably have to poke around the source code to understand, thanks!

noisesmith18:01:22

it's because function arguments are resolved before being passed to the function

noisesmith18:01:41

it's effectively a cached value - to see a new one you would need to call the function again (which means restarting your server, right?)

noisesmith18:01:57

if you had (future (while true (foo))) vs. (future (while true (#'foo))) you'd see the same discrepancy - the difference is that using the var means it dereferences on each call without running the whole form again

rymndhng20:01:36

ah fair, i see your point

noisesmith18:01:58

an alternative is to use a system like duct or stuartsierra/component to shut down the http server then restart it with your new code without doing a restart of the clojure process

zsck18:01:59

Hi all. I'm interested in picking up Clojure this year. I'm coming from a background of really appreciating statically typed languages, but find Rich's argument about dynamic typing very compelling. Could anyone point a newbie to some writing that might illuminate Clojure's design philosophy (as it applies to people writing Clojure, not so much Clojure itself)?

schmee21:01:03

everything in the About section on the official homepage is worth a read: https://clojure.org/about/rationale

schmee21:01:28

also, take a look at some of Rich Hickeys talks, which are very, very good

schmee21:01:39

I recommend Simple made easy and Language of the system to start with

schmee21:01:36

here is another one of my favorite Clojure talks which contrast a classic Java OOP design with a more Clojure-y design: https://www.youtube.com/watch?v=Tb823aqgX_0&amp;t=1s

zsck21:01:56

Thank you for these references!

rymndhng18:01:04

@noisesmith yeah, i'm definitely using that strategy at the moment, i'm looking at ways to reduce the feedback cycle more 😄

petterik19:01:08

I was surprised to find out that clojure.core/some isn't implemented with reduce. I.e.

(defn some2 [pred coll]
  (reduce #(when-let [ret (pred %2)] (reduced ret)) nil coll))

petterik19:01:08

It's quite a lot faster than the current implementation, and I'm wondering if it'd be a good enhancement?

petterik19:01:21

Didn't find a jira about this

Alex Miller (Clojure team)19:01:15

maybe, but need to analyze the bootstrap order - reduce and reduced might not be defined yet

ghadi19:01:55

it isn’t IIRC

mikerod19:01:19

I think several clojure.core fn’s are slow due the bootstrap order stuff

Alex Miller (Clojure team)19:01:21

but feel free to file a ticket with a patch if you get something workable (may be able to move some around, depends on what else depends on it)

Alex Miller (Clojure team)19:01:37

we also do redefinitions in some cases once we have better stuff

mikerod19:01:40

I mean relatively slow is a better way to put it

mikerod19:01:57

> we also do redefinitions in some cases once we have better stuff Yeah, I noticed that in a few

mikerod19:01:30

I guess the good part is if you need to write one of these things to be more performant for some usage, it isn’t typically too difficult

petterik19:01:01

@alexmiller I'll create a ticket then, thanks

zsck21:01:43

I realize this is an exceptionally broad question, but what domains does Clojure get a lot of use in? Of course I realize it's a perfectly good general-purpose language, but is there any domain where it's seen a lot more success than in others?

danielglauser21:01:29

@zack.mullaly There’s a decent amount of Clojure being written in the financial services/fintech space.

noisesmith21:01:40

I've used clojure for server side of web apps, sometimes with clojurescript on the frontend to go with it

zsck21:01:28

There's been some talk of people using Elixir these days for distributed systems. Am I correct in thinking there are ways of going about doing fault-tolerant systems in Clojure?

jsa-aerial01:01:25

Check out #onyx

qqq22:01:04

elixir has the erlang vm which has really light weight threads, which allows all types of cool OTP patterns; it's hard to do that on clojure

noisesmith22:01:09

clojure doesn't come with inter-process stuff baked in the way erlang does

qqq22:01:25

erlang vm processes's are so damn cheap, (I think 4kb overhead / process?) that you can do all type of nifty things

noisesmith22:01:17

and they can transparently collaborate across vms and even hosts - clojure comes with nothing like that

qqq22:01:20

it's not unusual to see a design pattern where a webserver gets a request, then FIRES UP A NEW ERLANG PROCESS to handle that one request (and the process dies afterwards), and it's fine because erlang vm processes are so cheap

qqq22:01:37

I almost used erlang until I realized: in distribution, one of the hardest problems is state -- and for state, I don't want to roll my own riak cluster using erlang - I want to just use aws dynamodb . redis -- and if I'm using that, my functions can be stateless on lambda -- and at that point, I can just use clojure for lambda, so erlang buys me nothing

zsck22:01:20

That's a very interesting approach. I'm in a situation where I'm not really sure where I want to direct my career from now on. I know I love functional programming and think distributed systems are really interesting to deal with, but I'm not really sure which technologies fit domains I might find interesting. With that said, I'm getting the impression that the Clojure community has a lot of great stuff, particularly since you can leverage existing Java code.

noisesmith22:01:12

and clojure can do much better than erlang in terms of resource usage and performance if what you do involves any substantial computation or memory

noisesmith22:01:10

the more I make distributed things though, the more I realize that distribution of systems is a liability that you take on in order to get some other property (like availability or throughput) and it's definitely not an end unto itself

noisesmith22:01:21

in fact everything becomes a lot easier if you avoid it

zsck22:01:39

Do clojure libraries tend to use event loops to do asynchronous work?

noisesmith22:01:42

futures, executor services, or core.async

noisesmith22:01:38

if you want repeated tasks a scheduled executor service is made for exactly that purpose and they come with the jvm, there's a thin wrapping library over that called at-at

zsck22:01:04

This all sounds really great.

zsck22:01:29

What would you say is the best way for an experienced developer to dive into Clojure and get going as quickly as possible?

noisesmith22:01:16

check out the puzzles at http://4clojure.com - it helps you think in idiomatic clojure and comparing your answers to the ones from other people can be very informative

noisesmith22:01:44

some of it is just code golf, but there's a lot of tricks to be learned by studying the answers there

noisesmith22:01:54

and the standard stuff, read code, write code, fix code

noisesmith22:01:43

authors like halgari, weavejester, amalloy, ztellman have good github repos for browsing exemplary clojure code

zsck22:01:44

Is there a guide or a book that might get me up to speed quickly?

noisesmith22:01:06

oh of course - if you are experienced, "Joy of Clojure" is great

zsck22:01:16

Perfect!

zsck22:01:30

Thank you so much for answering all these questions. I'm really excited to give Clojure a go.

noisesmith22:01:02

but "clojure applied" has more pragmatic "this is how you do it at the day job" kind of stuff

zsck22:01:47

I hope I can one day use Clojure at my day job! 😮

qqq22:01:58

start your own company

noisesmith22:01:06

if you have a java shop, it's easy to add clojure to an existing java ecosystem

ErhardtMundt22:01:29

I have a re-frame project and I can't get my uberjar working

ErhardtMundt22:01:07

with lein dev compojure serves all the public files

ErhardtMundt22:01:23

when I launch the uberjat it only serves index.html

ErhardtMundt22:01:46

I tried to extract the uberjar and the files are actually included

ErhardtMundt22:01:53

I don't know what to do

noisesmith22:01:49

@erhardt.mundt are you using wrap-resource to serve the files?

ErhardtMundt22:01:08

@noisesmith that's how I define my routes ☝️

ErhardtMundt22:01:39

am I missing anything?

noisesmith22:01:20

in order to serve arbitrary resources, there's usually a middleware used

noisesmith22:01:35

what to look out for in your case is that it's wrap-resources with the right directory root

ErhardtMundt22:01:58

any clue why it's working if I launch it with lein dev?

noisesmith22:01:25

the common cause is that wrap-file is being used instead of wrap-resource, and things inside uberjars are not files

ErhardtMundt22:01:45

well, FYI that's what I have right after the routes

noisesmith22:01:08

that's not what wrap-reload is, that's unrelated

ErhardtMundt22:01:43

I'm just wondering how is it possible that's working with lein dev

noisesmith22:01:29

could be figwheel depending on how things are configured

ErhardtMundt22:01:59

well, I'm a beginner but I find this part very confusing

noisesmith23:01:08

@erhardt.mundt did you use lein uberjar to make the jar, or lein ring uberjar - depending on how your project was created / configured it might need the latter to work properly

noisesmith23:01:09

try lein ring uberjar

ErhardtMundt23:01:52

@noisesmith I've tried with wrap-resource and now it works

noisesmith23:01:21

I think the ring uberjar solution might be the intended one though

ErhardtMundt23:01:25

one thing left is that my css file is served with text/plain MIME type

ErhardtMundt23:01:32

do you know how to fix that?

noisesmith23:01:13

hmm... no - if you don't get that problem usually try taking wrap-resource out and using lein ring uberjar maybe... not sure off hand though

ErhardtMundt23:01:35

it says that ring is not a task

noisesmith23:01:54

OK - I wasn't sure if were using the lein-ring plugin - different project templates have different assumptions

noisesmith23:01:28

@erhardt.mundt I don't see any content-type configuration with wrap-resource https://ring-clojure.github.io/ring/ring.middleware.resource.html but it could be you also need to add wrap-content-type https://ring-clojure.github.io/ring/ring.middleware.content-type.html

ErhardtMundt23:01:46

it might be because the file is empty 🙈

ErhardtMundt23:01:58

I'm trying some dummy CSS

seancorfield23:01:48

(a friendly admin reminder that this channel has over 11,500 members and there is a #beginners channel where folks have opted in to answer questions in depth -- or use threads for 1:1 conversations perhaps)