This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-07-22
Channels
- # beginners (20)
- # boot (5)
- # cider (14)
- # cljs-dev (15)
- # cljsrn (1)
- # clojure (81)
- # clojure-greece (7)
- # clojure-italy (17)
- # clojure-spec (5)
- # clojure-uk (15)
- # clojurescript (143)
- # data-science (1)
- # datomic (7)
- # defnpodcast (4)
- # docs (1)
- # figwheel-main (1)
- # fulcro (37)
- # graphql (1)
- # hoplon (3)
- # luminus (1)
- # reitit (5)
- # shadow-cljs (10)
- # spacemacs (5)
- # tools-deps (14)
- # vim (7)
@emccue The repo links to the official community docs
There's a #sql channel if you need more JDBC-focused help rather than Clojure-focused help.
Since I maintain clojure.java.jdbc
(and honeysql
now as well), I'm happy to help answer any questions you may have...
@roklenarcic Just do (meta *ns*)
So, I guess there's no way to have your return spec take into account the arity that was called? Say I have a function whose 1-ary returns an int?, but 2-ary returns a string?, and say my 2-ary has a bug which will return int? sometimes, any way I can spec it so check will find the bug?
The :fn spec can be used to check any relationship between args and ret
@alexmiller Oh, I see, so you're saying to use the fn spec to validate that the correct arity returns the correct value. Make sense. I guess fn can supersede ret in that case. Thanks
Hi, anyone know best practice to avoid side-effect? (like example write data on DB or change atom state)
Well, some side effects will be part of the essential requirements of your application, so you can't really avoid those. For the rest, write as much of your logic as possible as pure functions, accepting and returning immutable data.
I understand that the side effect is a part of programm. But my point in question is how righting designing app to maximize pure fn. (in example: fn -> fn -> fn -> write DB, all fn's is unpure)
When practical, what you can do is represent the writes as a data structure; this way your application is pure as it only has to emit data, and the side effects are performed by generic 'infrastructure' code. Datomic is very good at enabling this sort of an architecture.
This is often called "pushing side-effects at the edge of the system".
Its not so much avoiding, as much as its about isolating the side effects to known places, and maximizing the amount of code that is pure, so its easier tor reason about, test and reuse.
What I mean is normally people write code in a style like this: (fn[a] (b)) (fn[b] (side-effect) (c)) (fn[d] (e)) etc.
What you want instead is pull out the logic of what to do after each step into a top level orchestration function.
And now a, b, side-effect, c, d, etc. simply take argument and return result, they don't forward to the next step, that's been removed. side-effect performs side-effect, but similarly, it doesn't forward anywhere after, it just returns info about its execution.
If you do this to the extreme, your top level function would be the place where all side-effect are called and made from. This is essentially what the IO Monad is Haskell does under the hood. In Clojure, having a few layers of orchestration is generally more practical, but still try to limit the depth of it, favor breadth over depth.
In that style, it becomes much easier to see the flow of code at a glance, by peeking at the top levels. And functions can be tested in isolation, and also be reused, because you can easily have another orchestration that uses them in a different order for example.
@U06GS6P1N @U0K064KQV great answers! Do you know any open-source projects that could serve as good examples of the suggested approach
@U06BE1L6T I don't have anything better than Datomic to suggest š
Hmm. I was thinking more about real apps built using these technologies/approaches, but thanks anyway!
My "problem" is that I often hear to speak about this kind of approach but rarely see it applied in practice
@U06BE1L6T I think the story is a bit different in the backend, where there's usually no in-program state to keep. I confess that on the backend, I don't necessarily refrain from performing side-effects in the middle of request processing - I just push the side-effects towards the edge until my code feels testable enough, but I don't push them all the way towards the edges.
The one place where I apply this systematically is in my Graphql-ish writes - those generated pure data that gets composed into a Datomic transaction, and optionally some side-effectful callbacks that get called after the transaction succeeds (sending emails etc.)
can't show you any code unfortunately - all proprietary
I am writing a wrapper lib for a java api - I am trying to create a nice way of handling object creation.
(defmacro kv-calls [class m]
(let [xs# (map (fn [[k arg]]
`(. ~(symbol (name k)) ~@(flatten (list arg)))) m)]
`(-> (new ~class) ~@xs#)))
and then a call would look like:
(macroexpand '(kv-calls CollectionCreateOptions {:journalSize 20 :waitForSync [true 100]}))
(. (. (new CollectionCreateOptions) journalSize 20) waitForSync true 100)
(defn ^SomeClass map->SomeClass
[options]
(kv-calls SomeClass options))
but I get Don't know how to create ISeq from: clojure.lang.Symbol
when loading the ns, as I guess it is trying to expand the symbol options
- am I missing a tilda somewhere?is this approach something that can only work at compile time? i.e the map needs to be present...
solved my own problem - might not be best practice, but it works...
(defn fn-builder [[k v]]
(let [method-name (symbol (name k))
args (flatten (list v))]
`(fn [x#] (. x# ~method-name ~@args))))
(defn option-builder [object options]
(reduce (fn [acc fn]
((eval fn) acc)) object (map fn-builder options)))
during the compilation options
is just a symbol without any meaning. For me this case is perfectly solvable with a function call
is there any way to instantiate Java inner classes in Clojure? https://github.com/opencollab/jlatexmath/blob/master/jlatexmath/src/test/java/org/scilab/forge/jlatexmath/examples/basic/Example6.java#L76
an innner class is just a class with a funny name
what's the inner class?
if you want STYLE_DISPLAY that's likely an enum or static field and not an inner class
TexConstants/STYLE_DISPLAY
clojure makes things distinct that share syntaxes in java
Iām referring to new TeXIconBuilder()
which has the funny formula.
preceding it
so I guess I should write something like (org.scilab.forge.jlatexmath.TeXFormula$TeXIconBuilder. f)
you can import it (import (org.scilab.forge.jlatexmath TexFormula$TexIconBuilder))
it's not really inside the other class, so you need the full funny looking name, and it isn't actually brought into scope in any way by importing the parent
@noisesmith thank you, I will attempt this
Hi all. Im getting a compiler error
CompilerException java.lang.IllegalAccessError: length-of-longest-key is not public, compiling:(sketch/core.clj:1:1)
From a super simple file
I think it actually happens when I do this
(ns sketch.dynamic
(:require [quil.core :refer :all])
;; (:use [incanter.core :only [$=]])
;; (:use [clojure.math.combinatorics :only [combinations cartesian-product]])
;; (:use [clojure.pprint])
;; (:use [clojure.set :only [union]])
;; (:use [clojure.contrib.map-utils :only [deep-merge-with]])
;; (:import [org.apache.commons.math3.distribution ParetoDistribution])
;; (:import [processing.core PShape PGraphics])
)
;; (defn setup []
;; )
;; (defn draw []
;; (no-loop)
;; (color-mode :hsb 360 100 100 1.0)
;; (background 220 200 66)
;; (rect 100 100 400 400)
;; (save "sketch.tif"))
(ns sketch.core
(:require [quil.core :as q])
(:require [sketch.dynamic :as dynamic])
(:gen-class))
(q/defsketch example
:title "Sketch"
:setup dynamic/setup
:draw dynamic/draw
:size [900 900])
(defn refresh []
(use :reload 'sketch.dynamic)
(.loop example))
it seems like its something to do with quil?
I get the same error in either core.clj or dynamic.clj
I'm interested in introspection on closures returned by functions. I found that I could do this to get the namespaced symbol of a function that returned a closure:
(defn parent-symbol
"somewhat hacky method to get namespaced symbol for a function.
can find the parent of closures returned by functions"
[f]
(let [[ns nm]
(->> f
str
clojure.repl/demunge
(re-find #"^(.+)/(.+)/.*$")
rest)]
(symbol ns nm)))
Is there a better way to achieve such?
Are there other public functions like clojure.repl/demunge
that can be used to parse function string representations?
For example:
(defn returner [x]
(fn [a] (+ x a)))
#'user/returner
(parent-symbol (returner 7))
user/returner
@underplank Your code works for me with quil 2.7.1
-- what version are you using?
If you're using Leiningen, perhaps try lein clean
to see if you have some outdated class files lying around...
Im using quil 2.7.1 as well.. it seems to be working. And I did do lein clean, which maybe why its fixed itself.
thanks for checking!
lein clean
cures all manner of woes š
user=> (parent-symbol ((fn foo [] (fn bar [] 1))))
user/eval159/foo--160
I hadn't tried the nested case š
Need a better regex
it's the same thing, just using an anonymous function at the outside instead of a defn
ya I read it incorrectly, I would need handling for named lambdas
this is what it does for unnamed
user=> (parent-symbol ((fn [] (fn bar [] 1))))
user/eval165/fn--166
it behaves differently when the provider doesn't have a var
(defn returner [x]
(fn luck [a] (+ x a)))
(parent-symbol (returner 7))
user/returner
So named lambdas are ok
I am interested in getting at the var, which I have only been able to do with eval:
(defn parent-var [f]
(eval (list 'var (parent-symbol f))))
(parent-var (returner 7))
#'user/returner
this is really pushing things
:user=> (reify Object (toString [this] "Bob") clojure.lang.IFn (invoke [this] (fn[])))
#object[user$eval217$reify__218 0x2c7b5824 "Bob"]
:user=> (parent-symbol (reify Object (toString [this] "Bob") clojure.lang.IFn (invoke [this] (fn[]))))
NullPointerException java.io.Writer.write (Writer.java:157)
you are good at finding its shortcomings lol