This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-02
Channels
- # aws-lambda (5)
- # bangalore-clj (1)
- # beginners (96)
- # boot (66)
- # cider (39)
- # cljsjs (2)
- # cljsrn (5)
- # clojure (265)
- # clojure-android (1)
- # clojure-france (1)
- # clojure-greece (32)
- # clojure-italy (4)
- # clojure-russia (2)
- # clojure-sg (1)
- # clojure-spec (27)
- # clojure-uk (25)
- # clojurescript (88)
- # cursive (4)
- # datomic (31)
- # emacs (96)
- # hoplon (10)
- # immutant (14)
- # jobs (2)
- # luminus (1)
- # lumo (66)
- # off-topic (128)
- # om (8)
- # om-next (2)
- # onyx (9)
- # parinfer (5)
- # re-frame (37)
- # reagent (16)
- # rum (9)
- # schema (3)
- # specter (34)
- # unrepl (8)
- # yada (21)
How to use use
to load libraries at Leiningen REPL startup?
most people define an :init-ns
in project.clj
but if you want to do it by hand, (use 'my.ns)
@noisesmith Thanks, good idea. But I wander why I add (use '(incanter core stats datasets charts io pdf))
will failed lein repl
timeout?
that's not the syntax
or hmm...
you could set the timeout - but really why not make a namespace that uses those and switch to it on bootup?
and in the long run, it's better not to utilize use
@noisesmith If that, should I define my.ns
in :repl-options
or just in top level in profiles.clj
?
I'd do it in the way shown in lein help sample
(checking now...)
yeah, put it in :repl-options
Hi, everyone. May I ask a question of how to improve my clojure skills? I've been working on clojure for one year, and I have read the book Clojure programming
brave clojure
and also have some cljs
experiences. I have not working with java before that. I am now feeling comfort of writing clojure code and want to read some source code of clojure, like the source code of clojure language, or the source code of ptaoussanis
. I feel those difficult to start. I feel it easy to write a working clojure program, use some libraries written by others, and do the things I want to finish when doing my job, but I feel it difficult to start to write a clojure lib or design a new program. Should I learn java lang /jvm first, should I read the jdk8's core docs, or should I just write more and more applications? Thanks!
@noisesmith I checked out lein help sample
now, but have not found where is the :init-ns foo.bar
's namespace foo.bar
is defined? If I want to define namespace foo.bar
in Leiningen profiles.clj
, where should I define it?
you define it in src/foo/bar.clj
I mean profiles.clj
not project.clj
. Does ~/.lein/
can load src/foo.bar.clj
?
if you have a dependency that you want to load regardless of project, you should have an artifact for it and put it in your :dependencies in profiles.clj
you can run lein install
in a project to make it available from other local projects as a dep
(or use a proper library and deployment for serious things of course)
No, I want to load some dependencies with :use
instead of :require
at Leiningen REPL startup.
to use code it needs to be on the classpath
use rather than require is just a question of how you define your namespace (or which function you use)
lein is responsible for classpath and startup
I see, thanks.
I know that I can't write: (apply of (map f lst))
however, how what is the best way to say "if there some x in lst" such that (f x) is true ?
How to convert (use '(incanter core stats datasets charts io pdf))
into require
which load the incanter.charts/histgram
into histgram
?
@stardiviner : I've now cleared my debts and you owe @akjetma an answer
Oh, sorry for this. @noisesmith I use (require
LIBRARY :refer :all)` solved my problem.
@qqq I wish to load all functions under incanter.charts/
.
@stardiviner FYI that's identical to use
why wasn't use working?
@noisesmith I don't know. That's what I wander. But require
solved my problem, I will pass it off now.
Hi, Iโm pretty new to Clojure struggling to understand something. Why do (fn? inc)
and (fn? (first '(inc)))
return different values? How can I check whether a Symbol in a list refers to a function?
โ(inc) is not a list with a function, itโs a list with a symbol
symbols happen to be callable, but they donโt do what you want (unless what you wanted was the same behavior as keywords (โa โ{a 0}) => 0
the problem here is that '
is not a list constructor, itโs a way to prevent evaluation
@jlmr inc is a function ; it is found by first finding the var named inc (skipping over the namespace part here), and then dereferencing that var
I guess that one reason is that we donโt need/want to do magic with vars very often (thatโs the mutable part of the language, so you wouldnโt want it spread throughout your program)
@frederic are (deref (resolve 'inc))
and inc
not actually the same thing? or just seamlessly interchangeable? I mean in the first form you just instruct the runtime to do what it would otherwise automatically do with the second one.
(deref (resolve 'inc))
is executed at runtime, everytime and will pick up any changes to inc
@U060FKQPN class init time?
@matan โin the first form you just instruct the runtime to do what it would otherwise automatically do with the second oneโ yes, agreed
Hi, how should clojure programmers learn java and jvm? where to start and what are important things? Thanks very much!
Hi, I wonder if someone could help in regards with the usage of defs inside macros. I asked the detailed question on Reddit here: https://www.reddit.com/r/Clojure/comments/68ru92/newby_question_on_the_correct_usage_of_vars_in/
@qduval it's very uncommon to need to resolve symbols by hand inside a macro what you're trying to achieve is usually written like this :
(defmacro add [a b]
`(+ ~a ~b))
Hi @leonoel, thank you for the answer. I was quite sure it was not usual. But then the macro that you link just inlines the call to the operator +. It does not perform the computation at compile time.
I was looking for a way to still do things at compile time, but somehow split the code a bit, to make it more readable and reusable (by using constants and such).
Best is to declare your constants as (def ^:const YOUR-CONST 138234.234)
and then just write normal code. The JVM will optimize the constant expression
In fact, I was looking to mimic some meta-programming constructs I know from my C++ background: constexpr. constexpr add(int a, int b) { return a + b; } In that setting, add can be given any integer or constexpr: constexpr int x = 1; constexpr int y = 2; add(x, y); //would work fine Any chance I might fullfil this need otherwise?
@rauh so basically, if I just annotate my def, it should be fine inside the macro call? I will try.
No it won't be done during macro expansion, but the JVM will just inline the constant expression.
Ok, I just tried this and it fails indeed: (def ^:const x 1) (def ^:const y 2) (defmacro add [a b] (+ a b)) (add x y) What you are telling me is that I should be using const instead, like this: (def ^:const x 1) (def ^:const y 2) (defmacro add [a b] (+ a b)) (add x y)
Ok @rauh, this is pretty clear answer, thank you ๐ I just wonder, will it really happen at compile time (the computation), or at the load of the namespace, or at first call?
Ok great! I just tried this too (scoping the defs): https://gist.github.com/deque-blog/9b0ad33323a1eb232cb801359f402cd2 But is it even a good idea to try this?
What would be the best way to try to do these computations at compile time, and still have a limited scope?
Ok, I will do some experiments with both approaches, and have a look at the library you just mentioned. Thank you so much for the great answers, it helps a lot ๐
@qduval Note that the eval
appraoch doesn't work local scopes either, e.g. (let [x 1 y 2] (add x y))
will produce wrong results because it will look up x
and y
on the namespace level rather than in the current lexical scope.
I saw that indeed in my previous tries. I think the global scope is the only way. But this is not too bad for me: after all, my need is for declarative information about the program itself that I would like to somehow compile into some values that I can exploit at runtime. Global is okay there.
You can do this and it'll be straight forward java code:
(defn ^long eval-test []
(let [x 1
y 2]
(+ x y)))
I'd bet the JVM will completely inline this result and make it consant:
public static long invokeStatic() {
long x = 1L;
long y = 2L;
return x + y;
}
Yeah, best to rely on the Sufficiently Smart Compiler โข๏ธ ๐
@qduval Also forgot to mention: All the above is compiled with (set! *unchecked-math* :warn-on-boxed)
Also you could just do the entire computation in the macro which will just emit the constant:
(defmacro my-const-expr
[]
(let [foo 23.2]
(Math/sqrt foo)))
core.match seems like an awesome library but it also seems inactive, with the last release being a two year old alpha release. I wonder why? Is nobody using it? Are there better alternatives? I consider using it for matching messages received on core.async channels.
@andershessellund I've used core.match for exactly that - for dispatching events in an Om app
it's very flexible for matching, but one can't change the rules at runtime
simpler to use a map
@octo221 Thanks. I don't think I need to change the rules at runtime. I think I'll just go ahead and try it.
or, for async you can use pubsub
Hi folks,
Iโve enjoyed the Spec-ulation keynote by Rich Hickey (https://www.youtube.com/watch?v=oyLBGkS5ICk) and was wondering, are there any libraries that place the major, backwards incompatible, version in the package, like โฆ myproject.v2.stuff
?
I'm thinking about releasing my new library under a namespace preview
, since breaking changes are such a guarantee at this point.
woah woah. woah. what is going on with this destructuring syntax?
{[w h] :pixi.renderer/size, transparent? :pixi.renderer/transparent? :as options}
@tjtolton yeah destructuring nests but it gets harder to read with more nesting
In most cases I'd say the [w h] should be in another line of the let, but it's pretty simple in this case.
I just thought I was looking at some crazy, yet unknown 3 element sequence, forloop destructuring or something
Nesting map destructuring gets really ugly:
{{:keys [w h]} :foo/bar {x :z} :baz/qux}
That's almost unreadable ^^
eh, yeah its a little wonky I guess, but I think it's actually a pretty visually consistent way of reading the info, once you know what you're looking at.
perhaps, but it adds to visual noise. For example:
(defn my-func [{:keys [a b] :as mp} {{[w h] :qux} :baz}]
...)
How many arguments does that take, and what's its structure ^^
That's the problem I have with it a lot of times, I have to sit way to long and figure out what the function expects before I can use it.
Yeah, there are probably other ways you could write said helper function that would be more readable. Too much nesting is probably just language abuse.
Hmmm, interesting. I don't often part with @tbaldridge, but I honestly prefer that you tell me what crazy you expect rather than having to piece it together in my head throughout the body of the function.
Best is probably to not do crazy. But if you're gonna do it, make it 1) as localized as possible and 2) look crazy.
I guess, having said that, to your point, destructuring is great at both of those things!
A little "trick" I find helpful: If the destructing map key is a keyword, you continue reading left-to-right. If it's anything else, you read from right-to-left (So first read the value, then the key). That being said, I never nest destructing, I'd rather use a let
.
@rauh the idea is that the local you're binding is always on the left
Iโve extended my protocol to SuperClass
and provided it an implementation of my-proto-fn
, but when I call that on a member of SubClass
, no implementation is found
how do you know SuperClass is SuperClass? (classes with the same name loaded by difference classloaders are not the same class)
All I know is that SubClass extends SuperClass
(Java classes). Donโt know about the classloader. Iโm just working in the REPL right now, so I assume Iโm only dealing with one?
(isa? Inet4Address InetAddress)
is true
, so Iโm pretty sure I loaded it (`Inet4Address` and InetAdress
are sub and super, respectively)
have you pasted that in your repl, or required it, or some other means of loading it
yeah, trying to get that to work in isa?
now and it does not seem to be working
Inet4Address
es satisfy the protocol: (satisfies? IPAddress (InetAddress/getByName "0.0.0.0"))
. I canโt seem to create an object that is just an InetAddress
though
InetAddress is an interface (or an abstract class, I forget which), which by definition you cannot make an instance of, you can only make instances of something that implements the interface (for an interface) or extends the class (for an abstract class)
the javadoc (https://docs.oracle.com/javase/7/docs/api/java/net/InetAddress.html) says
public class InetAddress
extends Object
implements Serializable
. I think itโs non-abstractYeah, itโs weird. It functions much like an abstract class though: getByName
returns either an Inet4Address
or an Inet6Address
. I was trying to make an InetAddress
instance to see if it satisfied IPAddress
, which is my protocol
so Iโve got this:
(defprotocol IPAddress
(version [this])
(bytes [this]))
(extend-protocol IPAddress
InetAddress
(bytes [this] (.getAddress this))
Inet4Address
(version [_] 4)
Inet6Address
(version [_] 6))
and bytes
is the protocol function thatโs not finding an implementation. I could paste the same code under 4 and 6 and get the functionality that way, but I would like to find why this doesnโt work as I expectedok. Is this documented? I googled before I asked but couldnโt find anythingโฆ
depends what you mean, I don't know of something that says "this exact thing won't work" but there are no examples that show anything like it as working
Thanks for the help!
speaking of protocols and extending them, is there some โbest practiceโ for where to define protocol extensions in a project? e.g. so theyโre only defined in one place but get loaded reliably whether youโre doing REPL or running a JAR?
I think this is what I was looking for, in case anyone else finds it useful https://github.com/clojure-emacs/cider/blob/master/doc/debugging.md
gut feeling
complexity is less about line counts and more about structure and design
I find the "single responsibility principle" the best design principle to follow when determining complexity
hereโs a great talk from Sandi Metz talking about code complexity. It mirrors what Tim said. https://www.youtube.com/watch?v=8bZh5LMaSmE
what's a good metric for measuring code complexity in Clojure? LOC is obviously the minimum but not very helpful.
oops, just saw @matan 's q. must be a tool out there. but even if not: what properties should be measured?
That's the problem, none of that matters. It's mental complexity that matters. Simplicity of design in the face of requirements.
Is a PersistentHashMap more lines of code than a mutable hash map? Yes, does that mean it's more complex? Perhaps for the maintainers, not for the users.
So in my code reviews I value: Readability, which is subjective. Ease of extensibility, also subjective. And Leverage.
Readability - If I know nothing about the structure of your project, can I jump into it and understand what the code is doing? Do you use a lot of macros and clever tricks that are non-standard? Ease of extensibility - You may have three modules, how hard is it to add a fourth. If you currently accept data from two sources how hard is it to add a new source? Leverage - If I do write a new data source, can I leverage existing code, or is everything so tied to a single implementation that I have to rewrite it? Are your business rules spread out in many files, or are the general enough that I can use one set of functions to validate all data.
@mobileink see also https://codescene.io which tries (and does a very interesting job, I think) to measure some of the other dimensions in a project that might be considered measures of complexity
@tbaldridge: agree. just thinking there oughta be a way to at least approximately measure. for example "mental complexity" is too vague. there are at least 2 kinds of complexity, conceptual and formal (structural?). since names and concepts are closely related name analysis would be a start. fns with names like "glop-x-then-frake-the-whosit-until-done" could be flagged as conceptually complex for two reasons: invented terms and too many dashes.
@hagmonk looks very interesting, thanks. fwiw i think this issue is also closely related to the whole Literate Programming thing. Full disclosure: imo LP is completely wrong-headed, and lack of measurement is just one reason. What is code anyway, really? https://github.com/mobileink/codegenres/wiki
To be literal about it, code is a set of commands written by a person. As such it's not entirely dissimilar to any other thing a human writes down and expects other humans to read. How easy it is to understand is going to be highly variable depending on who is writing and who is reading.
code is a literary genre. as such, it can be investigated (and maybe measured) in the same way that that literature is studied quantitatively. http://digitalhumanities.org/companion/view?docId=blackwell/9781405148641/9781405148641.xml&chunk.id=ss1-6-9&toc.id=0&brand=9781405148641_brand
although exercises like the one you linked are very interesting, I don't see us computing the complexity of shakespeare in any globally useful way
i would not bet on that. it's pretty common these days to measure the complexity of speech - this politician speaks at a 6th-grade level, that at a 12th grade level (guess who wins). i don't see why such techniques could not be adapted to code in order to measure some kind of "complexity".
grade level is a proxy for how many symbols a reader would recognize, it really says nothing at all about the kind of complexity that bedevils software.
But questions of code complexity are often linked to other factors, like business logic complexity. For example, all tax software is going to be horrifically complex, although it may not be the fault of the software design. I guess I'm talking about incidental complexity there.
@tbaldridge check out that http://codescene.io project, it's super interesting to see some of the approaches they're taking. They have showcases of projects they've analyzed: https://codescene.io/projects/167/jobs/736/results
they are all proxies or "warning indicators" I would say, rather than strict measures of complexity, but some very interesting ones nonetheless
in systems thereโs a concept of requisite variety here - you need at least N moving parts to model a system with N moving parts you care about, might be related
I feel like anything with a highly dependent set of variables where you want to discover the global minimum ends up being NP-hard
think bigger. somewhere an English prof, a linguist, an accountant and an AI expert are making a system that understands all the vocabs involved and will be able to score your code for complexity as you write it. or maybe it will just write the code, heh, ouch.
mobileink: On that last note - there is quite a bit of work being done on this. Some of it more than just interesting. Here is a link giving a simple overview (but it is reasonably accurate): http://highscalability.com/blog/2016/7/6/machine-learning-driven-programming-a-new-programming-for-a.html
thanks for that link. i'm kinda glad i'm oldish. i think programmers's are ripe for replacement by AI. Let's talk again in 5 years. :)
It comes down to branches, right? And there are explicit branches and implicit branches. As long as problems in implicit branches don't creep back into your explicit model, they don't count against your design's complexity. But if your explicit design has unnecessary branches, that's overly complex.
But you could be sitting on a mountain of complexity and as long as the formalism being presented from below is consistent / doesn't break.
i mean formally. how can an analyzer pgm distinguish explict and implicit branches?
well, I mean, we've got branches down in the machine code that we don't care about. And the analyzer isn't going to be judging that complexity. Then you have libraries with branches we don't care about. But if we bring in a bad library that fails to hide its branch mechanics from downstream users, then those downstream users' code must become more complex, to accommodate the leaky model below.
I'm not sure if I have a good definition that would allow one to just write a complexity analyzer right quick
ok. but assume we have a whiz-bang complexity analyzer. it understands the language of your text, so it analyzes that. the fact that your text compiles down to machine microcode is out of scope. ditto for any lib calls you make, e.g. to java code.
I think what you want to get at is the organizational complexity rather than the informational complexity. Ordered complexity vs. disordered complexity. One is purposeful, the other is incidental.
Hard to explain... let me use cellular automata as an example. Wolfram classifies 4 types of CA. Class 1 pertains to highly ordered CAs. 2 to semi ordered. 3 to highly randomized. 4 to complexly ordered. 4 is more like 2, as it falls between 1 and 3, between order and chaos. Class 4 though has the necessary primitives to create unboundedly complex states of affairs. So does 3, probably, but it's too disordered to control. Basically an RNG.
i hope we're not talking about Intelligent Design. the amount of complexity associated with something is independent of intention
So, looking at code like a CA, there are certain code paths that will produce your desired behavior. Most of them will also, necessarily, produce some incidental complexity. The "bad complexity" is that kind. The "good complexity" is the kind that directly solves your problem.
"the amount of complexity associated with something is independent of intention" I fundamentally disagree
ok we're talking about different things. the fact that your code runs O(n) has absolutely nothing to do with intention or purpose. it's just a fact.
in cs compplexity is well studied. pretty sure it has about as much to do with intention as nuclear physics does.
In one place, a shift might be an addition, in another it might be a subtraction. In yet another, it might just be a shift. What it happens to be in a specific context depends on the purpose / intention related to that context.
fwiw i don't understand what "directly solves your problem" means. to me that means "abracadabra" and your problem is nagicalky solved. in reality nothing is ever "directly" solved, afaik.
oh goodness. no no no. it is what it is. if it really did involve intention, i could write "2+2" intending 5.
Suppose you have to clone an object every time you pass it, due to the mutability of the system. That creates incidental complexity, unrelated to your problem.
sure. using lambda creates "incidental" complexity, since combinatory logic is more fundamental (no vars/substitution). i guess i do not see the usefulness of a distinction between incidental and whatever kind of complexity.
relative to certain problems (purposes ;)) lambdas will create incidental complexity. Relative to some other problems, they will be the perfect fit.
fwiw i think "normal form" make a lot more sense than whatever it is clojurists want to call the opposite of "incidental complexity". it's very well understood and it means exactly the it cannot be further simplified, i.e. all "incidental" cruft has been removed.