Fork me on GitHub

Perhaps a stupid question. But, I’ve been reading about spec and wondering why (if it’s such a good idea) libraries don’t seem to support it. Any of the libraries I’ve used so far didn’t mention anything about spec. Am I missing something?


most libraries haven't had big rewrites since spec came out, spec is very new


But wouldn’t spec be a great feature to add to existing libraries? And can’t you partially add specs (For example, at the interfaces)?


I'm not saying it's neccessarily a bad idea, I'm saying this is why it hasn't happened


most clojure libraries don't need to be updated very often


most clojure libraries don't need to be updated very often This is something that I’ve noticed also. Some of the recommended libraries were last updated 3/4/5 years ago. Makes me pause a bit before I use them. What is the reason for that really?


because they operate on immutable data or stable java interfaces


if the world doesn't change underneath them (even for security updates you would just update the java lib yourself, no need to change the clojure lib)


so unlike many ecosystems, in clojure you really do see code that is seemingly "done"


Wow, makes sense when you explain like that. That’s a huuuuge +++ isn’t it?


indeed, it's a big payoff of good decisions in the design of clojure (and java and the jvm)


(and you'll notice cljs is less stable and has more deployment churn, because it's built on shakier ground)


most of clojure.core isn't covered by spec

Michael Fiano01:03:04

Well I've been using Common Lisp exclusively for over a decade, and I don't have any other experience with any other languages for the most part. I have never used Java or even the JVM. I am interested in learning Clojure if only for the JVM platform to expose my code to more people and to interoperate with more code (Java), but I was just wondering how hard of a time I am going to have learning everything all at once. I'm a game developer, with over a decade of Common Lisp libraries for writing raw OpenGL games (no frameworks or engines used) and it doesn't really look like Clojure has raw bindings for OpenGL or SDL2, so that's one problem already outside of learning the JVM, Java, Clojure, etc


@duminda Spec is also still in alpha


@mfiano: yeah, clojure won't have raw bindings to just about anything - the closest will be a java lib which we use via interop, and that lib might have individual implementations for various platforms but most of the code is going to be jvm specific, not platform direct bindings to libs


it's the tradeoff of a platform that emphasises portability - you get something that is easy to deploy in a self contained way, on many targets, but direct low level access to any of those is going to be rare


Also, worth mentioning, if you learn Clojure, you essentially know ClojureScript, which implies another whole slew of targets that are available to you

Michael Fiano02:03:26

Ok, thanks. I'm not sure if I'm ready to give up Common Lisp for game development yet if working with the GPU and the inherent windowing toolkits at a low level is going to be difficult


it's possible - there's just more abstraction layers - and clojure isn't as oriented to that kind of low level programming as common lisp either


@mfiano: on the other hand, if you want to make a service that stays running for a long time, performs well, and can directly use libs for the web/ services ecosystem (REST apis, kafka, zookeeper, cassandra, etc. etc.) - clojure is a great fit for that world

Michael Fiano02:03:06

Ok, it's still an interesting language I'd like to get familiar with - Clojure that is.


I think it's great and being able to work with it professionally has been awesome - but it's definitely better at some niches than others 😄

Michael Fiano02:03:13

By the way, I'm new here and I haven't mentioned this yet. I coordinate the annual Lisp Game Jam, and I haven't really announced it anywhere yet, but this year it's April 20-30th. I hope to see some Clojurians there next month 🙂


cool - you might want to mention that on #announcements


What’s the best way to read last n lines from a file in clojure?


File is quite big


Use a java lib?


@duminda the easy answer is (take-last n (line-seq (io/reader (io/file "my-file.txt")))) which will scan the entire file returning the last n lines same as tail -n n would.


if the file is long enough you could try to do something clever with .available and .skip on a FileInputStream, which avoids reading the data you aren't using - that depends on how big the file is and what assumptions you can make about file length and what your performance concerns are though


You could try to be smarter and manually use a RandomAccessFile, and try to find the last n lines by manually scanning chunks starting from the end of the file and working backwards.


yeah, that too


There's also probably a way to use an NIO mmap file of some sort... lots of ways to skin that cat.


oh yeah - that's actually the best one if performance is an issue


bit line-seq and take-last is the simplest code


So it looks like using FileInputStream actually won't work unless you manually do the ring buffer dance yourself and then you still have to scan the entire file for correctness since readers are unidirectional.


and the NIO mmap buffer thing is definitely possible but looks very involved


@arrdem: the FileInputStream wouldn't work, right, unless you open, skip to all but N bytes, and count newlines


being able to translate java SO answers into interop is a killer skill as a clojure dev :P


Hi, can someone help me understand the difference between spec/and and spec/merge? The example of merge given in the Clojure Spec guide (using :animal/common and :animal/dog) seems to work even if we use and instead of merge.


@anantpaatra Thanks. I’m trying there now.


I have a compojure api, I get a request from a device to the endpoint. The log is something like this:

2018-03-13 05:27:11,846 [XNIO-1 task-6] INFO - Starting :post /api/comms/new_packet for {"connection" "close", "accept" "application/json", "keep-alive" "timeout=30", "from" "xxxxx", "content-type" "application/json", "content-length" "217", "user-agent" "curl/7.54.0", "host" "xxxxx"}
2018-03-13 05:27:11,847 [XNIO-1 task-6] DEBUG - Request details: {:remote-addr "xxxxx", :server-port 8000, :content-length 217, :content-type "application/json", :character-encoding "ISO-8859-1", :uri "/api/comms/new_packet", :server-name "xxxxx", :query-string nil, :scheme :http, :request-method :post}
2018-03-13 05:27:11,847 [XNIO-1 task-6] INFO -   \ - - - -  Params: {}
After this, there’s nothing. No response, and my handler is not invoked. If I send a request from swagger ui to this endpoint, I see the response in the logs after that last line. I am sure that this is a bug in the device’s request. I only want to know how to get details on server side why the request is not reaching the handler. Any logging/debugging methods to find this out?

Drew Verlee17:03:16

Your using CompjureApi the lib? or you built an api using compjure?

Drew Verlee17:03:58

I would debug this by running the compjure client with the request: something like:

Drew Verlee17:03:26

In general, with clojure, you have to reach for a step through debugger less often because a) your writing smaller pure functions b) the repl gives you the feedback you would want from the debugger. This isn’t always true, for good reasons. In that case, i would start with print and pull in more techniques as you have time.

Drew Verlee17:03:35

also, a good place to ask more questions is probably ring-swagger


@U0DJ4T5U1: Using compojureAPI the lib. My question was about my handler not being invoked when a request is sent from a client. (Turned out that the request was buggy - content-length was wrong). I had no idea how to figure out why the request is not reaching until my handler invocation. And how to see where it gets stopped.

Drew Verlee02:03:26

Hmm. Yes, in that case a debugger might help.


Hi all …I am getting this error

Exception in thread "main" java.lang.RuntimeException: No such var: clojure.core/cheshire.core,
Could some one help me to get into this:pray:


error message seems self-descriptive enough, there is no such var clojure.core/cheshire.core. Where do you use it?


And it's doubtful clojure.core/cheshire.core is a real thing. Probably a typo.


perhaps in the ns definition


@U050PJ2EU yes it is!Confused with bracket in lisp way of coding..


Now installed plugin in atom which automatically deals with the bracket which i not supposed to care..


Did you see similar solution like io.pedestal.log just for http-kit?


does anyone have a good resource on form-3 components in reagent? I am struggling with the update mechanism

Michael Fiano15:03:41

is there an env var for controlling where ~/.lein is like boot's BOOT_HOME?

Russ Olsen16:03:08

I think it's LEIN_HOME


I'm having a bit of head-scratching around providing separate dev-build environments for a ring/postgres backend and re-frame front-end, and hoping there's just a semi-normal way to deal with it.


I started with environ because that's in chestnut.


The current pieces of config data that differ are the db connection url, the web address against which the cljs makes its xhr/fetch requests, and now an asset path for the webserver to use to collate PDFs together on the fly from a set of a few thousand.


so environ is fine for the first and third (clj concerns), but I haven't been able to use it for the front-end XHR url, since (obviously) the browser doesn't have an environ.


I tried the trick of making up a macro that does use environ and burning it in at the time I build my uberjar ... couldn't get that working but adzerk/env seems to have done the trick (and I understand it's doing roughly the same idea on the cljs side).


anyway now juxt/aero has caught my eye ... I have broad philosophical agreement that config should mostly just be a file instead of a dozen env vars (not including secrets, of course).


and generally tools like direnv and using profiles.clj seems to take care of that.


but the thing that seems to make this all a bit weird is my possibly-misguided way of configuring the XHR endpoint on the client side


Anyway, long story. Hoping there's a more intelligent way to deal with separate envs for back- and front-end.


@U08BW7V1V there are a good number of config libs out now for clj/cljs


Some of them have goals of reaching both the server and client side


So far, I’ve used environ in a simpler project, and juxt/aero in a more involved config project


I’ve just loaded config on server and let the client get some of that config via a REST request. That may not be appropriate for you though


thanks ... the chicken-and-egg thing I'm not seeing clearly enough is, how can I pull down config from an endpoint if the endpoint is part of the config?


Yeah, I detected you may have that concern 😛


There are ways to do it ad hoc, like building the URL into the initial document (html generated on server side can use config)


that may not be suitable for you either


well, that'd probably work ... I was close to breaking out sed as a part of jar construction.


but you can do some server-side rendering of your page that loads your js and all that too


just seemed like I was reinventing something that probably exists.


that might work


I’ve used server-side rendering of the “index.html” page to splice in some simple config values before


it is a real minimal approach. The libs that exist that transport the config from server-to-client, probably build it into the js somehow (haven’t looked)


trying to find one of those more recent libs for config, but can’t find it immediately. I know I’ve came across like 2-3 config libraries recently that may do some stuff for you


yeah, adzerk/env seems to burn it in using a macro.


yeah, I’m sure there are tricks to doing it


I haven’t dove into these server+client config libs yet. Still using juxt/aero and I’ve used the server-side rendering trick the few times I’ve needed it


maybe if you can get your URI out to the client, then the client can just http for the bigger config stuff hah


It really all depends on the situation I think


oh neat... that looks aero-esque but with the cljs side.


I believe that nomad is a pretty popular config lib out there right now


I’ve considered trying it out before long. I like some things with juxt/aero design-wise better I think. However, they aren’t necessarily taht different from one another I don’t think. And nomad may give you smooth clj + cljs side config sharing


<immediately rips out all current config code and stall feature progress>


cool ... the crux for seems to be swapping out the XHR endpoint so I was hoping there was a well-trodden path there.


everything else seems do-able with straight-up environ.


sure, you could do the server-sider rendering trick then for tha tif you wanted


like you could put a <script>var myUrl=<url-from-config>


hiccup makes generating the server-side html pretty smooth on the clj side


if you aren’t needing anything too fancy.


Ends up looking like:

(require '[ :as hicc]
         [hiccup.element :as elem])

(defn app-index
  (hicc/html5 {:lang "en"}

               [:meta {:charset "UTF-8"}]
               [:meta {:name "viewport" :content "width=device-width, initial-scale=1"}]
               [:title "My App"]
               ;; Whatever CSS
               (hicc/include-css "css/style.css")]

               ;; Where yo you are hooking on your React rendering presumably
               [:div {:id "app"}
                [:h2 "Loading..."]]

               (elem/javascript-tag (str "var myUrl=" (:my-url config)))
               (hicc/include-js "js/compiled/app.js")

               (elem/javascript-tag ";")]))


You could pass config then from environ since this is on the clj/server side


Just have to make sure whatever you splice in is in the appropriate format, such as a valid JS string for the myURL above


Your client-side could then access this via js/myUrl


Oh cool. It also just occurred to me I could also string replace on the initial js bundle going outbound, instead of a straight-up static file response.


Or do string replace on the index.html to do the trick above, instead of necessarily generating hiccup.


yes, I think I understand what you mean and that is a possibility


It also just occurred to me that nomad may not be the lib that shares clj to cljs config. I think I confused it with another. Just FYI since I may have been misleading there. I’d have to do some config lib research again to see what’s out there at this point hah.


Could someone explain why the following doesn't work for #39 on 4clojure?

#(flatten (into [] (zipmap %1 %2)))
It just says that the unit test failed, but running it locally works just fine:
user=> (= (#(flatten (into [] (zipmap %1 %2))) [1 2 3] [:a :b :c]) '(1 :a 2 :b 3 :c))


don't know why it fails, but that into call isn't doing anything


user=> (= (#(flatten (zipmap %1 %2)) [1 2 3] [:a :b :c]) '(1 :a 2 :b 3 :c))


oh right, flatten ignores hash-maps


could you elaborate?


Note that maps aren't ordered


so, there's no guarantee of the order... is that why it could be failing on 4clojure?


Maybe, IIRC 4clojure uses an ancient version of clojure, so you're probably on a different version than they are.


hm, ok. I guess the only way to really find out what's going on is to run it on my own box


you don't need the flatten


ah my bad. read the question wrong. You just need to change the vector to a list


#(flatten (into '() (zipmap %1 %2)))


well, hmm... some of the require results aren't lists... but it passes


hmm... so why does that work but [] does not?


mmm. afaict, the problem is not constructed right


(#(flatten (into `() (zipmap %1 %2))) 
  [1 2 3] [:a :b :c])
;=> (3 :c 2 :b 1 :a)


That passes, but they're clearly not in the right order


Zipmap returns an unordered type, you can eg map list over two collections instead


I figured. The problem is broken though, right? It should fail on that.


it’s allowed to have an order, it’s not guaranteed to scramble the order


@manutter51 thank you!!!!! i knew it had to be something tiny but I've been stumped for days


This is my project structure

├── resources
│   ├── css
│   ├── index.html
│   └── sounds
└── src
    └── drumkit
└── deps.edn
My deps.edn looks like this:
{:paths ["src" "resources"] 
 :deps  {org.clojure/clojure {:mvn/version "1.9.0"}
             org.clojure/clojurescript {:mvn/version "1.10.126"}}}

When I run the project using clj --main cljs.main --watch src --compile drumkit.core --repl It does not pickup my index.html in the resources dir. Is there a way to tell the CLI where to look for my index.html file?


are you referencing it as resources/index.html ?


Sorry, do you mean in my deps.edn?


I mean whatever code is looking for index.html - what path are you using to access it?


I am not referencing it at all. clj --main cljs.main finds the index.html file if I move it to the root, like this:

├── resources
│   ├── css
│   └── sounds
└── src
    └── drumkit
└── deps.edn
├── index.html


what do you mean by finds? why would it care if your code does nothing with that file?


Well, clj --main cljs.main --watch src --compile drumkit.core --repl is going to run a browser repl and launch the site, yes?


this is a brand new feature


so you mean clj should be picking index.html as the document to open in a browser for you


sorry I'm dense, I forgot this feature came out the other day


haha no worries.


But yes, it seems that it will use a default index.html if we do not provide one. However, I want to provide one, but not in the root of my project. So I am hoping I can specify a path