This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-18
Channels
- # announcements (9)
- # atom-editor (29)
- # aws (17)
- # babashka (72)
- # beginners (83)
- # braveandtrue (3)
- # calva (7)
- # cider (16)
- # clj-kondo (15)
- # cljs-dev (146)
- # cljsjs (1)
- # cljsrn (8)
- # clojars (1)
- # clojure (96)
- # clojure-dev (19)
- # clojure-europe (53)
- # clojure-losangeles (1)
- # clojure-nl (3)
- # clojure-spec (7)
- # clojure-uk (235)
- # clojuredesign-podcast (5)
- # clojurescript (81)
- # conjure (73)
- # cursive (7)
- # data-science (1)
- # datomic (5)
- # defnpodcast (8)
- # emacs (3)
- # figwheel-main (34)
- # fulcro (83)
- # graalvm (10)
- # graphql (6)
- # helix (49)
- # jackdaw (3)
- # jobs (1)
- # joker (1)
- # kaocha (1)
- # mid-cities-meetup (10)
- # off-topic (17)
- # pathom (16)
- # re-frame (11)
- # reagent (18)
- # reitit (18)
- # remote-jobs (4)
- # shadow-cljs (63)
- # spacemacs (18)
- # specter (20)
- # sql (17)
- # uncomplicate (1)
- # vim (28)
- # xtdb (32)
^ On that point, why do so many libraries use that syntax of optional key/value arguments in functions and call (apply hash-map args)
instead of just having their functions take a map? Is there some benefit to:
(-> (session ring-app)
(request "/search" :request-method :post
:params {:q "clojure"}))
VS
(-> (session ring-app)
(request "/search" {:request-method :post
:params {:q "clojure"}}))
A few Clojure core functions do it, too, e.g. http://clojure.java.io/reader and http://clojure.java.io/writer, so I suspect part of the answer to "why" is "there were public examples of it in Clojure libraries, so it must not be an absolutely terrible idea".
I have no measurements to say whether this is happening, or not, but would not be surprised if there were a trend towards passing a map instead.
I know as I was tackling both a logic based state machine, and an unrelated xform rule engine (and definitions for the rulesets) that there are lots of examples in core logic (and other places) that use vectors in a similar way. It felt like Rich was stating (sometimes directly) in places that vectors were idiomatic and you should use them if possible. That might play into it. Vector's can also be "more readable" when defining collections of rules or facts, but that doesn't seem to be the case here.
@jdkealy That's a good question. Named arguments are good for users to type in but, as you noticed, bad for programmatic use. Like @andy.fingerhut I suspect that the overall move is to a single options map argument instead -- although a DSL/API designed purely for human use rather than programmatic use might reasonably make use of named arguments (such as Spec).
I think the parts of Clojure that use that approach -- named arguments -- are older parts and maybe it's less common in more recent additions?
FWIW, when I took over clojure.contrib.sql
back in 2011, it was all named arguments (and based around a single dynamic Var for the current DB spec). Over time I moved it to use an options hash map instead, and pass an argument instead of relying on the dynamic Var, both at the suggestion of the Clojure/core team.
It's much easier to compose functions that use hash maps and it's only two additional characters for humans to type.
hi, using genclass: is there a way to get a this
reference on a constructor? found an old thread that gave me no answers: https://groups.google.com/forum/#!topic/clojure/0fvbdFC0be4
Imagine the target class something like:
class MyFactory extends SaxonTransformerFactory { public MyFactory () { super(); this.processor.register("My awesome thing"); } }
That is, I need to extend ctor so I can configure a few things on it after it gets created.
If you are curious, this is for a java library (JAXP) that will load the class with reflection... I'll do:
System.setProperty("javax.xml.transform.TransformerFactory", "my.package.MyFactory");
.... and then some other library code somwehre else will load MyFactory. This is to explain why I need genclasss, and to augment the constructor, no other way around it 😭I can't get genclass to work I was thinking of implementing it as java code... genclass would be nice because I'm not sure how I'm gonna provide the data for those register calls when implementing it as pure java. Probably will have an static ArrayList of this to register on the ctor... feels a bit hairy 🙂
btw, genclass has one of the worst documentation pages of all things... pretty frustrating</RANT>
but I think I found what I'm looking for!
https://github.com/clojure/clojure/blob/master/src/clj/clojure/genclass.clj#L565-L571
yaaaay success 🙂
(ns rainbowfish.xslt-factory
(:gen-class
:name rainbowfish.XsltFactory
:extends net.sf.saxon.jaxp.SaxonTransformerFactory
:post-init configure))
(defn -configure
[this & args]
(let [processor (.getProcessor this)]
(println "JAXP XSLT initialized with processor " processor)))
never used gen-class before, seems like I need to make sure (compile rainbowfish.xslt-factory)
is always called at least once before grabbing the generated class, rainbowfish.XsltFactory
Can someone help me. Why multithread sval of lazy-seq will make the cpu to 100% useage?
Does anyone know why libraries typically have a foo.core
namespace (rather than just foo
)? Is this considered a best practice? Or are library authors just taking after clojure.core
?
What I’ve seen is that most libraries use “core” as the entry, whereas applications use “main” This is not universal, and imho doesn’t really matter so long as there is internal consistency.
Okay, makes sense 🙂 I’m working on a single-namespace library and having foo.core
feels unnecessary to me, whereas going with just foo
feels a bit.. unconventional.
I don't know about Clojure, but in ClojureScript single-segment namespaces can result in errors: https://clojure.atlassian.net/browse/CLJS-1004
Oh, it's also relevant for Clojure, although the reason is a bit different: https://groups.google.com/forum/#!topic/clojure/gOffhotk25Y
@U15RYEQPJ it’s still good practice to have at least two namespaces
okay, thanks!
So considering how there seem to be multiple schema libraries (`schema`, spec.alpha
, malli
, …) in use — is it possible to design a library to support these libraries if/when they exist? Ideally I’d like to support more than one schema library, but without forcing projects that use my library to use or explicitly exclude them.
libs like reitit
abtract the routing schemas using a Coercion
protocol making the schema impl swappable (parameter & response definitions, coercion and api-docs). Mixing the three in a same routing app would be asking for trouble, but still possible. I think same applies for all apps. Problem is of course, none of the three is complete and could be used for all things.
Thanks!
any nice way to join vectors like this (every other element)? [1 2 3] + [4 5 6] => [1 4 2 5 3 6]
this came up in an effort to calculate moving averages, which can almost be done with (interleave coll (map average (partition period 1 coll)))
, but only almost
@restenb have you tried partition-all
- then you have to deal with a "dangling" coll
(ie. a coll that isn't a full period
elements)
that'll have the opposite effect of adding the last element twice it seems (at least on my test data)
so in the end no better than having to (conj moving-averages-of-coll (last coll))
at the end
btw relying on conj
for ordering is a bad plan (that conj will insert at the beginning if you use interleave)
you might get a more direct result with some sort of (reduce f {:state {} :result []} (map vector coll (partition period 1 coll)))
calling conj in f to update the state and result
actually given the way you are doing the moving average, you can just use []
result directly and need not carry state
which means you could use (mapcat (fn [[x :as sample]] [x (average sample)]) (partition period 1 coll))
(partition n 1 coll) and coll have a difference of n elements between the two
maybe you don't even want partition
You don't need to calculate the entire average every time, you can use a queue as a window then just calculate the diff. It covers the tails as well
Are Pedestal and Reitit alternatives or are they in different service spaces?
alternatives, Reitit has a comparison in their FAQ: https://metosin.github.io/reitit/faq.html
What else do you use Pedestal for? I haven't looked into it besides just seeing it on "inspired by..." lists
reitit author here. Pedestal definitely has more batteries out-of-the-box. There are reitit-ring
and reitit-http
modules with a lot of helpers for building web apps too. And, there is reitit-pedestal
, bridging the two. Have fun, with either one :)
here's an example of the two together: https://github.com/metosin/reitit/tree/master/examples/pedestal-swagger
good question from a coworker. obviously understand that we can use private vars with (#'ns/private-var ...)
but don't actually understand why. The reader ensures that we respect privacy?
when compiling, private vars are not available for implicit lookup
using var-quote sidesteps this mechanism
compiler, the reader just reads symbols
er, obviously implicit lookup is in the compiler. just wondering which part throws i guess
the error is a compiler error - it doesn't find anything for that symbol
foo=> (defn- foo-private [] 42)
#'foo/foo-private
foo=> (ns user)
nil
user=> (foo/foo-private)
Syntax error (IllegalStateException) compiling foo/foo-private at (REPL:1:1).
var: #'foo/foo-private is not public
user=>(#'foo/foo-private)
42
"syntax error" translates loosely to "error while compiling"
ok. i see resolve
and resolveIn
in the compiler. just trying to trace how var-quote ends up with the allowPrivate = true
(and thanks for your help @noisesmith)
@dpsutton I should correct what I said above - clearly based on the message here it does look at private vars, it just throws if you use them "implicitly" (without a var dereference)
it might help to look at the stack trace you get when you use a non-existant var inside defn
now that is some smart thinking. thanks! so obvious in retrospect but hadn't thought that lol
as compared to the stack trace for using a private var without explicit var quote
yeah perfect. I think it goe through TheVarExpr
which allows lookingup private. thanks
(read-string "'some-symbol")
returns (quote some-symbol)
is there anyway to have it return the original 'some-symbol
(or I guess just some-symbol) back instead?
there's a library that makes that happen - what's the use case?
oh, and clojure.pprint/pprint
does this already
@sansaripour btw (quote foo)
is literally 'foo
, it's the correct reader expansion of the shorthand
just like @foo
is the same as (deref foo)
etc.
the three of these are all equal:
user=> (= 'foo (quote foo) (symbol "foo"))
true
there are multiple ways to get some-symbol
from (read-string "'some-symbol")
. depending the use case, either of these might work:
• if you know it’s going to be a quoted symbol: (second (read-string "'some-symbol"))
• if you’re actually hoping to evaluate a string: (eval (read-string "'some-symbol"))
or, if you know you never want quoted forms anywhere in the output, and just want the unevaluated symbol instead, you can tree walk and replace all lists that start with quote
with the second item in the list
but it seems like a strange problem where usually the fix would be just not using '
in your edn files, which is why I ask what is actually being attempted
Thanks all for the help. I think I have a path forward now 👍
And, the use case is that I'm reading in the contents of a clojure (clj) file with read-string
in search of a particular form that contains a particular map.
I then return this map as a JSON string. The map may or may not contain keys formatted like 'some-symbol
. Right now, the output JSON gets an un-welcomed heaping of (quote some-symbol)
instead of the original 'some-symbol
as a result of the read-string
oh and Im using babashka to execute the above operation^
OK - so to be clear 'foo
is just a shorthand for (quote foo)
and has the same meaning, if you need to print more recognizably you can use pprint (or copy what pprint does), but as a last resort you can absolutely do a tree-replace of (quote x)
with x
- it's a pretty unambiguous thing to test for an replace
Yep, I understand this! Thanks! I was merely concerned with the textual representation and I should've clarified that
something like:
(clojure.walk/postwalk (fn [form]
(if (and (seq? form)
(= 2 (count form))
(= 'quote (first form)))
(second form)
form))
(read-string "{:a {:bar 'foo}}"))
although if it’s actually a clj file, you might want to just require it and call the function that returns the data. if you need access to it from cljs, you may consider using cljc