clojuredesign-podcast

Discussions around the Functional Design in Clojure podcast - https://clojuredesign.club/
nate 2020-11-15T00:00:47.072700Z

I haven't yet written any property-based tests. I would like to investigate using them, but haven't so far

jrwdunham 2020-11-15T00:01:43.072900Z

property-based tests are interesting, but often I find that I they simply cause me to re-implement something in a different way and test that both implementations generate the same results given equally spec-conformant inputs

jrwdunham 2020-11-15T00:02:28.073100Z

which can seem wasteful, but might be a good "laying-bare" of what testing actually is...

nate 2020-11-15T00:02:36.073300Z

that is a very keen insight

nate 2020-11-15T00:03:24.073500Z

much of the stuff I've recently tested would require a non-trivial generator to make the inputs as internally consistent as my hand-crafted data

jrwdunham 2020-11-15T00:04:03.074200Z

yeah, and crafting that generator would probably be a long way towards reimplementing your core logic (i'm guessing)

nate 2020-11-15T00:04:11.074500Z

precisely

neumann 2020-11-15T00:04:14.074700Z

For me, tests are most useful for testing the edges of a pure data model.

neumann 2020-11-15T00:05:29.076400Z

@nate and I end up with a lot of simulation style logic, so we have to handle different events that affect the state. It’s all a pure reducing-style data model.

neumann 2020-11-15T00:05:54.077200Z

The functions take the state and an event and return the new state.

neumann 2020-11-15T00:06:34.078200Z

Like what we talked about in our first couple of episodes on Tic Tac Toe.

neumann 2020-11-15T00:07:07.079100Z

Tests are great to ensure certain properties are preserved by the state transforms.

jrwdunham 2020-11-15T00:08:02.079400Z

Yeah, that all makes sense to me, I think. It can be a fine line not crossing those edges and ending up testing the database/API on the other side of that line though.

jrwdunham 2020-11-15T00:08:39.079600Z

but I think you're right that the edges are the place to look for where testing might be valuable, or particularly hairy blobs of logic (pure functions)

jrwdunham 2020-11-15T00:10:30.079800Z

i've been working with someone who's been telling me that we write tests when we can't understand something, so we should probably just understand it better

nate 2020-11-15T00:17:41.081600Z

Agreed. Tests are a tool to make sure code keeps on working, not to understand it. Fiddle code is a great tool for understanding code.

2020-11-15T02:51:10.083900Z

on the topic of rich comments containing tests, i have been using this a bit: https://github.com/sogaiu/alc.x-as-tests one can put simple tests within rich comments like this:

(comment

  (- 1 1)
  ;; => 0

 ,) 
there is a "runner" mode which can execute these tests

neumann 2020-11-16T16:51:03.085Z

@sogaiu That's neat! I could see that being useful for simple tests or getting some tests going quickly. Do you use code folding in your development environment? One of the reasons why I created separate "fiddle" files was to get the non-production code into its own place.

nate 2020-11-16T18:14:34.086900Z

This is interesting. Reminds me of Stuart Halloway's https://github.com/cognitect-labs/transcriptor

genekim 2020-11-16T23:53:43.093Z

OMG. I just learned how I could use commas to keep that last paren on a separate line!!! πŸŽ‰

nate 2020-11-16T23:54:37.093400Z

ah, that keeps it from jumping up to after 1)?

πŸŽ‰ 1
2020-11-17T01:59:42.093700Z

@neumann indeed i do use code-folding for comment blocks when using emacs. still trying to get that to work well in neovim but haven't had much luck there πŸ™‚ fwiw, in emacs i do something like:

(add-hook 'clojure-mode-hook
              (lambda ()
                (hs-minor-mode)
                (setq hs-hide-comments-when-hiding-all nil)
                (setq hs-block-start-regexp "\\s(comment")))

2020-11-17T02:01:54.093900Z

@nate yes, this definitely takes inspiration from stuart halloway's transcriptor. i don't know if you've taken a look at mal, but i just noticed in the last few days that its test files do something similar.

2020-11-17T02:05:38.094100Z

@genekim i learned about the "door stop" technique in #parinfer -- though there folks were using other constructs such as [] to achieve the same end. i have been collecting good uses for the comma in clojure -- it appears it's got more to it than at first glance. this particular use of "preventing the editor from moving things around" i also use for formatting part of cond forms and a few other places.

2020-11-17T02:12:50.094300Z

@neumann ah i forgot to mention -- one of my ulterior motives is to try to get simple / illustrative uses to live close to definitions. so i decided to try having the examples / tests live in the same file as the definitions. i'm not trying to have a comprehensive testing system -- it's supposed to be light and informative. geared toward explorative phases of development. i wrote a version for the janet programming language first before making a port to clojure. in both implementations, separate files are generated containing tests and these can be used as a starting point for more traditional testing if desired.

nate 2020-11-17T02:32:56.095700Z

@sogaiu I have folding working in neovim. I'll dig up the proper config bits when I'm at my terminal again.

2020-11-17T02:50:28.095900Z

@nate wow, that'd be great! looking forward to it :)

nate 2020-11-17T04:06:56.096100Z

@sogaiu I use https://github.com/gberenfield/cljfold.vim, with this in my vimrc:

let g:clojure_foldwords = "def,defn,defmacro,defmethod,defschema,defprotocol,defrecord"

2020-11-17T04:18:14.096400Z

@nate thanks! i gave that a try using "comment" as the value. unfortunately, the fold somehow seems to "swallow" defns that follow comment blocks. fwiw, here is a relatively minimal section of code that demos it here:

(ns my.ns)                                                                                                           
                                                                                                                     
(comment

  (+ 1 1)
  ;; => 

  )

(defn my-fn
  []
  :my-value)
any ideas about this? (it also seems to match on "comment-block?" which by sheer coincidence happened to be in the file i tested.)

nate 2020-11-17T04:19:44.096700Z

interesting

nate 2020-11-17T04:23:08.096900Z

perhaps put another new line between the end comment paren and the defn?

nate 2020-11-17T04:23:22.097100Z

I've found the cljfold to be a little eager sometimes

2020-11-17T04:34:35.097300Z

the extra line did it! thanks πŸ™‚ on a side note, i've been looking at nvim-treesitter recently. they seem to have plans for some folding, so perhaps there will be other options before long.

nate 2020-11-17T04:37:23.097500Z

indeed

2020-11-17T04:56:34.097700Z

for any interested parties, i jotted down some of the situations i've found the comma to be useful in: https://gist.github.com/sogaiu/d8d2b9765bef37f645211d4d5df1d7c8 happy to hear about other uses too :)

neumann 2020-11-17T22:43:29.098100Z

@sogaiu I like your idea of putting illustrative uses of a function near to the function. That is indeed handy. @nate is definitely more hooked on code folding than I am, but I can see how folding helps to eliminate some of the visual noise associated with mixing the function code and the example code.

2020-11-17T22:51:39.098500Z

i haven't found anything other than folding so far, but perhaps there are other alternatives (or will be at some point). at the moment i'm happy at least this option exists πŸ™‚ on a side note, i've also experimented with applying folding to long strings such as docstrings. i'm usually grateful for docstrings those but also find that those can interfere with my code reading process sometimes.