This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-19
Channels
- # aws-lambda (1)
- # bangalore-clj (4)
- # beginners (66)
- # boot (13)
- # cider (9)
- # cljs-dev (44)
- # cljsjs (3)
- # clojure (181)
- # clojure-austin (2)
- # clojure-greece (6)
- # clojure-italy (2)
- # clojure-russia (64)
- # clojure-sg (1)
- # clojure-spec (68)
- # clojure-uk (60)
- # clojurescript (66)
- # conf-proposals (12)
- # cryogen (1)
- # cursive (3)
- # datomic (44)
- # graphql (1)
- # hoplon (2)
- # jobs (2)
- # jobs-discuss (3)
- # keechma (2)
- # liberator (6)
- # luminus (2)
- # nyc (1)
- # off-topic (92)
- # om (10)
- # onyx (17)
- # parinfer (39)
- # pedestal (8)
- # proton (11)
- # re-frame (110)
- # reagent (2)
- # remote-jobs (11)
- # ring-swagger (9)
- # rum (2)
- # sql (2)
- # test-check (6)
- # untangled (138)
I don't know about the talk but there are ports to Ruby and JavaScript that I'm aware of
What options do you to do desktop GUI programming in clojure? I've seen a couple options like clojurefx and fn-fx, but they don't seem to be very active.
@donyorm: you might want to check out my ui.swing library, i've done a fair share of projects with it recently. it uses Swing, and requires that you learn how to use MiGLayout. https://github.com/yegortimoshenko/ui.swing
Is there a way to have one field of a record refer to another one of its own fields? Dare I say, like this
or self
?
Complicated... but I have three fields in my record: one that stores a function, one a list of arguments, and the third that function applied to the list of arguments
so just have a function that sets the arguments, and modify your third field when you set them ..?
(defn set-func-args
[your-record args]
(-> your-record
(assoc :args args)
(assoc :weird-field #(apply (:f your-record) args))))
yes, you're giving it a record which already exists. which you create with something like:
(defn my-record-constructor
[f args]
(->SophiaRecord f args #(apply f args)))
After you create that record it won't update the third field when the second one is updated...
records are like maps; immutable data -- if you "update" the second field via the function designed to update it (`set-func-args`), then the third one will be updated. essentially, you're creating your own interface to the data.
Yes, if I update one field then another one that references it will be updated. But you examples don't reference other fields. They just take the same initial arguments...
a meetup on this Thursday in Singapore https://www.meetup.com/Singapore-Clojure-Meetup/events/240601551/
@qqq what do you mean "revoke JWT tokens"?
long story short
JWT tokens are immutable so they aren't revokable directly, they only expire
you can maintain a blacklist if you like
but that introduces state into your app
recommendations i've seen from ppl like auth0 is to set a shortish expiry time and periodically renew tokens silently in the background to keep users logged in
yes, the whole idea of "revoke" is state
i don't see how you express the idea of "revoking" something without state
it's kind of funny how you can 'grant without state' (by providing a new piece of info to the client), but youcan't revoke w/o state
i suppose that the "info available to the client" is state in a sense
the problem is more that you cannot trust the client to change that particular state in the way you want
you can ask them nicely to forget the token, but what about people they gave it to, and so on?
i think auth0 suggest like an hour or so
they have an article somewhere that goes through all this
their system does maintain a blacklist when you call logout
it is stateful
but they also have a "renew" endpoint
they give you both options
it basically has to be short enough that you feel comfortable that it is "too hard" for maliciousness to occur
but not so short that basic network/downtime issues are going to suddenly log users out without notice when they fail to renew
and i think that really comes down to what you're trying to build
so a soken ends up being Encrypt(Key, {:logged-in-as "thedavidmeister" :expires-on "timestamp"})
and anytime the client wants, if the timestamp hasn't expired, I'll add 10 minutes from the current time
well, you get a new token
hah, i have all the same problems
worked through some of it, still have some things outstanding to sort out "one day"
is there any (easy) way to read 1.9-style EDN (with #:
in front of maps) in 1.8?
@bronsa duh! thanks 🙂
hello all; what's the right way to iterate through a sequence for side-effects, while using an index counter? I'm trying to make a macro that defines a set of related functions given an array of their names and argument types, injecting a sequential number based on the index of the pair in the array
Something like (doseq [[idx val] (map-indexed vector my-super-list-of-stuff)] (do-stuff idx val))
if it’s actually an array, dotimes
is a good option too
If you use Docker + Clojure, you might be interested in the new upcoming (currently beta) Docker feature called multi-stage builds, which let you easily run your uberjars in a tiny, JRE-only container. I wrote a blog post about it here: https://www.lvh.io/posts/smaller-clojure-docker-builds-with-multi-stage-builds.html
Is there any easy work-around when facing dependency cycle issue or it has to be a one way traffic.
For example: Say the ns: somepj.googlemap.core
is using somepj.helper.core
and some fn
in helper.core
now needs to be use some fn
in googlemap.core
. You will get Dependency Cycle
problem every-time after you :import
the namespace googlemap.core
. A workaround would be to use a fully qualified namespace where you needed to call a fn
in the helper.core
... Am I right by this assumption?
One solution is to just dump everything in one big namespace, then if necessary use declare
if you have two fns that depend on each other. Another is to factor the shared stuff out into it's own namespace and have the other namespaces depend on that. AFAIK your workaround won't work.
It indeed needs to be one-way traffic between namespaces, inside one you can use declare
.
@madstap Well, I did try and it works. The work-around I mean. e.g calling somepj.googlemap.core/somefn
works within some function in helper.core
using fully qualified names works if someone else ensured the thing would be defined, but it’s definitely a code smell
@noisesmith you are right
the pattern I often end up with is a protocols
namespace that everyone uses, an implementation
namespace that makes functions that implement the protocols / multimethods / whatever and a client
namespace that uses the functions defined in the protocols namespace
there is no reference to client in implementation, and the only reference of implementation in client is to instantiate something that implements the protocols / multimethods
what this turns out to be concretely is that every implementation can safely use the abstractions of every protocol without circularity issues, and the client can freely intermix those implementations.
Is there a way to create a uberjar containing all dependencies, but not the current project?
Hi, I'm trying to understand whether a failed agent can be automatically restarted. It doesn't appear so from my code example:
(def a (agent 0))
(defn h [a e]
(restart-agent a 0))
(set-error-handler! a h)
(send a inc)
;; 1
(send a #(/ % 0))
;; error handler h will be triggered
(send a inc)
;; ArithmeticException Divide by zero (agent didn't restart)
Am I missing something?@pradyumna the simple but slightly hacky way would be to make a new project with the same deps but no source code
“hacky” in a different way would be to have something modify the project.clj to have empty vectors for both the src and test directories
oh yeah, you would need the ^:replace metadata for that
but yeah
Something along the lines of:
:profiles {:shell {:source-paths ^:replace []
:test-paths ^:replace []}}
then lein with-profile +shell uberjar
? (completely untested)also…why do you want this? (out of curiousity)
Also, if you got hat route you'll probably want to add a :uberjar-name
entry to that profile, to avoid confusion
If you're using git to deploy binaries (which doesn't seem like a great fit), you can also just have a branch with just that one version that you force-push, as an alternative
stop using git for that, use something that actually can do binary diffs http://www.daemonology.net/bsdiff/
That may be a constraint of the environment you can't change, but yeah, I would also urge investigating that first
take a sha512 of the binary, push it to Azure Blob Storage, commit the sha512 or url to the repo
I have zero experience with Azure, but it feels unlikely there would be absolutely no way to push your source git repo and have it build the uberjar itself? Presumably it has Java installed anyway so it should be able to run leiningen?
I know. But I am trying to sneak in clojure wherever possible to my office. I have make it work to show them that clojure is a viable and good alternative
You could even convince them they can bring over all of their knowledge of libraries and stuff around node
@pradyumna is the node.js code checking in npm_modules
?
I guess having the compiled js code in git would still not be ideal, but at least it's text and git should be able to make some sense of it
it’s just relying on a grunt task, or similar, to do a yarn/npm install
, package, and then push it to Azure?
and the resuling .zip
that includes all the libraries and code isn’t checked into git, right? So why do that for the clojure version if that’s already not something they’re used to?
(I mean…yes, ideally you’d build these uber-jars and push to s3, or some other place, to store the built code with fetched libraries for repeatable deploys…but I’m trying to be realistic here 🙂 )
That can be next step. I would definitely like to improve the build and deploy process
if you don't want to single handedly go in and fight that battle, you might want to look at something like https://github.com/technomancy/lein-tar (not sure if the plugin still works)
java -cp foo.jar whatever
and unzip foo.jar && java -cp . whatever
are more or less equivalent
Thanks a lot for all your ideas and showing so many options. Tomorrow I 'll check them out set the deployment steps in a better way.
If you have npm working in Azure, what about a custom library? If you can currently use custom JS libs through npm, it may be a much easier sell to compile your cljs code down to a node.js library that you just package and put on some private npm repo, and have a very small js shim that you deploy normally
I haven't done that either, but if you're trying to introduce Clojure to a node.js shop I think a ClojureScript lib packaged for npm is going to be a much easier sell than making them use the JVM
Well, you definitely know more about the environment than I do 🙂 Just putting this out there as yet another option to consider: if your current deployment pipeline supports node.js projects with npm, packaging your clojure code as a cljs lib for npm might be the easiest route, ops-wise
Is there an int
that works on strings, but returns the value if it's already an int? I don't want to have to write logic around Integer.parseInt
'cuz that seems like that should already be solved. otherwise I gotta check types and it feels non-clojuric. (I have to do this for a java API)
it's non-clojurey to have magic functions that do two things instead of one (at least in the core library). write the conditional and keep going
it might be a pointer that you're doing something else un clojurey too btw. generally you want to separate things that are different, not treat things that are different as the same, if you get my meaning. so it might be an indication that two things that are actually different have been put together prematurely
at some point, we (as an industry? a discipline) really lost a handle on the lexicon of different ways to interpret a value as some other value
FWIW i was curious: https://stackoverflow.com/questions/8857763/what-is-the-difference-between-casting-and-coercing
i think the trick is that without a static type system, you can’t really cast the normal way. you can either coerce or convert, right?
see, to me, casting means reinterpreting the bit pattern, and that is it, which is not what that stackoverflow says
FWIW i had the same intuitive reaction: casting keeps the memory the same but changes the mapping over it, while conversion uses a different memory representation
but the most common casting related question I see is "how do I cast this string to some number type"
isn'tit the case that in c, cast is "host to interpret these bits" while in java, it's more like "which superclass or subclass of this nominal class should we use for method lookup"
I mean, by the official language definition of cast (and ignoring obviously wrong things like cast "5" to int when you really mean mapping or something)