Fork me on GitHub
#clojure
<
2017-04-03
>
didibus03:04:13

Question: How do people set up spec.check to run automatically? Like through lein test?

seancorfield03:04:43

@didibus The simple answer is that generally folks don’t. Generative testing should be considered separate from regular xUnit-style testing, so you’d normally have your generative testing handled separately from lein test.

seancorfield03:04:08

At Clojure/West, Alex Miller talked briefly about an experimental test runner that Cognitect are working on that would run continuously, invoking check as needed on functions that either have changed or which are dependent on other functions that changed.

seancorfield03:04:27

(BTW, there’s a #clojure-spec channel for more in depth discussion if you want)

didibus03:04:50

Oh, that sounds really nice. Ya, that's true, if nothing in the path of a function has changed, checking it again is just expensive for nothing.

seancorfield03:04:29

All that said, if you have only a few functions to check and you know they don’t take long, you could always write a deftest that called check on them.

didibus03:04:38

I didn't get much luck with answers over there, I don't think a lot of people look at it actively.

didibus03:04:17

Ya, I think this is what I'll do in the meantime. Thanks

seancorfield03:04:38

People who use clojure.spec probably pay more attention there than here 🙂

seancorfield03:04:15

Bear in mind that a) most US folks are probably not around much on Sunday b) it was Clojure/West this past week and a lot of those folks were traveling Saturday — you are likely to get more eyes on channels weekdays, during US office hours.

didibus05:04:56

Makes sense, I'll try and keep my spec questions in the other channel.

bcbradley06:04:12

I was wondering if there were anything like reductions from core except for transducers. Something like transductions maybe.

qqq06:04:37

is there a 'best of cljoure west' list somewhere? I know that all talks were great; but given limited time, one can only watch so many

didibus06:04:47

@qqq I can recommend my favs: Synthesis and Verification for All. Clojure Java 9 and You, Why Clojure?, Core.Async in use. I did not watch all 25 talks though, but out of the 10 or so I did, those were my highlights.

qqq06:04:49

Synthesis + Verification looks really interesting.

seancorfield06:04:25

@qqq Yeah, that was a good talk. She has done work with Prof Dan Grossman. I'm one of the mentors for the online version of his Programming Languages course.

seancorfield06:04:33

Her talk was particularly interesting to me because many years ago I did work on compilers to verification languages (MALPAS) so it was awesome to see how far that field has gone -- her recent work on Rosette is incredible!

seancorfield06:04:32

And, yeah, I'll second the other recommendations from @didibus -- Toby's talk about Java 9, and Tim's talk about core.async.

qqq06:04:29

Hmm, it's based on Racket. Is there a clojure port yet? 🙂

seancorfield06:04:36

Elizabeth's talk about Datomic finally helped me understood how it actually worked -- I downloaded Datomic that morning and have been playing with it ever since.

qqq06:04:52

What makes Racket better than Clojure for building DSLs

seancorfield06:04:45

Racket is a programmable language. You can easily create completely new dialects on top of the Racket engine.

qqq06:04:10

How is this different from clojure macros?

seancorfield06:04:28

It's also great for teaching since you can create subset and simple languages and let people build up to full Racket.

seancorfield06:04:42

Hard to explain -- you'd have to go learn it.

seancorfield06:04:04

How To Design Programs is a good book that focuses on the teaching language aspect of Racket

seancorfield06:04:17

Written by Matthias Fellesien (sp?).

yubrshen07:04:14

I have to develop in C++, but I wonder if there is any possibility to use Clojure to implement some of form of test for C++ code, treating the C++ code as data? I feel hopeful of the possibility after Watching the talk of Magic: Boom. Symbolic Assembly: Using Clojure to Meta-program Bytecode by @ra https://t.co/wzMBdKEvn6 Any pointer or comment is appreciated. I hope that the approach would increase productivity and rigor othe tests.

gazaxian08:04:44

Does anyone know if I can get a human readable string for a protocol fn?

gazaxian08:04:06

so for (defprotocol IFoo (foo [_] ))

gazaxian08:04:27

(str foo) returns an anonymous func str

gazaxian08:04:32

as does (type foo)

gazaxian08:04:38

which I can’t get the name from 🙂

gazaxian08:04:07

I could query the IFoo map I guesse? but that seems over the top

gazaxian08:04:18

I have a state machine and am using the protocol function as the state identifier 😄

qqq08:04:50

((juxt f g h) x) ==> [(f x) (g x) (h x)] is there a FOO where ((FOO f g h) [x y z]) ==> [(f x) (g y) (h z)]

gazaxian08:04:52

I could use keywords but dispatch would be a slightly slower and I want the str for debugging purpose

gazaxian08:04:46

that sounds very monadic and confused me qqq 😄

rauh08:04:51

@qqq use map with 3 arguments

qqq08:04:55

@gazaxian : sorry for interrupting your question

bcbradley08:04:01

hrm i'm having difficulty trying to conceptualize how i would make a transducible process that performs the job of reductions

cddr08:04:23

In our project tests, we are depending on a little bit of an upstream java project's test infrastructure. We are able to pull it in using this line in lein [org.apache.kafka/kafka-streams "0.10.1.0" :classifier "test"] Now I'm trying to download the sources for this dependency but I think because it has a non-standard classifier, mvn dependency:sources does not find it. Anyone know the correct incantation to get the sources for this?

qqq08:04:50

how does the clojurebot work, and how do I use it?

Niclas12:04:11

I’d like to know peoples’ opinion on implementing Go’s idiomatic error handling style in Clojure: https://blog.golang.org/error-handling-and-go In Clojure it might look something like:

(let [[res err] (db/query ...)]
  (if err
    ... handle error...
    ... handle result...))
Personally I find it to be a clean way of propagating errors throughout larger apps without littering the code with try/catch (which i.m.o. is a fundamentally flawed way of control flow) but I’d like to know your opinions on the pattern.

mrchance12:04:03

@looveh I like it too, Clojure has some libs for that, like https://github.com/adambard/failjure

lsenjov12:04:09

I hate Go's method of it. After every line of work, there's at least three lines of if err != nil {

lsenjov12:04:15

It makes code really difficult to read

mrchance12:04:34

@lsenjov The concept itself is sound, it's just the boilerplate around it and the lack of variant types that makes it ugly

mrchance12:04:45

My opinion at least 🙂

lsenjov12:04:01

The concept may be sound, but it makes code harder to read

mrchance12:04:16

When you have monadic composition along with it, it actually works out nicely

lsenjov12:04:33

I prefer exceptions over go's method, because (usually) the work of a function is all in one place

mrchance12:04:01

Personal preference I guess, but exceptions have their own problems

lsenjov12:04:03

I'm not suggesting using them for control flow, but for error handling and recovery

lsenjov12:04:29

I'm not saying they don't have their own problems, I just hate reading golang code because of this problem

mrchance12:04:45

The problem is that you don't get one without the other, if you have exceptions but handle them incorrectly you get weird control flow

lsenjov12:04:46

It takes a much longer time to figure out what a block of code actually does

mrchance12:04:10

Sure, if it increases volume by a factor that's the expected result 😉

lsenjov12:04:52

I'm more saying that exceptions are generally used in two cases: abort or self-heal (from my experience, if it's used differently feel free to correct)

lsenjov12:04:14

If it's abort, and multiple functions abort, why not have the abort code in one section?

lsenjov12:04:34

And for self healing, we can recur with fixed inputs

lsenjov12:04:57

As usual, your mileage may vary, but he asked for people's opinions 😛

mrchance12:04:09

Short circuiting serves the same purpose, and it doesn't need something that is essentially a goto

mrchance12:04:16

But yeah, opinions 😉

ghadi12:04:32

Any standout talks from Clojure/West?

jumar12:04:54

Check the former discussion in this channel - starting 6:10 UTC: https://clojurians.slack.com/archives/C03S1KBA2/p1491199837737261

bronsa13:04:03

obviously biased but i really liked nasser and tbaldridge's talks

nasser13:04:17

The time travelling NES emulator by @angusiguess was super cool

bronsa13:04:37

oh i haven't watched that yet, will do

danielgrosse14:04:49

I try to refactor a core.async function with transduce. I have a async caller, which returns a vector of numbers, now I use doseq to go over this numbers and put them in a channel. On this channel is a map transducer, which uses the async caller again with the id. This returns a channel, containing a map. Now I have a channel with a channel inside which contains the map an I have to use (<! (<! chan)) to get the value. Is there a way to return this maps in the containing channel?

(defn async-caller
      [args]
      (let [out (chan 1 xf)]
           (call-fn args {:success (fn [res] 
                                       (async/put! chan res) 
                                       (async/close! chan))})))


(defn foo
      [arg]
      (let [xf (map (fn [id] (async-caller id))
                    channel (chan 1 xf)
                    response-chan (async-caller arg))]
           (go-loop  [] (let [response (<! response-chan)]
                             (doseq [id response]
                                    (>! channel id))
                             channel)))) 

mrchance16:04:08

This looks pretty weird, where does the chan above come from, why is "out" unused in async-caller... I might be able to help you with a more complete example

danielgrosse06:04:44

(defn async-caller
  "Calls a remote function on a server, which returns a value on success 
  in the future. The uri is the route to the function."
  [uri args]
  (let [out (chan 1 xf)]
    ;this calls another function which handles the connection
    ;the returned values are put into the out channel
    (call-fn uri args {:success (fn [res]
                                  (async/put! out res)
                                  (async/close! out))}
             out)))

(defn foo
  "Receives the ids on the first call and then calls the function again with the result values"
  [arg]
  (let [xf (map (fn [id] (async-caller "path.getinfo" id)))
        channel (chan 1 xf)
        response-chan (async-caller "path.getids" arg)]
    (go-loop []
             (let [response (<! response-chan)]
               (doseq [id response]
                 (>! channel id))
               channel))))  

danielgrosse06:04:45

I reworked it a little. Maybe its now better to understand.

mrchance07:04:50

It is 🙂 Do you really have to use a channel of channels? I feel like a flat channel would be simpler here. I'll try to rewrite it a little

mrchance08:04:09

I would recommend something along these lines

(defn foo
  "Receives the ids on the first call and then calls the function again with the result values"
  [arg]
  (let [xf (map (fn [id] (async-caller "path.getinfo" id)))
        channel (chan 1 xf)
        id-chan (async-caller "path.getids" arg)]
    (go
      (onto-chan channel (<! id-chan)))
    channel))

mrchance08:04:17

Should be even easier with async-pipeline

mrchance08:04:42

It looks like your call-fn will only ever return one result, so you don't really need a go-loop

mrchance08:04:41

Especially without recur...

danielgrosse08:04:02

Thank you for the tips. The problem is, that I have to make the two calls, as they go to a different uri.

uwo14:04:10

is it a known issue that you can do (keyword “namespace” “1”) but you cannot do :test/1 ?

mpenet15:04:39

"1" is not a valid keyword, even tho it might allow you to create it via keyword : garbage in->out

dpsutton15:04:38

user> (source keyword)
(defn keyword
  "Returns a Keyword with the given namespace and name.  Do not use :
  in the keyword strings, it will be added automatically."
  {:tag clojure.lang.Keyword
   :added "1.0"
   :static true}
  ([name] (cond (keyword? name) name
                (symbol? name) (clojure.lang.Keyword/intern ^clojure.lang.Symbol name)
                (string? name) (clojure.lang.Keyword/intern ^String name)))
  ([ns name] (clojure.lang.Keyword/intern ns name)))
nil
user> 

mpenet15:04:54

https://clojure.org/reference/reader has the "spec" if we can call it that way

jsdiaz1915:04:40

can anyone help me to program a socket in clojure? i am new programming in clojure

gonewest81815:04:58

A socket to do what?

jsdiaz1915:04:42

i have to make a tcp cliente, i have to connect two terminals that i receive and send messages

jsdiaz1915:04:56

can anyone help me?

jstew15:04:51

@jsdiaz19 - Seems like a pretty straightforward assignment. You're either going to end up using Java interop, or this: https://github.com/atroche/clj-sockets

jstew15:04:40

Personally I would just use Java interop, since your assignment won't require much in the way of code.

dpsutton15:04:44

the code for the clj bot has a sockets implementation if you want to look at it https://github.com/verma/clj-slackbot

puzzler18:04:13

@qqq @seancorfield If you want to understand how Racket helps you build languages, you need to check out the online book "Beautiful Racket" at http://beautifulracket.com

puzzler18:04:47

If we really want to make Clojure a great experience for students, ideally, we need someone (summer of code?) to make a "Racket language" that is a subset of Clojure that can be used to work through the entirety of How to Design Programs curriculum in DrRacket using Clojure syntax and semantics. That way, we get interop with the functional graphics/animation libraries and integration with the pedagogical IDE (stack illustrations, etc.) for free.

qqq18:04:49

@puzzler: interesting

qqq18:04:28

@puzzler: how is racket support for (1) react/js [whalesong looks not as well done as cljs] and (2) persistent datastrcutresu?

qqq18:04:38

decent js support + persistent data structures = enough for me to switch

puzzler18:04:25

I know there's some kind of compiler from Racket to javascript that is used to power http://wescheme.org. I'm not aware of react support. There is a student-written library of persistent data structures, not integrated into the language the way it is with Clojure. But I'm not arguing that people should be switching to Racket. I'm arguing that a Clojure implementation in Racket would be the best way to on-ramp beginners to Clojure. It wouldn't even have to be a full implementation of Clojure, just a rich enough subset to work through a textbook.

qqq18:04:57

If it's truly that much beter than clojure for writing new languages, I want to learn it, and if I need to learn it, having decent js supposrt would be n ice.

tbaldridge18:04:01

there's other things that are less-than-nice in Racket though....like I think they only recently got a GC that didn't require restarting the interpreter every so often.

qqq18:04:24

how is it a GC if you have to restart the interpreter ?

noisesmith18:04:35

yeah - racket is awesome for learning, but I don't see much case for using it in prod

qqq18:04:35

that's like saying "malloc" is a GC

qqq18:04:01

Isn't Arc / Hackernews built on Racket?

noisesmith18:04:10

yes, and slashdot is php

eraserhd18:04:55

Tell me about best practices exposing a REPL from production systems. I'm thinking binding to localhost and ssh tunneling.

noisesmith18:04:14

eraserhd instead of using nrepl, us the clojure built in socket server

eraserhd18:04:16

The app has a web interface, so perhaps there's a web REPL that's an easy drop-in?

noisesmith18:04:23

it's available as a jvm flag without changing your code

noisesmith18:04:26

and yes, ssh in

eraserhd19:04:57

And rely on external tools (tmux in my case, emacs in other peoples' cases) for editing expressions and history and stuff?

noisesmith19:04:13

or just rlwrap

noisesmith19:04:35

with rlwrap, there's a shared history that ends up in a dot file by default

eraserhd19:04:09

Ah, I guess I could rlwrap ssh .. nc localhost:whatever

noisesmith19:04:30

that's exactly what I do, yes - well I use telnet but close enough

noisesmith19:04:35

in extreme cases I've even hot-patched code this way. It's possible but not something I recommend...

noisesmith19:04:19

or, a more benign example, change timbre's logging level without a restart

eraserhd19:04:33

Heh. Well the next thing I need to figure out is that I'm using component, and the system that's running doesn't have a global reference anywhere. 🙂

eraserhd19:04:04

I mostly need to run a few queries, maybe transact some data, kick a component that gets stuck.

triss19:04:40

hey all. off topic but what is your favourite way to clean up a strng with HTML tags in it?

triss19:04:52

I want to strip the HTML tags out compleetly

triss19:04:13

I guess there is a library lurking somewhere?

eraserhd19:04:35

Does it have to be in Clojure? From the command line, links -dump foo.html > foo.txt

noisesmith19:04:41

with enlive you can take an html string and extract eg. the content of each node

eraserhd19:04:47

(or lynx or elinks or whatever)

triss19:04:05

thanks chaps

triss19:04:20

will take a peak

noisesmith19:04:39

with enlive I think you'll want the [:body :> text-node] selector

noisesmith19:04:56

but it might be a bulldozer where you need a spoon

noisesmith19:04:28

@triss oh, and I just found this mailing list thread that might be informative https://groups.google.com/forum/#!msg/enlive-clj/rrY08JdI4Tc/FmDuNjc6w_oJ

dpsutton21:04:14

in a ring app, need to redirect in the route handler and it's not obeying the site base-url. Has anyone run into this in the past?

qqq21:04:13

Is it by design that (transient (transient {})) throws an exception?

qqq22:04:35

does java, by itself, have any databases builtin?

qqq22:04:53

there's all these libraries for extenral database ot use -- but the jvm seems ot ahve everything else, and I'm wondering if there's builtin dbs I can just use directly from clojure

puzzler22:04:23

Some versions of java come with Derby built in, I believe.

tanzoniteblack22:04:25

h2 can be used directly as a library that runs without external processes

puzzler22:04:38

H2 isn't built into java, but it is popular as a lightweight embedded database.

tanzoniteblack22:04:16

I guess it depends on what you mean by "builtin"; if you mean it runs in memory without external processes, h2 works for that (and so does sqlite, if you specify in memory?). If you mean available without having to include a dependency, then none that I'm aware of.

qqq22:04:37

yeah, I should have clarified; I was thinking "no external dependency"

qqq22:04:58

JDK provides everything else in its library; was surprised there was no database.

turbopape23:04:15

I am pretty happy with Berkeley JE

turbopape23:04:11

Try postagga, the natural language parser, with more accurate proper names detection, shipped with english and french