This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-07-31
Channels
- # announcements (1)
- # beginners (171)
- # cider (51)
- # clj-kondo (40)
- # cljsrn (5)
- # clojure (68)
- # clojure-dev (42)
- # clojure-europe (2)
- # clojure-italy (20)
- # clojure-spec (2)
- # clojure-uk (141)
- # clojurescript (19)
- # community-development (4)
- # core-async (17)
- # core-logic (3)
- # cursive (11)
- # data-science (1)
- # datomic (7)
- # defnpodcast (2)
- # figwheel (9)
- # figwheel-main (2)
- # fulcro (15)
- # graphql (21)
- # jackdaw (3)
- # joker (11)
- # juxt (1)
- # luminus (12)
- # off-topic (2)
- # pathom (73)
- # pedestal (2)
- # re-frame (41)
- # reagent (14)
- # reitit (4)
- # shadow-cljs (39)
- # tools-deps (4)
Hey, I am just wondering where clojure is used mainly, like python is good for data-science and backend, java is good for backend and mobile applications.
Clojure is pretty general purpose, but if I’d have to highlight something, I’d say it’s particularly good where the business problem is complex.
I.e., the inherent, irreducible complexity of the domain or problem you’re working on. Simple problems might yield simple enough solutions in any language. But when things get complex, the efficiency multiplier of Clojure starts going up.
@gagan.chohan According to http://blog.cognitect.com/blog/2017/1/31/clojure-2018-results the most popular area for Clojure is web development
^^ I think that reflects the distribution of the industry more than the distribution of Clojure, which is general purpose enough that someone is using it for anything you can think of
Good day! I started learning clojure from haskell. I practice on CodingGame or HackerRank. And can't understand how compiling works. They have a template for a task:
;;
(ns Player
(:gen-class))
; The while loop represents the game.
; Each iteration represents a turn of the game
; where you are given inputs (the heights of the mountains)
; and where you have to print an output (the index of the mountain to fire on)
; The inputs you are given are automatically updated according to your last actions.
(defn -main [& args]
(while true
(loop [i 8]
(when (> i 0)
(let [mountainH (read)]
; mountainH: represents the height of one mountain.
(recur (dec i)))))
; (binding [*out* *err*]
; (println "Debug messages..."))
; The index of the mountain to fire on.
(println "4")))
You could write a function in your current project that solves your problem and copy paste it in the solver in Codewars?
No. It has to have main and namespace given in the template. I can't understand this part.
How do I repl with main and namespaces.
Can you start a repl?
Try to start an init project and solve the problem in a isolate environment. Once you wrote a function that solves it, copy paste it back to code editor in your web browser and in the -main
function call the function you wrote
I want to understand the java interop, namespaces and main function in clojure.
Besides solving a task.
I tried to call
clj -m Player task.clj
But got a namespace errorI don't know how you can solve this with clj, but if you use lein, you could try to start a project and there develop locally with a repl
Player is a weird name for a namespace (there's issues with single-segment), but if Player.clj is src/Player.clj
then clj should find it
How do I run it in REPL on my machine? I don't know how to deal with main
and namespaces
I am trying to solve the following problem in clojurescrirpt. I would like to import a namespace foo
in my current one which contains the var-1
,..., var-n
variables. How can I reference them dynamically in my current namespace?
Dynamically?
The idiomatic way to go is to reference my-namespace/var-1
etc. as needed, so as to make it obvious that they’re coming from another namespace, and not unwittingly introduce naming conflicts.
If you want to reference a batch of data in one go, it might be better to use a map containing the composite data rather than splitting it up.
@hobosarefriends I don't think this is even allowed in clojurescript lol
not really a cljs question, just wondering if stuff like this would be possible in js theoretically, or do you just have to write it out 3 times?
I think that stuff is possible in react too, there’s libs that will let you map a function over a collection in pretty much the same way
Hi guys. I'm comming from Node.js (where we are used to set every IO task async by default) and I'm having some trouble to understand promise
and clojure.async
.
I just talked with some friends that work in big companies with Clojure and they mostly don't even care to do async and they're fine with blocking IO.
I just did a small test with only 10 messages (each blocks for 0.5~): sync code runs in 6.5sec while async runs in 2.7, it's quite impressive to me to just ignore that. I just placed (future
with a callback function where blocking IO happens to achieve that
- brief test explanation: https://github.com/plygrynd-jynkyrd/clojure-async/tree/master#clojure-async-test
- future function w/ callback: https://github.com/plygrynd-jynkyrd/clojure-async/blob/master/consumer/src/consumer/core.clj#L5
My questions:
- Do the clojure community and clojurians don't really care much about making every blocking IO async?
- Is okay to stick only with (future
to achieve non-blocking IO , and ignore core.async
?
- Is the knowledge of core.async
important to work as Clojure programmer?
each future is a thread. core.async, on clojure, can be implemented with threads (using thread) or without threads (using go) or a combination (each end of a channel can be different). so depends what you are doing.
Clojurescript runs on JavaScript so it is just like Js it is a single threaded runtime
clojure on the jvm has the advantage of a very good multithreaded runtime, which can run a thread count which is often shocking to people used to node's forced single thread just fine
and when you have a real multithreaded runtime, it is often not a big deal to block a thread for any reason (io, locks, etc), because blocking that thread doesn't impede progress of other threads
benchmark wise, I would be deeply skeptical of benchmarks written when you are just learning the language
Hey everyone - learning clojure and I am wondering why dec x
returns a different value from - 1 x
? thank you!
( defn internal-growth-rate [ income assets divis ]
(let
[ dividend-ratio (/ divis income)
b (- 1 dividend-ratio)
roa (/ income assets)
]
( / (* roa b) (- 1 (* roa b)) )))
(internal-growth-rate 100000 400000 20000) ; answer should be 1/4
( defn internal-growth-rate [ income assets divis ]
(let
[ dividend-ratio (/ divis income)
b (dec dividend-ratio)
roa (/ income assets)
]
( / (* roa b) (- 1 (* roa b)) )))
(internal-growth-rate 100000 400000 20000) ; answer should be -1/6
thank you @crispin
you've rolled your own using java interop. Maybe look at some existing servers. I use immutant myself. But there are a few choices. https://github.com/ptaoussanis/clojure-web-server-benchmarks
@hiredman I'm talking about Clojure really, so I wouldn't call "non-blocking IO" but "my app doesn't stop for IO and continue receiving requests", that was I'm trying to achieve and it worked doing (future
.
@crispin it was on purpose, I wanted to use wrap blocking calls (such HTTP or JDBC), that's what I did:
- Received 10 messages from A
- For each message an HTTP request to B (I used future here)
- After B response, I also notify A , that's why I used a callback
but anyways, is learning core.async
mandatory .. and clojure community doesn't really care much to do every IO async?
it isn't the clojure community, it is the programming community at large outside of javascript
and the js community instead of viewing it as a lamentable limitation, has decided it is the best, which means people who learn this stuff while writing js have a hard time recovering when they encounter runtimes with multithreading
@crispin such as.. I did with (future
? or it was OK? I'm just worried to apply to an Clojure job and not pass due not knowing clojure.async
or that (future
solution is "too ugly"
Try and just use plain clojure, and then watch it run and how it uses your cores. you may be surprised.
@crispin actually I'm quite proficient in clojure "plain" already, I just don't have professional experience and knowledge to deal with these kind of particular issues already. When I used "plain" clojure with those 10 0.5sec messages.. it got 4 seconds more than" (future
clojure", for 100 messages more than 50sec!! the problem is knowledge to deal with block IO, thanks for helping me 🙂
@crispin the problem is deref will block my app untill the response (without listening to other requests!)
@crispin listen to other requests incoming.
@hiredman yes, that was I achieved with (future
, I don't know if it's the best solution though
you would use something like select or epoll in a single listening thread to find out whats ready
For non blocking IO you can consider Aleph.
the general pattern for multithreaded servers is you have a thread accepting connections, when a connection is received the connection is handed off to another thread
@hiredman yeah, you're right, I think that I only did that callback to ensure that I was waiting to finish (and compute how long it took), thanks
single threaded event loop stuff, as well as async/await, have large costs in the user facing programming model
but the multithread stuff is more straightforward and doesn't chop your code up in to callbacks
that reminds me that I need to check on the JVMLS videos
@ghadi what’s the alternative to async/await - the v.2 technology?
we had a conversation yesterday about how people who learn async/await need to unlearn it
for example https://gist.github.com/hiredman/9a086f7b34f8d4fc3f95a251a616bafd is a little websocket chat app that uses a single threaded event loop and callbacks, and it is a mess (some because of the callbacks and some because of java.nio)
@crispin I think I got what you mean, I just don't get the "problem" of having an app where the main thread to listen to the requests.. and dispatch each request action (where blocks IO) to another thread to continue receiving more calls
I'm not just secure if that (future
is an acceptable solution for that for a job apply, could you suggest me a better solution? (aside libs, I really want that knowledge how to deal with blocking IO in clojure)
@hiredman indeed!! That's why I started to learn core.async
to have a better solution. Not comparing apple and bananas, but it's pretty straightfoward doing async with Node.js Promises, just got confused to achieve the same with Clojure
promises are really glorified callbacks. core.async is proper "inversion of control" and allows you to write top down "single threaded" code that is broken up into a state machine for you by the go macro
the best way, imho, to learn core.async is to do it. I never got it by reading. I had to work with it to get it.
core.async can help eliminate callback soup, if you are using a library/framework where you would have callback soup
when I first watched Riches launch talk, I was lost. But after grappling with it and learning by doing, I went back and watched, and everything made sense
but if you are not using such a library, it is not natural to have callback soup on the jvm, so using core.async can be weird
So in your hypothetical server, you can receive something from the network and just stuff it on a channel and then get the next.
https://www.infoq.com/presentations/clojure-core-async/ if you havent seen it
there is also a good walkthrough when you are beginning. https://github.com/clojure/core.async/blob/master/examples/walkthrough.clj
@leonardiwagner in your specific example, you could probably pass an Executor/ThreadPool to the HttpServer in its setExecutor method and the handler will just be called on those threads automatically
thank you! I'm gonna try that 😄
@hiredman @crispin thank you so much guys! I'm much more comfortable now, I'm going practice more
What is really different to me, is because reading most of clojure.async
stuff that I found, they most use deref (which blocks the application untill the completion). While in Node.js, at each promise completion I got a callback to do whatever I want with the result without blocking the app.
@crispin Thanks, I'm gonna watch that talk right now
well, go
returns a channel and doesn't block. and the channel will have the final form evaluation pushed down it when done... but thats getting way ahead of where you are. enjoy the talk
@crispin I'm gonna try that as well, thanks!
sorry to be repetitive, but last question. Was the (future
solution that I did "bad" in a level that could fail a job apply?
I don't want to be rude, but if I was hiring, it'd be a "no" from me. But you are on your way. Keep going. It will all come together with more experience.
@crispin thanks! I really appreciate your help and your time, thank you 😄
if you like promises, then CompletableFuture
in Java might be worth looking into
it isn't super nice to use from Clojure, but it's not too bad
haha that's what I suppose. I'm just trying to figure out the "clojurian way to solve problems", that's quite hard without working with other professionals but that's kind of help that I need, thank you!
generally speaking, "The Clojure Way" is the same as "The Java Way" in many instances.
Java interop is idiomatic and expected. Just because Clojure core doesn't have something explicitly built in doesn't mean it isn't idiomatic.
:thumbsup:
If you want something that provides a very thin layer of "syntactic sugar" over Java's CompletableFuture
, take a look at https://github.com/worldsingles/commons (disclaimer: it's my code).
thank you! I'm gonna check it!
This isn't really a clojure question but its only a quick one: I'm making a web app and I'm going to start sending data from my server to my app (posts, members etc). What is the best practice for this: A: Poll the entire state and then only poll again on refresh or whatever. I can't see this one being a good idea as that's a lot of data that may not be used B: Only poll the data required for the current page. I feel like this is the answer but can't be sure?
Usually in apps where communication b/w frontend and backend is some sort of RESTful APIs over HTTP, there is a lot of parochiality in creating more and more resources that are tailor-fitted to fetch just the right data for a specific use case (page/component) on the frontend.
An alternative is to make the backend expose it's data with a schema allowing the frontend to query what it wants. This reduces endpoint-parochiality. Checkout GraphQL (popular in JS land), and fulcro
and/or pathom
in Clojure(Script) land for this approach.
that's a big subject with a lot of alternatives, and the answer changes for different styles of pages
for an old school plain web page, just polling the data for the current page is the obvious choice, for modern "web app" situations, not only do you want to send extra context / data to make other views / transitions responsive, but you also want to be able to push updates ass applicable to the clients from the server (other user statuses, change in state of domain objects that user has some stake in...)
yeah, thats kind of where I'm at. I'm trying to think of the best approach to start you know? As a beginner it is a little daunting
if this is your first time doing client/server web stuff, start with the old school version I think, then you can look at incorporating ajax or websockets etc. if you need the features / behavior or get curious
thank you
Having done a little ajax, it doesn't make your life easier, unless that's what you actually need. So if you don't need to do real time page changes, don't, let your page changes be queries up to the server and just reload the page.
In my repl, I struggle to actually run code while in the Luminus template. I run (start)
from the user ns, but when I try to access any code I'm writing, such as things in the routes
I just get No such var: proj.routes.auth/func
. I'm going crazy. What am I doing wrong?
often that No such var
, when you know the file defines a var of that name, means that there was an error in loading the ns that got swallowed or hidden in output spam
try (require 'proj.route.auth :reload)
and if you see an error message look at *e
to see the full back trace of the error
That worked...
Thank you.
just curious, did it show you the real error, or did it fix the error?
fixed the error.
With that said, you should still use partials/partial pages. The modularity makes the design process go much faster and can make changing to something that like a web app or ajax driven approach easier.
If you try running the value instead of as a function call does it spit back an error? (So instead of doing (myfunc)
do myfunc
)
Same error
Hi! Still wrapping my head around namespaced keywords for map keys. Can somebody give an example of how one would benefit from using them?
{:com.example.product/id 1029
:com.example.product/price 10.5
:com.example.product/name "Super Shoes"
:com.example.product/category {:com.example.category/name "Shoes"}}
VS
{:id 1029
:price 10.5
:name "Super Shoes"
:category {:name "Shoes"}}
For exampleI too am interested, as the only I can think of is explicit declaration of where a thing lives.
@jplaza {:tree/bark false :dog/bark true}
in the dog
ns it's just ::bark
and it gets the right one naturally
@jplaza more generally, this lets you combine data from various sources without having to audit for clashes, or wondering where everything came from
this is particularly interesting when specifying a mapping from a key to a data constraint (eg. spec)
@noisesmith Would the idiomatic use of namespaces be to communicate the structure of the information (ie :dog/barks) or the structure of the program (program.ns.dog/bark)?
you can know that a :customer.record/id and a :vendor.account/id are different things, with different constraints, without every line of code being 300 characters long
ideally the information structure and program structure share some commonality, in practice namespaced keywords are useful for both
@noisesmith so NS are actually useful for development more than for the structure of the data. For instance, how would you translate the example you gave to a JSON representation?
{:customer.record/id 12
:vendor.account/id 1007}
;; JSON
{"customer_record": {"id": 12}
"vendor_account" {"id": 1007}}
;; or like this
{"customer_record_id": 12
"vendor_account_id": 1007}
Namespaces are about precision in the semantics of names.
Inside a program, the names don't matter (most of the time). We often have no names using positional args instead. But in the context of building a service, or a cog in a system, the names suddenly are scoped to the organization, or more often global.
Service A's :play
might be completely different from service B's :play
. So we use :A/play
and :B/play
. In fact, some other company might have a thing that has the name A
. And this is why the reverse DNS names are used by convention. So you would use :com.mycompany.A/play
and :com.mycompany.B/play
. These are strong names and play well with other data without requiring context.
Watch Rich Hickey's talk "Language of the System" for more on this.
Excuse me if I misunderstood your question. If you were asking how to translate these semantics to JSON, then my answer is, you can't. JSON doesn't even have a name type. You can use transit, but it's still not just JSON.
Yes that was actually my main doubt. Thanks for the long response @U883WCP5Z! All the benefits you get when using namespaced keywords are palpable inside Clojure
Even if using Transit, having dict keywords of the kind of Keyword("com.mycompany.A/play")
say in Python feel kind of weird
No problem! These ideas are useful anywhere but unfortunately are embraced fully only in Clojure. We must encourage others to use these things.
Exactly. It's unergonomic in most other langs to use these things, but that's not the fault of these ideas. As an example, the Java code underneath Clojure is not very idiomatic. Doesn't mean it's bad.
I'd prefer the latter (but neither cheshire nor clojure.data.json has either behavior out of the box)
cheshire just drops the namespace (so one id overwrites the other), data.json puts the / in the key directly
i personally like having / in the key but I understand that it doesn't match idiomatic JSON
Hi. I have a question that's not exactly specific to clojure, but a clojure context may be helpful for me. Is there a real difference between a linter and a formatter? Looking particularly and joker and cljfmt. Joker seems not to be concerned as much with formatting, but more with use of undeclared vars or empty let forms, etc. So if we wanted something for our team to use that would help make sure our code conforms to a similar style, I guess cljfmt would be the way to go? But then where does that leave linting? Are linters and formatters meant to be used together? Do they sometimes come packaged together? Is there a blurred line between the two? Not looking for answers necessarily to ever one of those questions but wanted to illustrate my thoughts. If anyone can shed some light that would be appreciated.
@brandon.ringe Linters often spot (potential) bugs in your code by pointing out "unusual" constructs, from a stylistic/semantic point of view, as well as spotting a lot of unused/unneeded things in your code. They can have great value on their own.
I don't find formatters to be much use because they nearly always reformat parts of my code in ways I don't like. And I don't mind slight differences in source formatting across team members (consistency within a single file is worth suggesting). Mostly, with Clojure, you can just let your editor take care of general indentations and just encourage team members to follow a few simple conventions.
In other languages, brace style and tabs/indentation can vary wildly between teams, so opinionated formatters can be very useful 🙂