Fork me on GitHub
#clojure
<
2018-06-27
>
mg01:06:44

@hiredman @shayanjm also this great talk on generative testing https://youtu.be/iYu_TrQJ8iU

Desmond07:06:51

hi i'm seeing an error i can't make sense of. I get this error even when I revert back to old commits that were definitely working, remove the target directory, remove .m2 directory, and rebuild from scratch. i'm very confused. how could this error happen with code that used to work? any guidance would be greatly appreciated.

java.lang.IllegalArgumentException: No implementation of method: :query* of protocol: #'reflection.util/IDataSource found for class: reflection.component.datomic.DatomicDataSource

aleksandr07:06:59

Hello! Can anyone tell me how to make an :after pseudo-selector in the Garden

aleksandr07:06:55

Garden doesn`t compile :after correct. If i wanna a word in a :content option, then Garden insert the word without ''

aleksandr07:06:21

So an after doesn`t display at all

aleksandr07:06:57

And another question How can I append native css files to a result compiled garden file?

gv11:06:56

Are there known problems with sort and vec? It seems to make a difference whether I use (vec (sort ...)) or (into [] (sort ...)) - the second returns the desired result

jmckitrick13:06:29

Is it safe to say that stest/instrument is not really a replacement for mocks via with-redefs ?

hyankov13:06:07

Can you give a specific example? Some quick examples work for me:

(def v [5 7 1 3])
(sort v) -> (1 3 5 7)
(vec (sort v)) -> [1 3 5 7]
(into [] (sort [5 7 1 3])) -> [1 3 5 7]
@gv

hyankov13:06:39

Can you give a specific example? Some quick examples work for me:

(def v [5 7 1 3])
(sort v) -> (1 3 5 7)
(vec (sort v)) -> [1 3 5 7]
(into [] (sort [5 7 1 3])) -> [1 3 5 7]

Nicolas Boskovic15:06:21

What's a good way of using try catch within a loop to break program execution on a function that fails within the loop?

Nicolas Boskovic15:06:00

(loop (try ... (recur ...) (catch ...))) doesn't seem right

bronsa15:06:18

it’s not even valid clojure

bronsa15:06:40

you just can’t recur to a loop point outside a try-catch block

Nicolas Boskovic15:06:43

So how could I handle this?

Nicolas Boskovic15:06:25

The idea is for the program to explode and notify on any failure, but if I don't catch the error in the loop I'll get the exception but not the stoppage

hiredman15:06:00

(try (loop ... (recur ...)) (catch ...)

matan16:06:28

Can one use clojure.spec for verifying an input json file yielding meaningful error messages? this is meant for a command-line tool that takes an input json file that is converted to edn

justinlee16:06:30

@matan do you mean verifying that the json is well formed and providing meaningful error messages in the case that it is not? the usual case people seem to be worried about is whether well-formed json has a particular structure. you can definitely use it for the latter case

matan16:06:46

@lee.justin.m thanks. I'm trying to come up with a pattern that will have some elegance.. will see what I come up with

jmckitrick16:06:13

Is it fair to say stest/instrument mocks should really only be used with generative testing and not standard unit tests?

matan18:06:41

@lee.justin.m as a curiosity, I have found a json schema validation library a more natural solution to the scneario

matan18:06:41

Those libraries sport error messages that are almost humane, while covering the entire range of errors that your json schema implies. (I have derived for this a schema from a sample valid json of mine, through those online pages that make this derivation).

justinlee18:06:05

@matan i don’t think anyone is elated with the current status of error reporting in spec. the expound library is a big help. phrase looks cool too. I’m pretty sure spec is going to be way more expressive than json schema, but that probably means that json schema can produce higher quality diagnostics. i think there are just tradeoffs

matan18:06:26

Fully agreed about the tradeoff of course.

matan18:06:36

Thanks for mentioning those spec add-on libraries, I should have a look...

rplevy19:06:38

There's some debate on my team/company over a house style practice of including examples in the code with a function's definition. e.g.

(defn x [y z] ... )
#_(x "foo2321312" "bar134324")
It looks a little messy but it has utility. It's not something you would replace with a test, because they are often example values within the context of a stateful system (database, etc). They aren't tests, they are a memory of recent usage in the context of interactive, stateful, repl-driven development. And it's also convenient to have the example next to the function. But ugh it looks sloppy, and sloppy code breeds more sloppy code. I'm thinking something like
(defn ^{:doc "the doc string"
        :usage ["foo11121212" "wee23322"]}
   x [y z] ...) 
And then editor tooling to support in-line execution with example usage. It would be pretty easy/quick, though I'm wondering if someone else has addressed this problem (better?) already.

practicalli-johnny21:07:12

@rplevy I have used the #_ syle of comments for what I call my REPL Experiments in my own projects. However, instead of in-lining this experimental code after each function, I have a separate section at the bottom of the file which is clearly separated from the production code These REPL experiments show the story of how the code had been developed, showing design choices that did and didn't work, with some text comments for context.

👍 4
dpsutton19:06:02

Tough thing is drift. In 6 months will those code samples still work?

rplevy19:06:27

@dpsutton most likely no, but also no one would expect them to

dpsutton19:06:38

then i don't see a benefit to them

rplevy19:06:02

because you are developing and you see the sort of thing it is, and then you replace it and execute the code

rplevy19:06:16

we like to leave them there as a trace or hint

dpsutton19:06:22

but if the code doesn't work it just tells you the signature

rplevy19:06:52

in practice it's more helpful than it is not

dpsutton19:06:50

go for it then. i've been burnt by comments that lied to me in the past. i'd drop it in a test and assert something so you have to keep it up to date and it won't lie. but if you get benefit from it go for it

lilactown19:06:06

my usual workflow is: 1. write fn 2. write commented examples next to it as I iterate to test things 3. finish writing fn 4. put those commented examples in a deftest somewhere

lilactown19:06:27

If it's something that people would refer to as documentation, then I put them in a docstring

rplevy19:06:48

We're often dealing with state here, so it's typically not something that would go in a deftest in a way that would be easily repeated by the next person, e.g, in a deftest I would mock the stateful aspects, but the usage for an example is to actually involve the mounted state.

rplevy19:06:54

That's why say these are meant to be examples, not tests.

lilactown19:06:29

then I usually put them in a docstring so that they appear in people's editors without having to go to the definition site

lilactown19:06:59

they'll also appear in generated docs if you decided to go that route at some point

rplevy19:06:50

my suggested solution above is similar to a docstring but unlike a docstring it's not difficult to eval inline. At least in cider I'm pretty sure eval-last-sexp won't work inside a string

dpsutton19:06:31

don't believe so. You could put it in a comment form. the insert and eval commands have gotten better. they are comment aware

lilactown20:06:50

but also unlike a docstring it won't show up in my UI when I'm inside the form / hovering over it

lilactown20:06:17

if it's just an example I'm usually not trying to eval it

rplevy20:06:51

Well that depends on how you integrate the use of this metadata into your editor tooling

danielglauser20:06:33

I’d be afraid that it would litter up the code. If it works for your team then it works, however I wouldn’t deemphasize good docstrings that describe what goes in and what comes out.

rplevy20:06:04

Well it's already part of the culture here, I'm just trying to reduce litter

rplevy20:06:21

House styles are house styles

justinlee20:06:27

for what it is worth, i do this for state manipulation functions that have sort of complicated data types. i totally love it. i put one or two examples in a comment block. it’s just easier for me to read but drift is what i worry about. i would like to have a little concise test instead of a comment.

justinlee20:06:50

the reason i do it is because i always end up searching for a use of the function in the code anyway

👍 4
rplevy20:06:01

@danielglauser (I mean the commented out example style, which does lead to litter increasing)

rplevy20:06:50

I think the first place I saw this style of including usage examples in the code it was in some of Rich Hickey's code in core or contrib. I thought it was sloppy in that case as well.

justinlee20:06:28

you say sloppy i say pragmatic 🙂

rplevy20:06:32

I think it definitely has value and it's underrated as a practice, however one of the reasons people don't like it that it is a "broken window" in appearance that leads to further commented-out junk

danielglauser20:06:36

Broken windows was the first thing that came to mind. 🙂

rplevy20:06:55

Sonian alumni

danielglauser20:06:02

@rplevy I’m sure some of our colleagues would likely disapprove but I favor consistency over “correctness” and tend to go with a house style, then try and convince other folks that there is a better way. Which it sounds like, is exactly what you are doing. 🙂

👍 8
🙂 8
Nick Cabral20:06:10

anyone know of a great article about datomic that provides examples by analogy? eg. “heres a typical many-to-many relationship in SQL, here’s how you might model that idiomatically in datomic”, “here’s a foreign key contstraint in SQL…” etc.

rplevy20:06:50

@noisesmith I googled for a library called slopmatic, searched github, before realizing you were coining a portmanteau of sloppy and pragmatic 😂

😀 4
👍 4
noisesmith20:06:35

it totally sounds like a ruby lib

12
Nick Cabral20:06:13

the datomic docs seem okay. But coming in new, it’s tough to draw the line of “this is a constraint it’s safe to implement in client clojure code” vs “this is something that should be enforced at the schema level”

mg20:06:57

@nick652 you can really only enforce cardinality (one vs many) and datatype in the schema

mg20:06:35

if you have other transactional logic beyond that, then there’s transaction functions

Nick Cabral20:06:23

That helps a lot! If you don’t mind, I have one specific question that will provide a lot of context for me: since writes are always serialized, is it accurate to say that as long as constraint logic is in place, concurrency issues due to write are not possible? Or does datomic retry transactions on conflict, kind of like clojure ref transactions?

mg20:06:09

It’s not possible to have “concurrent” writes since the Transactor does one at a time. If a transaction function throws an exception, the whole transaction will get rejected and it’s on you to decide what to do about that

😁 4
Nick Cabral20:06:56

Wow that seems… a lot easier. The main exceptions the docs mention seem caused by badly structured or uniqueness-violating datoms. None of the traditional concurrency concerns like dirty-read, nonrepeatable-read, or phantom-read.

Nick Cabral20:06:05

Thank you for clearing all that up for me. It seemed too good to be true, so I needed it spelled out. ha

mg21:06:08

Oh right I forgot about uniqueness, that’s another thing the schema can enforce

mg21:06:37

You do have the possibility of dirty reads, in that you could do a query in your client to check against some constraint - “I need to make sure there are any widgets left in the inventory before selling one to this user” - and there could be an in-flight transaction where another user is buying the last widget. So you’d want a transaction function that checks that there’s at least 1 widget left as part of that transaction

Nick Cabral21:06:07

Oh right, definitely. I should have prefixed what I said with “Within a transaction…“. So as long as I’m checking constraints within a transaction, state will not change before the transaction is committed. That’s differs (in a great way) from typical SQL-style RDBMSs where you have to actually consider which transaction isolation mode you’re operating in.

mg21:06:51

Yes, sounds like you got the idea

Nick Cabral21:06:01

Postgres, for example, has SELECT * FOR UPDATE, where it takes a write-lock on the selected rows for the remainder of the transaction, to guarantee no other transactions mutate that data during your trans. No need to emulate that with datomic, it sounds like.

Nick Cabral21:06:05

Awesome, thanks again!

Garrett Hopper22:06:39

Is there a way to make a deps.edn alias depend on another alias?

Alex Miller (Clojure team)22:06:45

that way lies programming. write a program.

👍 4
Garrett Hopper22:06:36

Fair enough. 🙂 Does :main-opts do weird spliting on spaces? I can't seem to pass an inline edn to -co in it.

Alex Miller (Clojure team)22:06:24

currently broken, sorry. if you have spaces in edn (not in embedded strings), you can use , instead (since it’s also whitespace)

dpsutton22:06:19

the corfield comma it's called, i believe

seancorfield04:06:42

I'm just glad that the horrible "Koenig name lookup" in C++ got named after Andrew instead of me (I suggested it as a joke and he realized it would actually solve the problem and turned it into a concrete proposal!).

dpsutton04:06:33

whoa you have to have this written up somewhere

seancorfield04:06:28

Just Bing/Google c++ koenig lookup

seancorfield04:06:51

It's literally famous in C++ circles. Pretty sure it's even called that in books 🙂

seancorfield04:06:09

As for my contribution, I suspect I'd have to dig back into the full working group minutes for whatever session it was (I was on the ANSI C++ Committee for eight years, and secretary for three) 🙂

dpsutton04:06:10

that's super cool. i hope we cross paths at the next conj or strange loop.

seancorfield05:06:21

I'll almost certainly be at Conj (as usual 🙂 )

Garrett Hopper22:06:20

Oh, I hadn't thought about that. Technically my edn would work without the space anyways. I just stuck it in a file to keep it pretty. I just wanted to make sure someone was aware. 🙂