Fork me on GitHub
#clojure
<
2019-08-28
>
ahungry00:08:20

Does deps have support for profile injection of code, similar to the same lein feature?

Alex Miller (Clojure team)01:08:34

Aliases can be used to do certain things that profiles can but they differ

st3fan01:08:24

Couple of days ago I asked about ‘patterns’ here - I completely forgot that I have this on my bookshelf … https://pragprog.com/book/mbfpp/functional-programming-patterns-in-scala-and-clojure

Alexander Stavonin01:08:39

how good it it? would you recommend to spent time reading the book?

the2bears02:08:47

This was one of the first few books I read when learning functional programs. Liked it.

👍 4
st3fan21:08:36

I’m still reading it but I like it.

st3fan21:08:03

One hilarious part is that many Java examples translate to 2 lines of Clojure or “use a map”

rampal02:08:46

Hello. Does anyone use Yada? Im trying to get started

nori03:08:07

what do i make of this?

seancorfield03:08:17

According to my search on Bing, that's most likely due to IP6 vs IP4 issues @norilinoriginal

seancorfield03:08:25

How are you starting the Socket REPL? What platform are you on?

ahungry03:08:16

Hmm...I am a bit confused on EPL / GPL incompatability that I am reading about. Statements such as "Clojure is EPL (1.0) and therefore any code written under GPL, but compiled with clojure libraries (even core language features themselves) is therefore impossible to distribute legally" (paraphrased) - yet, if I compile some C with gcc, that does not mean my compiled C code must be GPL just because gcc is gpl. So, why would compilation of a language (clojure) to java byte code imply that resultant byte code must be EPL?

seancorfield03:08:04

Where did you read that statement? It doesn't sound right to me.

ahungry03:08:21

or, if I type code with Emacs, which generates code / text based on my interaction with the program, despite Emacs being GPL, it does not mean that my resultant source code is needing to be GPL

ahungry03:08:33

let me plop down some of the links I've been reading tonight

ahungry03:08:07

it would be one thing if it was a user package like clj-http or jdbc or something that was epl and thus incompatible, because that would be closer to glibc and its LGPL license that accommodates gpl use (I think glibc is lgpl)

ahungry03:08:21

but to say, a core language would ban all gpl derivatives?

seancorfield03:08:58

GPL is a very problematic language from a programatic point of view. Lots of other licenses are not compatible with it -- and it's the GPL's "fault" because it is, essentially, a "viral" license.

ahungry03:08:39

But I don't think code written in any of the GPL lisps requires the derivative work to incorporate the host language's license choice do they?

seancorfield03:08:41

When I worked at Adobe, the legal team almost never approved use of GPL software if it might need to be combined with anything else (rather than just being a standalone tool).

ahungry03:08:54

guile-scheme is gpl right? but surely any scheme I write does not have to be gpl

seancorfield03:08:03

It's nothing to do with that.

ahungry03:08:05

(maybe it does 🤷 )

seancorfield03:08:21

It's to do with combining and distribution of code that is under different licenses.

ahungry03:08:35

guile is lgpl, so I suppose that's why it never has surfaced in things I've come across as a show-stopper as far as licenses are concerned

seancorfield03:08:20

Your problem isn't Clojure being EPL per se, it's about combining and distributing bundles of code as derivative works.

ahungry03:08:08

ugh, what a cross-roads, when ideology meets preference - clojure is such a great language, but to use a language constrained by a license that forces almost all things built on it to match the same license - maybe a language built with all of its runtime as GPL would be in the same boat

ahungry03:08:21

but it seems all the "gpl" flavor languages+stdlibs use lgpl to work around that

seancorfield03:08:21

The fault is GPL, not EPL.

✔️ 4
ahungry03:08:31

so derivatives can be mit / bsd / epl -basically anything

ahungry03:08:47

you say potato, I say potato

seancorfield03:08:50

EPL is very friendly to companies -- so Clojure is easy to use for businesses.

seancorfield03:08:39

If you write software under the GPL, a lot of companies won't touch it (unless it is a completely standalone tool that they don't have to combine anything with).

nori03:08:30

If so, is there any chance I could get a license of your program under the Lesser GPL? You can ask, but most authors will stand firm and say no. The idea of the GPL is that if you want to include our code in your program, your program must also be free software. It is supposed to put pressure on you to release your program in a way that makes it part of our community. You always have the legal alternative of not using our code.

ahungry03:08:53

So - is it correct that if a company writes a commercial app in clojure, due to EPL, anyone they distribute it to would have to also distribute the source code?

seancorfield03:08:10

No, absolutely not.

seancorfield03:08:32

Datomic is closed source. REBL is closed source.

ahungry03:08:48

Do I need to include the source code for such Program with the object code distribution? No. But you do need to include a statement that the source code is available from you and information on how to obtain it.

ahungry03:08:05

If I purchase dataomic or REBL, does someone tell me the source is available and how to obtain it?

seancorfield03:08:49

No, those are not EPL-licensed.

seancorfield03:08:01

That's my point, you can build non-OSS products using Clojure.

ahungry03:08:20

Are you sure the only reason they aren't subject to EPL is because Rich has a CLA for clojure? And thus full copyright of it?

ahungry03:08:41

he / owners of clojure code can relicense as non-epl their entire language, but only they have that privilege

seancorfield03:08:02

This isn't about re-licensing Clojure.

ahungry03:08:08

so, a derivative work (dataomic) can ignore the fact its host is EPL

Alex Miller (Clojure team)03:08:14

I feel like you are concluding things without actually reading or understanding any of the documents

seancorfield03:08:05

I was trying to figure out a polite way to say this 🙂

Alex Miller (Clojure team)03:08:37

sorry if that wasn't polite :)

ahungry03:08:29

"If I modify a Program licensed under the EPL and distribute the object code of the modified Program for free, must I make the source code available? Yes. By distributing the modified Program, even if it is only a free version of the object code, you are obligated to make the source code to the modified Program available to others."

ahungry03:08:51

Not intentionally - I have been digging through old postings but it would help if some official document / FAQ clarified all of this closer to the context

ahungry03:08:16

I read through the google groups posting and consideration of epl 2 (and rejection) and have been trying to do a thorough investigation - a few of my comments are conjecture / my own assumption yes

Alex Miller (Clojure team)03:08:21

with respect to something like Datomic, that sentence starts "If I modify a Program"

Alex Miller (Clojure team)03:08:31

Datomic does not modify Clojure and is not itself licensed under the EPL

ahungry03:08:43

Is this statement true or false - "Code written and compiled into the same JVM byte code space as clojure core is subject to the EPL 1.0 license"?

ahungry03:08:23

If it is false, then I believe if I use no 3rd party libraries, I can build a clojure GPL ecosystem

ahungry03:08:28

if it is true, then I can't

Alex Miller (Clojure team)03:08:50

legally, there are a lot of clarifications to the definitions of words in that statement before it can be evaluated

Alex Miller (Clojure team)03:08:38

and the notion of "linking" in particular with Java bytecode is a particularly thorny one

ahungry03:08:14

if the clojure jar functionality (the language primitives) are extended with user defined code, even as simple as a "hello world" main call - isnt that a modification of the original program?

ahungry03:08:22

because the program and what it does when executed has now changd

seancorfield03:08:25

The vast majority of people building stuff with Clojure are not "modifying the Program" because they are just using Clojure as-is.

ahungry03:08:31

it may not be a modification of the source files

ahungry03:08:54

if I #include <gpl-library.h> in a C program and write my own functions extending it

ahungry03:08:01

thats not a modification to the gpl program?

Alex Miller (Clojure team)03:08:45

I'm not qualified to answer that question

ahungry03:08:15

I'm sorry if any of this is coming off trollish, its not the intent at all, i'm trying to grasp at and understand how this all weaves together, and it seems like while some of the old article postings have cited a firm stance between Eclipes group and the FSF, the open source community itself, close to the language, still has a non-concrete answer

Alex Miller (Clojure team)03:08:46

and I'm not sure it's even a comparable question given that epl and gpl probably have different definitions of the words you're using

seancorfield03:08:22

I just realized that the Google Groups thread you linked to includes my answers to these questions in some detail so I'm just kind of repeating myself.

ahungry03:08:32

So - ignoring the GPL compatibility issues - EPL is most comparative to the LGPL? Linking code is fine, and proprietary binary shipping without source available is also fine, but if you modify an included lib itself, that must be a shared modification?

Alex Miller (Clojure team)03:08:35

they are both weak copyleft licenses, so similar in that regard

Alex Miller (Clojure team)03:08:20

but they differ in their obligations and probably other details like patent protection

nori03:08:37

the GPL website has an approximately 200pg faqs page that might help here

seancorfield03:08:00

LGPL is more restrictive than EPL in terms of usage of code released under those licenses.

seancorfield03:08:08

I guess I'd turn this around and ask: do you have a specific use case regarding code or an application you're writing and distributing, where you need to understand what licenses you can use for that code/application, when working with Clojure? @m131

ahungry03:08:02

yes, about 20 or so github things I'm tinkering on / working with, and I choose AGPLv3 as my de-facto license on the majority of them

seancorfield03:08:40

I'm fairly strongly "anti" GPL/LGPL precisely because of the difficulties they cause for anyone downstream trying to use them in conjunction with other software.

ahungry03:08:47

which, seems my license choice may be wrong/need to be reworked, or its impossible for anyone to use under my combination of language and my license choice - granted i'm only distributing my own created clj source code and no resultant dependencancies

seancorfield03:08:22

I tend to choose ASL -- Apache Source License -- by default, unless I'm writing a Clojure library in which case I use EPL. I like both licenses.

Alex Miller (Clojure team)03:08:24

At Cognitect we have chosen ASL2 at times when we thought it was a better match

Alex Miller (Clojure team)03:08:37

Like the transit libs, transducer libs, etc

seancorfield03:08:13

Yup, makes sense to me.

seancorfield03:08:01

When I worked at Adobe, we had to ask one OSS project to consider relicensing from LGPL to ASL because of the way it generated code and then expected you to combine your code with it. The project changed its license (otherwise we would have found another project or built something ourselves). A lot of people starting OSS projects don't think about the implications of the licenses they choose.

Alex Miller (Clojure team)03:08:25

well, look at what happened in React

Alex Miller (Clojure team)03:08:51

or even step back one step to consider projects without a CA where they don't even have the ability to relicense in the first place

seancorfield03:08:03

True, which is the vast majority of small OSS projects out there.

Alex Miller (Clojure team)03:08:02

I think AGPL / EPL are probably not compatible w/o some kind of exception like the classpath exception

Alex Miller (Clojure team)03:08:33

which should work fine but is more complicated

Alex Miller (Clojure team)03:08:01

Metabase is a Clojure project licensed AGPL with exceptions btw

ahungry03:08:28

maybe if that is good enough for metabase with 15,000+ github stars, its good enough for my tiny works then (I did see this commit earlier today: https://github.com/metabase/metabase/commit/666b1b453a71a1fca19e7b81739a58ce7fa45a14#diff-61e0bdf7e1b43c5c93d9488b22e04170)

nori03:08:33

>The idea of the GPL is that if you want to include our code in your program, your program must also be free software. It is supposed to put pressure on you to release your program in a way that makes it part of our community.

nori03:08:08

Just clarifying exactly what the difficulty is that's caused.

nori03:08:26

I default to GPLv2 for stuff that I want to stay in the open-source space and ad-hoc permissive/unpermissive licenses for other use cases.

ahungry03:08:10

So, technical question - I want to define a var in ns bar, while I am currently in ns foo - is the best way to just use in-ns? or some other means?

ahungry03:08:22

(defn proxy-def
           "Redefine a function with the wrapper around it. k = Symbol, v = Var to Fn."
           [[k v]]
           (eval
            `(def ~k ~(proxy-fn (deref v)))))

seancorfield03:08:03

Why do you want to do that? (genuine question) It seems like a bad idea to me.

ahungry03:08:59

I want to implement something in the flavour of the robert-hooke package (ala, emacs lisp defadvice) for runtime tracing/storage of function inputs/outputs and input types + output types - https://github.com/ahungry/determinism (excuse the cheesy name)

ahungry04:08:17

if you peek at the readme, the intent is that I would have an sqlite database that I could then augment an IDE with

seancorfield04:08:18

Take a look at how instrument in Spec is defined.

ahungry04:08:36

so i hover on function foo - it shows me the last N inputs/outputs it received at runtime on dev server etc

seancorfield04:08:45

(as I suspected, Spec uses alter-var-root to replace an existing definition with a new version)

seancorfield04:08:00

No need for eval etc.

ahungry04:08:10

thanks! I will give that a shot

ahungry05:08:43

this is an interesting one

ahungry05:08:49

what is the reason for this evaluation result?

ahungry05:08:57

(def my-dataset (atom {}))

         (defn fetch-data!                                                                                                                                               
           "Simulate a slow data condition and return back the number given,                                                                                             
           with the side effect of keeping a running sequence of n / sum."                                                                                               
           [n]                                                                                                                                                           
           (Thread/sleep 1e2)                                                                                                                                            
           (swap! my-dataset (fn [m] (conj m {(keyword (str n)) (+ n (reduce + (vals m)))}))))

         (defn get-data []                                                                                                                                               
           (reset! my-dataset {})                                                                                                                                        
           (dorun (pmap fetch-data! (range 6)))                                                                                                                          
           @my-dataset)

         ;; With pmap, this is produced?                                                                                                                                 
         (time (get-data))
         "Elapsed time: 100.93236 msecs"
         {:0 0, :1 25, :2 13, :3 7, :4 4, :5 54}

ahungry05:08:55

without pmap, using normal map, it would calculate as expected - the max value being 31 in the 5 slot: {:0 0, :1 1, :2 3, :3 7, :4 15, :5 31}

ahungry05:08:18

i could understand if the sums were in the wrong slot due to pmap chunking out the data, or if they were coming in at a lower total than expected due to the function application in the swap lexically scoping things oddly - but how is it getting up to 54?

craftybones05:08:37

While swap! itself is atomic, how does vals work?

ahungry05:08:09

its supposed to just pull the vals off a map, so {:x 1 :y 2} would result in [1 2] (or maybe (1 2))

craftybones05:08:24

That’s not what I mean

ahungry05:08:28

could a map exist in a state where it has a key but no val?

craftybones05:08:56

Which would give you lower results, not higher 🙂

ahungry05:08:20

yea...which is why I am very confused how it would get to 54

craftybones05:08:14

No, this makes sense

craftybones05:08:17

First 0 was processed

craftybones05:08:58

Then 4 was processed

craftybones05:08:12

Then 3 was processed

craftybones05:08:20

3 -> 7 (3 + 4 + 0)

craftybones05:08:41

Then 2 was processed

craftybones05:08:02

2 -> 13 (2 + 7 + 4 + 0)

craftybones05:08:09

Then 1 was processed

craftybones05:08:32

1 -> 25 (1 + 13 + 7 + 4 + 0)

craftybones05:08:40

So this makes perfect sense.

hiredman05:08:54

Put a watch on the atom and you'll see what it is swapped from to every step

ahungry05:08:14

thanks all

dominicm07:08:15

Has anyone used tap> in tests? Is it a good or bad fit for detecting actions taking place during integration tests?

vlaaad07:08:17

you mean leaving tap> in production code to use it for tests?

vlaaad07:08:19

I'd say tap> is like debugging prints, but with values instead of strings, so it should not be in production code. Why not use with-redefs to get a peek into implementation?

dominicm09:08:51

I see experimenting with using it as a mock, where I might previously have used something like core async channels in my mock

kirill.salykin09:08:22

Please help, why would (prn {:till-date #date "2019-01-01"}) fail with No reader function for tag date. no reading is happening env: (emacs + cider)

mpenet09:08:08

#inst "2019-01-01"

mpenet09:08:17

not sure where #date comes from

vlaaad09:08:13

reading is happening when you send this form to repl

kirill.salykin09:08:19

That makes sense

kirill.salykin09:08:58

> not sure where #date comes from #date is custom tag

jahson10:08:41

You need a custom reader for your custom tag

kirill.salykin10:08:05

I am not reading the custom tag, I am trying to serialize it

dominicm10:08:25

@kirill.salykin you can create a tagged-literal object

kirill.salykin10:08:49

Thanks, will look into it just found that tick procides #time/* tags will not reinvent the wheel and use it Thanks for the tick !

💯 4
👍 4
valerauko15:08:59

are there any plans for hygienic macros in clojure?

enforser16:08:06

Here's a blog post on this that I found: https://xivilization.net/~marek/blog/2013/09/17/clojure-and-hygienic-macros/ I think Clojure allows a programmer to write hygienic macros!

Alex Miller (Clojure team)16:08:48

with the use of syntax quote resolution and gensym, it's not really an issue in Clojure?

valerauko16:08:20

as long as i remember to # all the things

hiredman16:08:49

if you don't you will usually get an error

Alex Miller (Clojure team)16:08:00

well due to autoresolution, clojure will resolve the things you forgot and usually cause an error

hiredman16:08:52

user=> (defmacro foo [x] `(let [y 1] ~x))
#'user/foo
user=> (let [y 2] (foo y))
Syntax error macroexpanding clojure.core/let at (REPL:1:12).
user/y - failed: simple-symbol? at: [:bindings :form :local-symbol] spec: :clojure.core.specs.alpha/local-name
user/y - failed: vector? at: [:bindings :form :seq-destructure] spec: :clojure.core.specs.alpha/seq-binding-form
user/y - failed: map? at: [:bindings :form :map-destructure] spec: :clojure.core.specs.alpha/map-bindings
user/y - failed: map? at: [:bindings :form :map-destructure] spec: :clojure.core.specs.alpha/map-special-binding
user=>

valerauko16:08:17

i would've sworn i broke something like that once but i can't seem to find what it was

valerauko16:08:48

guess i'm just misremembering things.

valerauko16:08:27

that spec error looks pretty scary though haha

Alex Miller (Clojure team)16:08:54

It’s basically saying that there are several things it possibly expected to find but what it found was none of those - expected simple-symbol?, or vector, or ... (all the potential destructuring forms)

Alex Miller (Clojure team)16:08:54

This particular case of a failure at option fan-out is one where I think we could greatly improve the error message

Alex Miller (Clojure team)16:08:29

Imo, the next best problem to attack in this area

hiredman16:08:17

so basically there are facilities that guide you towards hygenic macros, but they aren't as strong as say racket's, and are easier to ignore, but that makes the macro system much simpler to implement and understand

arthur17:08:22

just bought my clojure conj ticket, nearly forgot so I thought i'd throw a reminder up here 🎗️

seancorfield17:08:46

See you there!

rgm18:08:50

I’m working on a library, and borrowing a txt definition file from a python lib that is inspiring mine. I realized I don’t actually know where the best/idiomatic place to stick these kind of things is… under /resources? Under /src/my/ns-prefix/? I’m using tools.deps and haven’t really needed to produce a jar.

rgm18:08:21

the file in question gets read at startup and defines a registry of dimension units

rgm18:08:46

so let’s assume that it gets slurped & parsed or such when my downstream project starts up, which I presume means directly relying on a filepath wouldn’t be a very hot plan.

ataggart20:08:42

If it is read-only, I’d go with accessing it as a resource.

rgm20:08:19

it is read-only … so that’d be and living under /resource, I guess.

👍 4
athomasoriginal18:08:47

Afternoon! Does anyone have any recommendations RE: Clojure libraries that they feel are good examples of using protocols?

chrisulloa18:08:38

clj-time imo

chrisulloa18:08:03

I followed that lib for some good examples of using protocols

seancorfield18:08:02

clj-time is deprecated. Please don't use it. Use Java Time directly or one of the wrapper libraries if you must.

☝️ 8
Suni Masuno19:08:34

How many times have I seen you write that in here now?

seancorfield19:08:58

Hahaha... it always bears repeating!

Suni Masuno19:08:30

The curse of the successful package, it can never truly die.

seancorfield19:08:08

I've only been getting "aggressive" about it since Clojure 1.10 made Java 8 the baseline. In theory, if you're on 1.9 or earlier and you're still on Java 7 or earlier for whatever weird reason, then clj-time is still useful. But I really don't want folks using it on new projects that run on Java 8 or later 😐

Suni Masuno19:08:17

Have you considered getting aggressive about it from the library level? Eventually that is.

Suni Masuno19:08:35

Far too subtle sir. troll

Suni Masuno19:08:44

Have you considered flashing text?

seancorfield19:08:18

<marquee>STOP. USING. CLJ-TIME.</marquee> :rolling_on_the_floor_laughing:

Quest19:08:45

Tangential, but there's no equivalent in CLJS to java-time is there? The only lib I've seen so far mimics the clj-time API, should it also be deprecated? https://github.com/andrewmcveigh/cljs-time

Suni Masuno19:08:18

Oh, now that's an actually interesting question

seancorfield20:08:11

@U22M06EKZ The clj-time readme links to a clj/cljs project that is Java Time in clj and the equivalent in cljs

seancorfield20:08:53

https://github.com/henryw374/cljc.java-time -- I think that was announced at Clojure/North earlier this year?

Chase20:08:33

This might be an option too.

Chase20:08:00

Is this the Clojure/north talk you were thinking of or were there two time libraries introduced?

Chase20:08:22

I just tried tick this morning on an exercism problem and it was pretty nice.

Chase20:08:48

ahh, it seems tick might be a higher level library on top of this cljc.java-time. Sorry for any confusion.

Quest20:08:51

This is a godsend. Since I looked at time libs in late 2017 I've been preparing to roll up my sleeves and wrap differing CLJ+CLJS libraries to achieve consistency in my own app. tick looks like exactly what I need -- I have some learning to do & thank you both @U04V70XH6 @U9J50BY4C!

seancorfield18:08:57

@tkjone Feel free to look at seancorfield/next.jdbc as an example of a protocol-heavy library https://github.com/seancorfield/next-jdbc

🙏 4
Lennart Buit19:08:46

just wondering: why are some protocol fns in next.jdbc prefixed with a dash, and others are not. Privateness?

seancorfield19:08:12

The - ones are "low-level" and have a wrapper function without - to provide multiple arities for convenience.

seancorfield19:08:48

(and that's a very good question!)

Lennart Buit19:08:09

yeah, I was thrown off because all appear to have a wrapping function. I do the same, but I have a fn without a dash to be able to attach an s/fdef to

Lennart Buit19:08:18

oh the arities

Lennart Buit19:08:22

I didn’t see that!