This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-09-04
Channels
- # announcements (5)
- # beginners (124)
- # boot (43)
- # braveandtrue (8)
- # calva (1)
- # cider (44)
- # cljs-dev (1)
- # clojure (188)
- # clojure-canada (3)
- # clojure-germany (1)
- # clojure-italy (5)
- # clojure-nl (13)
- # clojure-russia (1)
- # clojure-spec (14)
- # clojure-uk (42)
- # clojurescript (94)
- # core-async (5)
- # cursive (5)
- # datomic (45)
- # duct (3)
- # emacs (6)
- # figwheel-main (93)
- # fulcro (22)
- # graphql (3)
- # hyperfiddle (1)
- # leiningen (3)
- # off-topic (1)
- # pedestal (1)
- # play-clj (1)
- # portkey (1)
- # re-frame (17)
- # reagent (71)
- # remote-jobs (2)
- # rum (3)
- # shadow-cljs (45)
- # spacemacs (17)
- # specter (18)
- # tools-deps (27)
- # unrepl (1)
- # vim (3)
does anyone knows of good examples of apps that support oauth2 authentication (for example with Github)
I'm trying to add authentication to a project of mine and wanted to get some ideas for example about how to structure the database, how to use it with Ring etc etc
I've been wrestling with how to implement a new Exception subclass using AOT compilation to make it accessible from both clojure and as a Java library. Am I overlooking something?
(ns execution-tracing.execution-id-too-long-exception
(:require [execution-tracing.core :refer [maximum-id-length]])
(:gen-class
:name executiontracing.ExecutionIDTooLongException
:extends IllegalStateException
:state "id"
:init "init"
:constructors {[String] []}
:methods [[getMessage [] String]]))
(defn -init [id] [[] id])
(defn -getMessage [id]
(str "Execution ID exceeds maximum length of " @maximum-id-length ":" id))
I'm currently getting java.lang.ClassNotFoundException: executiontracing.ExecutionIDTooLongException, compiling:(core.clj:1:1)
whenever I attempt to start a repl in this project.
The best way to do this is to write it in Java
that's why it's failing for @jmromrell
So, assuming I am wanting to keep this library in Clojure, the solution is to publish a Java library containing only the exception I need, and then depend on that? Or is there a way I can directly package the Java .class or something with the clojure library?
or, if possible, you should consider not subclassing exceptions and using ex-info
instead
All right, that isn't too ugly, at least. I might poke around and see if I can get the project to work as-is if I define the exception class in Clojure as well as using gen-class (potentially fix the current resolution error via clojure repl, while still exposing a definition that can be used by Java library consumers)
I have kind of a silly question. I recently started using datomic, and everything is wonderful… except that I end up doing stuff like this:
(-> (d/q '[ ... query that should only return one value ... ] (d/db dconn))
(first)
(first))
Hello there, I’m writing a for-fun app to send me slack cat gifs at a random time between 12pm and 5pm. In so far I’ve got a channel emitting the current date every second but I’m curious if there’s a better way to model this logic with core.async.
@jayzawrotny one method is having a function that output values at random times onto a channel:
(defn randomly [outc]
(go-loop []
(<! (timeout (rand-int PERIOD)))
(>! outc :tick)
(recur)))
Then you'd have a consumer of that channel that would only send a cat gif if the time was in boundsAh that makes sense! Though I’m not sure I fully understand how your notion of periods\integers would work with that. Perhaps generate a random timestamp then calc the difference between that target and now to get the number of ms to set the timeout for?
no need for timestamp calculation, IMHO- but you can certainly calc to get more specific
I think I see, however the value of PERIOD depends on when randomly
func is called doesn’t it?
PERIOD should have been a parameter 😉 I was pseudocoding. randomly would only be called once and would run forever in the background
Cool, I gotcha. Agreed, I’m very interested in how other devs would solve this while keeping the trade-offs in mind 🙂
I think yours is a very elegant solution but my understanding is that because it’s interval based the channel would need to be started within the range of the target time for it to hit the correct time window. Am I missing something?
in my book it is important to keep the stimuli (the pulses) and the action based on the stimulus (sending a cat gif) separate
I think you're missing that i'm suggesting deferring the determination of the correct time window to the consumer of all the pulses
having the separation between stimulus / action can help iterate on both sides of the problem
you could do something more specific with https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/ScheduledExecutorService.html
And the pulses are more general, in which a consumer can check the time against the target window (or w\e conditional) and send the next gif.
Thanks, I’m looking at it now. The randomness would ensure that the times a cat gif is sent isn’t too patterned and predictable.
Is there a more clojure idiomatic way to work with the scheduler queue or would it be basic java interop with (shceduler\scheduleAtFixedRate time-test-fn, 0, PERIOD, scheduler/SECONDS)
?
The goal is really to learn with this project so may as well try a few of these designs and see what works the best. Thanks again for the help
When / why use deps.edn
? Can you recommend article to read which explain details in friendly way?
right, deps.edn cli is only for dep resolution, it doesn't do project or build features and doesn't have a plugin system (but people have tried to add extensions that build those features over in - they will never be part of the tool itself though)
if all you need is to pull in dependencies and you don't need to build, deploy, package, add dev tooling, etc.
(or if you prefer the ad-hoc system being built around deps.edn rather than a unified tool)
https://clojurescript.org/guides/webpack is it possible to not use deps.edn
in this example? Instead use project.clj
? I am trying to run it, but I have error:
aused by: clojure.lang.ExceptionInfo: No such namespace: reagent.core, could not locate reagent/core.cljs, reagent/core.cljc, or JavaScript source providing "reagent.core" in file ...
well actually it happen during clj -m cljs.main -co build.edn -v -c
which is something new for me
if you are trying to do web development with Clojure(script), my recommendation is to start with Luminus
I want to use npm dependencies. Hmm probably this part I should discuss on #clojurescript 🙂
But what about this question? https://clojurians.slack.com/archives/C03S1KBA2/p1536085084000100
I'm developing a Web app , this my project file, maybe could be useful: https://github.com/aarkerio/ZentaurLMS/blob/development/project.clj
clojurescript is obviously dependency when writing cljs code in project.clj / shadow-cljs.edn
yes, but assumption is everybody will use project.clj / shadow-cljs.edn in project anyway. So why this deps.edn file? What a value for that? Is it necessary from technical point of view? Why not remove this deps.edn?
if you are using leiningen, then keep using project.clj If you are are using the new clj command-line tools, you would use deps.edn
So while you use deps.edn how do you compile your code? by lein / shadow? What is the point then?
Can you recommend something to read? I didn’t find anything which explain it for me.
https://github.com/clojure/tools.deps.alpha#rationale -- there are a few links there, I'd start with the Guide
one of the strategic moves that tools.deps + the clj tools unlock is Non-Artifact Based Development. Instead of having to bundle everything into a Jar / artifact and deploy that, then bump dependencies, you can refer to a git SHA instead
comparing lein vs deps.edn isn't apples to oranges, lein is like a swiss army knife. deps.edn Sets Up a JVM classpath and launches a JVM... that's it.
so -- clojurescript compilation isn't something that is in scope for clj/deps.edn, but setting up an environment where you could compile clojurescript definitely is
to make sure people could just start up clojure 1.9 without a project manager
since it depends on another jar
What about all lein plugins / solutions etc.? What do we have with deps.edn
? Is it something what we should use in new project over lein?
hmm and what with build.edn
https://clojurescript.org/guides/webpack . I see it is supported by this new solution. So it also can compile code.
clj
is not intended to be a replacement for Leiningen or Boot. I am not familiar with all of them, but people are developing programs that can create the dependencies part of a Leiningen project.clj file from a deps.edn file (corrections welcome on the details there, since I haven't used them) and maybe also the other direction. clj
allows you to specify dependencies that Leiningen cannot, e.g. to specific versions of source code in a Github repo.
Can I simplify it to this sentence? deps.edn
is designed to manage dependencies and this is the right place for it. It should be there over lein / boot / shadow-cljs. But other things like how to compile the code etc. should be in lein / boot / shadow-cljs? The intention is to make Clojure dependency manager independent from other solutions. Split dependencies from tools / compile the code.
@kwladyka I'll also offer an observation that some Clojure shops (including where I work) had elected to put dependencies in external EDN files and use version overrides, via custom machinery prior to deps.edn
/ clj
-- we happened to use Boot but I've heard of folks doing it with Leiningen as well (it was more common with Boot tho' due to how programmatic it is, compared to Leiningen).
There are plugins/tasks for both Leiningen and Boot that let you use deps.edn
(and tools.deps.alpha
) to provide additional functionality on top of clj
's core abilities.
I think for any new project I was starting, I would go with deps.edn
and clj
plus associated tooling (like depstar
maybe)... and only go to Boot (or Leiningen) for a task that was outside that ecosystem (although I can think of anything right now -- unless I still needed to conform to the deploy-to-Clojars model for some reason, rather than "encouraging" folks to use GitHub as a dependency).
@kwladyka I think people might hesitate to tell everyone else that they should prefer to use deps.edn over deps in lein. If someone is happily using Leiningen and it meets all of their needs with no changes, why would I presume to tell them they should change that?
@kwladyka also some more context, there's a "basic repl" provided by "cljs.main" described in the new cljs quickstart. This setup sits on top of the new tools.deps infrastructure. Most people will end up using figwheel.main or shadow, sitting on top of the new tools.deps infrastructure. However, when someone from the core team produces a new guide or tutorial, more often then not, you'll see them built on top of the simpler, generic "cljs.main" basic repl. This is so that the core team can focus on fixing problems related to core, rather than the (hopefully) thousands of tools that want to build on top of it.
So, if you want to use the webpack tutorial, for instance, you're going to have to translate that to your tool of choice (which will hopefully be an expanding field of choices)
I think we don't need any more "comprehensive" build tools -- Leiningen and Boot are more than enough -- but I think there's plenty of room for small/narrow, focused tooling, built on top of deps.edn
etc. I think the new tools we see here https://github.com/clojure/tools.deps.alpha/wiki/Tools is encouraging.
what would be an elegant way to split a vector into two vectors, one containing the even-index items other odd-index items?
version with vectors:
(def input [1 2 3 4 5 6 8])
(defn every-secondv [coll]
(vec (take-nth 2 coll)))
((juxt every-secondv
(comp every-secondv rest)) input)
version with transducers:
[(into [] (take-nth 2) input)
(into [] (take-nth 2) (rest input))]
I find juxt is useful when you're composing the function and handing it elsewhere -- if the result of juxt gets immediately applied it almost seems like you're trying to use the juxt function
sure. I am just reading just juxt every day and cannot find good fit for it - so trying it everywhere I can 🙂
so far I have partition 2
followed by mapv first
and mapv second
.
@roklenarcic be aware of how partition works when it can no longer fill up an entire partitioner
I check for that explicitly
another solution that doesn't involve making a new vector but rather sequences
is to use range
with step of 2 and nth
As anyone tried hyper-deep code-walking ? A typical code walking situation is that of a macro that accepts arbitrary code and performs transformations at arbitrary depth in its tree-like structure. Now imagine that additionally to this the macro figures out which functions are called, get their source code, deep-change it so as to define clones, and so on. Is this a thing in Lisp ?
so treat every function as a macro?
somehow yes
using tools.reader as a basis (either to use directly or fork of off) I am sure it could be done
The core.async library does transformations at arbitrary depths of the tree-like structure of code within single functions. I am pretty sure it does not do so across function boundaries.
@andy.fingerhut does it do this by defining its channel ops as macros, or is there a deeper magic going on?
how does one produce a quoted form inside a macro? Specifically I’m trying to embed a Datomic query (`'[:find ?foo ...]`) in a macro, but I’m doing it wrong
as a literal or something passed in?
in that case (quote form) should suffice
oh, inside backtick, that makes it harder, yes
so yeah, yo want ~' on each of those symbol literals, or once on the whole form
right, 'foo and (quote foo) are always equivalent
the reader does that transformation when consuming your code
@noisesmith I think core.async is adding each form to a stack, sorta like a promise chain
as far as I know it only does that for the channel ops though - but I guess that would mean that instead of expanding the forms it does a transform on that line and the ones following when it finds them
core.async's go macro operates like a compiler for a lisp, it is just that the source language and the target language are very similar. it does macro expansion (using the macro expander from tools.analyzer) and then code generation
the channel ops like !> and <! are special forms in the source language that the compiler knows how to generate code for
the macro expansion is fairly vanilla, and pretty much the least interesting part of the thing
Is it every line or do you consecutive lines get bagged up until we reach a transforming function?
And the arguments to the go macro can span pages of code, if one were so inclined to write code like that.
So every form unwinds due to macro expansion, then they all become args to the go macro?
I'm guess it collects forms until it hits a blocking op, then shelfs all collected forms in a closure, throws it on the stack, then starts collecting again
clojure macros are arbitrary functions, so they can do whatever even "hyper-deep code-walking" whatever that is, but macros are purely about transforming syntax. many people new to macros think "oh, I have this hand wavy thing I haven't defined, maybe macros will help". It never does. Macros can give you a nice syntax on top of whatever semantics, but you have to come up with and have a good set of semantics and know how those semantics are represented without macros first.