Fork me on GitHub
#clojure
<
2017-04-12
>
lincpa00:04:07

@qqq using luminus,hiccup(html),cljs(ui event),http-kit(web server),websocket(c/s interact)

lincpa00:04:44

my project make desktop webapp using the teach stack on Windows.

lincpa00:04:04

chrome portable edition as ui-lib

lincpa00:04:35

and with postgresql + R portable edition.

lincpa00:04:45

for db,dataanalysis,datavis

darwin00:04:13

@qqq maybe you could write some Clojure macros which would take your Clojure code and emit ClojureScript 😉

Alex Miller (Clojure team)00:04:43

@hiredman it's not dead and it works pretty well with Clojure

john00:04:43

there you have it

john00:04:57

^ runs a webview

qqq00:04:26

@darwin: to avoid confusion with the official cljs compiler, I should name mine dirac-devtools :-

john02:04:03

I'm trying to make two functions - one calls the other - both of which can take a varying amount of arguments. How do you unquote-splice incoming arguments that get wrapped in a list?

john02:04:49

unquote splice while not in a macro, I mean. I usually use apply, but I'm having trouble doing that with two functions in a row

noisesmith02:04:24

do you want apply?

noisesmith02:04:13

if the first uses varargs, you can apply the second to the varargs

john02:04:15

Yeah, I'm just getting confused with two consecutive functions, because the arg is getting double boxed by the second call.

john02:04:34

Trying to whip up a minimal example

john02:04:57

Disregard. My error is not coming from that issue.

john02:04:06

@noisesmith how do you send forms to clojurebot?

noisesmith02:04:23

use the /clj command

beatboxchad02:04:36

/clj (println "booya!")

beatboxchad02:04:48

hmm I don't know how to slack apparently

john02:04:30

she had to get to know you first

beatboxchad02:04:40

I'm the same way

john02:04:06

ah, what was the trick?

beatboxchad02:04:13

No idea. haha

beatboxchad02:04:34

just didn't take the first time. I don't see a typo up there

john02:04:48

yeah 😕

beatboxchad02:04:57

the mysteries of life.

john02:04:33

where do all the nils go? We may never know.

beatboxchad02:04:38

yo @noisesmith I think I just un-borked that macro! bout to fire up the SuperCollider server and give it a shot, make sure I didn't break its actual functionality. It's still offensive in its form, I just teased out the recursive calls into another macro. I'll have to do some thinking before I figure out how to make it a less dirty trick

beatboxchad02:04:25

but no more stack overflow

beatboxchad02:04:27

thanks again for the boost earlier. I ran into that actually like a month ago but I was in music-playing mode and it was just a total gumption killer

noisesmith02:04:25

I've been doing music with software myself, but I use a raspberry pi which only has so many resources and I want to make the hardware do a lot, so for me it's OCaml (for all the midi / ui) and csound (for all the DSP)

beatboxchad02:04:11

I really oughta check out csound sometime. I didn't get really started in earnest till about, I dunno, 18 months ago, so I'm just leveling from a steep learning curve. I've wanted to do stuff like this for EVER, it was the whole reason I learned to code at all

beatboxchad02:04:52

what kinda stuff you doing?

beatboxchad02:04:10

are you like, playing out with it or aspiring to?

noisesmith04:04:24

yeah, playing out pretty regularly, with electric upright bass and raspberry pi and a PA

noisesmith04:04:09

had a big first recently, my sound system was officially too loud for the club where I was playing - which is hilarious given they had over 4kw of amplification (which I was not using) and I was just playing through my 1.5kw setup

john02:04:15

both your usernames check out

beatboxchad02:04:23

haha i was just thinking that

beatboxchad02:04:20

there's this ambient artist loscil whose name comes from a csound function. It's been on my radar since I read that a couple years ago

beatboxchad03:04:35

booya yup it works

wottis03:04:33

does someone know a larger project (present on github) that uses clojure.spec? I want to see how spec is really being used. All of the small, and simple repl example can't answer the questions i have.

donaldball03:04:27

clojure.java.jdbc uses it for some things

donaldball03:04:24

I’m not sure there’s enough usage in the wild yet for anyone to make a claim to idiomatic spec usage yet tho

seancorfield03:04:56

Yeah, it's kinda hard since most real world Clojure projects have not yet moved to 1.9.0 Alpha builds.

seancorfield03:04:56

And even while we're on 1.9.0 Alpha 14 in production at work, we don't actually load the (optional) java.jdbc spec namespace, even in testing at the moment.

seancorfield03:04:28

We're using clojure.spec for validation and conforming REST API input parameters (primarily) and only gradually branches out beyond that.

seancorfield03:04:22

We have a few bits of test.check usage in our test suites. We are starting to spec more and more things tho' so gradually it'll be the default approach...

benbot04:04:53

Can you tell me some bad things about clojure? I've been messing with it and it seems pretty good, but I'm sure i'm missing some dragons.

benbot04:04:13

What are some development pain points that some of you have run into?

noisesmith04:04:30

high startup time high ram usage with idiomatic code (using immutable data strcutures for everything) it can be easy to make ad-hoc designs that are hard to refactor it's possible to make high performing math heavy code for tight loops, but much easier to just write that part in java (some people might not consider this a minus)

seancorfield04:04:43

Since I write server processes, the startup time isn't an issue. I don't find RAM usage high for Clojure compared to any other JVM languages. I haven't found code harder to refactor than other languages.

seancorfield04:04:53

I've been using Clojure in production for six years.

noisesmith04:04:03

I'm trying my best to think of minuses here 😄

seancorfield04:04:34

I think Clojure shares all the same minuses as all other JVM languages -- the JVM itself, if you think it's a minus.

noisesmith04:04:35

I like using clojure, I still do - and in all fairness the bad design is 100% on me - but when I use a strongly typed language I find my own designs easier to refactor

benbot04:04:46

@seancorfield so after 6 years you must have run into some pain points

seancorfield04:04:13

@noisesmith Clojure is strongly typed -- but dynamically so. I assume you mean statically typed, rather than strongly typed.

seancorfield04:04:51

@benbot The pain points are more around getting devs up to speed on idioms and (some) tooling.

noisesmith04:04:27

I suspect that if it was strongly typed I wouldn't run into code that breaks becomes someone was calling merge on a vector and until recently it worked on accident.

elena.poot04:04:49

I agree with that, as the only clojure dev so far in my shop. A few others are learning, but the learning curve is sort of steep. (Not so much just learning to be able to write code, but learning to write good idiomatic clojure)

seancorfield04:04:50

Clojure is strongly typed. I think maybe you're misunderstanding the terminology?

benbot04:04:16

I want to try using clojure for a more serious project and I just keep hearing really good things and no bad things about it

benbot04:04:26

that's either a really good sign or a bad one 😱

benbot04:04:50

I don't really think the jvm is that bad, and I haven't heard anything bad about java interop

lincpa04:04:52

I write desktop app, clojure-clr (.net winform) clojure desktop webapp (luminus) , more than 40k lines clojure code , clojure is very good!

noisesmith04:04:22

@seancorfield the docs say that merge takes hash-maps, but it turns out you can hand it vectors and numbers and then it works until it mysteriously doesn't - maybe that's not about typing, maybe that's just lack of contract enforcement.

seancorfield04:04:41

I will say that our early Clojure code wasn't very idiomatic so it didn't really benefit from what Clojure offers -- and that took a while to fix.

elena.poot04:04:01

yeah, my code keeps getting smaller as I learn more. 🙂

seancorfield04:04:19

@noisesmith If you write code with undefined behavior, then it will have undefined behavior -- that's true in statically typed languages too.

seancorfield04:04:06

Some people just prefer static typing -- it sits better with the way they think -- and other people prefer dynamic typing.

elena.poot04:04:51

IMHO, it "feels" weakly typed if you come from an OO language, because it's values that are typed, not variables, which there really aren't any. I'd say data being the wrong "shape" is my biggest source of error. But of course, the data is what it is, I just built it wrong. But in an OO language, you'd assign it to something and that would be caught at compile time.

benbot04:04:35

So what i'm getting is that the main issue is you need to really understand clojure for it to be as good as people say?

seancorfield04:04:39

@terry.poot Very few languages are weakly typed. C is the classic example. Folks need to be more precise about terminology.

seancorfield04:04:52

Ruby is OO and it's dynamically typed.

seancorfield04:04:19

@benbot Yes, learning the idioms is key.

elena.poot04:04:37

OK, I'll cop to being not so good on terminology. And I'm coming from c based languages (C# most recently).

seancorfield04:04:52

My background: professional development for 35 years, background in programming language design and compilers (my PhD was Functional Programming Language Design and Implementation). I co-wrote the first ANSI-validated C compiler and was on the C++ Standards Committee for eight years in the 90's. So I might be a bit pedantic about terminology 🙂

elena.poot04:04:27

If you sit on standards committees, I'm sure it's a requirement 🙂

seancorfield04:04:41

Yeah, unfortunately 😐

seancorfield04:04:43

Part of the problem with static type systems in most languages is that they're terrible (C++, C#, Java). Haskell and Idris are good. Scala is ... intermediate.

elena.poot04:04:01

professional developer for 39 years, fortran -> C -> C++ (briefly) -> horrible microsoft basic garbage -> java (briefly) -> c# -> clojure

seancorfield04:04:39

Back to @benbot's question... in addition to the idiom and tooling challenges (Leiningen is wildly popular but Boot is far more powerful; and dealing with ClojureScript is still a bit of a moving target), there's also the issue of workflow -- the most effective ways to use Clojure are very different to how you use most other languages (with a handful of exceptions)...

seancorfield04:04:01

@terry.poot So... how "typed" is MS Basic? Can't say that's something I've used (but other Basics always felt dynamically typed).

benbot04:04:15

Can you expand a bit on that boot vs lein thing? I haven't really used clojure that long to I haven't run into any pain points in lein yet

noisesmith04:04:31

@seancorfield I accept your correction about "strongly typed", I was using the term wrong. I need to be more precise about the kind of errors I am talking about. Some examples: calling rest on a PersistentQueue, getting back a seq, from that point on what the author though was a fifo is a lifo using (-> m first second) to access the first value in a hash map, it's totally opaque why the code broke the first time a hash map with two entries came in it could be that these are signs of dealing with a team that doesn't know clojure until learning it on the job, but languages that advertised that they were "strongly typed" tended to have functions that were stricter about how they were used (in a way that goes beyond just static type checking) and avoids a lot of the entry level errors.

elena.poot04:04:22

@seancorfield most of the basic stuff I did was in access or excel, and mostly you're interacting with framework objects that are really COM objects written in C++, so that's pretty strongly typed. basic itself, is pretty loose I think, but you don't end up doing much with it that doesn't directly interact with those objects.

seancorfield04:04:03

Sure, Leiningen uses a declarative approach -- project.clj -- and specific plugins to provide functionality, but it's hard to "script" it when you're trying to construct a complex build process. Boot tasks are "just" Clojure functions, so it's easy to write new pieces of your build process.

seancorfield04:04:31

Our Boot-based build process has all sorts of custom tasks now, including on-the-fly module dependency analysis, and even building Docker images. Stuff we couldn't reasonably do with Leiningen.

elena.poot04:04:18

How is boot to get started with? Lein is easy to get up and running fast.

seancorfield04:04:45

Boot is a lot easier now than it was 🙂

benbot04:04:04

Apparently

seancorfield04:04:15

I wrote a series of blog posts about it, as I learned it, wrote boot-expectations, boot-new and so on.

seancorfield04:04:13

@noisesmith Yeah, I think those things are symptomatic of not being sufficiently familiar with the Clojure abstractions... taking a hash map and doing first and then second is pretty weird: hash maps are inherently unordered so first is a random operation and second relies on MapEntry being a vector -- it's more correct to use key and val there (and Alex Miller berated me about exactly that just the other day! 🙂 )

noisesmith04:04:31

right - and they were using repl based development and they always got a one element hash map in the early state of the app, so the (-> m first second) thing remained - and as a result there was no clue in the code that the value coming in was a hash-map

elena.poot04:04:42

that's a bit confounded by the fact that treating a map as a seq of key/value tuples is perfectly legit

noisesmith04:04:43

(until you deeply investigate the caller etc.)

noisesmith04:04:01

it's legit, and also completely implicit

noisesmith04:04:13

as with turning your queue into a list because you asked for the rest

seancorfield04:04:32

As for rest on a queue (or any collection type), the docstring is pretty clear that it produces a seq -- an abstraction. That's definitely one of the gotchas for folks new to Clojure: learning what works on collections vs what works on sequences, and what results you get from each operation.

noisesmith04:04:33

at it's best clojure tends to prefer explicit over implicit, but around sequential collections there are some gotchas

elena.poot04:04:55

early on the biggest issue I had was seq vs vector, and having vectors change into seqs when I wasn't expecting it (which was certainly a learning curve thing)

elena.poot04:04:12

so I kept conj'ing things onto the wrong end 🙂

noisesmith04:04:27

worst thing is the author there had known clojure well longer than I had (he first taught me clojure!) but he wasn't solid on some of the basics like "seq" abstractions, having come from common lisp and assuming he didn't need to read the basic docs

elena.poot04:04:05

one of those cases where being a complete noob can be an advantage

seancorfield04:04:00

Yup, def. agree that stuff can be a big stumbling block when learning Clojure /cc @benbot -- some good examples of the "bad" things here

john04:04:06

I personally don't understand the whole "steep learning curve" stigma. For my brain, clojure was the easiest language I've ever tried to learn.

elena.poot04:04:24

was it your first functional language?

john04:04:32

on the other hand, there are a few powerful functions in clojure I have hard time wrapping my head around.

elena.poot04:04:43

because I think "functional" is a large part of the learning curve for me

john04:04:09

I started on java, but OO never stuck in my head.

elena.poot04:04:26

there's a lot of things in clojure I haven't learned yet. I'm sure my code would be better if I did, but the nice thing is I'm quite productive even so.

benbot04:04:56

@seancorfield I've been watching 🙂

elena.poot04:04:01

The most surprising thing about OO for me, in hindsight, is how little you actually use all the touted advantages of it (inheritance, polymorphism, etc.)

benbot04:04:44

I think it's because those advantages work as long as you don't reference a class from within a class

benbot04:04:00

the guy who made smalltalk wrote about it a bit.... i think

seancorfield04:04:08

@terry.poot A less charitable interpretation would be that the promised advantages were... false promises... 🙂

elena.poot04:04:16

Well, to be fair, you use the heck out of them if you're building a framework or large library (if you do it right). Just not so much as a consumer of those things

noisesmith04:04:02

clojure uses all the good parts of OO extensively though - message passing, implementation of interfaces, ad-hoc polymorphism

elena.poot04:04:20

yes, that kind of surprised me, actually

benbot04:04:40

idk after working in OO land for like 10 years, I wrote something in elixir with the pipe syntax and there was a moment where I was thinking "This is how software should be written"

benbot04:04:03

@noisesmith I think that's a lisp-y thing

noisesmith04:04:10

they were just emphasizing the wrong features of OO - the good parts are already mainstream in fp

firstlast04:04:12

Youtube comments of all the places for an insightful discussion about FP vs OOPS : https://www.youtube.com/watch?v=7Zlp9rKHGD4&amp;lc=z13ayfapqqv4s1aq404cizhatoriy3ayvjo

seancorfield04:04:16

@terry.poot Well, OO as we know it in most modern languages is not what the original designers had in mind. And it took decades of "pattern" research to fix up a lot of the problems. For example, the J2EE Design Patterns book is almost entirely about fixing bad Java code and overcoming shortcomings in the language or its ecosystem...

benbot04:04:47

Yeah but I think the original OO ideals died before I was born 😕

firstlast05:04:02

We should probably move this discussion to #off-topic since this isn’t strictly Clojure related

seancorfield05:04:07

When I got started, I did FP at uni, then assembler and COBOL in the real world, then C, C++, Java -- while watching Haskell appear and evolve (and hoping it would take over the world!) -- and then Groovy, Scala, and then Clojure... as we started to see FP concepts surface in multiple languages.

benbot05:04:09

From what i've heard, smalltalk was one of the only languages that did OO according tot he original ideas

john05:04:14

When OO conflates with state - where uncoordinated state is spread across different places - problems. Immutable OO = fine

seancorfield05:04:42

@firstlast Yeah, you're probably right -- we are indeed #off-topic (as late night #clojure discussions tend to be!)

firstlast05:04:36

I enjoyed reading it nonetheless !

wottis05:04:46

clojure was my first functional language and thus needing a change in mindset, which required some time. i also experience that here with other devs i introduced to clojure.

wottis05:04:08

but once they saw the benefits their python code also changed quite alot 😄

benbot05:04:18

@wottis hop in #off-topic we're all talking in there now 🙂

jimmy06:04:02

I have problem with fat jar deployment and docker build. Is there any good guide to cache the lib jars so we can make the build faster ?

noisesmith16:04:56

any maven dep is cached locally in $HOME/.m2/repository/ on a per-user basis - perhaps theres a straightforward way to pre-populate that directory in your image

hit02306:04:10

As a solution to this problem: https://www.4clojure.com/problem/59#prob-title , why doesn't this work?

jumar07:04:27

@hit023 not sure what exactly doesn't work for you but I'd say that the problem is that you return the result sequence in reverse order

jumar07:04:47

you can use conj for appending to the end of result vector (`y`)

jumar07:04:00

(defn comb [& funcs] 
  (fn [& args] 
    (loop [x funcs y []] 
      (if (empty? x) 
        y 
        (recur (rest x) (conj  y (apply (first x) args)))))))

jumar07:04:13

otherwise it looks ok to me

hit02308:04:59

Oh! Okay. Thanks, @jumar .

thandogqwabaza08:04:03

anyone have a clojure friendly .emacs for me to use

thandogqwabaza08:04:28

new to clojure and emacs

andrea.crotti08:04:26

@thandogqwabaza hehe depends what you mean by friendly

andrea.crotti08:04:14

and with that I get everything I need really

andrea.crotti08:04:23

but it's not self contained

jumar08:04:23

@thandogqwabaza if you are starting with clojure and emacs, give the spacemacs a try: http://spacemacs.org/

jumar08:04:28

it really makes a difference

jumar08:04:52

I tried various options like Emacs Live and vanilla emacs, but so far the spacemacs is the best one

yonatanel08:04:57

@nxqd The clojure:*onbuild Dockerfiles add a caching layers that are invalidated only if project.clj (dependencies) or files change: https://github.com/Quantisan/docker-clojure/blob/f0fd68d6a197b4d1852aefab698b35ce1ea9881e/alpine/lein/onbuild/Dockerfile But that's just one way of doing it. I saw something where a build server plugin lets you cache maven dependencies on S3 etc.

camdenclark09:04:27

Am I missing out on anything by using atom and/or vim with a REPL jack in?

camdenclark09:04:32

yeah, I already installed it and watched that talk last night, it’s kind of amazing. Still trying to get around and use all the keybindings.

yonatanel09:04:29

@camdenclark I'm using Intellij with Cursive plugin. I'm already used to Intellij from previous life and it's easier for other team members who used it, and I can work on our node projects in the same IDE. Not sure you're missing anything because I never tried atom or emacs.

camdenclark09:04:40

I’m coming from a background of basically only using the jupyter notebook and vim for any serious editing. I tried to use IntelliJ but I think I’m too stupid for an IDE with lots of features like that.

andrea.crotti09:04:40

I just noticed this in Clojure source code

andrea.crotti09:04:43

(defn qualified-keyword?
  "Return true if x is a keyword with a namespace"
  {:added "1.9"}
  [x] (and (keyword? x) (namespace x) true))

andrea.crotti09:04:49

what's the third true for?

andrea.crotti09:04:23

isn't (and (keyword? x) (namespace x)) the same thing?

quan09:04:39

@camdenclark gorilla-repl is similar to jupyter notebook http://gorilla-repl.org/

camdenclark09:04:20

mmm that looks excellent thanks

bronsa09:04:26

@andrea.crotti it's to avoid returning the namespace rather than a boolean

bronsa09:04:48

(and (keyword :foo/bar) (namespace :foo/bar)) would return "foo"

andrea.crotti09:04:13

ahh I see good point

andrea.crotti09:04:22

same as somethinig like this (and (boolean nil) (boolean "string"))

andrea.crotti09:04:30

but I guess that's more idiomatic

matan10:04:50

new Java project, might sprinkle some clojure on top after the core is ready. should I have a better time with Gradle or Maven? skipping leiningen as I assume little eclipse integration.

mbjarland10:04:10

my vote is definitely on gradle

yonatanel10:04:53

Would a pure clojure kafka client be useful?

matan10:04:23

@yonatanel what are the alternatives?

matan10:04:47

I mean how bad are they to use (from clojure)

yonatanel10:04:07

I was hoping you tell me

matan10:04:29

All I can say is a Kafka written in clojure could be nice. No comments to a Kafka client, sorry.

mpenet10:04:59

heard good things about gregor and kinsky too

matan11:04:47

Really, Kafka was written in scala under a pure use-scala-as-plain-java coding discipline (so, the worst of both worlds). A clojure implementation for streaming could be much nicer and put clojure's concurrency idioms to the test. I wish that happened...

conormcd11:04:23

gregor isn't bad

cddr11:04:27

We use kafka quite heavily from clojure. The native interop isn't that bad but we did wrap a few things to try to make it more clojurey. Not sure we've found the best API for it yet though. The underlying library/framework is moving pretty fast so IMO it's a bit of a risk right now to go through a wrapper you don't own.

cddr11:04:48

I agree that integration points that involve scala are a bit of a pain. But honestly there's not too many of those. There are java interfaces for most of the integration points you need. And there's a lot of engineering effort you'd end up duplicating to get a "clojure kafka". Even for a pure clojure kafka client I think it would be difficult to keep up with the evolution of the wire protocol.

tankthinks11:04:56

Is anyone using clojure.spec.test with clojure.test? If so, do you have lots of deftests like:

danp11:04:48

Hi all, I've got two functions which use clojure.java.jdbc called: source-column-keys [conn source-table] source-data [conn table-name column-keys]

danp11:04:24

The first retrieves ordered set of column names for table-name from Oracle's data dictionary, and the second pulls data from table-name (columns retrieved based on provided column-keys).

danp11:04:49

To query the database, both functions need the JDBC conn string as a parameter.

danp11:04:35

As there's potential for more similar functions, is passing the connection as a parameter to each the "proper" way to do things?

jstew11:04:29

danp: how large is this system? Seems like a poster-child for the component library. But yes, you will usually end up passing in the connection as a dependency to all of the functions that work on the connection.

danp11:04:14

It's very small. I'll have a look at component for future reference though, cheers @jstew 🙂

jstew11:04:38

Another option is to use a dynamic var to store your connection but I would rather pass it in as a dependency. Here's a good read about that: https://stuartsierra.com/2013/03/29/perils-of-dynamic-scope

danp12:04:28

That looks useful, thanks. I did think about dynamic vars but haven't read too much about them yet and thought better of it.

deactivateduser12:04:14

I'm new here. Is it ok to ask for very specific help on?

deactivateduser12:04:26

Thanks 🙂 I'm using (and enjoying so far) clojure.data.zip.xml.

deactivateduser12:04:22

I'm trying to use xml-> in such a way that it always returns lists of the same size.

deactivateduser12:04:09

That is: xml-> should return ("Something" "") even when a node does not exist or is not matched.

deactivateduser12:04:49

Okay, this was probably too specific 🙂

tankthinks12:04:40

@deactivateduser16892 … I don’t think there is something built into clojure.data.zip.xml to do what you want

tankthinks12:04:24

I think you’ll have to stop at the element you know exists, e.g. :top :id :desc

tankthinks12:04:58

then have another function that’s with an (or ...) that returns empty string

deactivateduser12:04:15

Thanks @tankthinks - yes, that's what I'm exploring right now.

deactivateduser12:04:09

But the set of xml files is not known, so it's kind of a shoot in the darkness.

tankthinks12:04:20

I’ve done a bit of xml parsing with zip.xml … it’s a great lib, but xml parsing is always glueing pieces together

tankthinks12:04:18

Why do you want the empty string?

deactivateduser12:04:57

Well, any value would do - I just need xml-> to return the same number of values

deactivateduser12:04:22

because I use the resulting list within an interleave function

deactivateduser12:04:41

I will just find a workaround, but expecting a fixed number of values from xml-> seemed natural to me, I just wanted to make sure I wasn't missing something obvious. Thanks!

tankthinks12:04:56

sure … good luck!

hjrnunes13:04:04

Hi. When using dire.core I get a warning for a symbol replacement: WARNING: seqable? already refers to: #'clojure.core/seqable? in namespace: clojure.core.incubator, being replaced by: #'clojure.core.incubator/seqable? my ns requirement look like this: (:require [dire.core :refer [with-handler!]] I've tried excluding core.incubator.seqable? with :exclude, also tried requiring the incubator.core ns and excluding seqable?, and even excluding seqable? with :refer-clojure but nothing gets rid of the warning. Funny thing is, from what I gather, the lib doesn't even require seqable? from incubator.core. It uses :require with :refer on the symbol it needs only. Any ideias how to get rid of this?

elena.poot13:04:38

are you sure dire.core has anything to do with it? The error message only mentions clojure.core and clojure.core.incubator

hjrnunes13:04:03

well, it goes away if I don't require dire.core

pesterhazy13:04:43

I think you can safely ignore this warning

pesterhazy13:04:02

and submit a PR to the library you're using to update it to not throw this warning with newer clojure versions

pesterhazy13:04:10

you can probably just explicitly add the latest version of clojure.core.incubator in your project.clj too

pesterhazy13:04:46

(btw what I said wasn't relevant, clojure/core.incubator is already updated)

hjrnunes13:04:11

what do I get from adding the latest incubator?

hjrnunes13:04:58

I know I can ignore the warning but the program will be used by other people who might be confused about the message

pesterhazy14:04:05

do lein deps :tree to see which version of incubator is being used

pesterhazy14:04:39

my guess is it will show an outdated version (older than 0.1.4)

matan14:04:58

short question: why do we have to explicitly name a first argument for every defprotocol method? is that name ever usable for anything? e.g. (defprotocol P (foo [x])) as far as I follow x here is just a placeholder for the this argument. but unless we can use this name to some purpose, this may seem like boilerplate. What am I missing? Thanks in advance!

elena.poot14:04:04

@matan it is the this argument. It can be used to call other methods on the object, for instance. But also, that argument will be passed, so you at least need the placeholder for it to receive it.

matan14:04:21

But really, it can only be used in the implementing reified object can't it? Or is there any syntax that uses it inside the protocol definition itself?

elena.poot14:04:42

I knew I'd used it and that's probably exactly where I did use it. 🙂

Alex Miller (Clojure team)14:04:15

@matan it defines the signature of the function and can be referred to in the docstring

Alex Miller (Clojure team)14:04:30

implementors can call it whatever they want though

matan14:04:33

@alexmiller got it, it's the docstring that "uses" it, nothing else I guess 😉

matan14:04:26

I think the clojure api should have abstracted this away though. reify and friends could have made a this or other special thing available for use. As is, really this is boilerplate for something a homoiconic language could have easily abstracted I suggest.

hjrnunes14:04:31

@pesterhazy it did indeed! thanks!

bronsa14:04:47

@matan what you're suggesting is an anaphoric macro which have significant drawbacks

matan14:04:49

anaphoric?

matan14:04:11

yep, reading

bronsa14:04:32

proxy for examples does implicitely define this

matan14:04:46

yeah yeah 🙂 thanks already there

dominicm14:04:50

@matan I strongly disagree with your idea of this being special. The more local code is, the easier it is to read. I'm glad it's the way it is.

bronsa14:04:58

anaphoric macros are problematic because they break hygene and nesting

bja14:04:05

does anyone know the name of a component-like system that organizes itself with keyword dispatch hierarchies?

bja14:04:03

answering my own question, it is called Integrant

matan14:04:00

just wondering what's your use case for it

bja14:04:33

I've become unhappy with Cryogen's closed system nature and want to have a system with pluggable maps that contain dependency information and functions to run as steps. I remembered there was something like component but mostly data-based and thought it might fit. After some more consideration, I think I'll just use stuartsierra/dependency to generate a dependency graph and topo-sort it.

bja14:04:27

Cryogen being a static site generator I was using for a website

matan14:04:10

I'm not sure how these problems manifest on the defprotocol side, how would nesting break here, perhaps @bronsa you might elucidate. But in any event, I think https://clojure.org/reference/protocols should be edited to reflect the role of the first argument more clearly/explicitly than only: >The resulting functions dispatch on the type of their first argument, and thus must have at least one argument

matan14:04:08

As for me I played in the repl to confirm my understanding of this..

matan14:04:21

Anyway thanks for the discussion!

ghadi15:04:16

@hiredman I found a nice ergonomic improvement to that unfold function: Here's an example of using it to iterate through the docker registry API:

(defn full-catalog
  [client]
  (let [GET (fn [api]
              (client {:api api :method :get}))]  
    (successions (fn
                   ([] (GET "/v2/_catalog"))
                   ([resp] (GET (next-link resp))))
                 next-link)))

ghadi15:04:15

unfold is called successions there ^, and is now multi-arity. The arity-0 allows you to delay producing the initial value, which may be an API call

ghadi15:04:14

definition:

(defn successions
  [f continue?]
  (reify
    clojure.lang.IReduceInit
    (reduce [_ rf init]
      (loop [seed (f)
             ret  (rf init seed)]
        (if (reduced? ret)
          @ret
          (if (continue? seed)
            (let [next (f seed)]
              (recur next (rf ret next)))
            ret))))))

kevinbheda15:04:59

using ragetime migrations Want to create a concurrent index in psql , How to ? CREATE INDEX CONCURRENTLY sales_quantity_index ON sales_table (quantity);

matan16:04:21

Can we ad-hoc supply a fully qualified symbol name, rather than require it? something like a.b.c.symbol?

hiredman16:04:48

a.b.c.symbol won't cause a.b.c to be loaded

hiredman16:04:17

sorry, copy and pasting your stuff

hiredman16:04:27

namespaced systems are like a.b.c/symbol

hiredman16:04:56

and using a.b.c/symbol won't cause the namespace a.b.c to be loaded

hiredman16:04:11

it will work as long as something else has caused it to be loaded

matan16:04:38

:thumbsup:

richiardiandrea17:04:36

newbie question: if I have a java -Xms1g -Xmx4g -Dconf=production-conf.edn -jar target/uberjar/dada-0.1.18-standalone.jar -c 4869 --all

richiardiandrea17:04:49

and parse it with clojure.tools.cli

richiardiandrea17:04:19

with option:

["-c" "--club" "Load only the input club (an integer)"
    :parse-fn #(Long/parseLong %)]

richiardiandrea17:04:38

why do I get: Error while parsing option "-c ": java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String

richiardiandrea17:04:14

I needed "--club CLUB"

richiardiandrea17:04:40

I did not know it was analysing the string there

noisesmith17:04:39

transit says it is a work of progress currently - how realistic is it that transit would implement something incompatible with my current transit encoded data? https://github.com/cognitect/transit-clj#transit-clj

ghadi17:04:35

@noisesmith what is your current encoded data?

ghadi17:04:56

As long as you gave it a tag + handler, I'd think you'd be able to continue using it in the future

noisesmith17:04:07

all edn, no custom reader rules

noisesmith17:04:20

good to know, thanks

ghadi17:04:43

wdym " all edn"?

noisesmith17:04:01

that is, all data the cleanly round-trips via edn, sorry

noisesmith17:04:32

I mean, we could be using pr-str and edn/read-string but like the behavior that it rejects things that wouldn’t read back

noisesmith17:04:25

(and we wouldn’t benefit from transit’s structural sharing features that way either… though I haven’t tested that out extensively)

noisesmith17:04:46

oh, I guess that is actually called “caching” in transit

Alex Miller (Clojure team)18:04:09

@noisesmith to answer your original question, it is unlikely to change incompatibly

noisesmith18:04:11

thanks for the reassurance - and I’m glad you guys are so disciplined about compatibility, it’s a true pleasure

mattly18:04:58

@noisesmith FWIW I recently moved one of my API endpoints from EDN to Transit/JSON, and have seen huge gains in parse/load times

mattly18:04:02

(not relevant to your question, but)

caryfitzhugh19:04:54

ANy ideas why clojure says it can't find the static method?

caryfitzhugh19:04:56

if I run (r/reflect JWK), I can find the parse method in there as a static method:

<#C03S1KBA2|clojure>.reflect.Method{:name parse, :return-type com.nimbusds.jose.jwk.JWK, :declaring-class com.nimbusds.jose.jwk.JWK, :parameter-types [java.lang.String], :exception-types [java.text.ParseException], :flags #{:public :static}} 

hiredman19:04:40

you are asking it for the value

hiredman19:04:44

methods are not values

hiredman19:04:14

so when you ask for the value of a method like that, clojure assumes you are looking for a field

hiredman19:04:31

methods are not first class things on the jvm (unless you use reflection)

caryfitzhugh19:04:03

based on that, I thought it would work:

(Classname/staticMethod args*) ==> (. Classname staticMethod args*)

caryfitzhugh19:04:17

but, the expansion does work.

caryfitzhugh19:04:22

which I hadn't tried yet.

hiredman19:04:08

(JWK/parse ...) will work

hiredman19:04:16

that is entirely different from JWK/parse

caryfitzhugh19:04:42

i think at this point I'm running into a REPL weirdness now.. yipes.

caryfitzhugh19:04:57

b/c the repl I ran to test my theory - seems to work.

caryfitzhugh19:04:05

but my editor one is confused. doh.

mping19:04:03

can someone explain a bit of code to me?

mping19:04:48

whats that? a dynamic var embedded in the language?

mping19:04:57

sorry Im not that versed in clj

hiredman19:04:26

not sure what embedded in the language would mean, it is a dynamic var that is part of the agent system

mping19:04:36

thats what I meant 😄

hiredman19:04:43

the agent system binds it to the value of the running agent

mping19:04:58

so only 1 agent at the time?

hiredman19:04:12

dynamic bindings are thread local

mping19:04:29

so it means "the current agent I'm in"?

hiredman19:04:15

sure, I think characterizing it as "in" might be troublesome

mping19:04:43

I meant it should only work inside a body of a send right?

hiredman19:04:44

what you send to an agent is a function to run, that binding will be there when the agent runs the function

mbcev20:04:34

I'm writing a little bit of networking code and using Aleph+Manifold to do it. I've got the necessary code working in it's own network-code namespace, no issue. I wrote two wrappers around @(s/put! client data) and @(s/take! client) so that I could include only those two functions in a different namespace. What's tripping me up is that my (defn take-from-server [] @(s/take! client)) is returning an object in the second namespace rather than the dereffed value like it does within the network-code namespace.

mbcev20:04:21

Shouldn't the return be the same for the dereffed data regardless of if I call it as @(s/take! client) from within the network-code namespace in my repl, as it would be by calling (netIO/take-from-server) in my 2nd namespace?

mbcev20:04:57

when I use deref over @ my code works fine, I'm just curious if this is expected behavior or not. I thought @ was equivalent to deref

hiredman20:04:51

the reader expands @x to (deref x), so if you are seeing different behaviors betwen the two, the issue is likely you doing something else different

mbcev20:04:31

literally the only thing I changed in my code was to replace @ with (deref ... ) and it works.

hiredman20:04:29

my guess is you are using some tool that deletes and replaces vars (like the reloaded stuff) and for whatever reason it didn't reload the other namespace, so it is left pointing at the old vars

hiredman20:04:54

the change that made it work wasn't the change of @ to deref, it was any reload

mbcev20:04:27

I am using clojure.tools.namespace.repl for refresh so maybe that's what caused it.

hiredman20:04:00

if you violate any of the assumptions refresh makes, you will get weird behavior

hiredman20:04:37

I've never used it, so I can't speak to in detail

mbcev20:04:17

Yeah okay, that's probably what it is then. Thanks @hiredman I was thinking that my understanding of the reader replacing @x with (dref x) like you said was somehow misinformed.

hiredman20:04:23

there was a recent mailing list thread where someone had a similar sort of issue because they were running the reloading in another thread while also loading code in the repl

mbcev20:04:58

I'll have to look back on that to see, because I'm very likely doing something similar since I have two distinct threads for my app and was using the code reloading while I was debugging my networking code haha.

lxsameer20:04:19

hey folks, I have a channel containing vectores of channels, what's the best solution to flat this ?

jr20:04:41

(def out (chan 1 cat))

jr20:04:56

the channel containing the vectors can be created with a cat xform that will flatten the channels

lxsameer20:04:37

but I already have the channel

lxsameer20:04:52

it's the output of a pipeline

jr20:04:36

are you referring to the to chan?

lmergen20:04:41

isn't this something that manifold can do ?

lxsameer21:04:35

@jr is it to have nested pipelines?

kwladyka21:04:15

hi, i found strange behaviour during lein uberjar. Code failed, but works in REPL. https://pastebin.com/bgrn2CUm - details. Do you have any idea what is it happening? Is it a Clojure bug?

danielcompton21:04:16

@kwladyka it looks like test.check isn't in your :dependencies when the uberjar was built?

danielcompton21:04:05

When you build an uberjar Leiningen uses a default set of profiles which doesn't include :dev or :test IIRC

danielcompton21:04:49

So if test.check is in :dev, then uberjar will fail

danielcompton21:04:06

Running a repl by default includes the :dev profile, which is why there would be a difference

kwladyka21:04:21

oh… make sense

kwladyka21:04:46

and with this solution i am going to sleep 🙂 goodnight 🙂

beatboxchad22:04:23

Yesterday I got help in here fixing a broken macro from another codebase. Today I realized I was the one who originally broke it with clumsy :s/thing/otherthing/g vim commands. "Check your optics"

josh.freckleton23:04:15

is there a core fn like fnil but that doesn't plug the default into the fn, just returns the default?;

bradford23:04:06

Is there a unique-rand-nth?

bradford23:04:44

nm, I see I can do (take n (shuffle coll))

noisesmith23:04:41

@josh.freckleton something I’ve used for that - not as elegent - is (or (some-> x f) default), some-> ensuring that f doesn’t get called if x is nil

josh.freckleton23:04:05

oo, I like that thanks!

noisesmith23:04:23

and some-> is actually nice once you have two or more steps

josh.freckleton23:04:55

(I find myself missing the maybe monad 😢)

josh.freckleton23:04:18

@noisesmith there's not also by some chance something like (some-as-> x $ (f $) (g $)) kind of construct, is there?

noisesmith23:04:56

at that point you probably want to check out one of the monad libs I think 😄

noisesmith23:04:25

I guess you could write a some-as-> macro, neither some-> or as-> are super complicated macros if you look at the source