This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-07-22
Channels
- # aws (1)
- # bangalore-clj (3)
- # beginners (103)
- # boot (15)
- # cider (29)
- # cljs-dev (17)
- # cljsrn (43)
- # clojure (156)
- # clojure-gamedev (2)
- # clojure-italy (11)
- # clojure-spec (55)
- # clojure-uk (4)
- # clojurescript (76)
- # data-science (2)
- # datomic (7)
- # defnpodcast (2)
- # emacs (4)
- # leiningen (2)
- # luminus (3)
- # off-topic (11)
- # parinfer (3)
- # pedestal (1)
- # quil (1)
- # re-frame (3)
- # reagent (2)
- # ring-swagger (1)
- # timbre (3)
- # unrepl (10)
- # untangled (1)
- # vim (3)
- # yada (1)
I'll put some stuff out early next week - slides, code, and some more info
want to have a little more context than just dumping the slides. haven’t had a chance to do all that stuff due to the conf and today’s travel home.
I mean @alexmiller ^^
@mjo324_56 sh
is a blocking call:
(sh "ls")
(prn "finished")
(defmacro try-noooo "Returns the result of evaluating e, or :noooo if it throws an exception." [e] `(try ~e (catch java.lang.Exception _# :noooo)))(defn is-proc-running[p] (if (= (try-noooo (.exitValue p ) ) :noooo) true false))
@mjo324_56 If you use the built-in future to handle async, you can do this:
(def process-future
(future (sh "./my-script.sh")))
(when-not (future-done? process-future)
(prn "still running...."))
(let [result (deref (future (sh "./my-script.sh")) 100 :timeout)]
(if (= result :timeout)
(prn "time limit exceeded.")
(prn "process exited with: " result)))
Hi! What is the preferred way to do input payload validation for a json api in Clojure? If possible a solution that offers both input validation and machine-readable errors to be consumed by the client. Hopefully I won’t start a 40min heated debate like yesterday 😄
@hmaurer There are a few solutions. Compojure-API can use Schema or Spec. My own Ataraxy has spec validation in the latest version. There are also various validation and coercion libraries, but I think the most common approaches are Schema or Spec.
Spec isn’t designed around coercion so much, so I’m not sure how well it could handle that.
@hmaurer wrote a post about the coercion & error messages some time ago: http://www.metosin.fi/blog/clojure-spec-with-ring-and-swagger/.
I'm using integrant-repl and reading config from resources
folder in my preparer function (`(read-config (io/resource "config.edn"))`) and yet it won't pick up new values for mongodb host when I change them, forcing me to stop and start the REPL. Does this ring a bell to anyone? Any common gotchas?
I'd need to see more of your setup. If you're performing a reset, your prep function will be hit
Quick question: how can I pass a static function around? E.g. if I try to pass System/getenv
around I get Unable to find static field: getenv in class java.lang.System
that's a static method, methods unlike functions are not first class objects supported by the vm
you can't pass something as an argument that can't be put on the stack
that's why you need to create a function, which is an object (with a static method that gets called if you apply it)
so tl;dr there isn't a simpler way, that's the way you do it
@hmaurer you could check memfn
as well https://clojuredocs.org/clojure.core/memfn
@leonoel that doesn't work with static methods
and it's not any more succinct or efficient than creating a lambda in most cases
(that's what it actually does, it creates a function)
@noisesmith ah I see; I thought there might be something like that going on
hi all, i am trying to understand how reduce
works in the following example:
user=> (reduce str (repeat 3 "str"))
"strstrstr"
i don't understand why this returns what it does. can someone break down what reduce
is doing here?@rorysmith head to #beginners and I'll walk you through it
@weavejester yet another question on Integrant… Why is ig/suspend!
necessary? Couldn’t you do all the logic in ig/resume
? (naming it ig/swap
or similar). It seems to only be used when hot-swapping for dev
Consider the case of a web server. Suspend can tell the server to buffer connections until resume is called. After suspend we reload namespaces which can take several seconds.
Suspend and resume are only used for dev
ah right, so you wouldn’t be able to hot-swap in one go because reloading namespaces while requests are being processed would lead to issues I assume
Yes, because a promise blocks
Ah, so if the passed handler is a promise it will try to deref, which will block. ok.
Right
Suspend and resume are useful for keeping connections open and avoiding restart time during development.
Web sockets for example
How are you guys printing the guts of Java objects on the REPL? I'd love to be able to convert any java object to a graph of maps I can easily inspect. (similar to what the debugger in IntelliJ allows you to do)
I tried to make sense of clojure.reflect
but before I spent my time on that - shall we say - sparsely documented lib, I was wondering if someone had a neat java-to-map
fn
if I recall, bean used to be more general and didn't look for JavaBean specific stuff... let me see if I can find it
+user=> (bean (java.util.Date.))
{:day 6, :date 22, :time 1500741217657, :month 6, :seconds 37, :year 117, :class java.util.Date, :timezoneOffset 420, :hours 9, :minutes 33}
maybe it's that Date is a bean and I never realized it was?
yeah bean looks quite good
(bean (HTableDescriptor. (TableName/valueOf "foo")))
=>
{:familiesKeys #{},
:columnFamilies #object["[Lorg.apache.hadoop.hbase.HColumnDescriptor;"
0x124eda1b
"[Lorg.apache.hadoop.hbase.HColumnDescriptor;@124eda1b"],
:regionReplication 1,
:memStoreFlushSize -1,
:name #object["[B" 0x19dca84c "[B@19dca84c"],
:tableName #object[org.apache.hadoop.hbase.TableName 0x6328ce6a "foo"],
:metaRegion false,
:rootRegion false,
:compactionEnabled true,
:maxFileSi... snip
and you could start with bean's source code if you want something that isn't so JavaBean centric
I don't understand this line in the docs about clojure.spec "Thus a bare (s/keys) is valid and will check all attributes of a map without checking which keys are required or optional." What is it checking if there are no specs to check?
(s/def ::foo (s/keys))
(s/valid? ::foo {:yolo 42})
=>true
Are there any good debuggers that work at the bytecode level? I have cider, but I have an infinite loop somewhere, so I need ‘pause execution’
cider and cursive have this - to some degree, you need to turn off some clojure features for it to work well
usually I opt for adding (swap! debug-atom conj {:context ::foo :data foo}) in the middle of some function and then use the resulting atom in the repl to figure out what's going on (which does require iterating sometimes to figure out which data you should even be tracking of course)
@noisesmith is there an equivalent of Ruby’s “pry” in clojure? e.g. a way to open a repl at any point in a program, with access to local bindings?
@arohner I didn't check recently but at one point they were actually using jdx bindings to get into the byte code level - when I saw people claim "cider can debug like cursive now" I assumed that meant that feature was working
cursive definitely does byte code level debugging
@hmaurer that's hard with a compiled language
I don't think that exists, definitely not in a general way
@noisesmith that doesn’t look to be in the latest release: https://cider.readthedocs.io/en/latest/debugging/
@arohner oh, clearly I was misinformed and/or misunderstood what I was being told
thanks for the clarification
@hmaurer cider can do that by recompiling functions. Macros get access to all local variables in scope when compiling
i.e. (let [x 1] (my-dbg (inc x))
, if my-dbg is a defmacro, there’s an extra &env
variable that contains {x 1}
I find it easier to just use a macro that puts the locals in a hash map, then access it https://gist.github.com/noisesmith/3490f2d3ed98e294e033b002bc2de178
a bytecode debugger can see the locals in scope, but IIRC the compiler throws away the variable names in the bytecode, so you just get foo_1
, etc.
@arohner right that's the clojure feature I was t alking about - you can disable it
Has anyone used visualvm to profile clojure code?
I cant get it to work
yes - it works but yourkit is much better
is there any special setup in the project.clj to use YourKit? It seems a lot of feature are missing when i connect to my running repl
you might need to add jvm args to allow the kind of connection it wants
those would be the same args a java program would need
I've had a lot of luck with using the yourkit agent
seems to be working much better than visualVM
its hard to make sense of though
in the sense that it is hard to find which of my functions is taking the longest time amid all the clojure / java functions
yeah - it takes a while to figure out, I have a long term plan to do a talk on this topic
sounds good
my code takes 7 days to run ^^
but both are somewhat difficult because so much of profiling assumes that the class you are looking at is important, and most of the classes are going to be eg. clojure.lang.PeristentVector
it's definitely doable though - I've had a lot of help from profiling
well, I've been following the guide written here: https://torsten.io/stdout/how-to-profile-clojure-code/
@arohner oh, I haven't had that issue
it needs more time to start up for sure though
but it says Failed to Create JMX connection to target application
then you need to add the args to java to allow jmx connect
is there any good way to debug clojure without using a particular editor? (aka no cursive and no cider)
that's where swapping data into an atom excels
or you could use jdb - if you are familiar enough with clojure internals it can work
but it's confusing
@noisesmith funnily enough swapping data into an atom is the solution I came up with this morning
there's an old tool for setting up a "debug repl" that kind of worked but it was funky
@michaellindon are you specifically trying to get remote profiling working? Local clojure process should just work
@hmaurer as a level up from swapping into an atom, I also dump the relevant part so I can use it in a unit test when I figure out what is going on - I made a small lib for this https://github.com/noisesmith/poirot
@noisesmith oh yes, you sent that one to me already but hadn’t yet looked into it
@michaellindon oh - weird - I haven't experienced that issue, not sure what that's about
😞 Ive had this working on a remote process before... something about running it locally is not working
@arohner I just realized this would be relevant - if you send a signal you can make the jvm print all its stack traces (or you can use jstack from another terminal to get all stack traces by pid) and if you have a loop that isn't exiting a few stack traces should show where that's happening pretty quickly
I forget the signal name but on *nix terminals its bound to C-\
Can someone please remind me of the name of the clojure function which does the following: (f g :a :b :c) => [(g :a) (g :b) (g :c)]
?
@mobileink you did! that’s how I vaguely remembered there was a function for this, but I have the brain of a goldfish today so I couldn’t think of the name
Is there a form of resolved keywords which looks into refer
'd vars?
(ns foo
(:require [clojure.string :refer [blank?]]))
(println ::blank?)
;; (desired) => clojure.string/blank?
;; (actual) => foo/blank?
@hmaurer there's also sayid
: https://github.com/bpiel/sayid