This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-11-10
Channels
- # asami (41)
- # babashka (24)
- # beginners (48)
- # calva (41)
- # cider (10)
- # clj-commons (20)
- # clj-kondo (2)
- # cljdoc (8)
- # clojure (131)
- # clojure-australia (4)
- # clojure-europe (17)
- # clojure-hungary (2)
- # clojure-india (2)
- # clojure-nl (3)
- # clojure-uk (1)
- # clojurescript (12)
- # community-development (6)
- # core-logic (4)
- # cursive (11)
- # datomic (22)
- # emacs (25)
- # events (1)
- # exercism (2)
- # fulcro (30)
- # helix (5)
- # honeysql (6)
- # hugsql (3)
- # integrant (12)
- # introduce-yourself (4)
- # lsp (5)
- # malli (5)
- # nextjournal (31)
- # off-topic (4)
- # pedestal (3)
- # portal (51)
- # reitit (33)
- # remote-jobs (1)
- # shadow-cljs (12)
- # sql (10)
- # vim (7)
- # xtdb (37)
In an iterative process I have source, process and sink.
With transducers I specify just process. Source and sink are abstracted.
With reduce
I specify process and sink. Only source is abstracted.
Is there something that allows me to specify source and process, but not the sink? I.e. I have a non-standard source of items, but I don't want to specify the sink part.
An example would be a process that combines two different sources into one, sometimes taking an item from one source and sometimes from the other, and then passing the item on to the next step in the process, without specifying what that step is.
I wonder how Eduction will fit into this given that it "reruns" every time, and I'm not sure how you'll "switch" or interleave between two eductions
Hi. I have a need to dynamically choose the def
in various name spaces based on conditions. Assume i have three namespaces foo, bar and baz and they all have a (def name "i am foo/bar/baz")
. I need to access the the def in the namespace dynamically based on condition. like (defn your-name [s] (<find-namespace>/name))
. If this was a function i was able to do it with the help of resolve
and symbol
. But unable to access def in the same manner.
Has anyone tried something similar or can help with this. Thanks in advance
Clojure 1.10.3
user=> (ns a)
nil
a=> (def x 1)
#'a/x
a=> (ns b)
nil
b=> (def x 2)
#'b/x
b=> (in-ns 'user)
#object[clojure.lang.Namespace 0x6f6962ba "user"]
user=> (require 'a 'b)
nil
user=> @(ns-resolve 'a 'x)
1
user=> @(ns-resolve 'b 'x)
2
If you're on 1.10 or later, you can use requiring-resolve
to avoid the need to require the two nses:
Clojure 1.10.3
user=> (ns a)
nil
a=> (def x 1)
#'a/x
a=> (ns b)
nil
b=> (def x 2)
#'b/x
b=> (in-ns 'user)
#object[clojure.lang.Namespace 0x3ff57625 "user"]
user=> @(requiring-resolve 'a/x)
1
user=> @(requiring-resolve 'b/x)
2
user=>
(`requiring-resolve` is also thread-safe at runtime which plain require
is not, I believe)
Thanks @U04V70XH6
does this make anyone else uncomfortable?
(defmuli foo [event & _] event)
(defmethod foo :create-user [event user-id])
(defmethod foo :invite [event user-id date])
I’m not a fan and I’m trying to determine if its just superficial style or if its really not a great pattern.If you're worried about the arity mismatch, you could use a map instead of a variadic signature
yes that’s my gut reaction but i’m trying to figure out if its just stylistic or an actual concern
I think it comes down to personal choice but fwiw I'd use maps
It would become rather comfortable for me if foo
had a name that would clearly signal that the first argument defines the rest.
From just the snippet I would definitely change it to two defn
's with names that clearly signal their purpose
i guess its really just a variadic multimethod where different implementations have different arities
there are many more, just a minimal snippet that shows the pattern. multimethod that takes different number of parameters for different bodies. It feels funny but i’m not sure if it should
How does this edit feel?
(defmulti foo [event & _args] event)
(defmethod foo :create-user [event & args]
(assert (= (count args) 1))
(let [[user-id] args]
...)
(defmethod foo :invite [event & args]
(assert (= (count args) 2))
(let [[user-id date] args]
...)
Now all methods have the same arity. This should be completely identical (barring the exception thrown in case the argument number mismatch) to your example.
Not saying that this is how it should be done - just trying to explore the space.i don’t like that solution but i think that might highlight why it feels so weird to me. so its a good exploration
like that makes the code worse, but it makes it more honest. and that honesty to what is going on is what i don’t like about the solution
another option might be to wrap the variadic part up into a single parameter
(defmuli foo [event args] event)
(defmethod foo :create-user [event [user-id]])
(defmethod foo :invite [event [user-id date]])
Or even, to borrow a page from re-frame's book, go a step further and make the entire event, with its parameters, a single data structure – which could just be a vector
(defmuli foo [event] first)
(defmethod foo :create-user [[event-id user-id]])
(defmethod foo :invite [[event-id user-id date]])
it feels to me like "an event" is a single thing and passing it around in pieces – its ID here, its parameters there – doesn't quite line up semantically
I think i would just go to maps. It just feels weird for it to be structurally different (ie, number of args). Maps with optional keys is a well-explored and comfortable space
yeah, I don't know that I would necessarily advocate a vector as the structure of choice (it was just easy to mock up), just advocating the idea of putting it all in some singular structure
This might be silly, but why not just
(defn- foo-create-user [{:keys [user-id]}]
…)
(defn- foo-invite [{:keys [user-id date]}]
…)
(defn foo [event data]
(condp = event
:create-user (foo-create-user data)
:invite (foo-invite data)))
Multimethods are good, but if you don’t have a reason to have dispatch be extensible, ifs are still okayYesterday we found another reason for wrapping many sequential parameters into one structure (vector, map etc) - limitation of datomic db-functions with 10 arguments max 🙂 So, multi-sequential-arguments functions seems to look like stone age of programming and C language. Also they creates another problem - the order of arguments, followed by partial-curryng, existance of flip
in Haskell and so on and so forth
> Re-frame is moving in the same direction, I believe. @U2FRKM4TW what makes you say that? I would very much like for re-frame to move in that direction with subscriptions and events
And if you prefer to use maps over vectors - you can do that already! :) Just make sure that your own code always uses only 2-element vectors where the first item is the event/sub ID and the second item is the arguments. You can even write your own dispatch
and subscribe
that do that for you.
That is great news, I'll spend some time reviewing that issue. I have been working on a library for my job written on top of re-frame that adds some functionality to subscriptions and events (I am trying to see if we can open source it, but have to make sure the company will allow it). It has been difficult to work with the positional nature of passing arguments in a vector, since part of the library involves automatically injecting arguments into the vectors. Events are easy enough to deal with using interceptors. Subscriptions are another story. I have it all working by appending the arguments to the end of query vectors but I would feel a lot better about it if I had a map to work with.
Always nice to see more libraries take full advantage of the "throw everything in one map with namespaced keys" pattern
Hello, I have question for anyone who may be familiar with compojure-api. I have an api that I would like to document with swagger ui but I would prefer that the swagger documentation only be accessible to those who have been previously authenticated and otherwise redirect to the website’s login page. In compojure-api is there a way to add authentication verification middleware specifically to the swagger ui pages (e.g. to check whether the session corresponds to a logged in user)? Simple example:
(def my-api
(sweet/api
{:swagger
{:ui "/swagger"
:spec "/swagger.json"
:data {:info {:title "simple" :description "example"}}}}
(sweet/context "/api" []
(sweet/GET "/okay" []
:return s/Str
"OK"))))
Note in the above example, GET /api/okay
does not require authentication so my-api
cannot be wrapped in an authentication middleware.Do you recommend any stock market library to use in Clojure? something what I can use to count when and what sell / buy with which price. I am not exactly sure what functionality I am looking. I started to think about this today. Do we have good library for that purpose? (Clojure or Java)
I mean the main algorithm should be made by me, but I am sure there are some libraries which support such operations on stock market. And for sure this libraries implement common algorithms, statistics etc.
There should be some libraries which I can use for this purpose, but I don’t know yet I want to use them 😉
so something like backtesting and algorithms for technical indicators (e.g. macd, vwap)?
I'm not familiar enough with space to make a recommendation, but I do remember seeing https://www.reddit.com/r/Clojure/comments/cpf0xh/code_review_wanted_for_my_stock_broker_api/ by @U064UGEUQ
Yeah my project was for interfacing with Interactive Brokers (a particular stock broker) @UCSJVFV35 has some work on doing more trading analysis in clojure here: https://github.com/clojure-quant/trateg
I tried getting that one running @U064UGEUQ but wasn't successful. I am also interested @U0WL6FA77. Was just talking to another Clojurian about this stuff and how it seems like the backtesting infrastructure would be good to have shared.
Though I am particularly interested in crypto markets. I head that it might be difficult to have backtesting shared between crypto and traditional markets and most people focus on traditional
> crypto markets yes, this is what I am interested in too. Although I found interesting environment for some tests: eve online - this is a MMO game. But the math should be very similar. Of course effective algorithm is very individual thing. So I am thinking about make first simple ver. as a proof of concept for this game and next do it for cryptocurrency.
What is interested about this library is that it uses tech ml dataset for very efficient handling of tables, and Goldy for visualisation in the browser. The library is alpha, but it is already quite powerful.
Do you know good community (forum, slack, discord etc.) for software developing for cryptocurrency trading?
Is there some way to get a reify
object to NOT use its metadata when calculating equality? For example, a vector also implements IObj but ignores its metadata for hashcode purposes, so it’s fine to use these as keys in a map.
You'll have to implement equals yourself An object with meta is no the same object instance. The default equals implementation is identity
yes, that makes sense. any recommendations on the best way to do it, to say “identity of the thing wrapped in metadata”?
I guess I can just generate a UUID and use that, for this purpose
okay, nice, that is great.
roll back - what does the original question mean? metadata is never used for comparing equality
do you really mean "reify" objects have identity equality semantics and adding/changing metadata changes identity?
@U064X3EF3 yeah, take a look at
(defprotocol ICake (cf [x]))
(let [a (reify ICake (cf [x] x))
b [1 2]]
;; the resulting map has TWO entries:
(= 2 (count (assoc {a 1} (with-meta a {:k "v"}) 2)))
;; a vector manages to not use its metadata in equality / hashcode:
(= 1 (count (assoc {b 1} (with-meta b {:k "v"}) 2))))
just want to clarify, that's not a special property of vectors, it's the default behavior - metadata does not affect equality or hashcode as a general principle
reified objects extending from Object get Object behavior, which is based on identity
but it is affecting equality for the reify in this example, right?
you could provide your own equals when you reify ICake that does something different
you are saying that is a bug, and it should work like vector
ah, identity vs equality, got it
I think the defrecord solution is the right one, I have gotten away with this funky reify thing long enough
equality defaults to value-based in Clojure, but identity-based in Java. when you use reify you are tapping into interop and choosing that world
reified objects get the value metadata api not the identity metadata api, but have identity based equality by default
using a record seems like a reasonable alternative, but it's but one option. I don't know all the dimensions to compare them on.
for what? reify can close over locals
what problem are you trying to solve that's not solved by records or reify
or just maps :)
I don't understand the relationship from deftype to reify that you are trying analogize
a map-like that can also have custom protocol implementations that doesn't extend the protocols to the global map type
it wouldn't be necessary to do this in clojure.core, could have a library build it on top of reify
of course
this is not a feature request 😛 unless someone actually has a good reason for it. just was a thought.
what do you imagine "map-like" but "doesn't extend to the global map type" to mean?
you could mean "supports lookups" (ILookup) but is not a persistentmap (IPersistentMap / map?)
I think in most cases using such a thing you would quickly want the other parts of maps / records in most cases
we have a couple places where we've done things kind of like this in Java - TaggedLiteral, ReaderConditional or clojure (fspec comes to mind)
implementing only ILookup is trivial. the gap between there and what defrecord provides is large.
I am trying to tease this out a bit because there are times when I want the gross implementation guts of records but without records (and I'm sure this is in the ballpark of when people reach for Potemkin's various def-map-type, def-derived-map, def-abstract-type, deftype+ etc).
I think what I'm thinking of is solved by allowing your protocol to be extended via metadata
(defn postgres-component
[config]
;; creates a new map-like object (i.e. allows get, assoc, dissoc, clojure equality semantics, seqable, etc.)
(record config
;; extend some additional protocols
IStart
(-start [this]
(assoc this :conn (create-connection config)))
IStop
(-stop [this]
(close-connection! (:conn this)))
(dissoc this :conn))))
I think having a parameterizable map constructor would also be cool, which I think is what things like def-map-type
give. the ability to create something which, as you say, abstracts the gross guts of records but allows one to customize what happens on get
assoc
etc.
people have written such things, macros for custom map types, clj-http has a custom map type for headers making the keys case insensitive
(defprotocol ICake (cf [x]))
(let [a (reify ICake (cf [x] x))
b [1 2]]
;; the resulting map has TWO entries:
(= 2 (count (assoc {a 1} (with-meta a {:k "v"}) 2)))
;; a vector manages to not use its metadata in equality / hashcode:
(= 1 (count (assoc {b 1} (with-meta b {:k "v"}) 2))))
why isn’t namespaced vectors a thing?
not ready to bite on that idea yet. we've talked about it off and on.
(and just to stay clear with it, you mean namespaced vector syntax (neither maps nor vectors "have" a namespace))
the next logical step is - what about sets. imagining #:account#{:name}
made us wretch a bit and stop taking steps :)
I see your point. haven’t ever felt I wanted namespaced sets, but vectors pops up from time to time. (mostly datomic pull patterns and such)
[:company/name
:company/phone-number
{:company/employees [:user/name
:user/email]}]
stuff like thisit would also possibly support some interesting things in destructuring
Hello i am trying the bellow code, and sometimes it runs other times i get stackOverflow
(clojure.data.json/pprint [{"$set" {"array_1" {"$map" {"input" "$array_1", "in" {"$cond" [{"$ne" ["$$m1.id" 2]} "$$m1" {"$mergeObjects" ["$$m1" {"array_2" {"$let" {"vars" {"size_position" {"$reduce" {"input" "$$m1.array_2", "initialValue" [0 -1], "in" {"$let" {"vars" {"index_pos" "$$value", "m2" "$$this"}, "in" {"$let" {"vars" {"index" {"$arrayElemAt" ["$$index_pos" 0]}, "pos" {"$arrayElemAt" ["$$index_pos" 1]}}, "in" {"$cond" [{"$lt" [110 "$$m2.when"]} [{"$add" ["$$index" 1]} {"$add" ["$$index" 1]}] [{"$add" ["$$index" 1]} "$$pos"]]}}}}}}}}, "in" {"$let" {"vars" {"asize" {"$arrayElemAt" ["$$size_position" 0]}, "position" {"$arrayElemAt" ["$$size_position" 1]}}, "in" {"$let" {"vars" {"prv_position" {"$subtract" ["$$position" 1]}}, "in" {"$switch" {"branches" [{"case" {"$or" [{"$and" [{"$ne" ["$$position" -1]} {"$let" {"vars" {"m3" {"$arrayElemAt" ["$$m1.array_2" "$$prv_position"]}}, "in" {"$eq" ["$$m3.value" 43]}}}]} {"$and" [{"$eq" ["$$position" -1]} {"$let" {"vars" {"m3" {"$arrayElemAt" ["$$m1.array_2" 0]}}, "in" {"$eq" ["$$m3.value" 43]}}}]}]}, "then" "$$m1.array_2"} {"case" {"$ne" ["$$position" -1]}, "then" {"$concatArrays" [{"$slice" ["$$m1.array_2" 0 "$$position"]} [{"value" 43, "when" 50}] {"$slice" ["$$m1.array_2" "$$position" "$$asize"]}]}}], "default" {"$concatArrays" [[{"value" 43, "when" 110}] "$$m1.array_2"]}}}}}}}}}}]}]}, "as" "m1"}}}}])
its just a mongodb big query, i dont know which part causes it, but it doesn't happen always
i tried also https://github.com/dakrone/https://github.com/dakrone/cheshire which worked ok always, but the pprint result is nicer in clojure.data.json
what version of data.json are you on?
:clojure.main/message
"Syntax error (StackOverflowError) compiling at (live_j.clj:157:1).\nnull\n"
for the full error https://codeshare.io/oQdqBp
well that is certainly a long stack. I can reproduce it. I'll file a data.json ticket about this
it always worked when you tried it? for me sometimes works always, and other error (when i restart the app)
well I tried it once and it failed :) I think you're just getting lucky when it doesn't