Fork me on GitHub
#clojure
<
2021-01-31
>
akond14:01:17

i have

(def cli-options
	[["-i" "--input-directory DIR" "Source file directory"
	  :validate [#(fs/exists? %) "File must exist."]]])
for clojure.tools.cli/parse-opts, but i don't get any errors when there are no command line arguments. is that supposed to work this way?

borkdude14:01:22

@akond I think so. Often what happens, if no options are given, a tool decides to print help, for example. But this is on the tool.

akond14:01:49

[["-i" "--input-directory INPUT" "Input file directory"
	  :validate [#(fs/directory? %) "Input directory must exist."]]
	 ["-o" "--output-directory OUTPUT" "Output file directory"
	  :validate [#(fs/directory? %) "Output directory must exist."]]]
strangely, if i provide -i, there is no error for missing -o. am i missing anything?

borkdude14:01:24

@akond the parse-opts function only parses options. You can then process this information and do additional validation on combinations of required things, etc.

akond14:01:28

it's strange, because the doc mentions "required argument", so i though it should work out of the box

borkdude14:01:52

@akond required argument means: if you expect --args thing but the thing is missing.

4
borkdude14:01:15

unless I'm missing some feature in tools.cli I've never known about

akond14:01:37

interesting

kosengan16:01:05

"Scheme (and Racket) effectively implement recursion as loops wherever possible. And not only that, the Scheme standard requires it. This feature, called tail call optimization (or TCO), has been around for a few decades and it is a sad commentary on the state of our programming languages that none of the modern languages support it. This is especially a problem with the JVM as newer languages have emerged trying to target the JVM as a runtime architecture. The JVM does not support it, and consequently the languages built on top of the JVM have to jump through hoops to provide some semblance of a sometimes applicable TCO. So, I always view any functional language targeting the JVM with great suspicion. It's also the reason I have not become a fan of Clojure." https://mendhekar.medium.com/why-i-still-lisp-and-you-should-too-18a2ae36bd8

dharrigan17:01:01

It's my understanding that as part of Project Loom, Tail Call Elimination is on the table for implementation.

ghadi17:01:14

yawn

💯 3
Mike17:01:12

Scheme is nice. Currently doing, slowly, SICP with scheme. But I don't think it's used in the industry. Whereas clojure is used, and being a JVM language surely has its advantages.

andy.fingerhut18:01:07

Clojure lets you do manual tail call elimination using recur if you want. Using it is not built into the compiler, but as long as you know this, I have rarely seen programs where Scheme's automatic tail call optimization makes a huge difference. Seems like a pretty minor objection to Clojure to me, personally, relative to other differences, e.g. Clojure's built-in default implementations of immutable collections.

☝️ 12
andy.fingerhut18:01:41

Different people have different judgements for how important technical language differences are to them.

chepprey21:01:16

Do Scheme/Racket feature homoiconic maps, vectors, and sets? (I know it has lists covered 😆) Are its collections immutable?

chepprey22:01:01

I always view any functional language with non-homoiconic, mutable-by-default collections with great suspicion.

andy.fingerhut23:01:24

I am less knowledgeable about Racket, and could not answer for it, but Scheme definitely has mutable cons cells and set! .

euccastro00:02:39

Racket's cons cells are immutable. I don't think you want to pick a fight with Racket on syntax 😛

euccastro00:02:36

there's an (unmaintained) port of Clojure to Gambit Scheme which does have TCO: https://github.com/takeoutweight/clojure-scheme

euccastro00:02:10

most Schemes allow you to extend the reader to introduce data literals, and there are implementations of immutable/persistent data structures. Clojure doesn't stand out for what it can do (except if you count the reach of the JVM, but there are other lisps there). it stands out by the good things it nudges you to do and the bad things it discourages you from doing, which has helped create a more widely shared culture around those values

euccastro00:02:56

i.e., Racket probably has persistent data structures (I haven't checked), but if you grab any Racket library at random you can't assume its interface is based around them in the same way you've come to expect in Clojure

euccastro00:02:18

I think recur is enough for most application code in practice. TCO and continuation support would allow to implement things like core.async without macros: https://pastebin.com/ff732013 (this is just an old POC and it's of course much more limited in scope than core.async, but it has the fundamental mechanics). I don't miss them much, though

Claudio Ferreira16:01:55

Did someone here solved all the exercises at http://4clojure.com? Was it worth spending your time? Did u developed your clojure habilities?

👍 3
p-himik17:01:09

Note that that website hasn't been maintained for years. Apart from just having broken links, it also uses a quite old Clojure version so some of the things you know will not be useful. And conversely, some of the things you will learn with the website will be outdated.

andy.fingerhut18:01:45

several of the exercises focus on problems like "if a function like foo did not exist in Clojure, how can you implement it using other built-in functions?", to get you to think about other ways to do it. Such exercises can result in a better understanding of how those built-in functions work under the hood, and that there is pretty much always more than one way to do things, which can be a useful mind set to have. I wouldn't call those particular exercises useful when writing production code -- in production coding situations you would use the built in functions that let you do the job in the most developer-time-effective way you know.

👍 3
andy.fingerhut18:01:03

If you like programming, and like solving "logic puzzle" types of problems, 4clojure can be interesting and you can learn a few things from it. Many people have found it useful in helping to improve their understanding of Clojure as a language beginner. The easier and medium problems can typically be solved in a short amount of time. I wouldn't say "If you haven't done 4clojure problems, you aren't a real programmer" or anything like that.

noisesmith16:02:16

the old clojure version is intentional (the site maintainer thinks it would be unfair to past participants to introduce a clojure version that wasn't available to them) - but very little that you learn about clojure 1.4 doesn't apply to today's version

noisesmith16:02:50

I learned a lot about clojure from 4clojure (though many of the answers that others submit, if you compare your answers, are written for code golf and not quality)

p-himik17:02:13

Transducers are a significant chunk of Clojure that's missing from 4Clojure. I remember encountering some other issues where the documentation clearly states that something is possible but 4Clojure doesn't work with it - alas, I don't remember the details. @U051SS2EU Do you have a reference to that statement about an update being unfair (which, IMO, is not a good argument all by itself)? I know only of this comment that explains that the update hasn't been done only because of clojail: https://github.com/4clojure/4clojure/issues/303#issuecomment-509882098

noisesmith17:02:12

@U2FRKM4TW this is the explanation that amalloy gave when I asked about updating the version, he still hangs out on #clojure freenode IRC, though he isn't active in clojure dev any longer

👍 3
noisesmith17:02:03

yeah, clojail is a hack, a modern redo of 4clojure would likely be better off using a self hosted cljs in browser

noisesmith17:02:52

though that leaves an opening for exploits where a "solution" does something unexpected when run in your browser

andy.fingerhut18:02:58

I mean, if someone wanted to make http://5clojure.com , I doubt anyone at http://4clojure.com is going to complain 🙂

noisesmith18:02:52

since 4clojure uses clojure 1.4, maybe we are due for 11clojure

beders17:01:05

Can someone stop me from doing this thing?

(defn export [var var-fn]
  (alter-meta! var assoc :doc (:doc (meta var-fn)))
  (alter-var-root var (constantly var-fn)))
This can be used for forward fns defined in some other namespace and keep the doc around.: (declare myfn) (export #'myfn #'otherns/myfn) Please stop me, it feels wrong. (vs. a much saner (defn myfn [] (otherns/myfn []) )

delaguardo21:01:59

this is not wrong as an idea, but a bit smelly because of alter-var-root using. Have a look at this macro — https://github.com/ptaoussanis/encore/blob/master/src/taoensso/encore.cljc#L406-L431

👍 3
vemv02:02:01

This thread is worth a read https://groups.google.com/g/clojure/c/Ng_GXYSrKmI/m/q0cxahB3BAAJ indeed a thin replacement can be ok, but it's better to assess first the structure of your code

beders02:02:29

thanks a lot guys

dpsutton17:01:28

you could look at potemkin from ztellman. it has a "pull" type rather than a "push" type like you've got here. there's also a watch on each of them i believe to keep them in sync which you might like