Fork me on GitHub
#beginners
<
2018-09-15
>
guiferpa00:09:44

Hi there, I am a beginner in Clojure and I need learn more about Clojure and functional programming.

guiferpa00:09:29

Can anyone help me by giving course tips?

debamitro01:09:09

Hi, I am a beginner in Clojure but not a beginner in programming. I would like to study the codebase of a large, and preferably computation-intensive, Clojure program. I come from a C/C++ background and I want to see how large programs can be written differently. I had posted this question on #clojure and got two examples: https://github.com/uncomplicate/bayadera and https://github.com/area42/flare

eval202010:09:18

@U7FUA6VV3 http://open-source.braveclojure.com/ has a searchable list of active projects. For a somewhat larger clj-application https://github.com/metabase/metabase/ comes to mind.

tbsvttr10:09:11

Maybe this question seems a bit off, but a friend of mine is really pushing me towards Scala: So, why use Clojure instead of Scala?

leonoel20:09:39

Scala is an experimental language.

seancorfield20:09:41

That's not a very helpful (or accurate) response. Scala is used heavily in production by a lot of companies, more so than Clojure. Scala is much more widely used than Clojure.

👍 4
seancorfield20:09:10

I think borkdude's answer was pretty good. Try both languages for a while. See which you prefer -- they are very different. Also, your programming background will factor in to which language you find easier to learn and use. Since Scala can be used as just a "better Java" it can be easy to lean if you're a Java developer and just want something similar but "better" 🙂

👍 4
leonoel20:09:59

Every minor version of scala introduces breaking changes, and the upcoming scala 3 will even have a new syntax. The collection framework has been completely rewritten several times now. A fair amount of production code is stuck to older versions, some may never upgrade at all.

👍 4
leonoel21:09:30

Clojure language and ecosystem is mostly free of these problems, and this a big deal in my opinion.

val_waeselynck21:09:09

Why use Scala instead of Java?

seancorfield22:09:53

@U053XQP4S We used Scala at work in the 2.7 / 2.8 days and, yes, that was a very painful transition -- with every single milestone build having binary incompatibilities and we had to upgrade the entire tool chain every time and rebuild everything. The built-in actor library had memory leaks. 2.9 was a slightly smoother upgrade and it's gotten better since then. We switched to Clojure before the 2.9 release and we've been very happy with that choice. We run pre-release builds in production with no problems -- and have been doing so for over seven years now.

seancorfield22:09:30

When someone asks about Language A vs B on a Language A forum, being negative about Language B without providing rationale for those criticisms really isn't very helpful -- nor in keeping with how our community is supposed to behave. We're supposed to be better than that. And we're supposed to help beginners here.

seancorfield22:09:44

@U06GS6P1N I can understand choosing Scala over Java -- Scala is more expressive and more concise. I'd probably choose Kotlin myself, if I couldn't use Clojure.

👍 4
val_waeselynck07:09:38

@U04V70XH6 the question was rethorical :) it seems obvious to the OP why use Scala over Java, my point is that there might be a similar argument with Clojure over Scala.

val_waeselynck07:09:11

@tobias.vetter Having used all 3 languages, I find that Scala pushes the limitations of Java further away instead of eliminating them (e.g more powerful inheritance, but still inheritance; richer type system, but still a source of complexity; more options for program design than Java's class hierarchies, but still a source a paralysis). I think I've made this analogy before, but switching from Java to Scala was like switching from a balloon to a zeppelin, whereas switching to Clojure was like (finally) switching to a plane - with all its initially counterintuitive aspects (wait, you can't fly it without moving? / wait, no classes?).

👍 4
val_waeselynck08:09:49

Btw, do not take the above as a "proof" that you should be using Clojure - IMO only experience and sensitivity can leaf to an informed choice if language, not logic.

👍 4
leonoel09:09:02

@U04V70XH6 The question was explicitly about clojure's benefits wrt scala. I was assuming the OP was aware of technical differences and expecting more than a wikipedia-like answer, and I provided an information I'd wish I were given before investing professional time on both languages. Do you expect me to apologize for that ?

sveri14:09:19

@tobias.vetter I just want to add that I gave beginner courses for both Scala and Clojure for engineers with a heavy Java background. Teaching the very basics took almost 10 hours for scala while in clojure I got aways with something like 2 hours. So if you can somehow reduce the fear of parantheses, which is still very prevalent these days, its easier to teach / learn clojure from my experience.

4
👍 4
borkdude11:09:34

@tobias.vetter best to try for yourself. my 2 cts: Scala is a mix of OOP and FP and doesn’t clearly choose one paradigm over the other. So you see a lot of mixed styles over and in codebases. Some people are into pure functional programming and try to take that to the next level with Scalaz. So a lot of decisions you’ll be making in Scala programming are not primarily domain decisions/designs, but a language decisions, sometimes forced upon you by libraries. Clojure gets out of the way more and gives you better defaults (FP over OOP, no discussions about which category theory library or monad transformer stack to use). Some very well known Scala OSS contributors have now moved on to Haskell. If you want a statically typed FP language, go for Haskell. But if you want to leverage the JVM or JS ecosystems using functional programming and static typing is not a dealbreaker, go for Clojure. You’ll soon discover that you get work done very efficiently.

👍 4
dangercoder11:09:43

Hey guys when using Sente, is it possible to use a JWT (which is sent on every request) as a "userId"? I will send and validate the jwt on every request. Got this code right now (CLJS) from creating the conn...:

(let [{:keys [chsk ch-recv send-fn state]}
      (sente/make-channel-socket-client! "ws" 
                                         {:type :auto
                                          :host "localhost:3000"
                                          :params {:jwt "eyJhbGciOiJIUzUxMiJ9.eyJ1c2VyIjoiYWRtaW4iLCJleHAiOjE1MzcwMTQ2MTh9.7pwbHeYQXWxUbzJwT2GGz05BgxOk6r8YNZixzXkVe6Aga9zA6KV803uNEqVXqjO9C_mD-LqeNMlNC6UDZUGVZw" } ;; hardcoded test
                                          })]
  (def chsk       chsk)
  (def ch-chsk    ch-recv)
  (def chsk-send! send-fn) 
  (def chsk-state state))
CLJ:
(let [packer :edn
      chsk-server
      (sente/make-channel-socket-server!
       (get-sch-adapter) {:packer packer}

       {:user-id-fn
        (fn [ring-req] (get-in ring-req [:params :jwt]))})
      {:keys [ch-recv send-fn connected-uids
              ajax-post-fn ajax-get-or-ws-handshake-fn]}
      chsk-server]
  (def ring-ajax-post                ajax-post-fn)
  (def ring-ajax-get-or-ws-handshake ajax-get-or-ws-handshake-fn)
  (def ch-chsk                       ch-recv)
  (def chsk-send!                    send-fn) 
  (def connected-uids                connected-uids))
The server gets messages from the client but "connected-uids" is always nil. Do I have to store my jwt:s in :session or just a random guid?

dangercoder11:09:29

A user logs in, I generate a jwt and then I keep it in local storage.

borkdude11:09:41

Not really related to Clojure specifically, but this article speaks about it: https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

borkdude11:09:14

They recommend cookies because of security

dangercoder11:09:50

I think Sente requires me to store a user-id somewhere, it just needs a guid to find the user. I can still send the jwt in my reqs.

dangercoder11:09:11

I will read it thanks @borkdude

Andrea Imparato13:09:09

hello, very noob question, how do I “pass” a function parameter to a function call in the same function?

Andrea Imparato13:09:40

like (defn f[parameter] (g parameter))

Andrea Imparato13:09:05

it seems the compiler is unable to resolve the symbol 😕

Andrea Imparato13:09:56

^node is undefined

mfikes14:09:43

@andrea.imparato the node on line 4 should bind to the node parameter. What is the error you are getting?

Andrea Imparato14:09:10

Unable to resolve symbol: node in this context

Andrea Imparato14:09:31

I was thinking that it’s probably because xml-> is a macro somehow?

mfikes14:09:33

Yeah, you may need to share more context.

mfikes14:09:52

Where is xml-> defined? (Not familiar with it.)

mfikes14:09:06

Hmm. I don't see it there. If you can, provide a complete minimal repro.

Andrea Imparato14:09:13

sorry it’s in clojure.data.zip.xml

mfikes14:09:59

I can't find that namespace. (If you can, provide the require or ns form you are using.)

Andrea Imparato14:09:18

(require ‘[clojure.xml :as xml]) (require ‘[clojure.zip :as zip]) (require ’[clojure.data.zip.xml :as zip-xml]) (use ’clojure.data.zip.xml)

mfikes14:09:14

@andrea.imparato I can't repro:

$ clj -Sdeps '{:deps {org.clojure/data.zip {:mvn/version "0.1.2"}}}'
Clojure 1.9.0
user=> (require '[clojure.xml :as xml] '[clojure.zip :as zip] '[clojure.data.zip.xml :as zip-xml])
nil
user=> (use 'clojure.data.zip.xml)
nil
user=> (def characteristic {})
#'user/characteristic
user=> (defn extract-characteristics
[node]
  (xml->
   node
   :characteristics
   :characteristic
   (attr= :name characteristic)
   zip/node))
#'user/extract-characteristics

Andrea Imparato14:09:37

I’ll restart the repl

Andrea Imparato14:09:51

yep the repl was confused thanks @mfikes 🙂

Denis G15:09:41

Can you define nested functions (not anonymous) in clojure. Is it a good practice? For example in ML/OCaml you can do that so that you define a public function which internally can use some other subroutines which are defined inside that function

borkdude15:09:52

@denisgrebennicov in Clojure you do this using let. if you need mutual recursion you can use letfn. fn also supports naming

borkdude15:09:39

But the latter is more for debugging purposes: ((fn foo [] (println "dude")))

Denis G15:09:14

@borkdude thanks! But this is not so common technique, right?

borkdude15:09:38

@denisgrebennicov defining functions in a let is very common

borkdude15:09:28

(let [f #(+ % 10) g (f 10)] g)

Denis G15:09:38

great! Thanks!