Fork me on GitHub
#clojure
<
2018-12-11
>
eccentric J00:12:01

(defn create-wrap-rebl-sender
  [transport-class]
  (fn wrap-rebl-sender
    [{:keys [id op ^transport-class transport] :as request}]))

eccentric J00:12:38

I’m trying to create a function that dynamically returns a function with a type hint based on the class given as an argument. Any ideas how to make that work?

emccue00:12:52

I forget the exact attribute, but the type hints are carried somewhere in metadata

hiredman00:12:09

no, you can't do dynamic type hints

emccue00:12:37

it wont help the compiler though probably

emccue00:12:13

(what about dynamic on the macro level?)

hiredman00:12:20

type hints are static information that directs the compiler in method resolution, in the dynamic environment (runtime) code has already been generated so it does nothing

hiredman00:12:55

at the macro level maybe, but you shouldn't be dealing in function objects, but forms that evaluate to functions

eccentric J00:12:27

Thanks for the insight. However, I just realized this approach would not accomplish what I want anyway.

datran03:12:52

Is there a way to persist java objects? I'm using a java library for some crypto stuff, and one of the things I need to keep around is a com.codahale.shamir.Scheme, and I'm not sure how to approach storing it.

seancorfield03:12:32

@datran It looks to me like you can easily recreate a Scheme from random, n, and k values? And SecureRandom (the type of random) is Serializable so you should be able to persist that (and the simple values n and k).

datran03:12:50

great point! I'll do that

eccentric J03:12:57

So I want to share the code between the modern nrepl\clojure.deps version with the leiningen version. The implementations are the same but the imports are from different places. How can I share the implementation between the two?

dpsutton04:12:28

@jayzawrotny here's how cider-nrepl does it. https://github.com/clojure-emacs/cider-nrepl/blob/master/src/cider/nrepl/middleware/version.clj#L6 Waiting on a leiningen release and then slim it down to only one.

dpsutton04:12:53

it gets hairy making sure the piggieback/nrepl/figwheel versions are all nrepl aware through the whole eval chain

eccentric J04:12:54

That’s perfect, thanks so much!

datran04:12:32

@seancorfield do you know where I can learn more about Serializable (protocol, I assume)? I'm new to java interop and I'm not sure where to look for documentation about that

datran04:12:38

ah, I found it, it's a Java interface

datran04:12:27

okay, so it looks like you convert it to an ObjectOutputStream and then to a byte stream.

idiomancy05:12:06

is there some way to manually close a go-loop? it's not hitting the recur path, but its also not closing. 😕

idiomancy05:12:50

oh wait.. actually, I think I get why it isnt

Saikyun10:12:03

are there any articles on implementing a frontend talking to nrepl? is it hard? 😮

noisesmith17:12:05

to see an example, there's technomancy's grenchman project. He also has a frontend in fennel (a lisp on top of lua) but I don't recall the name off hand

Audrius10:12:27

Can spec detect duplicates in some nested map fields? like 'city_id' should be unique in nested maps. Can it be done with spec?

taylor10:12:12

Yes, you can use arbitrary function predicates as specs

Saikyun10:12:02

@masta maybe you can use spec with https://github.com/nathanmarz/specter ? 🙂 you might be able to select then count

Saikyun10:12:21

haven't used specter myself, but it sounds like the kind of use case it'd be good for

idiomancy17:12:42

oh man, you gotta try it. you don't know what you're missing

Saikyun10:12:48

or I guess a zipper might work as well 🙂

erik12:12:40

using spec.alpha and spec.gen.alpha, I get:

> (gen/such-that #(not= "" %) (gen/string-alphanumeric))
AssertionError Assert failed: Second arg to such-that must be a generator
(generator? gen)  clojure.test.check.generators/such-that (generators.cljc:346)

Alex Miller (Clojure team)12:12:57

The spec.gen.alpha combinators take generator thunks, not generators (to allow a hook for dynaloading)

Alex Miller (Clojure team)12:12:54

I can’t tell from what you’re doing if you are using spec gen or test check gen, or a mixture

Alex Miller (Clojure team)12:12:46

But they differ in this way

erik12:12:01

spec and spec.gen only

erik12:12:12

how would I use spec.gen.alpha/string-alphanumeric with spec.gen.alpha/such-that then?

Alex Miller (Clojure team)12:12:13

(gen/such-that #(not= "" %) #(gen/string-alphanumeric))

Alex Miller (Clojure team)12:12:09

I’m on my phone, so can’t check this but that’s what I would expect

erik12:12:33

> (gen/such-that #(not= "" %) #(gen/string-alphanumeric))
AssertionError Assert failed: Second arg to such-that must be a generator

erik12:12:18

...weird, it works now using just (gen/string-alphanumeric)

Alex Miller (Clojure team)12:12:40

ok, opened a repl. I was wrong about the function wrapping - the spec gen string-alphanumeric returns a function so it was right originally

Alex Miller (Clojure team)12:12:43

user=> (gen/sample (gen/such-that #(not= "" %) (gen/string-alphanumeric)))
("32" "8" "Z" "IkcC" "eLq" "n" "87nE" "edj" "166k" "E2")

Alex Miller (Clojure team)12:12:21

if you were using the test.check.gen, I think you would want

(gen/such-that #(not= "" %) gen/string-alphanumeric)

erik12:12:25

alright, thanks. I wasn't using test.check.gen, but apparently it "leaked" in somehow, then

restenb14:12:41

anybody familiar with the built-in http client in re-frame? or cljs-ajax as it's heavily based on that?

restenb14:12:24

i want to know what the correct configuration map for a post request uploading a pdffile ought to be

lvh15:12:03

Hi; I'm trying to get in to thi-ng/geom since my dog ate my geometry/woodworking notebook. One of the first things I'm trying to do is "create a line, then create another line constrained by a shared point and an angle between it and the first line". Is that something geom is good at, or am I thinking too much like CAD-style constraints here? (I know how basic trig works; but if you're familiar with how CAD usually works then you probably know why basic trig isn't the answer :-))

aisamu16:12:39

Yes, I believe what you're trying to achieve is the job of a constraint solver, which might not be present in geom

lvh15:12:30

I'd really like to do Clojure CAD but the Nice(TM) CAD program is Fusion 360, and they deprecated JS scripting, leaving C++ and Python. Despite knowing a fair bit of Clojure + JNR I have 0 intention of dealing with a C++ API being called over the C ABI from JNR, because this was supposed to be fun 😉

shaun-mahood16:12:04

You could always use OpenSCAD (starts at about 17:30 in) https://www.youtube.com/watch?v=uk3A41U0iO4 🙂 AutoCAD still has an active JS API (https://df-prod.autocad360.com/jsapi/v3/docs/contents.html), or you could always try ClojureCLR for it - but I have no idea if what you're trying to do can be done there or not. If you can get useful geometry/woodworking CAD working in that would be way cooler, though.

lvh16:12:56

Yeah, I looked at that a while ago, one of the things I don't love is that I'm not really trying to produce, like, an STL I can go 3D print per se: I'm trying to produce sketches for my notebook, so lots of dimension lines and labels that are helpful for when I take it to a tablesaw. OpenSCAD AFAICT doesn't do that at all. (Not a criticism! It's a solid modeler by defintion and I think the punchline is just "what you wanted is a lot closer to dr geo than openscad".)

lvh16:12:30

Oh hey, apparently someone wrote that for OpenSCAD: https://www.thingiverse.com/thing:280469

shaun-mahood16:12:41

Yeah, OpenSCAD is also pretty unpolished if you are used to something more commercial - I tried playing with it when I was thinking of building a Dactyl and by far the coolest part was how much work went in to use Clojure with it 🙂 I found the time it took to render (at least for the Dactyl) really painful, but that might just be for a more complicated model. I couldn't find anything that jumped out at me as any better (QCAD or TinkerCAD seem at least have a usable JS API, but everything else I could find or know of would be a pain to get to work with Clojure).

lvh16:12:56

i also have a hard time believing that "spit entire model file, load from scratch" is a great idea when you have something non-trivially sized

shaun-mahood16:12:25

Yeah, definitely. Just put in a talk proposal for next Conj “Writing a CAD Program for Woodworking in Clojure” (which I’m sure would be automatically accepted) and then you’ll have something nice to use right after the talk is due.

Daouda19:12:42

hey guys, can you guy help me with good clojure libs for working with graph algorithms?

Daouda19:12:07

libs for graph

semperos21:12:39

and depending on your exact needs, https://github.com/Engelberg/ubergraph supports some additional graph features on top of what Loom does

Lennart Buit21:12:25

Oh loom looks cool

Lennart Buit21:12:40

I had manually written some graph algorithms already

the2bears22:12:00

We've had great success with Loom. The core of my project is a DAG, thus making Loom a very key library.

Daouda19:12:32

thank you @the2bears?)

👍 4
khardenstine21:12:22

Is there anyway to use aliases on a local procurer in deps edn? e.g. parent project foo depends on {:local/root “bar”} but also wants to include alias “baz” from bar

Alex Miller (Clojure team)21:12:18

aliases affect the set of dependencies to resolve, so there would be a bit of a logical cycle if aliases affect dependencies and dependencies affect available aliases

Alex Miller (Clojure team)21:12:09

so there are no plans to support a way to use aliases from transitive deps

khardenstine21:12:58

thanks. sounds like I am barking up the wrong tree to be generating multiple builds/artifacts within one deps.edn file

istvan21:12:00

is the the right chan to ask about java interop?

istvan21:12:11

i am going nuts over java static methods and clojure

hiredman21:12:00

are you trying to call a vararg java method?

istvan21:12:04

Clojure does not even sees the static method does not matter if i implement it in Java or Clojure

hiredman21:12:31

that isn't a static method

hiredman21:12:48

or it is, but it also isn't

hiredman21:12:32

EchoHandler::handleEcho isn't a static method, what happens is javac looks at the type and generates an adapter from the interface expected to call the static method

hiredman21:12:47

(it is a SAM, single abstract method)

hiredman21:12:35

so you need look at the docs to figure out which interface the .json method takes, and use reify to create an instance of that interface which invokes whatever static method

hiredman21:12:49

(I would avoid the static method stuff and just have it invoke whatever function)

istvan21:12:54

alright, i would just ivent a time machine and fly back to 1995 and murder the guy who created static, abstract, single abstract and co

istvan21:12:19

how would you avoid this entirely?

istvan21:12:27

i just need to look into .json?

hiredman21:12:35

the EchoHandler::handleEcho syntax for automatically generating the adaptors is newish (maybe in java 7 or 8)

istvan21:12:43

yes it is java 8

istvan21:12:17

problem is that Clojure did not keep up with these and in the interop there is nothing about it and nobody talks about how should we do these

istvan21:12:31

few scratches in stackoverflow

hiredman21:12:55

my standard spiel is clojure doesn't have java interop, clojure has jvm interop

hiredman21:12:09

every place java the language and the jvm differ, clojure exposes what the jvm does

hiredman21:12:40

in this case the sam stuff is all generate by the java language compiler and the jvm doesn't have anything special to support it

istvan21:12:41

right, unfortunately people write Java code and we need to use these in Clojure

hiredman21:12:08

sure, and java runs on the jvm, so you can do that just fine

istvan21:12:19

public void json(ReqHandler handler) {
		HttpHandlers.register(http, routes, verb, path, jsonOpts(), handler);
	}

istvan21:12:25

this is the json method

hiredman21:12:33

you just have to use the common denominator which is the jvm

hiredman21:12:45

ReqHandler is the interface you have to implement

istvan21:12:57

public interface ReqHandler extends OneParamLambda<Object, Req> {

	Object execute(Req req) throws Exception;

}

istvan21:12:36

can i simplify this somehow in Java and have a small amount of Java code so that Clojure has a better time?

istvan21:12:03

lein is happily compiling Java sources in the same repo

istvan21:12:16

@hiredman thank for the help i am looking into implementing this with reify

lwhorton22:12:50

what are people using nowadays to package up and deploy an app? i’ve seen some combination of thin jars, uberjars, tools like deps-star, cambada, etc.. i’ve also read about strategies to make thin jars and upload each individual dep into a heavily cached system (like https://github.com/HubSpot/SlimFast). just curious what’s been working for people and what’s a real pain. (for example, cambada uberjar worked great until I added a dep that used a signed jar, and now uberjars aren’t going to work without some filtering mechanism)

flefik22:12:25

always docker 🙂

nickmbailey22:12:10

uberjars inside of docker

flefik22:12:17

that's what I do to

lwhorton22:12:23

in what sense? do you just upload a dockerfile and not bother with a jar? or do you put an uberjar inside a docker file?

nickmbailey22:12:07

my dockerfile is responsible for building the uberjar, the final docker image that is output just has an uberjar and java and runs that

lwhorton22:12:23

FROM java:8-alpine

WORKDIR /app
COPY target/*standalone.jar .

CMD java -jar *standalone.jar
right now that’s what i’m working with, but i wonder if there’s some way to not have to ship MBs of dependencies all over the network

flefik22:12:28

i use something like

FROM alpine:latest AS build
RUN apk add java...
RUN boot build uberjar

FROM alpine:latest
RUN apk add jre
COPY --from=build uberjar /app

nickmbailey22:12:01

yeah i have lein but pretty much the same

lwhorton22:12:11

cool, so seems like we’re on the same page

nickmbailey22:12:16

@UAEFFG05B do you build docker images in a CI environment?

nickmbailey22:12:45

i currently have an issue where my builds on circleci are always redownloading deps

flefik22:12:48

yes, currently use a mix of dockerhub with hooks (terrible) and travis or gitlab

nickmbailey22:12:10

i've been trying to decide if i should mount in a cached m2 dir as volume

flefik22:12:37

what is the benefit you would get from that?

lwhorton22:12:37

have you tried circleci 2.0 caching?

nickmbailey22:12:34

not redownloading dependencies from the internet on every build

flefik22:12:08

so to get around installing your deps you can do something like:

FROM alpine:latest AS build
COPY deps.edn /app
RUN ... install deps only
COPY . /app # copy rest of app
RUN lein uberjar

flefik22:12:50

that way you will only need to reinstall your deps if that first COPY layer has changed

nickmbailey22:12:54

@U0W0JDY4C i enabled docker layer caching in cirlce ci (have to pay for it) which helps some

lwhorton22:12:54

between a pom file and caching dirs on circle we’re getting pretty good caching, just make sure to pre-fix your cache keys with v1 for emergencies

- save_cache:
          key: v1-deps-{{ checksum "pom.xml" }}-{{ .Branch }}
          paths:
            - ~/.m2
something like that

istvan22:12:06

Uberjar -docker

nickmbailey22:12:32

@UAEFFG05B the problem with that approach is my project.clj file changes on most builds cause the version gets bumped. maybe if i switched to deps.edn that would solve my issue. haven't figured out how well that plays with lein

istvan22:12:33

@U0W0JDY4C do you use slimfast with Clojure?

lwhorton22:12:04

@U49Q4205T no, i was just looking to it for inspiration. i didnt want to tangle with mvn at all avoidable

nickmbailey22:12:17

@U0W0JDY4C yeah i use the circleci cache like that which is good for test run jobs, but docker builds i'm not currently mounting that .m2 cache into the docker file as a volume

👍 4
lwhorton22:12:28

but this https://product.hubspot.com/blog/the-fault-in-our-jars-why-we-stopped-building-fat-jars pretty clearly explains the issue with big-fat-jars floating around your network (especially on a big team)

flefik22:12:08

@U0K6PH6TU sure that makes sense. we use boot, so that isnt an issue and we never build anything other than 0.1.0-snapshot 🙂 .. the git commit SHA is our version number

istvan22:12:05

this is why i spend hours on exclusions in my project.clj

istvan22:12:20

basically for every opensource project i have an exclusion list

nickmbailey22:12:32

@UAEFFG05B yeah maybe i need to switch to boot and deps.edn heh

lwhorton22:12:39

i’ve so far been able to skip boot/lein entirely on my latest proj, getting by with just deps and some shell/make

flefik22:12:34

that works for lein?

nickmbailey22:12:06

that would definitely solve my problem

nickmbailey22:12:07

well. assuming it plays nice with lein-nvd and other plugins

flefik22:12:40

i hope it works out!

dominicm08:12:03

Slimfast is almost identical to packs skinny jar mode

dominicm08:12:05

I considered adding a feature for what slimfast does, but it's a bit pointless, because you can just do this with a jvm newer than 5: -cp 'lib/*' when starting the JVM