Fork me on GitHub
#clojure
<
2017-04-06
>
rmuslimov00:04:27

Let’s suppose I have deftype looking next way:

(deftype ^{A: a} Name [])
I want define macro generating deftype:
(defmacro dotype [name]
  `(deftype ^{A :a} ~name []))
However, I’m losing information about metadata.
(macroexpand-1 '(dotype T))
;> (clojure.core/deftype T [])
I tried to use tricks with vary-meta to avoid using ^{} in macro. Unfortunately, deftype doesn’t support IObj interface (doesn’t support metadata), and all my tries didn’t work. Please suggest the way to implement this macro. thanks!

lincpa00:04:35

using with-meta

rmuslimov00:04:28

I tried vary-data, I guess it almost the same

noisesmith00:04:30

rmuslimov the macroexpand won't show metadata unless you bind *print-meta* true

noisesmith00:04:14

oh - wait, it's a map at that point (or should be...) ... never mind

rmuslimov00:04:03

@noisesmith cool thanks, didn’t know about it

rmuslimov00:04:43

(defmacro dotype [name]
  `(deftype ~(with-meta name {:a :a}) []))

(set! *print-meta* true)
(macroexpand-1 '(dotype T))

;> (clojure.core/deftype ^{:a :a} T [])

rmuslimov00:04:18

however still not clear

rmuslimov00:04:22

(deftype ^{A :a} TestClass [])

rmuslimov00:04:28

actually A is not defined

rmuslimov00:04:59

but here i works, when I’m using with-meta: Unable to resolve symbol: A in this context

rmuslimov00:04:19

so, what’s this ^{A :a} might be

lincpa00:04:54

Java.lang.Class can't be cast to clojure.lang.IObj

rmuslimov00:04:43

ok, nevermind, last stupid question

lincpa00:04:54

type can't with meta

noisesmith00:04:28

these are not type annotations

rmuslimov00:04:07

what’s that then?

noisesmith00:04:30

it's an annotation - the annotation is imported from javax.jws in the example

noisesmith00:04:41

(the class of the annotation that is)

noisesmith00:04:47

you can use ^{:type Foo} if all you want is a type annotation, but the ^{Foo bar} form is for when you want to attach the key Foo, in this specific context for an annotation (but we also use annotations like :doc etc.)

noisesmith00:04:06

maybe you already understand this and I misunderstand the conversation at this point

rmuslimov00:04:29

no, I didn’t get that so far, thanks for explanation

noisesmith00:04:27

in a java program, it would look like @Foo, but we use metadata instead of the @ syntax

qqq01:04:57

High Level Problem: I want to use Spec for validation during production. For example, a schema of a database, and using Spec to verify that the input matches the schema. Low Level Question: Now, during production, spec/asserts will be turned off. My question now is: are these certain spec tests that will be run even when spec/asserts is turned off?

dpsutton02:04:44

does a namespace implement anything? ie, #namespace[cider.nrepl.middleware.stacktrace] ? what is this? is it just a symbol with a reader notation? does it implement anything, have any fields?

arrdem02:04:48

@dpsutton namespaces actually do quite a lot if you dig around in the implementation. They are global, mutable unreadable objects

dpsutton02:04:17

Yeah I found the clojure Lang namespace file

dpsutton02:04:03

I need a reliable translation from namespace to where a file would be found if it's part of the project, like what require does but only source not dependencies

arrdem02:04:08

tools.namespace gives you the classpath search stuff for that...

arrdem02:04:37

I've written a "use tools.namespace and filter out things that are in a dir tree / not in jarfiles" function before.

dpsutton02:04:49

Oh that would be amazing if it's there

dpsutton02:04:43

I'm building a cider feature to filter the stack Trace down to just your application and it's surprisingly difficult to figure out the name of a project

noisesmith03:04:48

@dpsutton well, I'm allowed to install any number of namespaces with any paths I like in one project

noisesmith03:04:14

clojure doesn't enforce any rules about that (except the namespace name having to map to the classpath relative path for require to work, of course)

dpsutton03:04:57

what do you mean?

dpsutton03:04:15

based on talking yesterday, if i can get the canonical representation of a file from a namespace, i can then check if that file exists. this is true, yes? but i'm worried if this is run and connected rather than jacked in

lvh03:04:15

With specter, is there a way to use walker but still collect the path to the found thing?

noisesmith03:04:23

@dpsutton my point is that "project name" isn't going to be a reliable thing you can check for- I can create files with all kinds of silly paths that have nothing to do with each other, under one project

noisesmith03:04:48

why would connecting change how your mapping to files works?

dpsutton03:04:39

yeah project name is definitely no good

dpsutton03:04:47

case in point, cider-nrepl doesn't match up 🙂

dpsutton03:04:05

i was prototyping using the file location and the user.dir but that doesn't work once compiled

dpsutton03:04:15

ie, when running tests, you lose the prefix

noisesmith03:04:34

why would you need user.dir - the file paths are absolute

dpsutton03:04:52

yeah, to get the prefix

noisesmith03:04:07

or do you only want file paths if they are under user.dir - what about just assuming that if it came from a file on disk and not inside a jar, the user considers it "theirs"?

dpsutton03:04:13

i resolved the file from the var metadata and checked if it started with the user.dir

dpsutton03:04:30

but the file metadata loses that prefix when compiled into a jar for testing or however that works

dpsutton03:04:40

yeah that was the idea

dpsutton03:04:49

but it's not a strong enough idea

noisesmith03:04:54

if you use io/resource you get either a jar uri, or a file uri, for the resource

noisesmith03:04:12

io/resource takes a relative path - you can infer relative path from the namespace name

dpsutton03:04:27

and it's funny how simple a problem this is, it's just difficult to determine what the common ns part is for the user's code

noisesmith03:04:34

when would the definition come from a file on disk, and not be something the user owns?

dpsutton03:04:53

some for example

noisesmith03:04:57

I mean directly, without using a jar uri

dpsutton03:04:30

i'm a .NET guy at work so I'm really out of my depth in the guts of how the jvm lays things out. so i'm learning and when i'm understanding more i'll have the patch

noisesmith03:04:53

some is clojure.core/some

+user=> ( "clojure/core.clj")
#object[java.net.URL 0x41d426b5 "jar:file:/home/justin/bin/bench!/clojure/core.clj"]

dpsutton03:04:55

oh i wasn't using jar uri's at all, and in fact that would have signalled that it wasn't from the project

noisesmith03:04:28

if I ask for foo/bar.clj instead it would give me a file uri

dpsutton03:04:10

i know i've seen temp2342352.clj as filenames in the past when watching the nrepl traffic so i'm hesitant to rely on filename

noisesmith03:04:28

but only the user's own code will be in that right?

dpsutton03:04:32

but if it points to local disk rather than a jar perhaps it would work

dpsutton03:04:38

yeah you may be right

noisesmith03:04:43

you could exclude /tmp/ to be safe?

noisesmith03:04:50

that just seems to make things simpler

noisesmith03:04:47

alternatively, you could parse project.clj and look at their source paths

noisesmith03:04:54

and correlate that with pwd

dpsutton03:04:14

if i parse project.clj i'm stuck supporting lein only

dpsutton03:04:24

and i think CIDER is a little lein biased to begin with

noisesmith03:04:35

you could look at classpath and filter for files

noisesmith03:04:30

=> (System/getProperty "java.class.path")
"/home/justin/bin/bench:src"

noisesmith03:04:37

for each entry, test if it is a directory

dpsutton03:04:17

versus a jar?

noisesmith03:04:41

yes - that's my clojure.jar repl (I name the jar bench because it's executable and contains criterium)

noisesmith03:04:49

this is from lein repl

=> (System/getProperty "java.class.path")
"/home/justin/target/classes:/home/justin/.m2/repository/org/clojure/tools.nrepl/0.2.12/tools.nrepl-0.2.12.jar:/home/justin/.m2/repository/clojure-complete/clojure-complete/0.2.4/clojure-complete-0.2.4.jar:/home/justin/.m2/repository/criterium/criterium/0.4.2/criterium-0.4.2.jar:/home/justin/.m2/repository/org/clojure/tools.trace/0.7.6/tools.trace-0.7.6.jar:/home/justin/.m2/repository/alembic/alembic/0.2.0/alembic-0.2.0.jar:/home/justin/.m2/repository/lein-as-resource/lein-as-resource/2.1.3/lein-as-resource-2.1.3.jar:/home/justin/.m2/repository/org/flatland/classlojure/0.7.0/classlojure-0.7.0.jar:/home/justin/.m2/repository/org/tcrawley/dynapath/0.2.3/dynapath-0.2.3.jar:/home/justin/.m2/repository/org/clojure/clojure/1.8.0/clojure-1.8.0.jar"

dpsutton03:04:37

and so all would be jars except for /home/justin/target/classes?

noisesmith03:04:54

but you can actually test instead of inferring from name 😄

dpsutton03:04:07

and it looks like tools.namespace can search a directory for namespaces inside a directory

dpsutton03:04:22

so then, any namespaces matching the namespaces from directories and not jars must be the users code

noisesmith03:04:39

very likely, at least...

dpsutton03:04:00

close enough for me

dpsutton03:04:15

it's tough to write tests for tooling though

dpsutton03:04:31

because those tests will likely fail during lein test

dpsutton03:04:36

(nsfind/find-namespaces
 (map 
      (filter (complement #(.endsWith % ".jar"))
              (clojure.string/split classpath #":"))))
(cider.nrepl.test-session
 cider.nrepl.test-transport
 cider.test-ns.first-test-ns
...
thanks <@U051SS2EU> this might be something i can attack here

dpsutton03:04:05

i'll need to do reading if the classpath separator is consistent across platforms etc but this feels promising

dpsutton03:04:24

and i can add things like .isDirectory and such

noisesmith04:04:15

@dpsutton the classpath delimiter is consistent, but as seen in my first example, not all jars end with .jar

noisesmith04:04:31

but you can call io/file on the classpath entry, and check .isDirectory

dpsutton04:04:24

yeah i was just doing that as an easy way to toss out the jars. thanks for all of the help. jars not ending in .jar is definitely some useful info

leonoel06:04:27

Hi all

(= (partial + 1) (partial + 1))
=> false
Does that mean partial is impure ?

lincpa07:04:15

difference function

leonoel07:04:23

different functions that are perfectly interchangeable, it would make sense to me if they would be equal

leonoel07:04:40

is it a design choice ?

schmee07:04:02

@leonoel it is impossible in general to know if two functions are equal

schmee07:04:06

because of this, functions are never equal

leonoel07:04:45

well, to me function (as of ifn?) is an interface, it is up to the underlying type to define equality or not

leonoel07:04:44

to implement IFn and to implement equals sounds totally orthogonal to me

leonoel07:04:14

moreover, it's always possible to know if two functions are equal because all objects have an equals method

leonoel07:04:56

@rauh thanks, that's what I was looking for

rauh08:04:16

@leonoel Just for fun, don't do this:

(defn my-fn-eq?
  [f1 f2]
  (and (= (class f1) (class f2))
       (= (vals (.& f1)) (vals (.& f2)))
       (= (keys (.& f1)) (keys (.& f2)))))

(let [f1 (partial + 1)
      f2 (partial + 1)]
  (my-fn-eq? f1 f2))

leonoel08:04:26

(my-fn-eq? (partial + 1) inc)

peterromfeld12:04:56

Hi i am having problems with lazyness or some kind of optimizations i think: I try to solve a problem on hackerrank https://www.hackerrank.com/challenges/cube-summation so far i went from doall reduce to doseq with atom (i try to avoid atoms) latest bit more ugly try:

(require '[clojure.string :as s])

(let [n-tests (Integer. (read-line))]
  (doseq [_ (range n-tests)]
    (let [[n ops] (s/split (s/trim (read-line)) #" ")
          result (atom (mapv (fn [_] 0) (range (Integer. n))))]
      (doseq [_ (range (Integer. ops))]
        (let [[action & numbers] (s/split (s/trim (read-line)) #" ")]
          (if (= action "UPDATE")
            (swap! result (fn [r] (update r (- (Integer. (first numbers)) 1)
                                          #(+ % (Integer. (last numbers))))))
            (println (apply + (subvec @result (- (Integer. (first numbers)) 1) (Integer. (last numbers)))))))))))
put it never prints when i expect it to print (it asks for the next input, before it prints the previous print

peterromfeld12:04:48

the issue i get is:

Your Output (stdout)
~ no response on stdout ~
so i guess it expects me to print at the time it sends the query

peterromfeld12:04:06

same with dotimes it asks me for next input before it prints previous println

peterromfeld13:04:59

tried to add flush same result

borkdude13:04:12

nm, I’ll solve it another way

leonoel13:04:30

@peterromfeld what is your input ?

peterromfeld13:04:48

2
4 5
UPDATE 2 2 2 4
QUERY 1 1 1 3 3 3
UPDATE 1 1 1 23
QUERY 2 2 2 4 4 4
QUERY 1 1 1 3 3 3
2 4
UPDATE 2 2 2 1
QUERY 1 1 1 1 1 1
QUERY 1 1 1 2 2 2
QUERY 2 2 2 2 2 2

peterromfeld13:04:28

@borkdude from java perspective i guess you make a object that has a close or stop method after you started it

dpsutton13:04:30

would it be absolutely true, or at least a reasonable assumption given standard practices, that every namespace in a users project shares some common prefix?

peterromfeld13:04:39

@dpsutton i found it the hard way that its verry good to have everything in your project namespaced by some unique project name or you can get easy into clashes with things like user and co

dpsutton13:04:58

i agree, but just wondering if that's basically guaranteed for every project

peterromfeld13:04:39

@dpsutton i dont fully understand your question, you can use whatever namespace you want, but to make sure you dont clash with other namespaces its best practice to use prefixes

peterromfeld13:04:03

we tried to flatten our directory structure and soon got the problem that user ns is already taken, so going forward i would always prefix my project namespaces

leonoel13:04:25

4
4
27
0
1
1

peterromfeld13:04:00

@leonoel yes that the expected output 🙂

dpsutton13:04:25

@peterromfeld i'm building a feature in CIDER that will flag user's code in stack traces. I'm inspecting the classpath and finding local namespaces to find all loaded namespaces. However, due to lein profiles, not all of the code is on the classpath (think test ns's here) so i'd like to build a way to match against known namespaces and match likely namespaces as well. So i'm reducing all of the namespaces to a common prefix, and I'd like to know if this exists in general

peterromfeld13:04:27

@leonoel but not working and think its because read-line executes before println

peterromfeld13:04:31

@dpsutton for me personal it sound to much magic, and user should explicit tell his namespace prefix

istvan13:04:41

hi guys, does anybody have a newbie's guide to transcuders with practical examples?

dpsutton13:04:06

then you're tooling requires input

peterromfeld13:04:02

@istvan i dont know of a newbie guide for transducers or laziness, and for practical i dont have experienced performance bottlenecks that transducers solve so far (usually there are enough other bottlenecks), what i liked for profiling to find actual issues is https://github.com/ptaoussanis/tufte 😉

peterromfeld13:04:41

formerly timbre (they spliced it now)

peterromfeld13:04:31

in addition ive seen that added complexity with more junior team mebers slows down team-performance more, then complex code helps application performance in relation

istvan13:04:58

yeah KISS is a great principle 🙂

peterromfeld13:04:12

i believe if you consider yourself a newbee you should look more into how to make small composeable functions, improve your naming to make other better understand your code, (my personal favourite, how to make more poweruse of datastructures to escape nesting - in some cases you need nesting for frontend rendering)

lvh16:04:09

Things I was wrong about: specter

lvh16:04:30

I’ll still happily believe there are lots of things that don’t really need it but I’ve now used it in a few places and it’s pretty slick

lvh16:04:39

writing your own selectors is still, uh… a little dark magic

lvh16:04:02

but hopefully that will get better over time as I get more experienced, docs get better, and common idioms get added to specter

lvh16:04:25

(I previously thought: uh that’s cool but what’s with the upper case also I don’t really know if I’m going to use this)

mpenet16:04:57

the graphql lib from walmart labs has a lot of transformations, walking, also uses ordered maps via flatland lib internally etc, etc, lots of potential uses for specter imho there

mpenet16:04:06

and that's a context where it'd make sense to optimise a lot

triss17:04:20

i’m using clj-http to get some json

triss17:04:49

and it has some keywords like in :@id it it

triss17:04:06

:@id chokes the reader

triss17:04:59

I’d love to convert all instances of the :@id key in a nested map to :id i guess

noisesmith17:04:07

@triss it's better to just not turn keys into keywords

noisesmith17:04:30

but there's clojure.walk/prewalk which makes it easy to detect map-entries and rewrite their keys

triss17:04:50

thanks @noisesmith i’ll see how easy ho i like dealing with string keys

rauh17:04:03

@triss Just parse it manually with cheshire and let clj-http return you the string

rauh17:04:15

Chesire allows you to specify a key fn

noisesmith18:04:28

it's a legitimate difference of philosophy of course, but given that there are many valid json keys that are nonsense as keywords, I prefer just to keep it as strings

tanzoniteblack18:04:11

^^^ It's also faster to not convert them to keywords, and keywords don't really ever get garbage collected, so if you're parsing a very very large number of json documents with very varying keys over time....

noisesmith18:04:36

@tanzoniteblack happily that's no longer true (keywords are now weak refs)

tanzoniteblack18:04:43

oh really? Awesome

tanzoniteblack18:04:49

what version did that change in?

noisesmith18:04:57

I still stand by the other arguments against keywordizing though :)

triss18:04:05

i think I’m a keyworder at heart

triss18:04:26

went with chesire and fn in the end 😀

jumar18:04:30

@peterromfeld as regards to hackerrank I would recommend to separate the sideeffects (reading input, writing output) from computation - otherwise it's hard to reason about the function. I came up with something like this

jumar18:04:22

Although it's not efficient - will timeout for more complex test cases - it should work for simple cases.

jstew18:04:02

I prefer exercism to hackerrank. The clojure problems on exercism seem to be made by a clojurian rather than translated from another language.

greg_arcara18:04:24

Is it more interesting to have problems tailored to the language you choose?

jstew18:04:51

Not especially. Parsing stdin for input gets old, fast though. On exercism you work on problems with a real app locally so you can use all of your own tooling without having to copy and paste.

jstew18:04:37

Try both and see. IMO, it's a much smoother experience.

fenton18:04:36

how to make: (myfunc '(1 2 3)) go to (myfunc 1 2 3)

spei18:04:07

(apply myfunc '(1 2 3))

fenton18:04:29

@spei thanks! 🙂

greg_arcara18:04:45

@jstew i've been doing hackerrank problems, and hadn't heard of exercism, so I will check that out. I feel like the stdin thing is only a problem once or twice, I have a function I write and just basically copy into each solution. Will check out exercism though, thanks.

jstew18:04:05

I think you will love it. I don't hate hackerrank, I just really like exercism. 🙂

tmayse19:04:30

I just checked exercism and am excited to give it a whirl. thank you for pointing that out @jstew

fenton19:04:36

are these equivalent: (.log js/console 43 {:g 1}) and (apply #(.log js/console %) '(43 {:g 1}))

fenton19:04:06

they dont appear to be

rauh19:04:46

@fenton (apply js/console.log '(43 {:g 1}))

fenton19:04:36

@rauh thx ill try that

jr19:04:25

(apply js/console.log js/console '(43 {:g 1}))

jr19:04:40

you need to pass js/console as the first arg when calling apply on console.log

rauh19:04:34

@jr apply will do that for you, and the clj -> js-array conversion

pesterhazy19:04:44

there's also .apply, which does require an extra argument

jr19:04:56

ah right

pesterhazy19:04:37

but for console.log it doesn't matter. var f=console.log; f("foo"); works, at least in chrome

pesterhazy19:04:53

so you can (.apply js/console.log nil "foo")

timgilbert19:04:46

Say, looking at this page: https://clojurescript.org/reference/javascript-library-preprocessing ...am I correct that this isn't currently available via the cljsbuild lein plugin?

timgilbert19:04:36

....since I don't have a place to define a (defmethod) that is available to the clojurescript compiler?

noisesmith19:04:54

@timgilbert don't actually do this, but you can put arbitrary code in a project.clj inside a ~

jkieberk21:04:55

if a function I write will throw an error if its input is anything except a string, should I change the function to allow for any kind of input? Or is it idiomatic to have it throw an exception?

jkieberk21:04:17

(or should I catch the exception in the function?)

octopuscabbage21:04:17

in my opinion you should throw a more descriptive error as to why it only accepts strings

octopuscabbage21:04:45

alternatively, call clojure.core/str on your input

jkieberk21:04:10

ah, good idea on calling str on the input

jkieberk21:04:33

and that makes sense that there should be a good reason why it would only accept strings

josh.freckleton21:04:11

i'm a bit unsure on profile s, can I reliably switch on a profile to run a program differently in dev vs prod? If so, how can I find out dynamically which profile is being run? (if not, is there a better alternative?)

hiredman21:04:44

don't do that

hiredman21:04:25

lein profiles are entirely about how lein is configured, and you should not be using lein at all after you have deployed (to dev or production or whatever)

bradford21:04:43

Do I need Clojurescript to run Datascript? I want a little in-memory DB for a server I'm building

bradford21:04:50

but I don't wanna bother with cljs deps

hiredman21:04:08

have you seen clojure.set/index ?

josh.freckleton21:04:49

@hiredman should it be my own config variable then, for switching on whether it's dev/prod?

hiredman21:04:11

there are also a bunch of configuration libraries

hiredman21:04:46

I am not a huge fan of a single dev/prod switch, I prefer something like a configuration file

hiredman22:04:30

the simplest configuration file is just a file containing a clojure map that you read in using read

st3fan22:04:09

i have a function that takes a numeric id - what is a good way to make sure it actually is positive integer? should i do a precondition? is that a common thing to do?

st3fan22:04:36

i want things to fail in case it is called incorrectly

timgilbert22:04:04

I tend to use preconditions for that kind of thing

josh.freckleton22:04:43

@hiredman i actually agree with dev/prod switch is bad mentality... not sure how to do this otherwise tho I've got a huge Component system map, and need to remove one component from a huge map when in development, and don't want 2 massive, almost identical edn/clj files defining the map. Is there a way around a conditional switch I'm not seeing?

timgilbert22:04:44

These days you could also use spec

hiredman22:04:34

@josh.freckleton (component/start (cond-> (build-system) (System/getenv "NO_THING") (assoc :thing :dummy))

timgilbert22:04:49

@josh.freckleton: I agree this is kind of a pain point. In the past I have sometimes used lein profiles to include one of two possible additional source paths for this kind of thing, like env/prod and env/dev

timgilbert22:04:11

But I actually found it to wind up causing me a lot more trouble than it was worth

hiredman22:04:13

alternatively make thing something you pass in to build-system

timgilbert22:04:50

These days I tend to have my apps figure out what environment they're running in on start-up, regardles of what build was used to create them

timgilbert22:04:33

...which you could do by inspecting the URL or maybe looking for a cookie to set "dev mode", etc

hiredman22:04:21

I have this repo that I haven't pushed or worked on in a while "morphogenesis" which is supposed to be a library for using a rules engine to manage configuration

timgilbert22:04:44

One way this is helpful is that it makes it easier to debug problems caused by advanced compilation if you were only deploying your :advanced build in a production environment

hiredman22:04:46

most configuration systems seem to be about trying to limit the amount of conditional configuration to a few prescribe things(override or configuration inheritance rules), but for any long lived large project conditional configuration takes over everything

hiredman22:04:07

so why not just start with the ultimate if/then/else kind of system a rules engine

hiredman22:04:19

most likely crazy, and I doubt anyone would let me use it on a real project

hiredman22:04:34

anyway, the way to parameterize things (anything) is with a function

hiredman22:04:03

so if you want to parameterize how your system map is created, write a function that creates your system map, don't just def it at the top level

josh.freckleton22:04:44

I like that example code, would this be similar in spirit, or would you forsee pains in swapping out your (System/getenv ...) with a similar (env :dev-flag) (from environ) and :dev-flag is in profiles.clj

hiredman22:04:54

the component Lifecycle protocol is extended to Object as a noop, so you can put anything in the system map and it will be fine

hiredman22:04:15

you could certainly do that, I've never used environ

hiredman22:04:19

as I said, I don't like a coarse grained thing like a dev/prod switch, so whatever mechanism I used I would prefer something like enable/disable thing

timgilbert22:04:37

I agree, something closer to feature-flags is easier to manage than build parameters in my experience.

st3fan22:04:01

What is the idiomatic way to check if a set (of keywords) contains a value?

xiongtx22:04:19

Call the set on the keyword, or vice-versa

xiongtx22:04:48

(:b #{:a :b :c}) ;; => :b

st3fan22:04:19

Oh that is nice and short

not-raspberry23:04:38

contains? works with false and nil

(contains? #{:a :b :c} :a)
(contains? #{:a :b :c false nil} nil)
(contains? #{:a :b :c false nil} false)
are all true

colliderwriter22:04:39

Re: config, maybe have a quick look at Aero? It solved my issues in an elegant way. YMMV of course

st3fan22:04:47

are named arguments common in clojure? i'm creating a wrapper for Bugzilla .. so i'd like to query like :project Firefox :status :NEW .. should my (query-bugs ...) just take a map like (query-bugs {:project Firefox :status :NEW}) or is there a way to make that a bit more strict?

st3fan22:04:33

I see Practical Common Lisp creates a DSL for querying an MP3 database .. maybe that is an interesting example.

not-raspberry22:04:30

@st3fan somewhat common. There is a way to do that by destructuring a variable arguments list into a map.

not-raspberry23:04:29

@st3fan

(defn a [& {:keys [arg1 arg2 arg3]}] (println "my args are" arg1 arg2 arg3))

not-raspberry23:04:09

Still, not super strict, since unrecognised arguments are ignored.