Fork me on GitHub
#clojure
<
2017-06-30
>
wei00:06:20

is there an idiomatic way to create a keyword in the current namespace, or is (keyword (str *ns*) s) pretty much it?

hiredman00:06:35

don't do that

hiredman00:06:19

the behavior of *ns* is almost certainly not what you expect it to be

hiredman00:06:38

there is no such thing as the "current namespace" at runtime

wei00:06:42

what about at compile time? is there a shortcut for a keyword in the namespace I’m writing the code in? something like ::. I could do (keyword "app.models.user" s) but that seems verbose and potentially brittle to refactoring

noisesmith00:06:43

if you want it to be the namspace calling your function/macro then *ns* works - but that won't give you the ns your definition came from

hiredman00:06:55

I am not sure how to read that, but it doesn't seem to be correct

hiredman00:06:16

*ns* is set by the compiler when compiling code, when running code its value is arbitrary

noisesmith00:06:13

sorry, right - it will be the arbitrary value of *ns* at runtime for a function, but for a macro it will be the ns being defined

hiredman00:06:20

some execution environments preserver the value of *ns* between compilations (the repl), but common environments do not

hiredman00:06:44

macro expansion happens at compile time, so macros can observe a meaningful value of *ns*

hiredman00:06:59

when a function is being compiled, the compiler uses *ns* to figure out which vars it uses, but those vars are then embedded in the generated bytecode, and when the bytecode is run, it never looks at the value of *ns* again

seancorfield00:06:49

What we do at World Singles is to have (def ^:private my-ns *ns*) near the top of each namespace where we need the “current namespace” and then use my-ns instead of *ns*.

seancorfield01:06:23

That way it’s bound to the file’s namespace at load/compile time and doesn’t change during program execution.

csm02:06:30

why does (get-in {:a (vector {:b :c})} [:a 0 :b]) work, but (get-in {:a (list {:b :c})} [:a 0 :b]) doesn’t?

csm02:06:10

ah, I guess the answer is “lists aren’t associative, but vectors are”

csm02:06:37

not that that’s all that satisfactory, but it makes sense

devn03:06:42

@csm it's good to have that choice, no?

aconanlai05:06:14

is this a good place to ask newbie questions?

noisesmith05:06:40

there's #beginners

aconanlai05:06:05

cool, thank you

mjo324_5605:06:08

I asked beginner questions here 🙂

mjo324_5605:06:14

and nobody complained!

seancorfield05:06:11

Depends on the audience and the time of day. But we try to encourage focus to ask beginner Qs in #beginners so folks can opt-in/-out.

devn05:06:33

What I remember of clojure IRC was that you were free to ask beginner questions. I know because I asked many of them. I'm not sure the distinction. I'm still a beginner.

seancorfield05:06:11

@devn We're all beginners on different topics 🙂 The main difference from IRC (apart from the wonderful Slack UI/UX) is the plethora of channels here... (and this is getting meta so #off-topic if we really want to go down that path).

burke07:06:10

Hello everyone, I have an app which generates documents (for example blog posts). Each document has an ID and consists of Text, Tables, Lists etc. and is completely defined in EDN. I want to store these documents but due to not consistent, changing keys it is not easy to store this in a RDBMS-Table. So at the moment I have a table in my h2db which has two colums "ID" and "data", where data is a cblob and stores the edn serialized as a string.. Is there a better "clojury"-way to store edn documents?

mkvlr10:06:53

@burke there’s also https://github.com/cognitect/transit-format which is what we’re using which is a good fit if you want to use it in a browser because it can be used on top of json

curlyfry10:06:39

@mkvlr @burke However, transit isn't for storing data (yet) > NOTE: Transit is a work in progress and may evolve based on feedback. As a result, while Transit is a great option for transferring data between applications, it should not yet be used for storing data durably over time. This recommendation will change when the specification is complete.

mkvlr10:06:42

@curlyfry right… we just ignored that. it does seem fairly stable at this point there’s not much activity in the repo anymore. Was wondering if that recommendation was going to change…

burke10:06:57

@curlyfry I was thinking about using nippy, because of their built-in compression functionality. But my main concern is not the serializing part, but using the clob or blob for storing the data. Accessing the document doesn't feel native (sql query, reading clob, deserialize data). I hoped there was an mongodb-equivalent for clojure/edn 😅

sundarj10:06:02

what about datomic?

burke10:06:17

Its a low budget project, Im looking primarily for open/free software

a1310:06:25

datascript

sundarj10:06:54

datomic starter is free

burke10:06:02

@sundarj: but after 1 year there will be no updates and my project relys on an old unmaintained version, if I understand the description correctly?

mpenet10:06:39

No go for serious work imho

sundarj11:06:06

ah didnt know that, havent used it myself yet 😛

jgeraert11:06:39

maybe it's time for an edn datatype in postgresql 😉

val_waeselynck13:06:04

@burke storing fressian in a BLOB or edn in a CLOB is fine as long as you don't need atomic updates or native queries, otherwise I strongly advise against it (you may then want to use JSON support in a sql db, or a document store). There is no such thing as a 'clojury' way of designing a database imho - this should be language independent :)

burke14:06:05

val_waeselynck: updates are rarely and only done from one person (the document author). Native queries aren't needed. The documents are self-contained, so there are no dependencies to other tables. But inside the document there are dependencies, thats why I was unsure if I should break the document hash-map into normalized database tables or just store the whole document in a clob just like it is stored at runtime. I think I'll stick with the clob solution.

souenzzo13:06:47

I still think that will be awesome do something like :find ?edn :where [?e :graph/data ?edn] [(contains? ?edn :foo) true]

val_waeselynck13:06:04

There is no way to make this efficient in Datomic currently

souenzzo17:06:03

not efficient.. just possible 😜

xificurC13:06:34

starting nREPL for the first time on this machine says "could not transfer ... unable to find valid certification path to requested target". We have a custom certificate at work that sits at top of everything. What should I do to get nREPL (is it using maven behind?) to use it when downloading artifacts? E.g. in pip I need to add in ~/.pip/pip.conf a line saying cert = /etc/ssl/certs/ca-certificates.crt

noisesmith14:06:09

by nrepl do you mean leiningen?

noisesmith14:06:40

lein does not use maven, but it speaks to the same repos, you probably need to make sure your java certificates are properly set up

xificurC14:06:50

@noisesmith I installed leiningen and ran cider-jack-in in a .clj file in emacs

noisesmith14:06:36

right, but nrepl doesn't download things, leiningen does

xificurC14:06:06

I get that, but I don't know where to stick in the certificate

noisesmith14:06:13

anyway, depending on your OS there's various ways to make sure your java certs are OK

xificurC14:06:00

well if you have a link or something, hit me 🙂 ubuntu

xificurC14:06:54

we use maven here but it's all proxied through a locally set up mirror

noisesmith14:06:44

oh, that's the one I know /var/lib/dpkg/info/ca-certificates-java.postinst configure

xificurC14:06:57

that did write a lot of "Replacing ..." lines and a "done." in the end which didn't solve the problem

noisesmith14:06:54

what about the SO version?

xificurC14:06:22

still a nope

noisesmith14:06:47

weird - is the cert installed in such a way that ubuntu ca-certificates would know about it / use it?

noisesmith14:06:06

because that should have fixed it if it is

xificurC14:06:20

yes it's correct, other package managers work fine with it

xificurC14:06:28

(once I set the ca-file)

noisesmith14:06:41

no I'm saying add the ca-file to ubuntu itself

noisesmith14:06:52

then set up java's certs from ubuntu

noisesmith14:06:08

though, if you want to do it the tedious way you could also manually add that cert to java...

xificurC14:06:32

the askubuntu link you sent is how we set up the certs in ubuntu

noisesmith14:06:02

then I have no idea what's wrong here

xificurC14:06:02

the best option would be to add the mirrors we use for maven into my leiningen profile. I'm just not sure how to write it down. I'd need a ~/.m2/settings.xml to leiningen profile converter

noisesmith14:06:18

this isn't maven, lein doesn't use maven

noisesmith14:06:31

it can access maven repos... but doesn't use maven itself

noisesmith14:06:47

sorry, misread

noisesmith14:06:10

this should be system level config properly propagated to java, it shouldn't even be leiningen's concern

xificurC14:06:11

it's hard to tell where the problem lies, it could even be that the network here is deliberately blocking direct access to the repos since they want us to use the supplied mirrors

noisesmith14:06:32

one thing to rule out would be that ca-certificates.postinst or the purge / reinstall of ca-certs didn't undo your custom cert addition

noisesmith14:06:30

there might be a less heavy handed way to add the cert and also make sure it updates java without doing a purge / install cycle...

xificurC14:06:16

I managed to add our mirror to profiles.clj but it only mirrors the maven repo, so I get the same error when I get to dependencies that are on clojars 😞

xificurC14:06:56

@noisesmith I found the culprit - the certificates are OK, for some reason a bad java is being used. Now I just need to find out who picked that version and why

noisesmith14:06:32

in terms of the wrong java being installed, or the wrong one picked out of those installed?

noisesmith14:06:17

if the latter, that can be fixed with update-alternatives

xificurC15:06:00

the wrong one picked, because I installed lein via nix 🙂

noisesmith15:06:30

that's not what decides it is it? I mean lein just looks for the first java on path

noisesmith15:06:36

unless nix changes that...

xificurC15:06:47

I'm pretty sure nix changes it since they are all about being reproducible and immutable etc. Also command -v java from emacs returns /usr/bin/java which points to ubuntu java, not the nix one

xificurC15:06:02

all in all I just got it to wok 🙂

noisesmith15:06:04

using lein via a package manager seems fishy to me, sort of like using the jvm inside a container - I know there are valid reasons, but lein already manages its version better than most package managers will and the jvm already isolates differences between environments...

mokr15:06:49

Hi, all! Does anyone have some good recommendations on resources covering/showing proper use of records and protocols? I’ve been using Clojure happily for three years without them, mostly on a hobby basis, and feel that I understand them pretty well, but when I start using them or thinking about how to do it, I feel like I’m going all OOP. Hopefully the question makes sense.

Lambda/Sierra15:06:43

@mokr I cover this a bit in my presentations about Component https://stuartsierra.com/presentations

mokr15:06:51

@stuartsierra Thanks, I’ll have a look.

mokr15:06:36

A follow up question: In my current project where I believe records/protocols is the good fit, I start out with CSV records with lots of fields. Many are not always present. Is it ok to create a record with just a few fields as required (eg. “logtime” and “id”) and the rest as optional, event though many other fields are highly useful and used in calculation?

noisesmith15:06:19

that's a pretty normal way to use records - adding fields that aren't defined on them

noisesmith15:06:53

but if you know what they will all be, you could just have them all nil by default...

mokr15:06:22

@noisesmith Thanks. What’s the benefit of having them be nil? Would that make the generated ->MyRecord requiring a lot of paramters, and possibly not making it a MyRecord if you use map->MyRecord if you provide a map missing some keys?

Lambda/Sierra15:06:26

@mokr Records are usually indicated when you also have Protocols (or interfaces) and you plan to have multiple different types of records implementing the same functions for polymorphic behavior.

noisesmith15:06:27

@mokr map->MyRecord always makes a MyRecord, even for an empty map

noisesmith15:06:52

and yes, with more than ~4 fields I would always use map->MyRecord rather than a positional constructor

mokr15:06:40

@noisesmith Thanks, the former was new to me. I guess I need to experiment and see how it goes.

mokr15:06:29

@stuartsierra I guess my “fear” is to make everything a “method” instead of a function. <- My best description of where I feel it turns strange when using a functional language.

Lambda/Sierra15:06:29

@mokr You only need "methods" in Clojure if you need polymorphism: different behavior for different types, where the caller doesn't know which type it is.

mokr16:06:25

@stuartsierra I believe that is the use case I have in my current project, hence the desire to finally dive into records and protocols. I’m using re-frame for the GUI, and tend to aim for generic code. In this case I’m presenting information where the GUI code displays :display, creates tooltip from :tooltip, sets react key from :react-key and so on. What these keys contains differs based on type. I like the way generic code makes it clearer what the code is trying to accomplish, without mixing in a lot of “how”. Now the plan is to turn these keys (:display, :toolstip, :react-key, …) into method on a protocol like “Displayable”. Anyway, thanks so much for the imput. Now I need to focus on dinner preparations.

lwhorton16:06:25

what’s the idiomatic way to guarantee some unknown value is inside a sequence, where that value could or could not already be in a sequence?

lwhorton16:06:14

(into [] val) ;; fails if val isnt already in a seq
(conj [] val) ;; always works but might nest, i.e. [[val...]]

lwhorton16:06:23

(oh and not be nested, if already in a seq)*

lwhorton16:06:38

is it simply (flatten (conj?

noisesmith16:06:44

(if (sequential? val) val [val])

noisesmith16:06:50

flatten is terrible

Alex Miller (Clojure team)16:06:03

generally the best answer though is to arrange your data so this doesn’t occur in the first place

noisesmith16:06:15

the best thing is to not write code that sometimes returns a collection and sometimes a single item (but I realize you aren't always the one who implemented the source of the data)

Alex Miller (Clojure team)16:06:43

things that are either <foo> or <collection of foo> tend to be always broken and/or special cased

lwhorton16:06:51

^ agree with alexmiller, except in this case it’s relating to an (assoc vs an (assoc-in.. as in someone might hand me a value to put at [:foo :bar] or just :bar

noisesmith16:06:02

and they create contagious complexity in consuming code...

noisesmith16:06:24

@lwhorton there's a reason assoc and assoc-in are two different functions though

lwhorton16:06:37

if you’re familiar with http patch semantics, i’m trying to implement something following the {:op "replace" :path "/foo/bar" :value "bob"}. the issue is with :path, which could be some arbitrarily nested path into a resource

lwhorton16:06:12

so i figure assoc-in with a “guaranteed to at least be a sequence” is a good solution

noisesmith16:06:22

always turn path into a collection, even if it's a one item coll

lwhorton16:06:43

hmm .. that sounds smarter

joshjones16:06:11

and it's (computationally) cheap, versus the complexity that results otherwise

lwhorton16:06:48

thanks guys, great help

cpmcdaniel16:06:57

does anyone know of alternatives to slingshot for easily creating custom exceptions, or is it pretty much “de facto” if you don’t want to compile a bunch of custom exception types?

mpenet16:06:48

ex-info and ex-data is all you need

spieden16:06:26

@lwhorton i think of e.g. transforming a scalar to a single element collection as desugaring that happens in the first layer of code that processes some input

jeff.terrell17:06:47

@cpmcdaniel - I've used hara.event before and enjoyed it. It's a little more than custom exceptions, though. It changes how control flow works with exceptions to be more like how Common Lisp does exceptions.

alricu18:06:03

Hi all, Is there any way to create a hashmap interactively. I mean, I have the keys and values in separate lists and I need to associate as a hashmap

alricu18:06:23

for instance I have a list keys with 1 2 3

alricu18:06:42

and values list "one" "two" "three"

alricu18:06:11

and need to create {:1 "one" :2 "two" :3 "three"}

alricu18:06:52

my problem is that I do not have an actual list

alricu18:06:12

I use a method to get each element of the list

alricu18:06:26

for instance I use doseq to get each value

alricu18:06:46

how can I create a vector with the elements of the Doseq?

hiredman18:06:15

don't use doseq

hiredman18:06:54

(reduce (fn [m k] (assoc m k (* 2 k))) {} (range 10))

eriktjacobsen18:06:16

Want to share code? Could you just wrap your method into a lazy-seq? a list where each item is the result of a function is still a list.

noisesmith19:06:27

@alricu aside from the other excellent answers, if your inputs are [:a :b :c] and [1 2 3] this is exactly what zipmap is for

noisesmith19:06:28

also, please don't use :1 - the clojure reader accepts this keyword, but it's not actually valid, it's perfectly acceptable to use a number as a key in a hash-map if that's what you need

eriktjacobsen19:06:18

Why isn't :1 valid?

noisesmith19:06:11

the reader accepts it but the clojure docs rule it out

noisesmith19:06:19

which means that in the future the reader might stop accepting it

noisesmith19:06:53

I admit that's unlikely, but when we have the choice, I think it's better to not use things that clojure claims it shouldn't accept

noisesmith19:06:54

@eriktjacobsen for example cljs read-string doesn't allow it

noisesmith19:06:07

and that's not a cljs bug, since clojure's docs already say it's not valid

noisesmith19:06:43

there's lots of things that accidentally work in clojure, but we shouldn't assume are intended

noisesmith19:06:11

+cljs.user=> (cljs.reader/read-string ":1")
TypeError: Cannot read property '0' of null
+cljs.user=> (cljs.reader/read-string ":a")
:a

jaydeesimon19:06:19

i’m currently diagnosing some garbage collection issues and am wondering if maybe i should be using the oracle jvm instead of openjdk

jaydeesimon19:06:34

i cant find any evidence that it matters but i cant say for sure

ghadi19:06:41

it won't make a difference

jaydeesimon19:06:43

does anyone have any opinions on thi?

ghadi19:06:51

you suspect a leak in your code?

jaydeesimon19:06:27

no, im looking into very long stop the world pauses ~20 secs

jaydeesimon19:06:46

i guess im wondering if the implementation of garbage collectors makes a difference

jaydeesimon19:06:56

ok i just wanted to hear someone say it wont make a difference because that’s my instinct too

jaydeesimon19:06:13

while we’re on the topic, just so i’m clear, the implementation of g1 garbage collector in openjdk is different than the implementation in oracle jvm right?

ghadi19:06:23

it is not different @jaydeesimon

jaydeesimon19:06:46

ok thank you for clarifying that

ghadi19:06:35

have you looked at heap profilers?

ghadi19:06:04

the choice of GCs makes a difference with pause times, and your allocations are going to be workload dependent...

ghadi19:06:42

i've found usually that there's an offending spot in my code, but it can be tricky to track sometime

ghadi19:06:53

A quick temporary fix for long pause times is to a) make your max heap size smaller and b) remove any JVM command line flags that somebody pasted into your deployment (probably directly from stack overflow)

noisesmith19:06:42

I was almost going to mention that making the heap smaller thing, but then I realized it sounded really weird and I didn't have a cite... thanks for confirming that though

noisesmith19:06:26

also, I recently learned the term "jvm smoke break" for this kind of problem, which I find amusing

ghadi19:06:44

the advice is totally counterintuitive. mem leak => long GC => increase heap size => larger leak => longer pause time

hmaurer21:06:48

Hi! Is Clojure 1.9 stable enough to start a project on it now which will be pushed to production in a couple of months?

jaydeesimon21:06:58

@ghadi which heap profilers do you recommend?

hmaurer22:06:57

Is it ok to have side-effects in clojure specs? e.g. a database call. The application I am thinking of is checking that an email hasn’t already been used on a “signup” API payload

hiredman22:06:49

seems gross

gmercer22:06:53

@hmaurer only if idempotent

hiredman22:06:09

and implies effectively global scoping of the database connection, which is also gross