Fork me on GitHub

cool. that is what i was thinking. and someone recently gave me a lot of resources on repl driven development i still need to go through. i am curious. does the general work flow usually go you write a function or expression in your actual program file, send it to the repl to see if it works, and keep going? a lot of the tutorials seem to just be almost building the entire program in the repl itself but then am i supposed to go back and put those in the actual .clj file?


i know this is probably super beginner stuff that i should just learn along the way but i needed a break anyways. sorry if this is too trivial for the beginner chat.


no no, that's exactly right 🙂


which one? program file first, then to the repl or vice versa, build the function using the repl and then send that to the program file?


most folks do the repl first, then add it to the .clj


and then periodically "reload" the cljs that are part of the project


so that you can interact in the repl with the current way the program is structured across namespaces


cool beans. it does seem like a fun way to develop.


btw as I mentioned in a reply above, def and defn return vars, it must be some emacs function returning nil


i've been debating which lisp family language to take a deep dive into first. I think i ultimately would want to use clojure for my projects but would it help to use something like racket's how to design programs, or SICP and scheme, or Practical Common Lisp to get a better foundation for programming before switching to Clojure? I'm using Clojure for the Brave and True right now, just not sure if it's recommended for a pretty new programmer to jump straight into clojure.


hard to say; it is definitely the case that clojure is intended for professional rather than educational use (though of course there are many teachers using it as a teaching language), while scheme and racket have more pedogogical and conceptual material supporting them


and clojure exposes one to more and more disparate things (mostly java related) which can definitely be distracting and confusing


yup. but i'm hoping "developer motivation" can maybe see me through. i like using books so plan on using Brave and then Living Clojure. I guess if I just find it too difficult i can always switch gears. or maybe even after i get some clojure under my belt i can try to do something like the SICP text with clojure instead of scheme? that might get a little too hairy though.


yeah, would concur with hairy; one really wants to be able to exactly replicate the experience the book leads one through; there are all sorts of details in SICP that do not directly translate to clojure

dpsutton00:07:02 only half completed but right up your alley


cool! this is what I call a damned productive break!


there's lots of cool stuff. @tbaldridge has video series on the compiler behind core async and a series on making a JIT. ccgrande made a vm to parse clojure forms with regexes. Clojure is great because it's still playful as a lisp and can get you a paycheck as well


that last sentence is exactly why i wanted to do the deep dive in Clojure right away if feasible. especially with the potential for the full stack web app with clojurescript on the front end.


this might be up your alley as well then


plenty of folks here to help you through!


for something like reagent, is not knowing javascript and react really going to hurt me there? I guess people are able to learn clojure without knowing java so hopefully not.


and when i start trying out clojurescript, if i can skip learning javascript, will i still want a very strong foundation in html/css? or is that part of clojurescript capability too?


my personal feeling is/advice would be- the sense that one has to understand the lower level stuff right away to learn the higher level stuff is- generally speaking, not to be trusted. you can totally learn clj and cljs without knowing java or js or css beforehand, and just fill in the gaps as you go. in reality that's what everybody does. in fact, working in the higher level of abstraction, achieving a certain level of mastery, then going down a level- this for me is much more satisfying. whole new insights open up about the higher level that previously was well known. on the other hand, when you're at a lower level just because, and you really want to be at the higher level- to me, that's kind of wasting time. ymmv.


that all said, one does see a lot of java in clojure, and a lot of js/etc in cljs- and seeing that stuff can be totally befuddling and frustrating. but it can be worked through.


great response! You just alleviated a lot of anxiety I've had on my approach to this whole intellectual curiosity and desire to learn clojure. thank you!


glad to help, you're very welcome!


Doing SICP exercises with clojure. For exercise 1.24, here is the expmod function written in clojure:

(defn expmod [base exp m]
  (cond (= exp 0) 1
        (even? exp) (mod (expmod (square base) (/ exp 2) m) m)
        :else (mod (* base (expmod base (- exp 1) m)) m)))
Now, (expmod 189 1999 1999) throws ArithmeticException integer overflow clojure.lang.Numbers.throwIntOverflow ( How do I tell clojure to use bignums in this case?


I tried the below and it doesn't work either (I get the same error).

(defn expmod [^BigInt base ^BigInt exp ^BigInt m]
  (cond (= exp 0N) 1N
        (even? exp) (mod (expmod (square base) (/ exp 2N) m) m)
        :else (mod (*' base (expmod base (-' exp 1N) m)) m)))


@chase-lambert My experience? Reagent hides React very well. HTML and CSS are linear atrocities, so bearable, and massively documented.


(defn expmod [base exp m]
  (let [bibase (BigInteger. (str base))
        biexp (BigInteger. (str exp))
        bim (BigInteger. (str m))
        bizero (BigInteger. (str 0))
        bione (BigInteger. (str 1))
        bitwo (BigInteger. (str 2))]
    (cond (= (.compareTo biexp bizero) 0)
          (= (.compareTo (.mod biexp bitwo) bizero) 0)
          (.mod (expmod (bisquare bibase) (.divide biexp bitwo) bim) bim)
          (.mod (.multiply bibase (expmod bibase (.subtract biexp bione) bim)) bim))))


Surely there should be a more concise way of coding this in clojure?


Or, doesn't clojure have language support for bigint / bignum?


My mistake. Second version works properly. I was calling it like this: (expmod 189 1999 1999) while I should have been calling it like (expmod 189N 1999N 1999N)


beginner top tip: use cool names for bindings if you want to get a lot of attention to your question 😄

👏 5

asked this question in the web-security channel but I think its quite dead (only 45 members). Is there any need for a "Security step" on the sign-up part of a web-app? I understand if you are logged in and u use tokens to see if ur a valid user. Unsure about the sign-up part though. The sign-up endpoint will only be accessable from localhost.


@jarvinenemil What exactly do you mean with "Security step"?


That's what I am trying to figure out. I created this sign up endpoint but since this is my internal api there should be no need for jws etc. I will have some api endpoints which 3rd parts will be able to access (Where i use jws)


Perhaps there are two questions: 1. does a registration flow have to be authenticated or otherwise protected from attack? 2. do any needed protections need to be applied to an api listening only on localhost?

✔️ 1

What's up with threading in Clojure? I never had to deal - or understand threads - with JS/Python/PHP/... but everyday I see "thread-safe" etc. when working with Clojure. Why should I care about threads with Clojure?


The Java VM supports multiple threads — multiple different bits of code all running at the same time. A good example is a web server: the server spins up multiple threads, so that it can process multiple web requests at the same time.


The reason you should know/care about threads is if you ever use something that is not thread safe, you could have one thread trying to do something with some data, and have a separate thread accidentally writing its own data on top of what the first thread is trying to do.


you should know about threads if you are writing js, because odds are you are working on a website, so infact your distributed system is multithreaded


We had this recently with date formatting: we set up one global date formatter for all the threads to share, but it turns out date formatting is not thread-safe, so sometimes we’d get dates that were garbage strings.


I see. Thanks for the clarifications.


This book also gives a good overview of how hairy multi-threaded programming can be: (Java Concurrency in Practice)


in core.match, how do i match against a set of of args?

(let [apparel-clause '(:or "Baby & Toddler Clothing" ;; i also tried #{"stuff"....}
                                                     "Apparel & Accessories"
                                                     "Baby & Toddler Clothing Accessories"
                                                     "Clothing Accessories")
                                x               "Clothing Accessories"

                            (match [x]
                                   [apparel-clause] "matched"))
doesn’t work. this does work:
(match [x]
                                   [(:or "Baby & Toddler Clothing"
                                         "Apparel & Accessories"
                                         "Baby & Toddler Clothing Accessories"
                                         "Clothing Accessories")] "matched")
but i’d rather abstract those 4 strings into a binding

Josh Horwitz19:07:11

I’m using the emacs set up from , I wanted to add evil mode to it, how would I go about that?


@joshua.d.horwitz I don’t know about only adding evil, but is pretty good for clojure and easy to setup


evil mode ships with emacs, you can just turn it on whenever you like with M-x evil-mode or iirc (evil-mode 1) in your init


also, is matching guaranteed to be top-to-bottom? I’m relying on:

(let [x [1 1 2]]
              (match [x]
               [[_ _ 2]] :a0
               [[1 1 2]] :a1
               [[1 2 3]] :a2
               :else :a3))
to return :a0 (which it does)


(I mostly solved my previous set-of-matches problem by wrapping it in a let and doing (contains apparel-set apparel)


Yes. Underneath it can reorder column matching but not row matching.


ah ok. that makes sense


Easy way to remember is that it's common to put a wildcard matches at the end (I think the macro does this automatically too. Been a while) and if it could reorder rows it would possibly match the most general case


@noisesmith evil mode doesn't ship with emacs, it has other built-in vi modes though