This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-03
Channels
- # adventofcode (198)
- # aleph (10)
- # announcements (7)
- # aws (17)
- # beginners (353)
- # boot (1)
- # calva (13)
- # cider (18)
- # cljdoc (2)
- # cljs-dev (11)
- # cljsrn (1)
- # clojure (87)
- # clojure-austin (1)
- # clojure-brasil (2)
- # clojure-greece (13)
- # clojure-italy (18)
- # clojure-kc (2)
- # clojure-nl (9)
- # clojure-quebec (1)
- # clojure-russia (1)
- # clojure-spec (55)
- # clojure-uk (114)
- # clojurescript (18)
- # clojurex (14)
- # code-reviews (5)
- # core-async (17)
- # cursive (23)
- # data-science (1)
- # datomic (82)
- # docker (8)
- # duct (10)
- # emacs (8)
- # figwheel (3)
- # figwheel-main (5)
- # fulcro (13)
- # hyperfiddle (8)
- # jobs (1)
- # midje (1)
- # mount (1)
- # nrepl (2)
- # off-topic (72)
- # om (2)
- # pathom (10)
- # portkey (2)
- # re-frame (9)
- # reagent (3)
- # reitit (9)
- # ring-swagger (14)
- # schema (1)
- # shadow-cljs (91)
- # spacemacs (21)
- # sql (6)
- # tools-deps (19)
- # unrepl (9)
- # vim (41)
hey guys. how can i achieve this (s/defschema Person {:age s/Num > 0 & < 200})
, please?
I found how to to that here: https://www.metosin.fi/blog/schema-spec-web-devs/
I don't know much about Plumatic and schema, but you can define an anonymous function literal to bounds check a number like this: #(< 0 % 200)
thank you very much @ben.grabow 🙂
Is there a better way to write this?
(map #(hash-map :value %) [:a :b :c])
;; =>
({:value :a} {:value :b} {:value :c})
ooooooohhhhhhh thank you @jayzawrotny 🙂
is there a naming convention for the function that actually does stuff? like in the linux kernel they have maybe divide
, which does some prep on the data and calls do_divide
which actually does the division
i think the equivalent in python is divide
and _divide
?
There are several pairs of things in clojure.core like that, e.g. let
and let*
, fn
and fn*
, where the one with *
at the end actually does the things, although that isn't a completely accurate characterization, since the one without the *
is often doing something active, too, e.g. using a macro to change destructuring into simpler bindings.
I myself have on occasion created foo
and foo-helper
, but that is by no means a common convention that I am aware of.
i see, thanks!
defrecord getBasis behaves differently when used to look up record fields
(defrecord Person [name age company]) (def p1 {:name "foo", :age 27, :company :bar}) (map #(% p1) (keys p1)) ("foo" 27 :bar) user=> (map #(% p1) (Person/getBasis)) (nil nil nil nil) user=> (map #(class %) (Person/getBasis)) (clojure.lang.Symbol clojure.lang.Symbol clojure.lang.Symbol clojure.lang.Symbol) I dont wish to use keys on the record instance since the instance might be missing some fields in the record
How do i get (map #(% p1) (Person/getBasis))
to work
Based on the (map class (Person/getBasis))
, you're seeing that you're getting Symbol
types back...
...but in p1
you have keywords for keys -- and that's also what you get in records.
So when you use symbols to lookup in p1
, you get nil
because they don't match -- keywords are not symbols.
Does that help @gayathrik
Thanks @seancorfield. How do i dynamically come up with generic look ups like these (:name p1) where :name is inferred at runtime from the record definition itself. May be the answer to this will help me understand the different between keywords and symbols.
I'm not sure why you don't want to use keys
?
The declared fields of the record can never be missing -- but you might have additional fields. So (keys some-person)
is always going to have at least (:name :age :company)
but some may be nil
and there may be other fields.
FWIW @gayathrik (map keyword (Person/getBasis))
will give you a sequence of keywords...
@seancorfield cool thanks. For some reason I overlooked when trying on repl. I thought keys would not return all the fields of an instance if not present on the instance to begin with. Also thanks for map #((keyword %) p2) (Person/getBasis))
awesomne
@quieterkali Not sure what you mean -- fixtures execute outside any deftest
code
@gayathrik You don't need the #(f %)
-- that's just f
It would definitely be easier to read (map p2 (map keyword (Person/getBasis)))
for example...
(a hash map can be used as a function to lookup things in itself)
i am new in those clojure stuff so please, feel free to correct my poor code understand please
(ns nukr.profile-test
(:require [cheshire.core :as cheshire]
[clojure.test :refer :all]
[nukr.profile :refer :all]))
(deftest create-profile
(let [profile-one {:firstname "Maflany"
:lastname "Traore"
:visibility true}
created-profile-one {:id (+ @id-seq 1)
:firstname "Maflany"
:lastname "Traore"
:visibility true
:connections #{}}]
(is (= created-profile-one (add! profile-one)) "Add new profile test failed")))
(deftest get-profile-from
(let [profile {:id @id-seq
:firstname "Maflany"
:lastname "Traore"
:visibility true
:connections #{}}]
(is (= profile (get-profile @id-seq)))))
(defn nukr-features [get-profile]
(create-profile)
(get-profile))
(use-fixtures :once nukr-features)
lein test nukr.core-test
lein test nukr.profile-test
Ran 4 tests containing 9 assertions.
0 failures, 0 errors.
@quieterkali That doesn't make any sense I'm afraid -- fixtures are intended to set up an "environment" in which to run tests.
Fixtures do not include tests.
I don't understand what you're trying to do.
deftest
defines a (sequence of) tests.
Fixtures are only needed if you have code that needs to execute before/after your tests.
You should not have dependencies between your tests.
Each deftest
should be self-contained and should be able to execute in any order.
so the right way will be write afunction that will do the first one and the i call my deftest
You don't call the deftest
functions -- the test framework does that.
like this example `(def add-to-profile) (deftest get-profile) (defn nukr-features [get-profile]
(add-to-profile)
(get-profile))
(ns nukr.profile-test
(:require [cheshire.core :as cheshire]
[clojure.test :refer :all]
[nukr.profile :refer :all]))
(def add-to-profile)
(deftest get-profile)
(defn nukr-features [get-profile]
(add-to-profile)
(get-profile))
(use-fixtures :once nukr-features)
It's not how you use fixtures.
You just don't need fixtures here.
get-profile
could simply call add-to-profile
as part of its body here
But add-to-profile
is not a test.
It's just a function.
Right, so write separate tests.
And keep test logic and setup logic separate.
Sounds like you need two tests add-profile-test
and get-profile-test
and it just so happens that both call add-profile
as part of their code.
Also, the fact that you're jumping to an atom
suggests you are depending on side effects and you might be writing non-idiomatic code here.
You really want functions to be pure where possible without mutable state.
Mutable state, like atom
, makes tests harder to write and generally makes your code hard to work with.
Sure, but you push that out to the edges as much as possible.
so if i have a function which only get a data in an atom or database, it is under side effect.
There are some very basic operations that aren't worth testing.
Writing a record to DB -- it's not worth testing that the result gives you an extra :id
field to be honest.
Simple side effects are both hard to test and somewhat pointless to test.
Better to have a third function call both. Then you can write tests for the pure function. And ensure the side effecting function does nothing but the side effect (which isn't worth testing).
It's like this. If you mark functions with side effects in your codebase, they should be a tiny proportion of all functions. Because they are harder to test, and reason about.
but in my understanding it's like if i make only one call to a side effect function and there are some other 30 functions call after that, all of them become side effect function, unpure function
Don't worry -- it's a big shift when you come to Clojure, trying to get the hang of separating out pure functions, immutable data, and side effect!
If you have 30 pure functions and one impure function, write the 32nd function that calls the 30 pure ones and the impure one.
Now you have 30 pure functions that are easy to test.
If your impure one is simple enough, it probably doesn't need testing.
You can also test your combination function by mocking the impure function (`with-redefs` for example).
so if i need a data from the database, it's better to retrieve it once and then pass other others functions
then i will have only one accessing the database and the others one will only work with the data
i mean when i see that i am about to call an unpure function, use that func, passs to it the function and params, then it will do the call for me and give me back the result
@quieterkali you can do something like this. I use it in my code:
(defmacro unsafe!
"Wrap around potentially side effecting expression(s).
Either it catches the exception if thrown returns it as a value
or the result of the computation if successful."
[& body]
`(try
~@body
(catch Exception e# e#)))
Can be used like (unsafe! (/ 4 0))
it will return the exception rather than throwing them. Otherwise returns the result like (unsafe! (/4 2)) => 2
works wil any number of forms inside the (unsafe! ...)
block
You can check if it failed like this:
(instance? Exception (unsafe! (/ 4 0)))
=> true
You want this "wrapper" around an impure function call, for documentation purposes?
yes. body
can be any form
protect in what way?
Do you mean, you want to prevent impure functions from being called, unless you call them by using this new function?
If so, I don't know any way to do that in Clojure. Haskell, perhaps.
so i ask, what about having a function that i will use in the middle to hanlde those call to unpure function?
So function P is a pure function, IMP is impure. You want to know if there is a way to write a function "IMPURE-ARMOR" such that if P calls (IMPURE-ARMOR IMP ... args for IMP here ...)
, then you get an error message?
Or that IMP's side effects don't happen?
I don't think that is possible in general. It is impossible to write an algorithm that can determine with 100% certainty, for all possible code you could write, whether that function is pure or not.
I guess what youre looking for is a Monad, which is not really idiomatic in Clojure. Here the side effect throw exceptions like in Java. The one i sent is an approximation of a Monad in Haskell.
For some special cases you could do it.
The genral way is to throw exceptions from a side effect and let it bubble up. like @andy.fingerhut said its not that clean to to write one in clojure
@rahul080327 If you call libraries written by others, and they didn't write their code so that it optionally throws an exception when a side effect occurs (and most people don't write code that way), then that technique would only work for you own code, written using that style, and if you forget to throw an exception on some side effects, then that case won't be caught.
I am not saying it cannot be done -- it just seems very fragile.
youre right @andy.fingerhut. This is not very common in idiomatic clojure
On the positive side, people typically will document which of their library functions can have side effects, and which are pure functions.
Or at least sometimes that is mentioned, but more often perhaps "expected to be understood if you understand the library"
@quieterkali so when a side-effect
occurs its something that is outside of the usual program flow and is abnormal like a file being missing, or no network etc. These are situations where its not possbile for the code to return normally. hence we throw and exception denoting that something abmormal has happened
@rahul080327 Is there some earlier code you are referring to that has the name side-effect
in it?
no i try writing functions with a !
at the end of the names to denote a possible side effect
Your statement above confuses me. Are you saying that you consider the term "side effects" to only include situations where abnormal things are occurring?
Because I think most people use 'side effects' to a situation like: a function writes output to a file on disk, or receives input from a network socket, even when nothing abnormal occurs
I meant situations where things apart from the intended flow happen which may lead to external problems. sorry for being vague
The definition of 'referential transparency' I think kind of depends upon who you ask to define it. Some people use the phrase 'this function is referentially transparent' to mean the same thing as 'this function has no side effects, i.e. is a pure function'
doesn't mean that if i have a function being called in another one and i just take it away and put the value it is suppose to return, the whoe thing should still work perfectly?
Yes, that is a pretty common definition of the term.
I have an article I have written about referential transparency, which while doing research on it I found some definitions that I don't fully understand, but seem like they may be subtly different. Here is a link to that article, if you are interested in reading it: https://github.com/jafingerhut/thalia/blob/master/doc/other-topics/referential-transparency.md
I think it is usually safe to assume that "referential transparency" and "pure functional programs" are often intended to mean the same thing.
At least in computer programming. Not sure about philosophy.
Philosophy seems to be where the term originated.
You can edit your earlier messages content if you want.
At least with web interface for Slack.
so back to my question, i make a funtion to call database, and i use it in another funtion
No, because the return value cannot be determined solely by the arguments.
how ive come to understand referential transperency is that if the outcome also depends on something other than your code like in your case the database connection, data availabilty, File IO errors etc, its not referentially transparent
That isn't a very satisfyingly clear answer I wrote there, but I think it is because the meaning of referential transparency isn't simply that you can replace a function call with its return value.
if anything that make your output change or broke because of something else, then you don't have referencial transparency
Here is a definition copied from a book referenced on the Wikipedia page for referential transparency: “A [programming] language is referentially transparent if we may replace one expression with another of equal value anywhere in a program without changing the meaning of the program. This is a property of pure functional languages.” The book is "Concepts in Programming Languages" by John Mitchell
It seems to me that for a function call that reads from a database or a file, there is no constant expression you could put there that would not change the meaning of the program, in the general case that the database or file contents could be different.
As long as you can laugh at it and enjoy the process of learning, you are good 🙂
Hey all, Hope you're all well. Does anyone know whats the most popular CMS written in Clojure?
you right @andy.fingerhut 🙂
how can I get a list of pairs of items from a list, such that [1 2 3 4]
turns into [[1 2] [1 3] [1 4] [2 3] [2 4] [3 4]]
?
or the brute way
(into #{} (for [a [1 2 3 4]
b [1 2 3 4]
:when (not= a b)]
[a b]))
heys guys, let's say i have a hashmap
and a collection of keys
, is there a way to get all the corresponding value from the hashmap
at once?
but don't want to do a for or map or any kind of iteration to get those values, just pass thoses keys and voilá
it should give me back the corresponding values 😄
@quieterkali maps are functions. (map {:a 1 :b 2 :c 3} [:a :c])
is much more idiomatic
that's why i like this community, full of smart people, you right. i'll definitely use map
I’m having trouble creating a java File from a string, any pointers?
like, a file that can be compiled into a java program?
In clojure I want (defn str->file)
which returns a java.io.File
I’ve tried to spit
and read it back from the file system but some data gets lost in that translation
Hm, well if you’re getting all the way to and from the filesystem with spit
and slurp
(or however you’re reading the file) then the issue is likely not your use of spit
, but it’s hard to say for sure without a clearer picture of what
> some data gets lost in that translation
means
I’m manipulating .p12 certificates
and downstream when java processes the file object it complains with :cause DerInputStream.getLength(): lengthTag=111, too big.
That seems likely to me to be an encoding issue, e.g., spit
is likely outputting the .toString
of bytes when a DerInputStream
expects the binary representation, etc.
My experience with PKCS is that it’s super fiddly to get right and what I would recommend is to find a known-working example of your workflow, ideally an example from a nearby repo that already talks to the services you’re working with, and just cravenly steal their code via Java interop. 😇
hahahhaa, yeah, my problem is that with a certificate I have in memory, passing the (io/file certificate)
works perfectly. When talking through an api with another service, the certificate is sent as an encoded string
that’s where my problems begin
pvillegas12, are setting file to be UT8 when you open file? It may be the reason you "lose" data?
How do I pass a list into JDBC? (jdbc/query conn ["SELECT Id FROM table WHERE Name IN ?" ("Alice" "Bob" Charlie"))
@grierson You need to quote it in order to prevent clj from evaluating it as a form '("Alice" "Bob" "Charlie")
@chris.klaou I'm actually using a symbol to the name list. How do a quote the symbol?
I'd guess it's probably because you're trying to map multiple values to a single ?
placeholder. I haven't done the jdbc stuff for a while though
(jdbc/query conn ["SELECT Id FROM table WHERE Name IN (?,?,?)" "Alice" "Bob" "Charlie"])
?
@chris.klaou That does work, but I simplified my question; the name list is actually a parameter.
Which I thought was horribly ugly 😉
Whoops, typo (fixed)
Should have repl’ed it before posting, now it looks better.
Yeah I think that you need to provide the exact number of ?
in the sqlvec string. If you want to make it somewhat more dynamic you have to resort to a solution like @manutter51's
I’m going back to HugSQL now
@chris.klaou Maybe (repeat "?," (count names))
Not quite, you’ll have an extra comma at the end that way
FWIW honeysql and hugsql both have reasonable, contrasting solutions to this problem of constructing dynamic sql queries
honeysql is very nice, hugsql felt very verbose and weighty to me
hi, making some babysteps in cljs (having zero xp with JavaScript). i'm trying to make an ajax-call (using cljs-ajax) to my clj compojure backend service that returns a simple plain/text response. i can call my service like this:
$ curl -v
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 9500 (#0)
> GET /scramble HTTP/1.1
> Host: localhost:9500
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Mon, 03 Dec 2018 17:40:14 GMT
< Content-Type: application/octet-stream
< Cache-Control: no-cache
< Content-Length: 4
< Server: Jetty(9.2.21.v20170120)
<
* Connection #0 to host localhost left intact
TRUE
my cljs call returns a valid response it seems. i get a valid response, cljs-ajax logs to js/console "CLJS-AJAX response: TRUE", and i can log an object instance 'goog.net.XhrIo' which i seemingly can inspect in chrome, but i have no clue how to "discover" valid attributes/functions:and on learning cljs in general: is it good advice to do something like https://javascript30.com/ first?
@quieterkali yeah, ~12min now 🙂
the XhrIo object is something that is useful in chaining a callback on completion, as you don't want to block your only thread on IO
waiting here https://www.twitch.tv/timpote, droping the link here if anyone want to participate
@klaus.azesberger also MDN, the javascript site from mozilla, is a good resource once you identify a datatype or function from js https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX/Getting_Started
@klaus.azesberger and for the specific wrapper object it handed you - that's a google extension https://google.github.io/closure-library/api/goog.net.XhrIo.html
but that's underdocumented and seems to assume you understand the content of the MDN docs linked above
thanks a lot @noisesmith! this now the second time you help me 🙂 very much appreciated!
I can’t seem to get my test to pass. I think it’s because I set my ID to SERIAL so each entry gets a new id. Is there a better way to write that test so it doesn’t break if each insert gets a unique id?
@jayzawrotny which assertions fail?
or because you are passing in the number 1 and the type of your column 1 is varchar, which sometimes jdbc drivers or the database will do the conversation for you, but I wouldn't depend on it
I don’t know lein-refresh, but if your db is clean every test run and you only insert one webhook then getting id 1 should work
Was just including it for reference because those tests pass. I think I found a possible solution though: https://www.hugsql.org/#using-insert
Ok found a good solution to get the last row inserted which I can then test against. What’s a recommended way to test a map if it contains a sub map or a series of specific key-value pairs?
For instance I don’t care about testing the created_at value which will be an auto-generated timestamp.
I see so something like
(is (= {:payload {:message "Hello World"}}
(select-keys result [:payload}])))
and for “sub-map” get-in
is your friend:
boot.user> (get-in {:a "b" :c {:d "e" :f {:g "h"}}} [:c :f :g])
"h"
boot.user> (get-in {:a "b" :c {:d "e" :f {:g "h"}}} [:c])
{:d "e", :f {:g "h"}}
boot.user>
Ack. Sorry I wasn’t clear, I meant more for like (contains? {:a 1 :b 2 :c 3} {:a 1 :b 2}) => true
ah, so there I think every?
:
(= s2 (select-keys s1 (keys s2)))
(let [correct-kvs {:a 1 :b 2}
test-kvs {:a 1 :b 2 :c 3}]
(every? #(= (get % correct-kvs) (get % test-kvs)) (keys correct-kvs)))
or the much cleaner thing @UBRMX7MT7 just said. ^_^;
Also found
(defn submap?
"Checks whether m contains all entries in sub."
[^java.util.Map m ^java.util.Map sub]
(.containsAll (.entrySet m) (.entrySet sub)))
from https://stackoverflow.com/questions/20421405/how-to-check-if-a-map-is-a-subset-of-another-in-clojureHey does anyone know how to prevent control characters from showing up in my repl? I'm using rlwrap ./node_modules/.bin/shadow-cljs node-repl
and every time I hit up to browse history, it adds "[A" to the beginning of my line, which borks up cursor position. It's driving me nuts. This only happens after navigating left or right with my arrow keys.
rlwrap should be eliminating that problem, unless your terminal is misconfigured or there's unusual delay in a remote connection
It's possible, I have a pretty loose grasp of how terminal input/output works. This is unique to shadow-cljs though; for example the python repl works fine.
(deftest test-webhooks
(jdbc/with-db-transaction [t-conn *db*]
(jdbc/db-set-rollback-only! t-conn)
(let [webhook (db/save-webhook! t-conn {:payload {:message "Hello World"}})]
(is (= {:payload {:message "Hello World"}}
(select-keys webhook
[:payload])))
(is (= {:payload {:message "Hello World"}}
(select-keys (db/get-webhook t-conn {:id (:id webhook)})
[:payload]))))))
java -cp target/uberjar/app.jar clojure.main -m app.core
Also, is there a way to run a built jar in a way where I get errors? My app is immediately exiting when I run that.what is the return code? - you can use clojure.main to start a repl from your jar
one common problem is to make your main call a lazy function without realizing it (and thus lazily doing nothing)
sorry, a function that returns a lazy seq I should say
(there is run!
for that right)
that’s one of many ways to solve that
if it's returning 1 there should be some error message / stack trace
it has bitten me at some point yeah, where I was trying to each
over a collection and clojure promptly decided it had to do nothing at all :’)
It’s a luminus template not saying that couldn’t be the case but I don’t think that’s the issue.
Oh! I see 😅 it dies if postgres can not be connected to and I’m running postgres in a container but running the uberjar outside of it.
that would do it
you can uberjar as part of constructing the container
then you have the advantage of not needing lein inside the container
also issues with caching deps are mitigated
Hmm may need to make a separate docker file\container for that then. The one I’m using is for development with a postgres instance. The production version will be deployed to heroku.
running lein inside the Docker container is also an option, but that means you are rebuilding your app when restarting effectively
and either you pre-propagate your deps in a cache for the container, or you have to download the whole world on every restart...
Ah, I do have it running lein deps as part of the build process for this development container
version: '3'
services:
db:
image: postgres:latest
volumes:
- "dbdata:/var/lib/postgresql/data"
repl:
build: .
tty: true
stdin_open: true
command: lein repl :headless :host 0.0.0.0 :port 7000
ports:
- "3030:3000"
- "7000:7000"
depends_on:
- db
volumes:
- .:/opt/webapp
volumes:
dbdata:
FROM clojure
EXPOSE 3000
EXPOSE 7000
RUN mkdir /opt/webapp
WORKDIR /opt/webapp
ADD project.clj .
RUN ["lein", "deps"]
If I add the uberjar step to the dockerfile that means I’d have to rebuild the image every time I want to run uberjar before making a deploy though right?
how does docker get your current code?
in that case you could as easily put an uberjar in there too
unless it only gets that source via git?
Nope, the docker setup is currently for development purposes. The code is a git managed dir on my host mac and then I run the docker containers with postgres and the clojure image with the source mounted volume running lein repl.
Very similar setup to https://github.com/beetleman/docker-luminus-example
After running lein with-profile uberjar run
to run the server in a production-like environment I get:
Error encountered performing task 'run' with profile(s): 'uberjar'
Suppressed exit```using the uberjar profile to run seems weird
Ah, though it does seem to mimic the behavior of running the jar that exits immediately.
Gonna take a lunch break. Still just nothing when I execute this jar. Any better ways to run lein run
in a prod like environment?
Ah-hah! The jar reading the production config variables. Am I supplying it incorrectly:
java -jar target/uberjar/ts-api-explorer.jar -Dconf=prod-config.edn
you want -Dconf
before the -jar