Fork me on GitHub
#clojure
<
2016-02-24
>
hugesandwich01:02:51

Does anyone have thoughts on an idiomatic approach for converting to/from Scala types from Clojure? I'm writing some clojure api clients against scala and I can't help but feel that it's a huge pain. Right now I'm dispatching by type on some conversion multi methods to convert things like Some, Map, Iterables, etc. to java types which due to Clojure's design, mostly just work. The issue is I constantly have to write functions that thread input/output through these converters. Just dreadful when compared with working with Java even. Any example code or best practice beyond what I described?

hugesandwich01:02:58

more specifically, I'm using scala.collection JavaConverters and JavaConversions. But maybe there's something out there in clojure already that wraps scala well?

lfn303:02:23

I know a dude I work with (@angusiguess) couldn’t find a good way of dealing with Scala. Idk the details tho. He might have something to offer, aside from tales of eldritch horrors, but he won’t be online for a while.

hugesandwich03:02:09

@lfn3 thanks. Horror tales are also appreciated.

dmitrig0105:02:04

i've used it and it's worked pretty well

hugesandwich05:02:54

@dmitrig01: nope, but just checked it out. Looks a bit uglier than what I have, but looks useful more going to scala. I think going from scala->clojure is more annoying me, but I'll check this out more and maybe something will help.

dmitrig0105:02:36

it's only for scala->clojure

dmitrig0105:02:37

> from-scala provides some syntactic sugar on top of Clojure's Java interop support and some utility functions for directly interfacing with Scala libraries from Clojure.

hugesandwich05:02:54

yes, for calling scala

hugesandwich05:02:24

it looks nice for some things, but not so much my use case

dmitrig0105:02:55

we mean different things by scala->clojure

hugesandwich05:02:20

there's a few things that might prove useful, we'll see

hugesandwich05:02:24

hopefully I won't need it though

michael_at_sosupper08:02:00

Anyone here using Expectations?

jonathanj08:02:39

First I’ve heard of it, looks quite interesting.

michael_at_sosupper08:02:43

(expect) calls seem to run out of order (running after all other code, especially database-changing code, has run)

michael_at_sosupper08:02:55

I like it for non-db stuff, but for db I'm quite frustrated

michael_at_sosupper08:02:50

It's very difficult to structure the code in a way that you won't be testing against a db that's in a different state than what the code would suggest

jonathanj08:02:53

Hmm, I’ve only had a cursory glance through the docs but this seems relevant: http://jayfields.com/expectations/interactions.html

jonathanj08:02:54

(Since creating stuff in your database is a side-effect.)

michael_at_sosupper08:02:55

Ahh I didn't notice that

michael_at_sosupper09:02:26

Thanks for the notice. I'll see if I can use that properly

michael_at_sosupper09:02:38

it seems like a whole lot of extra work to wrap my many db calls. I don't quite get why it doesn't just run the (expect) at the moment it is reached in my code, because at that moment my test would make sense.

michael_at_sosupper09:02:50

but I'll assume it's because I'm new to Clojrue

nha11:02:01

@futuro: I tried compojure, pedestal and I now use yada (I heard that httpkit is in maintenance mode now)

mariogintili11:02:52

is compjure the de-facto web framework for clojure?

nha11:02:28

@mariogintili: kinda yes. I consider it as the easiest to get started.

mariogintili11:02:40

what are the other alternatives??

mostr11:02:07

@mariogintili: luminus is a full-blown web framework

mariogintili11:02:27

@mostr: right, and compojure is more like flask/sinatra

mostr11:02:28

it contains all the stuff (views, routing, persistence, etc)

mostr11:02:51

while compojure is like tiny “adapter” connecting your app to http

mostr11:02:30

so it gives you routing + some bonuses (views, sessions etc), but no structure, no persistence built in etc

sveri11:02:22

I disagree here, luminus is not a webframework

sveri11:02:02

At least not in the traditional RoR sense. It gives you some predefined libs and a structure. There is no upgrade path, no scaffolding, nothing "frameworky".

mostr11:02:20

@sveri: from the page tagline: "Luminus - a Clojure web framework” simple_smile

sveri11:02:58

I know, but it has a different meaning than in the rest of the web dev world

mostr11:02:05

it’s not that feature-loaded as RoR but it is similar kind of thing I guess

sveri11:02:33

Luminus is a leiningen template,

andfadeev11:02:26

i think "framework" in description is just for "marketing" purposes)

sveri11:02:44

Hm, ok, I just looked up the wikipedia definition of webframework and I have to take a step back. Sorry.

mostr11:02:11

ok, I that sesnse I agree that it’s bunch of tools taken together with predefined structure

sveri11:02:13

My point is that I think luminus is easier to take apart, change / fit to your needs than maybe RoR

mpenet12:02:43

yada is worth mentioning too, but it's also not a framework

mpenet12:02:54

compojure-api as well, etc etc

mpenet12:02:47

compojure-api has a confusing name tho, misundertood by many

jan12:02:56

@yogthos: Hi there, sorry to bother you again. I am trying to follow chapter 5 of the book and

clojure
(defn encode-transit [message]
  (let [out (java.io.ByteArrayOutputStream.4096)
        writer (transit/writer out :json)]
    (transit/write writer message)
    (.toString out)))
is giving me a
bash
Exception in thread "main" java.lang.ExceptionInInitializerError
	at clojure.main.<clinit>(main.java:20)
Caused by: java.lang.ClassNotFoundException: java.io.ByteArrayOutputStream.4096, compiling:(guestbook/routes/ws.clj:21:13)
error. Am I missing something?

spelufo12:02:05

Hello, does anyone know if there is any clojure pattern matching library that supports repeated occurrences of a pattern? I don't think core.match supports them. Something like racket's ... or regex's *.

kardan12:02:50

@jan: sure it’s not (java.io.ByteArrayOutputStream 4096) ?

kardan12:02:43

(just a quick guess)

andfadeev12:02:11

(java.io.ByteArrayOutputStream. 4096) maybe? with space

jan12:02:12

@kardan: I was missing a space in there.

andfadeev12:02:33

(java.io.ByteArrayOutputStream 4096) this will not compile

andfadeev12:02:43

(new java.io.ByteArrayOutputStream 4096)

jan12:02:48

thank you very much, you probably saved *hours* of my life

dev-hartmann13:02:04

hey fellow clojurians, is there an equivalent to assoc for lists inside maps?

slipset14:02:06

(update-in m [:key] conj "foo")

dev-hartmann14:02:49

sry, doesn't seem to work

dev-hartmann14:02:59

but i guess the problem is on my side

dev-hartmann14:02:47

{:name "ben2", :email "<mailto:[email protected]|[email protected]>", :password "test", :user_roles ()}

dev-hartmann14:02:03

that's the map i have and i want to update :user_roles

dev-hartmann14:02:29

I'm using korma to get the user_roles, which gives me a lazySeq

dev-hartmann14:02:51

(defn find-user-by-name [name] (let [user (find-user-by :name name)] (update-in user [:user_roles] (find-user-roles (:id user)))))

dev-hartmann14:02:04

that's the function with update-in

dev-hartmann14:02:34

ClassCastException clojure.lang.PersistentList cannot be cast to clojure.lang.IFn clojure.core/apply (core.clj:625)

dev-hartmann14:02:39

that's the error

pbostrom14:02:01

the 3rd arg to update-in should be a fn

dev-hartmann14:02:47

sry, newb here 😉

dev-hartmann14:02:25

the fn would then do a conj on the list?

slipset14:02:53

Since your map is not more deeply nested than it is, you can also use update

pbostrom14:02:55

maybe (update-in user [:user_roles] conj (find-user-roles (:id user)))

dev-hartmann14:02:00

with for the elements of the list i'm getting from find-user.roles ?

dev-hartmann14:02:19

thanks, i'll try!

pbostrom14:02:21

@dev-hartmann: actually you may want (update-in user [:user_roles] into (find-user-roles (:id user)))

angusiguess14:02:09

@nkraft We use hayt and alia

dev-hartmann14:02:38

thanks again, but i'm getting this error

dev-hartmann14:02:39

ClassCastException clojure.lang.LazySeq cannot be cast to clojure.lang.Associative clojure.lang.RT.assoc (RT.java:778)

dev-hartmann14:02:42

maybe the :user_roles list inside my user map is a lazySeq

hugesandwich14:02:53

Does anyone have any opinion/thoughts on pros/cons of doing conversions between clojure, Java, and Scala to/from using multi-methods vs. protocols vs something else? I'm doing some performance critical conversions, but I still need to leave users of my library open to extension which is why I thought of using multi-methods or protocols. Would you expect that for example it would be faster/less overhead to convert a java type to a map with a protocol rather than a multi-method dispatching on type? I figured someone might have hit this, but if not I guess I'll have to profile/inspect what is being generated at runtime... Thanks.

hugesandwich14:02:27

also should note, I don't care about calling via java/scala, this is purely for the clojure users of my code

angusiguess14:02:52

@hugesandwich: It's probably worth trying to measure it but I would expect type hinted deftypes/reifies to be faster?

hugesandwich14:02:28

@angusiguess: Well, I definitely have type hints all around using protcols and multi-methods as well. What I mean is for example a ToClojure protocol vs. something like scala->clj that is a multi-method. For using actual scala/java classes with things like callbacks, I definitely use reify + protocols + type hints which works well. I'm asking more about the former.

hugesandwich15:02:58

basically the same idea, just written a bit differently

hugesandwich15:02:13

for other usages like calling into java, definitely using reify a bit as mentioned

hugesandwich15:02:33

ignore the second snippet, pasted the wrong thing

hugesandwich15:02:00

but general idea is there

angusiguess15:02:20

I haven't tried it, but intuitively I think that the dispatch overhead on protocols should be faster.

hugesandwich15:02:35

I also thought protocols should be faster

angusiguess15:02:36

If you do benchmark the two approaches I'd be very interested to see the results!

hugesandwich15:02:42

Alright, if I get a chance, will let you know. Probably not today but maybe later in the week. I'm knee deep in writing this, but I know I need to refactor the conversions soon so thought I would ask in case anyone has done something like this before and maybe can tell me I am being totally stupid with both approaches simple_smile

mostr15:02:27

@dev-hartmann: doesn’t this work for you?

(def roles (lazy-seq [:foo :bar :baz]))
(update-in user [:user_roles] into roles)

eraserhd16:02:48

I’m drawing a blank - what was the lens-like library that Marick was talking about recently?

eraserhd16:02:21

It had something like SELECT for a function name?

shaun-mahood16:02:37

@eraserhd: Was about to suggest that - he wrote a short book on it recently so figured that would be the one. https://leanpub.com/specter

eraserhd17:02:13

first use case fails? Can’t transform map keys?

eraserhd17:02:22

Perhaps I don’t know what I’m doing.

hugesandwich18:02:56

Is there anything built in that wraps a Java future so I can call a function on it when it returns automatically? I've adapted (stolen) what is in future-call and it works, but I can't help but feel I'm reinventing the wheel a bit. My goal is to return a future that can be manipulated as any future in clojure (IDeref, IBlockingDeref, etc) can and hide the Java library returning the Java future.

kul18:02:28

Interesting thought, i was dealing with java futures a while back and had exact thoughts

kul18:02:10

Not sure if it would be possible to retrofit existing future functions as they dont belong to any protocol

hugesandwich18:02:50

not so far as I can tell.....I just wrote a simple method that passes in the future instead of creates it

hugesandwich18:02:11

it works just fine, but I keep wondering if this isn't a common problem that is better solved some other way

kul18:02:33

Still not sure if extend can help here

hugesandwich18:02:48

that's what I am saying, I can't find anything so far that I could easily extend

hugesandwich18:02:10

but I agree that would be the better course

kul18:02:58

Ok let me know if you find it

hugesandwich18:02:04

will do, thanks

hugesandwich23:02:29

What's the best way to wrap a java object that implements iterable? I'm reifying a class that wraps a Java class implementing iterable, and I'd like to be able to work with it nicely in clojure, and perhaps transduce the output of the java iterable (java classes) to clojure maps. I know about iterator-seq and simply implementing Iterable and returning the original iterator, but neither really seems to be great. Is there any preferred approach for wrapping a Java iterator to make a nice clojure reified object out of it that plays nice and doesn't require an extra function added to my own protocol? Sorry for all the interop questions today, but not finding good info beyond things I already know.