This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-04-14
Channels
- # aleph (2)
- # announcements (11)
- # aws (4)
- # babashka (42)
- # babashka-sci-dev (81)
- # beginners (90)
- # biff (2)
- # calva (40)
- # cider (16)
- # clj-kondo (26)
- # clj-on-windows (1)
- # cljdoc (4)
- # cljfx (1)
- # cljsrn (2)
- # clojure (92)
- # clojure-austin (2)
- # clojure-europe (23)
- # clojure-nl (5)
- # clojure-uk (3)
- # clojured (3)
- # clojurescript (19)
- # community-development (3)
- # conjure (1)
- # cursive (4)
- # datalevin (3)
- # datomic (5)
- # emacs (13)
- # events (1)
- # fulcro (26)
- # graphql (1)
- # hugsql (15)
- # introduce-yourself (5)
- # leiningen (1)
- # lsp (29)
- # minecraft (19)
- # music (1)
- # off-topic (36)
- # pathom (12)
- # podcasts (2)
- # portal (8)
- # re-frame (12)
- # reagent (11)
- # rewrite-clj (4)
- # shadow-cljs (56)
- # spacemacs (2)
- # vim (12)
- # windows (3)
- # xtdb (43)
I'm trying to build a local library so that I can reuse code. I see that the library is now in my local .m2 repository, and would like to use it via deps.edn in apps that I'm building. I'm not publishing the library to clojars. The local library I'm trying to build is standalone and will have other clojure apps calling it. What's the correct coordinates for :deps{} in my apps' deps.edn?
Why don't you put it on a git forge like github/gitlab and use it like a normal git dependency?
If you are just sharing this lib with your other projects, then you can access the shared library via the local/root
coordinate. See https://clojure.org/guides/deps_and_cli for more.
hello friends, I've written a post on using clojure from windows with cmd.exe https://www.spapas.net/2022/04/14/clojure-windows/
I’m trying to determine the absolute minimum for a Clojure application using deps.edn
.
As far as I can tell, this is it:
.
├── deps.edn
└── src
└── core.clj
deps.edn
only contains an empty pair of curly braces: {}
.
core.clj
doesn’t contain anything yet.
So one subdirectory (`src`) and two files: deps.edn
and src/<whatever>.clj
.
Is that all required to fire up a REPL using the clj
command using deps.edn
?Awesome! That’s remarkably clean and simple. I don’t know why I spend so much time messing around with Leiningen, deps-new, templates, etc.
By the way, kudos for writing https://clojure.org/guides/deps_and_cli. It was straightforward to follow. I just wanted to make sure I had understood correctly how little is required to get rolling.
@U064X3EF3 Am I correct in assuming that the Clojure CLI install has the equivalent of :path ["src"]
, so that the src/core.clj
file in lelfericf's example is found on the class path without needing to be specified in the project deps.edn
Ah yes, I also found /usr/local/lib/clojure/deps.edn on my file space. Thank you.
The file on disk is there for legacy but it's not used
The root is a resource loaded from the tools.deps jar (really the uberjar in the cli)
Yeah, I could fire up the REPL with clj
without deps.edn
. But I think it’s rare that there will be no dependencies for my projects, so I view it as necessary. I tried running clj
with an empty deps.end
, but that resulted in an error. It was happy as long as it got a pair of {}
.
Is anyone has a suggestion wether to use amazonica or aws-api (cognitect) for aws integration? - note that we have to use presigned-url (s3) functionality which looks like it is still missing from aws-api, but maybe there are more things to consider. our mainly uses are S3, SQS, and cognito services. happy to hear your thoughts. thanks! 🙂
The algorithm for signing is well documented, and all the crypto code for it ships with the jvm, so it is a nice little exercise to sit down and write. Zero dependencies.
I’m trying to replace boot but it’s such a large job I need to do it piece meal, so I want to use new libraries like io.github.clojure/tools.build
in the same program as boot for a while but boot can’t pull coordinates off git sha which is the only way that library makes itself available, is there a work around to be able to load libraries from git via boot even if manually?
https://github.com/clojure/tools.gitlibs from boot maybe
Hi sorry to disturb @U064X3EF3 any news on this one?
Sorry, what's the question?
Ah we might have come to a work-around internally on this, we’re trying to use tools.build from a boot system but tools.build is only available as a git sha at the moment we’d like it to be on maven ideally I think our work around is going to be to create a library that uses tools.build, then turn that into a jar, then require that jar into our other repos
I'm planning to make it available as a maven artifact too, just haven't gotten around to it
there's an issue you can vote for at https://ask.clojure.org/index.php/11433/will-tools-build-be-released-as-a-jar
Is there a way to bind a value to a symbol similar to intern? I.e. how would I define intern-locally
?
(do (defmacro m [x exp] `(intern-locally [~x "foo"] ~exp)) (m 'y y)) => "foo"
if you want a macro to introduce a locally bound function you can do that (and they are called anaphoric macros)
qp=> (defmacro anaphor [& forms]
`(let [~'x 1]
[email protected]))
#'nocommit.qp/anaphor
qp=> (anaphor (+ x 1))
2
Thanks, I also want to provide a symbol as an argument which the forms
in your example would use.
isn't that just going to be let
? unless I'm missing something
(ins)user=> (defmacro m [x exp] `(let [~x "foo"] ~exp))
#'user/m
(ins)user=> (m y y)
"foo"
user=>
it actually gets more complex if you want y
to be quoted in the input list
anyway, let
and fn
are the things that bind bind a value to a symbol in a lexical scope
The actual problem involves parsing forms and that’s how I get a symbol. I think I’ve thought of a workaround though which doesn’t answer my original question though.
if the symbol isn't known at compile time, a macro is not the right way to do this
Essentially intern does what I want where you provide a symbol argument and assign a value to it.
you'll need eval
, or to write an interpreter for your DSL
yes, because namespaces are mutable, and intern isn't a macro
I’m not sure I follow about the symbol being available at compile time. I’ll try to give an example of what i’m trying to do.
(let [a 1
b (+ a 1)
;; the line below is generated by the macro (pos? b) is the form provided to the macro
b (if (pos? b) "foo" "bar")]
b) => "foo"
ill do this in an editor 😄
so when traversing the let form b is available as a symbol (on line 4).
OK so that's the expansion, what would the input look like?
the input is the form (pos? b)
no, I mean the whole thing, including the macro call
(let [a 1
b (+ a 1)
:do-test (pos? b)]
b)
The only macro call in what you wrote is let
Macro calls always look like (macro-name <zero or more expressions here>)
So the macro I want to write takes that form and generates the snippet at the beginning of this thread.
(defmacro m [&forms]
…)
(m
(let [a 1
b (+ a 1)
:do-test [(pos? b) "foo" "bar"]]
b))
=>
(let [a 1
b (+ a 1)
;; the line below is generated by the macro (pos? b) is the form provided to the macro
b (if (pos? b) "foo" "bar")]
b) => "foo"
You want to write a macro, for example named mylet
, and then put mylet
in place of the let
in the expression you wrote?
Apologies for the lack of clarity. I’m reaching here…
It seems odd to want to write a macro where the input is almost exactly the same length and complexity as the output
but maybe you have other use cases in mind where the output is trickier or more tedious/long to type?
It involves monads 😄
So it looks quite doable to write a macro that would take that let
form as input, and transform it into the let
form you show as the result, by writing appropriate Clojure code that turns one of those expressions into the other.
More precisely it involves clandestine types with values wrapped in tag-tuples
The :do-test
should always look for the most recently bound symbol, and bind it again, I suppose?
That’s right!
So the most recently bound symbol is right there in the vector of expressions after the symbol let
. Should be straightforward to look for 3rd, 5th, 7th, etc. elements of that vector equal to :do-test
, and if they are equal to that, replace it with the element 2 elements earlier?
Perhaps, I’m concerned about the row above only in my case.
I’m traversing the pairs of symbol--values in reverse order.
Do you want to allow, or signal as an error, an input with two "consecutive" :do-test
symbols? I don't know the meaning you are going for here, but if you want to allow that, perhaps going in forward order rather than reverse order would be easier.
It could be that the order does not matter. I haven’t thought about validating input yet.
I’m working with for
rather than let
I might add.
it shouldn't be hard to translate into :let
clauses in the for
- but definitely go in forward order rather than back to front
watch out for emitted code size being too large for a method body though - for
is a beast and can produce huge output already
Thanks for the tip. I created this problem for myself because of how challenging the implementation of for
was to understand.
right - for is a beast, but I think you can just expand into a for
invocation, rather than re-implementing it
I am using the sequence monad from algo.monads instead already actually. Simplifying the syntax using macros was the last hurdle before finishing up this project and the write-up.
Thanks for all the help! I’ll have to return to this problem later.
given that your problem statement is "I have a thing that works, and want a better syntax", it might help to think of macros differently here - fundamentally they are a function that takes a form, and returns a new form to be compiled. if you are worrying about semantics you are probably going astray, they are a syntax -> syntax transform
so eg. instead of looking for a mechanism that creates new local bindings, you'd look for a transform that creates the form that establishes those bindings
I see what you mean. My aim originally was to have an extended version of core/for, which could be used interchangeably with core/for. This somewhat puts constraints on the syntax used for the resulting macro.
macros are expanded during compilation, if the symbol is not known when compiling, the only way a macro is useful is if you add a new, later compilation stage after the binding of the symbol (eval)
Why do I get an integer overflow when I do this?
(defn fib-add [[x y]] [y (+ x y)])
(iterate fib-add '[1 2])
I'm trying to generate a Fibonacci sequence like (1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...)
btw you don't need to quote '[1 2]. [1 2] is the literal vector. It's only lists and symbols that are special
Because iterate is a function that returns a collection that has an unlimited quantity of elements. You have to use some other function to collect the results, like the 'take' function for example. See the docs and examples here https://clojuredocs.org/clojure.core/iterate Start trying (take 1 (iterate fib-add [1 2])) Then take 2 etc.
millionth fibonacci result
also, if you prefer heap exhaustion rather than integer overflow (or, more seriously, if you want results too large to fit in a Long), you can use +'
instead of +
iterate returns an infinite sequence which will get pretty big eventually :)
I see. Indeed just doing (take 5 (iterate fib-add [1 2]))
fixes it
eventually
+'
instead of +
should allow it to use big integers instead of 64-bit integers, when the numbers get big enough to warrant it.