Fork me on GitHub
#clojure
<
2021-01-19
>
nhanclassroom03:01:08

(defn handle-args
  "Handle your program arguments here.  You may support zero or more.

  Ensure that you use the exit function when processing is complete."
  [config {:keys [options arguments]}]
  (if (seq arguments)
    (if (= 1 (count arguments))
      [0 ["there is 0 arguments"]]
      [0 ["> 1 argument"]])
    [0 ["No argument handler"]]))
Can someone explain me [0 ["string here"]] meaning. This is a template name lein-bin. handle-args function is call in main fuction. It is also the entry where we put something we want to work in cli here. I can understand the abstraction layer. But the syntax is strange. Why we need ["a number" ["code"]] in here. It put directly "code" it will not work. What is the meaning of those numbers?

andy.fingerhut03:01:18

What is the function that calls handle-args doing with the return value?

nhanclassroom03:01:47

(defn run 
  "Processing starts here.  Use this function when running from a REPL.

  The help option and any errors are handled here.  Otherwise, processing
  is passed to the argument handler."
  [& args]
  (let [config (configure)
        {:keys [options arguments errors summary] :as opts} 
        (-> (parse-opts args (:cli config))
            check-options
            (update-in [:options] merge logging-options)
            configure-logging)]
    (cond
      (:help options) (exit 0 (usage config summary))
     errors (exit 1 (error-msg config errors))
     :else (let [[exit-code message] (handle-args config opts)]
             (exit exit-code message)))
    ))
handle-args being called from here

nhanclassroom03:01:48

(defn -main
  "Entry point for command-line processing.  This will be used when running outside of a REPL."
  [& args]
  (System/exit (apply run args)))
And run being called from here

andy.fingerhut03:01:59

This line of code (let [[exit-code message] (handle-args config opts)] is using a Clojure syntax for something called "destructuring". Are you familiar with that?

andy.fingerhut03:01:36

If not, I can explain it.

👀 3
nhanclassroom03:01:46

Ah, thank you. Can you give me some good document url. I can learn by myself. I should not waste your time

andy.fingerhut03:01:03

No worries. The quick explanation is that when you do (let [[a b c] (some expression here)] ...), it calls (some expression here), gets the return value, and as long as that return value is a sequence kind of thing (either a list, a vector, or a sequence), then a is bound the first element, b to the second, and c to the third. Any remaining elements are ignored in that expression.

👀 3
🎉 3
andy.fingerhut03:01:03

Here is a link to an article on http://clojure.org with many other things destructuring can do, but you might want to focus on the part for sequence destructuring and save the parts that can take apart maps for later when you need it: https://clojure.org/guides/destructuring

3
nhanclassroom03:01:59

ah. So num in this case is exit-code

nhanclassroom03:01:09

wow. Thank you very much.

andy.fingerhut03:01:44

So the symbol exit-code is bound to that first element, which are the numbers 0 in the sample code you pasted earlier. Those are passed to the function exit, which probably passes it to the Java method System/exit, and that becomes the exit status when the process exits, which some ways of invoking a program pay attention to to see if an error occurred (convention is 0 for all OK, non-0 for some kind of error).

🎉 3
andy.fingerhut03:01:41

The symbol message is bound to the second element, which in your example is a vector of one string. I don't know exactly what exit is doing with that vector, probably printing the string somehow.

3
nhanclassroom03:01:33

`(defn exit [exit-code message] (if (= 0 exit-code) (apply infoc message) (apply errorc message)) exit-code)

nhanclassroom03:01:37

ah, I can find defn of exit here. Thank you very much

nhanclassroom03:01:02

infoc and errorc is import from other package

jumar05:01:08

Is there still a use case for definterface or should I always use defprotocol instead? Joy of Clojure, 2nd ed. (p. 302-304) mentions primitive arg types and return values as the primary advantage of definterface. Has that changed over they years?

didibus05:01:28

I think that's still accurate.

didibus05:01:29

In that protocol functions are always boxed and can't be made primitive.

didibus05:01:50

As far as I know they still don't support primitives, so if you do need that definterface can be an alternative

didibus05:01:33

Though I'm not sure if proxy or reify can generate primitive types, but I guess if the book says so

seancorfield05:01:56

https://corfield.org/blog/2013/05/01/instrumenting-clojure-for-new-relic-monitoring/ @jumar That is probably the only time I've used definterface and deftype myself...

😺 3
jumar05:01:48

Cool, thanks for the example!

seancorfield05:01:06

Oh, and in next.jdbc...

borkdude11:01:51

@jumar definterface can be useful if you want to provide a marker type, i.e. an interface for the sole purpose of being able to say (instance? Marker foo)

borkdude11:01:49

see e.g. core.match where this is used

Vlad18:01:44

quick question - a project that is set up with lein - is there a simple way of updating the documentation based on the project.clj ?

Vlad19:01:23

it might be that the answer is no -

caumond20:01:02

Did you have a look to available plugins in leiningen https://github.com/technomancy/leiningen/wiki/Plugins#documentation . Gargamel or codoc, depending on what you are looking for.

teodorlu19:01:58

Good evening. I'm trying to look up an old post by Stuart Sierra where he argues for something along the lines of > it's better to have a broad API with many functions that's possibly difficult to understand than a narrow API that hasn't been battle-tested, and that might not have what I need. Digging through his blog now, https://stuartsierra.com/blog/page/26, haven't found it yet. Any advice?

teodorlu19:01:14

specifically, I think he mentions that he often prefers to use a big java package directly, rather than going through a Clojure wrapper that might just cover certain parts.

3
grazfather20:01:26

I disagree. and I think that most would. Peek at "the philosophy of software design"

phronmophobic20:01:17

having a narrow api that only indirectly gives you access to an underlying platform sounds a lot like https://en.m.wikipedia.org/wiki/Inner-platform_effect

3
3
phronmophobic20:01:02

I like the adage, “make the common case easy and the complex case possible” since it’s all too common for libraries to do neither

6
3
vemv21:01:42

ah this q is for me - I'm quite a big S. Sierra fan :) https://stuartsierra.com/2013/07/28/the-amateur-problem

🙌 3
didibus06:01:09

Interesting, hadn't read that one before

didibus06:01:27

I think he makes a great point actually. But I think it would have been nice for him to describe when does BIG become Bloated.

😄 3
teodorlu09:01:14

@U45T93RA6 thanks a lot! 😊

teodorlu09:01:22

https://clojurians.slack.com/archives/C03S1KBA2/p1611087986264200?thread_ts=1611085678.261200&amp;cid=C03S1KBA2 @U01KUQRDMLG Care to elaborate? I've begun reading that book, and I'm enjoying it so far. To me, it rhymes with a lot of what Rich said in The Language of the System, and the principles behind namespace-qualified keywords.

Travis Brown20:01:43

Is there a tool that allows generation of a spec based on sample data (as a starting point to further refine the spec)? Asking here because searching the terms "generate spec" are all about s/gen, and I don't see such a thing in the toolbox

Travis Brown20:01:24

exactly this! 🙏

richiardiandrea23:01:38

Hi there, does anybody know an alternative to https://github.com/jebberjeb/specviz? I would like to see my model in a nice graphical format and I wonder what I can use.