Fork me on GitHub

anybody know if there’s somthing required to turn on fdef instrumentation at the REPL


(defn foo [] false) (s/fdef foo :ret int?) doesn’t seem to check the return value postcondition automatically


@elliot It is expected that :ret is not checked. See, in particular "Note that the :ret and :fn specs are not checked with instrumentation as validating the implementation should occur at testing time."


hrm thanks. so supposing I’m repl-driving-development, the assumption / normal workflow that everybody else is doing is that there’s sort of an auto-test-runner running in parallel? I’m hoping the software can help check my invariants while I’m fiddling with things


One long-term strategy that might pan out is that once a function has been tested, this fact can be remembered. Then something else can calculate when that function's dependencies have changed, essentially invalidating the previous check. It would be interesting to see something along these lines that churns along in a background thread…


that’s interesting. I might be doing my workflow backwards right now (insofar as, I keep vacillating between whether I want fn f to return a seq or map, based on how g (that depends upon f) looks when f returns one or or the other.)


@elliot Have you watched Stu Halloway's "REPL-Driven Development" talk?


not recently if at all--will check it out!


In particular, he says he doesn't type anything into the REPL -- he types into a file and evaluates forms in the file (via the REPL). That's how I work as well, with code and "tests" and -- if I want to verify an fdef -- calls to spec.test/check.


So all of my code and tests and specs start off in one file as I work with the REPL and then I move test code into tests (or something just leave it in the source in a (comment ...) form since it can be eval'd into the REPL with just a key stroke.


I never use a auto-runner for tests, nor a file watcher (I might if I was doing cljs dev perhaps).


this is all very fascinating. much more to learn. thank you all!


Recursion help, please. Can recur somehow refer to an outer loop/fn? The following example fails, because the intention is from recur to "restart" the (outer) loop rather than the inner fn:

(loop [i 0]
  ( (fn []
      (if (= i 3)
        (recur (inc i))))))

Pankaj Shet02:10:58

Hi Guys, Thank you for your help regarding books, but if I need to choose 1 book which should I choose? Getting Clojure? I already have Brave Clojure with me.. :) sorry for late response..!


I do not know of any direct way in Clojure to make a recur go back to anything other than the innermost enclosing loop or function definition.

Pankaj Shet02:10:37

Is it worth switching from Java to Clojure after 8.6 yrs Exp in JAVA? I am already learning Scala... :)


There is a JIRA ticket here proposing adding that capability to Clojure, which anyone with a free JIRA account may vote on if they wish, but no promises that such a thing will ever be added:


Pankaj, I think it is worth the time for every professional developer to learn multiple quite-different programming languages, for the things you will learn, even if you don't end up with a job that enables you to use them (but certainly becomes more likely if you do know the language).


If you have never learned any kind of Lisp programming language, Clojure is a good one to learn in that family.

Pankaj Shet02:10:12

Thanks Andy for your help.. Which book should I start with?

Pankaj Shet02:10:22

I am thinking to start with SICP first.. What's your say?


I have not read many of the books on Clojure, only Clojure Programming (one author being Emerick) and Clojure Applied (not meant as a beginning book), so I may not be the best person to ask.


SICP is an amazing book to learn new things from, for certain. It isn't written with Clojure in mind, but Scheme, which is another Lisp with many things in common with Clojure, and quite a few differences in details.

Pankaj Shet02:10:27

Ok thanks Andy :)


@pankaj.shet123 If you've read Brave, then Getting Clojure is probably a good "next book".

💯 4

And, yes, definitely worth considering switching from Java to either Scala or Clojure -- learning new languages is always worthwhile.

Pankaj Shet04:10:47

Thanks Sean.. Which should I consider? Scala or Clojure?

Pankaj Shet04:10:31

How do Scala and Clojure compare?


Well, Clojure is "more different" so I think you'll grow more as a programmer that way.


I went from Java to Groovy to Scala to Clojure.


(I started with Java in '97)


Both Scala and Clojure allow you to do fairly natural functional programming -- but Scala doesn't force you down that path: you can simply use Scala as a "better Java" and continue to write code much the same as always... which you won't learn much from.

Pankaj Shet04:10:54

That's great Sean I would surly like you to mentor me how should I go ahead.. :)


Well, I'm already mentoring a bunch of folks right now so I don't have bandwidth for anyone else right now. But you'll find folks here in #beginners are always happy to help folks who are new to Clojure!


hey, next week im gonna give a talk at my collage about functional programming and clojure. my talks title is intro to a jedi. do you have any suggestions to make the prensentation more interesting because my friends believe that functional programming is like rocket science 😁


This is still my favorite page of content that convinced me to stick with Clojure, it's from the book "Programming Clojure". And I also like the suggestion to build something with re-agent in front of them. Just make sure you have everything pre-made (in case something goes wrong) and it fits in one source file.


And if you want general advice on how to make a presentation about functional programming more entertaining and exciting, I really like this one in terms of flow and tone:


The way I understand it is that main idea is that the functional paradigm favors starting with functions (bottom-up design) and composing them, rather than creating an overall structure first and forcing functionality into that (OOP top-to-bottom design).


@UCG8KE0SG thank you i will research deeply these suggestions


I'm a fan of how Eric Normand defines functional programming. Don't focus too much on the how-to details right away; give them a high-level view of FP as a paradigm where you strive to segment your program into data, functions and IO/side effects, and push as much code as possible towards the left of these three. Then once they realize that FP isn't so scary, you can hit them with plenty of awesome Clojure code samples, showcasing its efficiency, like the Programming Clojure excerpt deliciousowl posted. You should probably talk a bit about the parentheses as well, as some people could spend the whole presentation being bothered by those.


+1 for the Eric Normand approach; highly recommend checking out his article 'Programming Paradigms and the Procedural Paradox'; and his articles 'Composable parts', 'Reasoning about code', 'Global mutable state', and 'How to switch from the imperative mindset'. also his talks: 'A Theory of Functional Programming', 'All I needed for FP I learned in High School Algebra', and 'Building composable abstractions'


I found great success with just building something in front of them, especially with reagent


I had the initial setup done, and built a dnd stat roller live in an hour


Actually seeing the results was a huge bonus


Watched rich Hickey's talk today


What a intro to clojure !!

Mario C.16:10:53

I am looking at the docs for binding. And one of the examples doesn't make sense to me.

;; Here are the definitions.
(defn mymax [x y]
  (min x y))

(defn find-max [x y]
  (max x y))

user=> (let [max mymax]
         (find-max 10 20))

20 ;let is ineffective outside current lexical scope

user=> (binding [max mymax]
         (find-max 10 20))

10 ;because max is now acting as min


Hi. Is there some other function similar to empty? I could use here? (remove (comp empty? second) {:one [] :two "hi" :three :boom})

Mario C.16:10:10

In both the let and the binding we have [max mymax] but how does that come into play with find-max?

Mario C.16:10:30

How does one return 20 and other return 10?


@cristibalan (every-pred seqable? empty?)

👍 4
parrot 4

@mario.cordova.862 the value introduced by let doesn't alter the existing binding, it just shadows it, and the lexical scope of the shadowing doesn't propagate upward to the function


binding, on the other hand, alters an upstream binding


so it has a more promiscuous scope


I don't think that code would work as shown, because max is not declared dynamic

Mario C.16:10:08

Ahhh got it

Mario C.16:10:35

basically find-max is using max. In the let it doesn't get rewritten

Mario C.16:10:50

didn't see it at first


What;s the general case for using nil as values in maps, is it considered bad practice?


Interesting question. I don't know that I'd say it's "bad practice" per se but I think it's likely unusual/rare. After all, in most situations, nil means the "absence of a value" and so there's likely to be no functional difference between {:a nil} and {}. That said, JSON interop (where the former would become {"a" : null} vs the latter still being {}) could impact your choice, as well as situations where your key/value pairs are iterated over (via map or even reduce), depending on how you process the values.


At work we have some specific situations where we do need nil values in a map because of JSON interop. Or at least to make the JSON interop simpler.


You'd just need to guard against a lot of nil-punning issues via contains? et al


@lockdown- In addition to the above, the other place I've run into needing nil values (or not needing!) in a map is SQL interop.