This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-23
Channels
- # admin-announcements (1)
- # arachne (3)
- # aws (1)
- # bangalore-clj (2)
- # beginners (209)
- # boot (81)
- # capetown (2)
- # cider (16)
- # clara (13)
- # cljsjs (16)
- # cljsrn (6)
- # clojure (217)
- # clojure-czech (1)
- # clojure-greece (4)
- # clojure-italy (3)
- # clojure-korea (3)
- # clojure-russia (3)
- # clojure-sg (3)
- # clojure-spec (104)
- # clojure-uk (23)
- # clojurescript (7)
- # component (7)
- # cursive (18)
- # datomic (12)
- # devcards (34)
- # dirac (17)
- # editors (3)
- # emacs (1)
- # events (1)
- # hoplon (62)
- # immutant (12)
- # incanter (1)
- # jobs (1)
- # klipse (2)
- # ldnclj (1)
- # luminus (1)
- # mount (1)
- # off-topic (8)
- # om (50)
- # onyx (46)
- # parinfer (5)
- # pedestal (4)
- # perun (2)
- # reagent (1)
- # rum (1)
- # schema (5)
- # specter (30)
- # untangled (5)
- # vim (46)
hello guys, little question about clojure.spec
! I have been playing with it and I find it awesome! But I am quite confused on how to use it at runtime
which is the best approach, :pre/:post
or using conform/valid?
in my function for example. I know it really depends on the level of error you want to get but I would be glad to have feedbacks of people using it in prod
is there any public repo where spec
is massively used ?
I have played with it and it's awesome, really
But I still look for an example of how well it can be integrated in a robust project
for example, ring
maintainer made a different lib for validating request
response
handler
I played with ring as well https://github.com/mpenet/ring-spec, but I am not sure this qualifies as "massively".
not used in core
there's clojure.jdbc that has specs and I have some for 2 projects, but they aren't not covering generation on one of them
oh ok, let me see it then
https://github.com/mpenet/alia/tree/master/modules/alia-spec https://github.com/mpenet/hayt/blob/feature/specs/src/clj/qbits/hayt/spec.clj
you earned +1 follower on twitter 😉
ultimately I'd like to be able to generate a valid cql schema and queries for that schema and run arbitrary queries against cassandra
for alia
- (haven't checked everything) - you define specs and use it in core or it's up to the user ?
I use instrumentation in the tests, but otherwise it's totally optional yes, up to the user to add them to their dependencies and use instrumentation at dev time or not
same for the other project, it's both to generate random schema/queries and tests cassandra itself and to validate query generation via the dsl or the ast in hayt
up to the end user. Then ultimately, once things settle I might integrate this more deeply, but it's all still alpha
ok, nice !
I really have to go but I'll look at it this afternoon!
Anyone knows a good way to visually explain immutability the concept? (not the implementation with tries)
@ashnur do you mean patterns of usage? The raw concept is pretty basic: you can't mutate them
it's a definition
how do you explain immovability the concept?
I'm saying there's nothing left to explain
so I'm thinking you want something else explained
oh, well, if someone already understand what they are talking about, certainly there is nothing to be explained
like "how to use immutable data structures to do normal things"
it means the data structure is frozen; you can read from it but you can't make changes to it
⇑ I'm just using more words to say "you can't mutate it"; I can't tell what else you want
right, i am not trying to explain immutability to people who already understand that what they are doing is mutating things, even though if i asked they would probably realize
i am trying to explain it to people who do not think about these things, they just write their neat java code all day long, everything works fine, what do you mean "mutate"? like a database?
okay, so you need to get into things like when two objects are different vs the same?
references and values?
my problem is that i am not pitching clojure this time, but it's something from the blockchain 😞
the blockchain itself or some component of it?
not sure what you mean by "itself". and of course some people imagine mutable blockchains.
I was just curious what aspect of a blockchain you were trying to describe as immutable
nah, I just think of the distributed datastructure formed from linked blocks that consist of list of transactions.
well, normally it should be immutable, that's one of the promises, that you can check all transactions from the genesis block until today
I think blockchains have a lot of conceptual overlap with git in this respect
didn't the ethereum community just rewrite history at will? :)
only a special gc operation will remove that objects, and when they are disappear from reflog
@ashnur "can in theory" and "can in practice" are different in this case
blockchains are rewritable in theory the same with a git repo is in practice
gfredericks I don't think it's fair to compare. one requires one person to want something, the other required a lot of people to agree
sure but that's a property that's a level or two above the data structures involved
they both use hash-addressable content to drive immutability
niwinz but I can change the history. I can rewrite it, and force push it, and if you pull it might happen that you lose things you don't want to lose, doesn't it?
gfredericks right, the blockchain term might mean just the data structure, or the technology that includes the consensus algorithm and a bunch of other things.
when you rewrite history in git is like transoform inmutable hash-map, some objects become invisible/unreacheable by normal code
@ashnur clojure's distinction between values and identities would probably help here
git and blockchains have a very similar approach to representing values
(objects with cryptographic hashes as their IDs)
they also both have identities
git has a bunch of them, you can create them anytime
a blockchain generally has one, and a fancy algorithm for everybody to agree about the value of the identity at any given time
so when you talk/ask about immutability on a blockchain, I'm thinking only about values, not identities
crosspost from beginners: hopefully some of you fellow clojurians can help me out i have a map that has an event keyword as key and a fn as a value in some of these pairs the i get this result :user.handler/confirm-invite #object[clojure.lang.Var$Unbound 0x31e50ab5 Unbound: #'users/confirm-invitation-handler] other pairs in the same map, coming from the same namespace do not have these issues
issue meaning fn's beiung unbound
@ashnur a value is immutable; an identity is a reference to a single value, that can potentially change over time
@ashnur are you familiar with this? http://clojure.org/about/state
in git, the values are commits, trees, files; the identities are branches and tags; in blockchains the values are blocks and their contents; the identity is the most recent block
it's like a repo with just one branch that only moves forward
@mpenet nice lib 🙂 (`alia`)
do you plan to generate test based on you specs ?
Thanks. Kinda once hayt specs are complete this should be usable with alia, there shouldn't be much to do in alia directly (generate a cql schema from hayt specs, and then derive cql statements from there to be used with alia and run tests against these).
the specs in alia are just guards for devs (instrumentation), or pieces to build validation for libs using it (ex with cluster options, some libs expose them in their conf, for instance cyanite/pithos could build validation on top of these)
nice job 🙂
it does mean that you have to force the user to use clojure 1.9.* ?
ultimately if hayt gen work well enough this could be used by other cassandra related projects
@ashnur every commit contains a directory structure (a "tree"), so a path is a way to identify a file object in a tree object
Just like a sequence of keys you could pass to get-in
No, the branch is the identity
An identity is something you can dereference. So something like (-> branch deref :tree (get-in [...path...]))
here's a shot in the dark. has anyone read some OpenJDK source code and know where to find this doc/server_compiler/checktype.txt referred to in http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/oops/klass.hpp#l132
@mikerod have you looked through the whole history?
Correct
Or has been renamed
Ok. Luckily, I know very little about navigating Mercurial - so I guess I should figure that out
I think I’m too new-age when it comes to source control and just think everything should be like git
You can convert the repo
There are some mirrors on github
I’m using Sente for communication between my web server and the clients. If I have more than one web worker, what method can I use to synchronize them so that when a message is sent to a client, it reaches it no matter which web worker it connected to?
This works as expected when I run it from within the repl, but when I run it from an uberjar, I get java.lang.IllegalArgumentException: No method in multimethod ‘baz’ for dispatch value :lol
I’m guessing this has to do with the compiler doesn’t include the boo
ns since noone is referring to it, but I’m not sure how to fix this.
Your multimethod definition (defmethod boo/baz :lol ...)
needs an argument. In effect, it determines :lol
by applying your dispatching function - :bar
- to all the arguments in your implementation.
hello guys does someone know if it's possible to use nested defmulti/defmethod
in clojure.spec
?
@slipset Shouldn't your defmethod
in boo
refer to foo/baz
, not boo/baz
, since that's the multifn to which the method is being attached?
@sinistral: correct, but that's another snippet-slip
another problem is I can"t figure out how removing namespace with spec in this example
(gen/sample (s/gen :button/button))
I got =>
({:title "", :button/type "type-round"}
{:title "4", :payload "2", :button/type "postback"}
{:title "", :payload "+16505551234", :button/type "phone_number"}
{:title "47cfSAK", :payload "+16505551234", :button/type "phone_number"})
but I don't want the namespace :button
any idea guys ? (sorry for the length of the message)
@baptiste-from-paris the :button/type is being added based on your retag in s/multi-spec
yes, but I need a mutli-spec
I think I miss something here
its exactly my use case
One common occurrence in Clojure is to use maps as tagged entities and a special field that indicates the "type" of the map where type indicates a potentially open set of types, often with shared attributes across the types.
kind of interesting - doesn’t look like that will work in tandem with multi-spec using the defaults
but I think it can be made to work, give me a sec
thank's a lot @alexmiller
actually the doc string gives an example with unqualified keys
ok, give me 5min and I'll try to be more understandable with the doc example
I’m not sure how general this problem is
but what’s happening is that the generator is generating random :type’s which create instances that don’t conform to the spec
so the multi-spec gen fails
you don’t want to constrain the :button/type spec though (since it’s an open spec)
(that’s even warned against in s/multi-spec doc string)
if we take the guide example :
(s/def :event/type keyword?)
(s/def :event/timestamp int?)
(s/def :search/url string?)
(s/def :error/message string?)
(s/def :error/code int?)
(defmulti event-type :event/type)
(defmethod event-type :event/search [_]
(s/keys :req [:event/type :event/timestamp :search/url]))
(defmethod event-type :event/error [_]
(s/keys :req [:event/type :event/timestamp :error/message :error/code]))
(s/def :event/event (s/multi-spec event-type :event/type))
we do constrain the :event/type
right ?
the :event/type type doesn’t constrain it to just :event/search or :event/error
it’s spec’ed as keyword?
so open to add new keywords
that example gen's
but if you had for example
(s/def :event/type keyword?)
(s/def :event/timestamp int?)
(s/def :search/url string?)
(s/def :error/message string?)
(s/def :error/code int?)
(defmulti event-type :type)
(defmethod event-type :event/search [_]
(s/keys :req [:event/timestamp :search/url] :req-un [:type]))
(defmethod event-type :event/error [_]
(s/keys :req [:event/timestamp :error/message :error/code] :req-un [:type]))
(s/def :event/event (s/multi-spec event-type :type))
or I guess that :req-un should be [:event/type]
I did not know we could use both :req
and req-un
those s/keys specs will gen fine
but they will generate random keywords for :type
oh ok, got it, not what I want though ^^
well the generator for the multi-spec deals with this by only generating the registered dispatch values
but there must be an assumption in there that is breaking with the unqualified keys
so, atm I’m saying it looks like a bug
atm means ? (not english native ^^)
sorry, “at the moment"
what, are you from paris or something?
yes, surprising giving my username ^^
but I thought it was a good way to find other clojurians from paris
I thought this could be addressed via the retag function but doesn’t seem to work
I am trying little hack here, I let you know where it goes but I am not sure I can resolve a clojure bug even after I read your book 😉
ok, if you take this code
(ns specs.core
(:require [clojure.spec :as s]
[clojure.spec.gen :as gen]))
(s/def ::type keyword?)
(s/def :event/timestamp int?)
(s/def :search/url string?)
(s/def :error/message string?)
(s/def :error/code int?)
(defmulti event-type ::type)
(defmethod event-type :event/search [_]
(s/keys :req-un [:event/timestamp :search/url]))
(defmethod event-type :event/error [_]
(s/keys :req-un [:event/timestamp :error/message :error/code]))
(s/def :event/event (s/multi-spec event-type ::type))
(s/valid? :event/event
{:type :event/search
:timestamp 1463970123000
:url ""})
(gen/sample (s/gen :event/event))
it will give you something like this:
({:timestamp -1, :url "", :specs.core/type :event/search}
{:timestamp -1, :message "v", :code 0, :specs.core/type :event/error}
{:timestamp 1, :message "kw", :code -2, :specs.core/type :event/error}
{:timestamp 0, :url "w40", :specs.core/type :event/search}
{:timestamp -5, :message "Ek", :code 1, :specs.core/type :event/error}
{:timestamp -5, :url "", :specs.core/type :event/search})
so it means I can't have unqualified key with multimethod i guess
@fellshard I did not know when I subscribed but yes, there is a user group here, which is really cool
I can’t think of a good reason that this shouldn’t work with unqualified keys so I’d call it a bug and I’d be happy to log it and take a longer look at it later
ok then, if I have spare time to look at it, have you any guess in the code-base ?
Quick question any ideas on the release of 1.9.0? I’d like to start picking up spec but it looks like it’s not production ready yet?
@nfisher we’ll prob have some more stuff to say about that next month
@baptiste-from-paris this seems to work for me if I switch to a clean repl (multimethod was holding onto state)
(defmulti button-type :type)
(defmethod button-type "type-round" [_]
(s/keys :req-un [:button/title :button/type]))
(defmethod button-type "type-square" [_]
(s/keys :req-un [:button/title :button/type]))
(s/def :button/button (s/multi-spec button-type :type))
(gen/sample (s/gen :button/button))
({:title "", :type "type-round"} {:title "", :type "type-square"} {:title "R", :type "type-square"} {:title "", :type "type-square"} {:title "ww", :type "type-square"} {:title "NcyuB", :type "type-round"} {:title "9UjE", :type "type-round"} {:title "4Q37a", :type "type-round"} {:title "3dA89v", :type "type-round"} {:title "7", :type “type-round”})
so I’m going to say it’s fine :)
@alexmiller awesome! 🙂
nice ! I'll look at it right now
working for me, thanks a lot for you time 🙂!