Fork me on GitHub
#clojure
<
2015-06-18
>
teslanick02:06:48

keep seems like a weird function. It's like map and filter smashed together.

ahinz03:06:08

I'd appreciate if anybody could help me with a core.typed question... just starting out so it may be a bit obvious. Why does (IPersistentMap Integer myapp.core/Thing) Integer not match (t/Option (ILookup t/Any x)) t/Any do I need to explicitly lift the map into the Option type?

aengelberg04:06:35

There are probably more people able to help with that in the #C051QCQUF channel.

rob05:06:42

I feel like manifold.stream/throttle doesn’t work how I thought it would: https://gist.github.com/ottbot/f2ffc9b8abbb64dac1dd

rob05:06:51

instead of making take! wait, it goes straight through

ulsa08:06:41

@ragge: been offline, saw your lambada stuff just now, gonna look into that, thanks

ragge08:06:00

@ulsa: did you see I released the thing as a library now? found a different approach to solving the class loader issue

ulsa08:06:35

@ragge: yes, very cool

ulsa08:06:33

@ragge: it works, awesome! Clojure in Lambda!

ragge08:06:49

@ulsa: cool, thanks for giving it a go... i think there might be room for an additional, slighly higher level interface that deals with the json parsing, as that's will likely be the most common way of using lambda

ragge08:06:34

@ulsa: instead of dealing with streams, you could provide a fn from (map, context) -> map, and lambada could do the json deserialization/serialization

ragge08:06:59

@ulsa: as all the aws events are json

phil09:06:30

ej: I use Buddy heavily.

phil09:06:57

Not sure how it compares to Friend, but I'm very happy with it.

phil09:06:34

Which is a great resource.

niwinz09:06:55

Nice to hear that! 😉

kachayev11:06:05

Hi, guys! what is the most popular Clojure library to deal with functor/monads? I know that there’re algo.monads & cats & few others, just curious which one is more useful/helpful/popular

txus11:06:25

@kachayev: Fluokitten looks very, very complete: http://fluokitten.uncomplicate.org

jrychter11:06:59

@aengelberg: what keeps you on Clojure 1.6?

gmorpheme12:06:24

@kachayev: I found https://github.com/bwo/monads much more natural for me than algo.monads where the implicit return in the do-monad body kept getting in my way (if i remember correctly). though i’m far from an experienced monadicist. bwo/monads hasn’t been touched for a while either

kachayev12:06:40

thanks @txus! fluokitten looks nice

dialelo12:06:16

@kachayev: author of cats here, AFAIK is the only one that supports both Clojure & ClojureScript in case you need that

dialelo12:06:01

see http://funcool.github.io/cats/latest/#_rationale for the reasons we wrote yet another monad library

kachayev12:06:00

actually, just now I’m looking for a library to cleanup server-side code (with many ad-hoc implementations for functor-like flows). no plans for ClojureScript, maybe in future

pesterhazy12:06:00

cats looks pretty cool

gmorpheme12:06:19

yep certainly does - guess I’m now looking to alias >>= back to bind and come up with some cunning way of turning haskelly mdos into mlets...

txus12:06:38

@dialelo: wow, cats looks actually nicer

txus12:06:42

didn’t know of it

txus12:06:20

gonna start using it 😄

dialelo12:06:30

thanks @txus, @niwinz and I would be glad to hear your feedback

txus12:06:19

happy to contribute too, I wrote a similar thing for Ruby (https://github.com/txus/kleisli) and I miss all this stuff in Clojure!

txus12:06:30

although cats looks already very complete

dialelo12:06:18

I miss it in other languages too, specially the error types (maybe et al)

kachayev12:06:26

the main problem with mlet is that most probably you will "get it” if you know Haskell do-notation, otherwise it’s not that simple to get the idea behind it. and if you know do-notation, most probably, it’s ok for you to see >>= in code

txus12:06:54

aah i was gonna say, mlet looks delicious!!

dialelo12:06:46

@kachayev: yep, but the docs show what pattern mlet captures. it starts showing de desugared way of chaining computations and refactors it to mlet

dialelo12:06:35

@txus: thanks! we made it very similar to for for a Clojure-y feel

txus12:06:59

most of the interfaces look very idiomatic too

txus12:06:00

great job!

txus12:06:24

aah too bad, I was hoping I’d get to write the category theory library for Clojure….

kachayev12:06:35

btw, is it possible to “hook” somehow into native clojure for?

pesterhazy12:06:48

I quite liked the approach in http://adambard.com/blog/five-mistakes-clojure-newbies-make/ (using attempt-all, which I think is based on algo.monad)

dialelo12:06:45

@kachayev: not sure i understand your question, you mean that if mlet could use for for sequence comprehensions?

kachayev12:06:01

Scala use the same syntax for sequences and monads with for…yield. which is really convenient

niwinz12:06:57

I'm not pretty sure if a for can be used in same way as in scala ...

dialelo12:06:32

you can use some built-in Clojure types with mlet, lazy sequences should be equivalent to for in a mlet

txus12:06:32

I don’t think (for) in Clojure is just sugar for a well-defined protocol….

txus12:06:47

so it’d be hard to make it play nice

dialelo12:06:16

but as @txus say, no way to use for as mlet

txus12:06:52

by the way @dialelo, ever thought of giving core.typed a shot for cats?

txus12:06:12

it’d be great to verify correctness, and also very handy for its users if they use core.typed

txus12:06:31

I might give it a shot at annotating some protocols

dialelo12:06:52

I've thought about it and I'd love to annotate the library, if you give it a shot it'd be very welcome

borkdude12:06:44

Anybody got tips on rendering PDF from a clojure ring based site (similar to wicked in Rails)?

niwinz12:06:45

+1 (we no had time for it :P)

txus12:06:56

definitely, sounds like a good excuse to get my hands dirty with core.typed on a real project 😄

sveri12:06:37

+1 for core.typed on any project simple_smile

sveri12:06:45

I thought about this too (not for cats, but in general) and did not do it, because, you need the commitment of any maintainer and commiter to that library to fix the annotations if the API changes / new functions got added

txus13:06:42

well, the properties you can prove with core.typed can save you loads of unit tests — which need maintaining as well, so you’d probably save maintaining effort in the long run @sveri simple_smile

sveri13:06:05

@txus: That's why I use core.typed occaisonally on my own projects, no need to convince me 😉 We just have to start convincing library authors

txus13:06:41

nothing more convincing than a PR with a bunch of annotations and some unit-tests removed simple_smile

pesterhazy13:06:03

borkdude: you could just generate an html file using hiccup and then shell out to wkhtmltopdf to turn it into pdf

pesterhazy13:06:54

looks like somebody already did just that: https://github.com/pdfkit/pdfkit-clj

martinklepsch13:06:28

@txus: @dialelo is there a thing I could read to get a better idea about functors/monads and what I’d use them for?

txus13:06:57

@martinklepsch: definitely, I got a few good bookmarks, gimme a sec

txus13:06:09

@martinklepsch: these 4 are really good to get started

dialelo13:06:57

@martinklepsch: @txus great recommendations, after that cats' docs should make more sense

pesterhazy13:06:59

@txus: that does look useful

txus13:06:17

thanks to @leonardoborges for writing it 😄

kachayev13:06:33

Deep technical question about cats library: how can I specify return/pure/mzero context for any record/type that satisfies given protocol?

dialelo13:06:14

@kachayev: cats.core/with-monad sets the context so you can use return et al

dialelo13:06:17

also, return and mzero have two arities and they accept an optional first parameter with the context

dialelo14:06:34

also, for having your own types work seamlesly in mlet blocks you can tell cats their context https://github.com/funcool/cats/blob/master/src/cats/monad/maybe.cljc#L46

kachayev14:06:08

yeah, I did it for own types

kachayev14:06:14

my problem is that I’m working on library that works with records/types provided (not only own)

niwinz14:06:22

As cats implements everything using protocols, use third party types should not be a problem

txus14:06:45

I ran into a strange issue with AOT compilation — I have a Compojure-api app that runs fine, but when AOTing I get: unable to resolve symbol: missing-required-key in this context in the middle of the DSL. There’s absolutely no missing-required-key anywhere, even after macroexpanding, or in the compojure-api or ring-swagger codebase 😞

kachayev14:06:07

@niwinz: I don’t want third party to deal with cats protocols

pesterhazy14:06:17

missing-require-keys: that sounds like prismatc schema, no?

pesterhazy14:06:24

missing-required-key, that is

dialelo14:06:16

@kachayev: so you want to receive values from types you don't own and make them participate in some of the cats abstractions without them implementing the protocols? I'm not sure I understand your question

txus14:06:16

hmm true

txus14:06:20

compojure-api uses schema

kachayev14:06:12

@dialelo: yep. let me share an example

kachayev14:06:13

library that I’m working on helps you work efficiently with remote data sources, and implementation is based on the idea of building declarative AST of everything that you need to fetch from different sources and all functions that you want to apply to the results

kachayev14:06:44

obviously, AST is a monad

kachayev14:06:58

(fmap f AST) -> AST

kachayev14:06:08

(bind AST f) -> AST

kachayev14:06:35

and now I use ad-hoc fmap and flat-map to describe everything

kachayev14:06:22

user have to define only how to fetch data from remote source, using simple DataSource protocol with a single function (fetch [_] _)

kachayev14:06:58

and my fmap knows that AST node can be represented either as MuseAST or DataSource

kachayev14:06:28

I want to make it compatible with mlet/mreturn syntax, and you can see what I did (I defined ast-monad and updated all AST nodes implementations)

pesterhazy14:06:33

kachayev: I saw muse the other day

kachayev14:06:38

and now you can you cats.core/fmap with any AST node, but you can’t do this with your DataSource (only with this value modifier)

pesterhazy14:06:46

it looked interesting, but I couldn't really understand what it does simple_smile

kachayev14:06:06

@pesterhazy: i’m working on better examples!

kachayev14:06:15

will share them when ready

pesterhazy14:06:43

that would be great

niwinz14:06:59

@kachayev: yes, you are right, user defined datasource will not play in cats abstraction

pesterhazy14:06:00

actually transparently grabbing input data from remote locations is a problem I have very often

pesterhazy14:06:24

so from the description it sounds awesome

kachayev14:06:34

@pesterhazy: me too. that’s why I built a library for it simple_smile

niwinz14:06:39

hmm, but I'm not clearly known how we can solve this problem. Maybe a greeat workaround is provide some kind of adapter

niwinz14:06:07

some function that takes a used defined datasource and return muse defined type that already implements all necesary protocols

kachayev14:06:03

@niwinz: yeah, as I wrote in the example you can use muse/value that will create a simplest AST node with your input

kachayev14:06:42

which is not that bad, but requires additional movements from library users

kachayev14:06:10

it would be nice to be able to extend cats.core/get-current-context function somehow...

dialelo14:06:25

definitely, not sure how to open it to extension though

niwinz14:06:54

Some kind of internal registry that allow attach context to a specific protocol

niwinz14:06:26

It need more thought...

dialelo14:06:05

yes, needs some hammock time

niwinz14:06:03

In any case, @kachayev , any ideas, suggestions or troubles, let us know!

scttnlsn14:06:16

Anyone have recommendations for interacting with a SOAP service? Looks like clj-soap is no longer maintained.

kachayev14:06:56

@dialelo: @niwinz I also need some time to “meditate”. will share all good ideas simple_smile

dialelo14:06:14

looking forward to your feedback!

juhoteperi15:06:21

@txus: It is best to avoid AOT with Compojure-api. It is doing too much macro magic.

txus15:06:41

sadly I need to uberjar -> uberimage for docker :S

juhoteperi15:06:42

Related: I set up #C06GSN6R2 for talk about Compojure-api and other libraries using Ring-swagger.

juhoteperi15:06:03

@txus: Just create a wrapper namespace which doesn't depend on your other ns, and does require + resolve in runtime.

niwinz15:06:02

@txus: uberjar does not requires aot everthing

niwinz15:06:14

as far as I know...

niwinz15:06:38

the only AOT required ns is the entry point

dagda116:06:04

is it possible to include the last item using take-while? When the condition is false the current item is not returned

aengelberg16:06:02

(let [p (partition-by pred coll)] (concat (first p) (take 1 (second p))))

kachayev16:06:36

(let [[start end] (split-with pred coll)] (concat start (take 1 end))

aengelberg16:06:38

That would work if you know it starts with some true values

aengelberg16:06:15

@kachayev that would be slightly less performant as two traversals are made (take-while then drop-while)

ghadi16:06:07

@kachayev: see issue CLJ-1451, take-until

ghadi16:06:25

(defn take-until
  [pred coll]
     (lazy-seq
       (when-let [s (seq coll)]
         (if (pred (first s))
           (cons (first s) nil)
           (cons (first s) (take-until pred (rest s))))))))

kachayev16:06:41

@aengelberg: slightly less right, partition-by will also do (drop )

ghadi16:06:42

the ticket also contains the transducer flavor too

ghadi16:06:05

there's a terrible Hive thrift API that forces you to use it, because its chunked resultset implementation has a hasMoreResults method

aengelberg16:06:32

@kachayev good point. partition-by doesn't run the predicate twice per element, though. But yeah, it's probably similar performance.

kachayev16:06:43

@ghadi I never used Hive, but it’s a common situation. I.e. our server-side API produces for mobile clients sequence of items and special “cursor” = id of the next element in a collection, to make next request to get more data (flexible pagination)

ghadi17:06:08

i'm not 100% sold on the take-until name, but don't have a good alternative

aengelberg17:06:04

IMHO, the name implies it's just the opposite of take-while (complements the predicate essentially) even though it has slightly different functionality

voxdolo17:06:03

@scttnlsn did you get a response earlier? just went through this myself.

scttnlsn17:06:32

@voxdolo: No, ended up playing around with clj-soap

scttnlsn17:06:45

Had to fork it to get some things working

voxdolo17:06:05

scttnlsn: so I went the route of generating stub java classes to interact with the service

voxdolo17:06:19

you can use the wsimport tool that ships with java to do this

voxdolo17:06:48

wsimport -keep -extension

voxdolo17:06:14

this will build java classes and then I wrote a light clojure wrapper around them to interact with it

scttnlsn17:06:38

@voxdolo: Okay, I’ll look into that as well. Is there documentation about how to interact with those generated classes?

voxdolo17:06:18

not really anything cohesive

voxdolo17:06:32

googling around "JAX WS clojure" is fruitful though

scttnlsn17:06:44

Okay, thanks

voxdolo17:06:24

though, all said and told, I probably spent a day or two getting the initial wrapper written

voxdolo17:06:34

and it's not been without a few hiccups since then

scttnlsn17:06:59

@voxdolo: Good to know. I may stick with my clj-soap fork until I encounter more trouble.

voxdolo17:06:45

if I understood SOAP better, I'd probably avoid the wsimport-generated java classes entirely, as they're pretty bad Java code and pretty obtuse when trying to grok them

voxdolo17:06:07

it worked though, which was my litmus test 😄

voxdolo17:06:53

@scttnlsn: if you get very far with the clj-soap fork, I'd be interested to hear.

voxdolo17:06:22

and actually, if you need a hand, I'd be happy to lend one… I have a vested interest at this point.

scttnlsn17:06:22

@voxdolo: Minor changes to the way responses are parsed: https://github.com/scttnlsn/clj-soap

scttnlsn17:06:10

Was having trouble parsing responses with a custom type

scttnlsn17:06:26

Now I can defmethod for a custom type and parse the element as needed

arohner17:06:09

is having foo.clj and foo.cljc in the same directory supported, and a good idea?

arrdem17:06:58

arohner: the clj file gets load priority over the cljc file, so ClojureJVM will never load the cljc.

arrdem17:06:43

I think there was chatter about loading both for a bit but that got discarded as having huge issues with load order.

arohner17:06:00

yeah, that would be tricky

hlship18:06:02

Ah, I think I found something:

trptcolin19:06:28

cool! never seen that before.

arohner19:06:33

is there a core.async function like take!, that returns the value? I want to take an item off the queue without blocking, return the value if it exists, or nil

martinklepsch19:06:11

any hot tips for solid slug generation libs? simple_smile

ghadi19:06:19

arohner: poll! coming in version.next

arohner19:06:06

@ghadi: so I’ll have to workaround using e.g. an atom until then?

arohner19:06:34

(let [val (atom)] (a/take chan #(reset! val %) true)) @val_waeselynck)

arohner19:06:48

s/take/take!/

ghadi20:06:24

arohner: i don't know if it is ok for your use-case, that code will throw away the taken value

arohner20:06:44

@ghadi: why is that? I’m sticking it in the atom?

ghadi20:06:03

the atom won't be accessible after the let binding

arohner20:06:24

ah, that’s just sloppiness on my part

arohner20:06:32

if I move the @val_waeselynck over, it works though?

ghadi20:06:34

if the @val yields nothing then is immediately fulfilled, you'll lose the value

arohner20:06:56

ok, so I’m apparently misunderstanding what on-caller does (?)

ghadi20:06:06

you're probably calling that in a loop, no?

ghadi20:06:41

on-caller only applies if the value is immediately available

ghadi20:06:56

if it isn't immediately available, it will happen in the background

ghadi20:06:24

but point being, if a value will appear in the channel, then it will happen

ghadi20:06:37

so that sort of thing is very tricky to reason about

arohner20:06:07

that would have been a very ugly bug down the line simple_smile

ghadi20:06:35

for now an ugly way to do it is with alts!:

ghadi20:06:38

(a/alts!! [(a/chan)] :default :nada)

kachayev20:06:59

@pesterhazy: as I promised earlier.. I added new section “The Idea” to the README file to describe the problem and the solution suggested. Does it make sense? Does it make things more clear?

kachayev20:06:22

there is also a full-functional example with SQL data source & postgres.async

Lambda/Sierra20:06:23

arohner: You can use alt!! with priority and a (timeout 0) as a workaround

Lambda/Sierra20:06:58

Or what @ghadi suggested.

Lambda/Sierra20:06:06

I should really read the history.

niwinz20:06:34

@kachayev: awesome! now is much clearer the first contact.

kachayev20:06:13

happy to hear it!

val_waeselynck21:06:16

@arohner wait, move me over to where?

emil0r21:06:14

are there any circumstances under which component/stop wouldn't run when the entire system is shut down?

emil0r21:06:21

nm... the answer is when you forget to return this

arohner21:06:38

@val_waeselynck: ha, sorry. That was clojure code that slack interpreted as @ val

val_waeselynck21:06:15

Luckily my name's not state :)