This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-04-18
Channels
- # announcements (1)
- # aws (13)
- # beginners (55)
- # calva (8)
- # cider (73)
- # cljs-dev (96)
- # clojure (119)
- # clojure-europe (4)
- # clojure-italy (41)
- # clojure-nl (14)
- # clojure-uk (6)
- # clojurescript (90)
- # cursive (14)
- # data-science (1)
- # datomic (20)
- # dirac (1)
- # emacs (32)
- # figwheel-main (11)
- # fulcro (81)
- # hoplon (2)
- # jobs (1)
- # lein-figwheel (2)
- # luminus (1)
- # lumo (19)
- # nyc (3)
- # off-topic (60)
- # other-languages (1)
- # pedestal (5)
- # quil (1)
- # re-frame (3)
- # reagent (3)
- # reitit (5)
- # remote-jobs (1)
- # ring-swagger (2)
- # shadow-cljs (43)
- # sql (15)
- # tools-deps (20)
- # vim (21)
- # yada (6)
If the lib you need requires concrete inheritance, then you have to do it anyway. In a specialized domain, you may not have a choice. And the Java programmers who wrote it are just doing what makes sense in that world. I personally would rather Clojure was a little more accommodating of this situation, but I accept that this is probably unlikely to change. (I have fought the gen-class
and contained it.)
I like the fact that I can use a class from defrecord as an early guard against invalid inputs to calls I want to make on it, for instance:
(defmulti alive? class)
(defmethod alive? UnitModel [{:keys [hp]}]
(> hp 0))
But, if there was any CL CLOS like facility, it would be even nicer if I could have a more specialized call like:
(defmethod alive? UndeadModel [{:keys [hp]}]
(< hp 1))
to me, its nicer to read a very small specialized/dispatching function, rather than a big case/cond within a defn that has to hold all current and future logic
I want flip flopped alive logic - if the unit is normal, hp > 0, if its undead, hp less than 1. If its some future type, like "plant", maybe its alive or dead based on which season of the year it is
I mean I could just use a 'type' key in a map and a case to choose which fn to dispatch to
basically, a combo of defrecord / spec and a custom factory fn (`make`) so I can ensure I always have valid state units in game
I was just hoping to branch it out into MobModel and PlayerModel actually, so I could keep AI logic separate from player specific functionality - in current iteration it is just plain maps and mobs become mob by having the :mob key added to their map
just seems kind of fast and loose and future error prone (when I have to backtrack through 100 function calls in the future and identify all fields a unit should have)
I am not sure what you mean about back tracking through 100 function calls, if you have a spec that says what should be in a map, you have a spec
The error is: Execution error (ExceptionInfo) at expound.paths/in-with-kps (paths.cljc:183). Cannot convert path. This can be caused by using conformers to transform values, which is not supported in Expound
namespaced keys is a lot of work when its user inbound json populating the keys though
I dunno about the expound stuff, I think I am using it somewhere to get some nicer spec errors in one place, but otherwise I am not familiar with it
Hm, that might be a bug in Expound then related to errors on ‘fspec’ if this is happening on latest expound.
afaik, i'm not explicitly calling it explicitly anywhere, unless cider (Emacs) is injecting some call - I am on clojure 1.10
(alive? {:hp 30 :name "Bob"})
- that call is fine, works alright. This one: (alive? {:xhp 30 :name "Bob"})
error
(I saw something similar with return values for fspec, that are keys, so I think it might be expound bug). Feel free to file a bug and I’ll look into it.
It’d be best to find what is doing that (maybe look at deps tree to start) but in a pinch you could reset the default printer. I’m on my phone but something like ‘set! s/explain-out s/explain-printer’
I guess that's what I get for running code I didn't fully read yet 🙂 (luminus lein template)
I looked closer at that code and now I’m not so sure why you’re getting that error. Just curious if you happen to have an earlier version.
It was 7.1, a definite PEBKAC error (I altered the templated clojure version from 1.9 to 1.10 and nothing else) 😞 7.2 does seem to fix it, thanks again!
For dispatching, you may have fun with polymethods and dispatching off of s/valid?
or whatever https://github.com/johnmn3/dispacio#spec-validation-dispatch
If I have a clj-time date-time (which is UTC), say (date-time 2019 4 18 12 0 0)
, but I want it to become the same date in Europe/Amsterdam, ie, it should be:
2019-04-18T12:00:00.000+02:00
, how do I do that
ie. i don’t want it to shift hours, ie. I don’t want to end up with 2019-04-18T14:00:00.000+02:00
aah no it’s this: (.withZoneRetainFields input-date (DateTimeZone/forID "Europe/Amsterdam"))
Who here uses https://github.com/cognitect-labs/transcriptor in anger?
i don't know about in anger, but i've tried it a bit. i think @U38J3881W has too: https://oli.me.uk/2017/10/06/an-introduction-to-transcriptor/
Yep, not in anger though either 😊 I wrote a lein plugin for it and found it interesting. I think a regular test suite still does it for me but it might suit others better!
(meta ((fn [x] ^{:k 9} x) {:a 1})) ;; ==> nil
(meta ^{:k 9} {:a 1}) ;; ==> {:k 9}
(-> {:a 1} ^{:k 9} meta) ;; ==> nil
the ^
syntax is applied at read time to the next read form
(-> {:a 1} ^{:k 9})
will throw a read error meaning you are putting it on the meta form
this throws a read error because there is no "next" form to apply it to
so in the first line, it's applied to the symbol x, which is not going to be ignored when compiling the fn.
in the second line, it's applied to the literal map {:a 1}
in the third line, it's applied to the symbol meta
, where it won't do anything
if you want to apply metadata to things at runtime, it's better to use with-meta
(meta ((fn [x] (with-meta x {:k 9})) {:a 1})) ;; ==> {:k 9}
(meta (with-meta {:a 1} {:k 9})) ;; ==> {:k 9}
(-> {:a 1} (with-meta {:k 9}) meta) ;; ==> {:k 9}
Are there any weird gotchas I need to know if I'm combining clojure.core.async
code with promises?
I want to combine async code with http-kit because I had problems with Java blocking IO hanging
if you are having trouble with blocking io, switch to non-blocking is only going to make your io problem harder to debug
The information I've found seems to imply that the trouble with blocking IO is inherent to blocking IO, an unreliability in linux's blocking select call, and that async IO will react to that unreliability better
@atamiser a Clojure promise is just a container that starts empty and can only have a value assigned once - it's hypothetically useful to communicate between async operations, but has very few features
and really a channel is a better fit if using core.async
clojure's promise is built around blocking (it blocks execution when deref'ed) so while combining it with core.async is possible (and core.async uses them under the hood here and there), in general you pickup core.async because you don't want threads to hang around blocked which is at odds with promises
waiting on a promise can introduce the kind of deadlock core.async is designed to eliminate
a go block using channels is a much nicer alternative to js promise chaining, with the same semantics (each channel read or write in a go block is conceptually equivalent to a .then
invocation)
Yeah, but the pure core.async HTTP client implementations are a tad barebones? Maybe a little immature
you might want to look at aleph, which is dedicated to nonblocking IO with an abstraction that's very similar to core.async channels
aleph uses manifold, which integrates directly with core.async as well
I ran into it when looking at web servers, but glossed over that it integrates with core.async
cognitect's aws-api library make's use of cognitect http client library which seems to have a core.async interface which I haven't been able to find the source for, but seems to be get'able from maven, and appears to be apache licensed
https://mvnrepository.com/artifact/com.cognitect/http-client/0.1.87 https://github.com/cognitect-labs/aws-api/blob/master/src/cognitect/aws/client/api.clj#L9
so if you felt adventurous you could grab that library and make some wild guesses at how to use it
there are a few limitations of the cognitect http-client (streaming support being the largest one)
i thought java defaulted strings beginning with a zero to base 8 when parsing? ie, (Integer/parseInt "09")
should throw?
that's for literals in source code, not parsing
yes just remembered that's a read-string and literal issue. thanks @noisesmith
the Integer/decode
method can do this
also since clojure defaults to longs, I almost always use Long/parseLong for such use cases
yeah, that one assumes you know the radix
=> (Long/parseLong "100" 32)
1024
for those that use clojurewerkz.elastisch
, my team recently moved from elasticsearch 5.6
to 6.4
and a majority of the functions broke, but were fixed by passing in {:content-type :json}
when calling clojurewerkz.elastisch.rest.connect
i.e.
(esr/connect host {:content-type :json})
Apparently clojurewerkz.elastisch.rest.document.scroll-seq
had a similar issue but i eventually fixed it by actually just copying the scroll
and scroll-seq
function from their github and just pasting it into the same .clj file
Since scroll-seq
returns a lazy sequence i think there's some weirdness with fully evaluating the rest calls which causes the content-type
to be lost since the exception i was getting indicated a json parser error
figure i share in case some else out in the clojure community is also using the clojurewerkz.elastisch
library and scroll-seq
@deleted-user I know of Daniel Compton's at https://www.therepl.net/ and Eric Normand's at https://purelyfunctional.tv/newsletter/
I post every week at https://insideclojure.org