This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-01
Channels
- # beginners (121)
- # boot (12)
- # cider (14)
- # clara (19)
- # cljsjs (1)
- # clojure (124)
- # clojure-italy (4)
- # clojure-nl (2)
- # clojure-russia (47)
- # clojure-spec (20)
- # clojure-uk (7)
- # clojurescript (102)
- # cursive (16)
- # datomic (10)
- # emacs (2)
- # events (2)
- # immutant (3)
- # luminus (5)
- # lumo (33)
- # off-topic (2)
- # om (5)
- # onyx (22)
- # parinfer (1)
- # pedestal (32)
- # protorepl (1)
- # re-frame (6)
- # reagent (2)
- # ring-swagger (2)
- # rum (1)
- # spacemacs (8)
- # specter (17)
- # yada (1)
IMO that’s a little extreme when we’re talking about something like seq
working on arrays of primitives.
seq
creates an IndexedSeq
on arrays
Sorry if my tone sounds extreme, but clojure.set/union is an example of something that in some cases returns what you want if you give it sequences rather than sets, but if you think it returns the union, you are in for a big disappointment. What seq does on Java arrays of primitives is anyone's guess until/unless you understand the source code.
which looks like it should handle long-arrays jsut fine
The doc string for seq promises absolutely nothing in that case.
@andy.fingerhut That sounds like a mistake I may bump into. Using a funtion in an undocumented way. This sounds like something a Linter could catch. I guess I should be linting my clojure code.
@nagi clojure.spec when enabled may help in catching you if you pass a non-set as input to clojure.set/union, I believe, warning you of using a function in undocumented ways. I don't know if it would give any warnings/error for using seq with an undocumented argument.
Or I suppose now it is called clojure.spec.alpha?
Ahh, I havn't encountered clojure spec yet. Thanks for the tip. I really will have to get my code reviewed, I havn't written it yet, but I'm sure my first clojure app will be bad in lots of ways like this.
To be clear, I am not saying that these kinds of things are likely to hit you at every turn in Clojure. They are relatively few and far between in my experience. But when they bite, they bite.
@tbaldridge : block vs park: is "block = pauses the underlying jvm thread" and "park = underlying jvm thread goes and does other thing; only the go block is paused" -- since the model ns N go blolcks on M threads
that's pretty much right
park really means the go block turns your code into a callback and adds it to a list on the channel itself
@qqq so it's not so much about "the thread goes on and does other things" it's more that "the code currently being executed is attached to something else
oh right; there are 'no go threads', it's all giant state machines created by this macro which inverts everything with respect to <! and >!
https://clojuredocs.org/clojure.core/float-array what are the functions for get/set ?
aset-float, and aget
somehow my brain is stuck today. what's the easiest way to make a "stateful" function that returns elements of a list, first call the first, then the second etc
your function should have inner state (atom maybe) and return lambda that, in addition to returning an item, changes those atom
(let [b (.iterator [41 13 7]) a (fn [] (.next b) )] (take 3 (repeatedly a)))
this works
(deftest should-calculate-score []
(with-redefs [subs/score-entry (fn [_ _] (rand-int 100))]
(is (= {:stable-result true} (subs/calculate-score {:some "user-entry"} testdata/valid-data)))))
as i said, i could maybe make a simpler mock that depends on the two params being passed in
(def dripper (atom [41 13 7]))
(defn drip []
(let [d (first @dripper)
_ (swap! dripper rest)]
d))
(drip)
;=> 41
but it seems so complicated for "just" wanting to return 3 values one after the other
and you can close over that atom if you make a mk-dripper
function that returns a function
here's how I would do it
you know with which arguments subs/score-entry
will be called each of the 3 times
the best way to make a function from a finite set of inputs is a literal map
(deftest should-calculate-score []
(with-redefs [subs/score-entry (comp {[x1 y1] r1, [x2 y2] r2, [x3 y3] r3} vector)]
(is (= {:stable-result true} (subs/calculate-score {:some "user-entry"} testdata/valid-data)))))
@looveh You were asking earlier about Clojure AWS Lambda experience in production. I have mostly experience on Clojure JVM Lambdas. They work well if you are doing something asynchronous and you accept that in worst case processing can takes seconds (cold Lambda startup with Clojure is sloooow)
@qqq, sure extend it to Object
@mhjort do you have a working example? i have trouble using even the basic example from the AWS site
This should work https://github.com/mhjort/lambda-demo
qqq: Not sure, but datomic do it very well. db/id
record serializes to #db/id[-1231]
. (Aka: it's possible)
https://github.com/lambdaisland/uri/blob/master/src/lambdaisland/uri.cljc#L11 Checkout this.
@qqq transit does it pretty seamlessly, as does Fressian
I understand that records are just 'tagged maps'; what I don't get is: when reading things back, when transit sees a map, how does it know whether to create a map or a record?
Well the correct way to do it is to write a tagged reader/writer for the maps (it's about 10 lines of code to do this)
so it writes the data out as [record-name record-data], and when it reads the data back in transit will dispatch on record-name to create the record
Whenever I use defrecord instead of plain maps, I get all types of weird subtle hard to debug issues with code reload and interactive development. When transit writes/reads records, how does it assure that "record at time of writing" and "record at time of reading" match up? [sorry for ambigious terms; I can't find the right words to express this]
It doesn't. That's up to you. But records can have arbitrary keys, however.
hi, should I be using clojure.spec for validations for my data maps, or should I wait for clojure 1.9 to use it? would you recommend any other library for nicely validating the structures (and some times maybe also some values) of maps?
I'm implementing a clojure binding of the vulkan api by using lwjgl. In vulkan there are a lot of functions like:
VkResult vkEnumeratePhysicalDevices(
VkInstance instance,
uint32_t* pPhysicalDeviceCount,
VkPhysicalDevice* pPhysicalDevices);
which returns a value (error or success code) and which mutate the arguments. For instance, this function checks to see if pPhysicalDevices is null, and if it is then the number of physical devices on the system is overwritten on the memory pointed to by pPhysicalDeviceCount, otherwise pPhysicalDeviceCount must contain the length of pPhysicalDevices which will be overwritten by the pPhysicalDevices of the system (to capacity if necessary), and the number of physical devices written will be written over the pPhysicalDeviceCount.In other words a lot of vulkan function are stateful to the extreme, and I'm trying to think about how best to expose the vulkan api in clojure
The best idea i've come up with so far is to expose all these stateful arguments as atoms
The other alternative is to expose the vulkan api without using stateful arguments (would involve some copying), but that begs the question of how to return it-- the return value is already occupied. I suppose I could expose the VkResults a different way but that feels overly circuitous.
bcbradley: I don’t have much good advice, but lower level graphics APIs are traditionally heavy on mutability for performance reasons… it’ll probably be hard to contain/abstract that away without significantly changing the API
It depends, the API call you’re highlight could turn into a passing a hash and returning a new one. For enumerating devices that’d make sense as you’re only going to call it once per app so you’re not going to be too bothered about efficiency
I only know a little about Vulkan but with most low level APIs mutability is something you try to keep for low frequency operations
And if you have things running nicely you’re mostly updating params that get sent one way to shaders
So hopefully expensive calls where you’d have to copy new data back to clojure from mutated arguments though slow wouldn’t mean a properly writtten clojure app would be slow
in standard logic programming, during unification, there is an 'occurence check' right? to avoid infinte oop;s what happens if lhs = var a rhs = list of all vars that start with 'b' does it just infinite loop ?
I don't think your hypothetical logic program is well formed enough to give an answer
logic variables are similar to mutable variables in that the name is kind of a pointer to a location, so when you unify A and B, you are saying A and B both point to the same place
I was just implementing unify again in a different way, and this thought hit me -- "what is one of lhs / rhs is a lazy infinite seq" 🙂
before this, I'd always assumed both lhs and rhs were finite, in which case this issue would not show up
on a related question; what is the fastesxt way to merge a list of sets (apply merge lst)
qqq: Probably a reduce using a transient for the accumulator
maybe someone here can help. I am going through the java trails for digital signatures https://docs.oracle.com/javase/tutorial/security/apisign/gensig.html and from this I have the following in clojure:
(ns crypto-test.core
(:import (java.security SecureRandom KeyPairGenerator)))
(defn keyGen
[]
(KeyPairGenerator/getInstance "DSA" "SUN"))
(defn rng
[]
(SecureRandom/getInstance "SHA1PRNG", "SUN"))
(defn initKeyGen
[]
(.initialize keyGen 1024 rng))
(defn pair
[kg]
(.generateKeyPair kg))
(defn hexify [s]
(format "%x" (new java.math.BigInteger s)))
but whenever I run
(let [key (keyGen)
random (rng)
_ (.initialize key 1024 random)
pair (.generateKeyPair key)]
(println (hexify (.getEncoded (.getPublic pair)))))
308201b73082012c06072a8648ce3804013082011f02818100fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c70215009760508f15230bccb292b982a2eb840bf0581cf502818100f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a038184000281805f083516344e7a14f347ec3c58ada2ebd3a829b2b12f7185f149eec2eecdeb09620f303e3144908ae8556f511294688c8fc5537d919cbc82c307cfc7322315849efd7a4a44d2add6cbb87882d5242d242e42d79e7d86e0f446997932c65a47d2fc25f224bc43d223ee78a9297d7a9008ff081a77ebbd41783dd62e190e4b9e07
=> nil
I get the same hex string over and over again.
Shouldn’t the rng
function provide some sort of random or pseudo-random value each time it is called?