This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-12-20
Channels
- # adventofcode (17)
- # announcements (1)
- # aws (1)
- # beginners (102)
- # calva (27)
- # cider (16)
- # clj-commons (34)
- # clj-kondo (33)
- # cljs-dev (5)
- # cljsrn (4)
- # clojure (124)
- # clojure-europe (17)
- # clojure-nl (8)
- # clojure-spec (13)
- # clojure-uk (6)
- # clojurescript (68)
- # datahike (21)
- # datomic (23)
- # emacs (3)
- # fulcro (30)
- # introduce-yourself (6)
- # jobs-discuss (6)
- # lsp (31)
- # nextjournal (3)
- # off-topic (1)
- # other-languages (45)
- # portal (4)
- # re-frame (8)
- # releases (4)
- # shadow-cljs (39)
- # specter (6)
- # tools-build (18)
- # tools-deps (11)
is there a library for doing seq ops, but continuation passing style? i.e.
(reduce
(fn [k acc x] (k (+ acc n)))
0
[1 2 3])
;; => 6
If you look at usages of fold in haskell, you often need to watch out for space leaks, because the accumulator becomes a big deferred calculation, instead of, you know just a number
how does trampolining behave? I don't yet have an intuition for how trampolined algorithms act w.r.t. memory
I was asking the question specifically in the context of writing a bunch of algorithms using CPS + trampoline in Clojure, and looking to see if maybe someone had done it for me
If you mix it with trampoline I don't think at any point you'll allocate more memory than the original collection. You can map over a collection and create all the continuations, then compose them and trigger them with trampoline
The thing to avoid is mixing and matching, my use of clojure.core/reduce above could be altered to build a fn that could be handed to trampoline to run the reduce, but because it is split like that, reduce building thinks, trampoline discharging at the end, stuff hangs around in memory
A proper cps reduce for trampoline would use trampoline to drive the loop, so thunks are discharged immediately
This might be a dumb question, but now that cognitect has been acquired by nubank do any of its “economic priorities” change? Like, facebook’s primary revenue stream is ads so making rocksdb open source was by whatever calculus the right call. I don’t know if that is community support or PR or what. There is no proven, well supported open source direct alternative to Datomic and i’m just hoping out loud. (crux is, to the best of my knowledge, a different kind beast)
Suspect their need to get people with little/no knowledge of clojure "up to speed" as quickly as possible has increased.
Have you seen https://flur.ee/? It's an immutable 3+ tuple store written in clojure. It's open source and has commercial support.
1. No internal application has need for “the blockchain” 2. That has only existed for 2 years 3. If you work on it i’m definitely being rude, but i’m okay with that. I am absolutely sick of “web 3" crap
It's not actually a blockchain in the cryptocurrency sense, just in the git sense - a "chain" of "blocks" that you can traverse to verify provenance.
> With blockchain cryptography, optional decentralization, and configurable rules written directly to the ledger,
From the technical docs: > Fluree is a private blockchain: Fluree's network and consensus will be more like Hyperledger Fabric than public blockchains like Bitcoin and Ethereum. This in no way means the data housed in Fluree cannot be made publicly available - it can and often is - this distinction is only focused on who gets to vote on the validity of a transaction. Public/Private is a fairly big tradeoff, offering different benefits - while not common, Fluree has plenty of customers that utilize both in the context of a single solution.
To speak to the original question, I imagine that the economic incentive to keep Datomic maintained and operational is stronger than ever (since it is used by Nubank). On the other hand I imagine that Datomic licensing revenue is a drop in the bucket compared to Nubank's other revenue streams. So I imagine that the incentive to add or maintain features that are not of interest to Nubank has been reduced. I have no idea what (if any) features those might be.
Is there any material around or a good example for an HTTP API client written in Clojure? Trying to keep it data oriented
Do you mean 1. A client library for an http service 2. A library which helps you make http requests
I want to build a data driven client with the terminology and concepts of the API I'm communicating with. Base URL and authentication are handled by the client, actions I want to model and drive with data
It always depends. Any good reading material or references you'd recommend? I'm displeased with my first iteration
not really. Remote api libraries can often just look like local libraries from a contract perspective
I can do everything with types and protocols, but that kinda sucks from a Clojure perspective
so maybe a first step if you want to provide this abstraction layer is to doodle out what the available operations are, what they options they accept, and how if at all they can be combined
so one way is just some.resource.api
with create, update, delete, some-command, other-command
if its a REST style api
The doodling bit is why I end up in rewrite land. I started in some direction, got a feel for it, then decided there's a better way
The API itself has some primitive operations, then all the interesting application level operations are done with them. I think this is good enough to get started
Another thing, would you rather use an api where the arguments are provided as a map or as positional arguments?
and the fact that the maps you pass are 1-1 with what the api takes, not kebab-cased
for vanity’s sake or whatever
The client itself should take a map, that makes sense, but if I want to provide convenient functions to build that map, do I go for positional or map args?
;;; Positional
(defn prim-op [x y z w])
(defn op1 [a b] (prim-op a b "foo" "bar"))
;;; Map
(defn prim-op [{:keys [x y z w]}])
(defn op1 [{:keys [a b]}] (prim-op {:x a :y b :z "foo" :w "bar"}))
A single invoke function that takes a client instance and a map that describes the operation to perform
Ah I see that is basically the call stuff above and you are now just talking about helpers to build the op map
I wouldn't bother, clojure has great functions already for building and manipulating maps
But I would try to wrap the API behind a single function as much as possible, describe operations as data, have a single function to execute them
Are you thinking of using the Swagger metadata to allow you to auto-generate the programmatic interface on the client side?
I guess it depends on what you mean by specs for different requests, the library provides a function for listing operations and for getting docs about them
I know it runs off of the json docs that describe aws operations, and I vaguely recall maybe those being translated to clojure.specs but I am not sure
Html documentation is often regular enough in format that you can parse it and generate a client from it
I've done that a few times, one time the API we were integrating with obviously generated their docs from swagger, but didn't publish the json for it
Is there an argument for updating the docs in clojure.instant
to point people towards considering java.time instead (and possibly deprecating it — though there are a lot of subtleties here)?
A colleague unfamiliar with the history of java.util.Date
and the various java time APIs had started using read-instant-date
; then later discovered that java.util.Date
doesn’t handle timezones properly etc.
but even in modern Java, an Instant does not equal a ZonedDateTime, they're different classes so clojure.instant might make sense when considered for representing "instants", and when not having extra expectations about what it provides I could be wrong though :)
Yes, these are the sorts of subtleties to which I was referring… i.e. java.util.Date
’s constructor is not actually deprecated; just almost all of its methods etc…
the Eastwood linter observes deprecated Java methods, so one could use it as a hard CI check I have it on the radar to allow users to specify extra methods that they'd want to consider "deprecated" even if they're not. So one could be extra picky around Date.
Cool good to know.
I guess I’m just saying —
1. It might be useful to add some notes in the docs saying “you probably don’t want this, look at java.time
instead”.
2. Potentially asking the powers that be to consider whether the ns or some of the functions within it should be deprecated or not.
Personally I would be skeptical about deprecations, that's simply my impression though.
An alternative path could be further developing what an #inst
means, other than a cool reader representation I'm not sure there's exactly a vast API supporting it (such that, for example, one could not use a 3rd-party lib at all)
I definitely agree deprecation might not be the right thing — that’s why I’m just suggesting people more knowledgeable about the subject than me might want to consider it; rather than advocating for it to actually be deprecated.
I’m not sure I see a reason to pursue your alternative suggestion though. We have clj-time
already, and tick
etc which are both excellent libraries and provide more comprehensive support for time.
(I meant clojure java-time not clj-time
, though that is ok for legacy joda stuff)
It would be quite the precedent for Clojure to recommend a specific third-party library :)
😆
True but I’m not suggesting they recommend a clj library; I’m suggesting the docs point people to java.time
which is part of the JDK since Java 8.
java.time
is the right answer. This is one of those times where the Java underpinnings of Clojure start to bleed through. I don’t know that there is a great answer here. The world of dates and times is a notorious mess in most languages. Anybody who is writing any code that deals with dates or times needs to understand the mess and navigate it carefully. In other words, this is bigger than simply avoiding instants in favor of something else. You need to know what else you would use and how to convert between multiple historical attempts at getting it dates/times correct.
ah, java.time the package I had trouble parsing that 😇 one particular thing I recall is a difference in time resolution between JDK8 and later versions
@U7BEY9U10: I agree. My point is really that clojure.instant
isn’t really helping language users, such as my colleague with that complexity, but arguably adding to it.
I guess it might be useful to add a function read-java-time-instant
to that ns; and add a docstring to encourage users to do (binding [*data-readers* {'inst read-java-time-instant}
] ,,,)`
I’m aware that we can’t obviously change that default, and that (.toInstant j-u-date)
is all a user essentially wants to do most of the time (or perhaps just use java.time
directly), but it would be nice to encourage them to fall into the pit of success here rather than one of misery and despair :-)
is there a cleaner way to write this :)
(fn [opts _]
(fn [handler]
(fn [request]
(wrap-initialize-request handler request opts))))
You could make a function that takes a function of three arguments, the opts, handler, and request, and turn it into this nested structure.
(defn make-handler
[f]
(fn [opts _]
(fn [handler]
(fn [request]
(f opts handler request)))))
(make-handler
(fn [opts handler request]
(wrap-initialize-request handler request opts)))
That’s actually pretty clean and shows what it happening. If you’re thinking there’s a lot of boilerplate there, then yes, you could use a macro or helper function to reduce it.
@U5NCUG8NR you know what I believe that exactly what I'm looking for, Thank you. Yes, a macro seems a viable solution too
Apologies if this has already been discussed to death; for creating a new from scratch Clojure project, what is the best way to ensure no dependency uses log4j ?
I would actually recommend clj -X:deps list | grep 'log4j'
- the former would list it even if excluded (with an X at the beginning)
but note that that does not protect you from a lib (wrongly) including log4j directly in its own jar
The above is a great way to see if a dependency depends on log4j if you're using deps.edn. From there you can put exclusions on any root-level dependency that depends on log4j to ensure it's not included (and put in e.g. a log4j to slf4j bridge as a replacement, and use that bridge and a different logging implementation like logback that doesn't suffer from the vulnerability). You can find similar deps listings and exclusion methods for other build tools.
As a followup to the above, is there a way to run a Java program with the option of limit UDP/TCP to 192.168.x.x ? I.e. this is a Clojure program that takes data from filesystem / other machines on private network, and it has no business talking to general internet.
Wouldn't it be better solved by the thing that manages that app, e.g. its container? Even if it runs on a raw Linux host, you should still be able to limit IP ranges the app can use. That's probably also true for non-Linux hosts.
it'd be safer to do it at a lower level (container, os) so that if something does escape the app (shell call etc) it still gets limited
Exactly. A long time ago we used SELinux for this kind of stuff - I'm not sure if it's still a hot thing but it's doable that way. Or you can isolate machines instead via things like AWS security groups.
firewalld on some linux’s. we basically use a block zone that blocks everything but then you allow ip’s to that.
Why does this function return nil
?
(def sm (sorted-map-by
(fn [_ _] 1)
"item1" 1
"item2" 2
"item3" 3))
(sm "item1")
I want to keep my keys manually sorted
sorted maps compare keys using a comparator and sort things that way https://clojure.org/guides/comparators
it sounds like what you want is commonly referred to as an "ordered" map, meaning it keeps keys in order of insertion, which there some libraries that provide that kind of thing, but nothing in clojure itself
hmm I see
thanks
in particular your function that always returns 1 means keys never compare equal, so you can never look anything up
would need something stateful like a counter right? Guess I better use a vector and use into
when I need a map
an ordered map is a fundamental different thing from a sorted map, and you cannot build one from a sorted-map using a different comparator
I think Lacinia uses this library for its ordered maps, perhaps worth a look: https://github.com/clj-commons/ordered