This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-04-23
Channels
- # aws-lambda (1)
- # bangalore-clj (13)
- # beginners (12)
- # boot (3)
- # cider (1)
- # cljs-dev (20)
- # clojure (208)
- # clojure-finland (1)
- # clojure-france (1)
- # clojure-russia (30)
- # clojure-serbia (12)
- # clojure-spec (7)
- # clojure-uk (14)
- # clojurescript (16)
- # cursive (6)
- # datomic (10)
- # emacs (1)
- # hoplon (4)
- # keechma (14)
- # leiningen (2)
- # off-topic (6)
- # om (43)
- # onyx (32)
- # pedestal (8)
- # perun (2)
- # re-frame (7)
- # reagent (33)
- # specter (5)
- # vim (4)
- # yada (9)
@zak yes after a lot of explanation I understood that. Thanks! I still find it strange that thy would not simply use the second construction in the koans; much easier to understand for a beginner.
is there a way to, via reader macros write things that are ignored by clojure runtime, but are useful to linters ?
@qqq Depends what you want to be able to annotate. You could use metadata, but not everything accepts it. If you want to be able to mark everything, then something like #_:my-flag
can go anywhere in the file.
You probably know that: 'foo
=> (quote foo)
, and (case x (0 1 2) "0 1 or 2")
so (case x 'x "x")
is (case x (quote x))
.
if i have a function that returns a uuid, how do i fill a vector with a specified number of uuids?
I got it: (mapv (fn [x] (uuid)) (range 10))
. what threw me off was that the #
macro seems to require that you use %
arg.
I kept getting an arity error when I did: (mapv #(uuid) (range 10))
.
@ezmiller77 You probably want repeatedly
Is there a library which produces a dead-simple AST of clojure code? I don't want it to do any evaluations. The info I want is: 1. form (+ children) 2. position in reader. line via LineReader. column too if possible. I want to do some basic linting. Current system doesn't allow me to load in an arbitrary string for the clojure code, and depends on the eval'd version of the function. No good for realtime feedback.
I think you'll find what you're looking for here in this video https://youtu.be/KhRQmT22SSg
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LineNumberingPushbackReader.java Looks like I'm after this plus tools.analyzer
Yep, or tools.analyzer.jvm specifically
Be aware though, it only works on syntactically correct code. Missing parens will break the reader. Some editors support linting of broken code, but such readers are rather hard to write.
@tbaldridge I'm happy to just bail when that happens.
@tbaldridge In fact, it'll be very common, as I expect this to be used from editors in an as-you-type situation.
(deftype LVar [name])
(LVar. "hello-world")
now, what do I have to override to make it prettyprint display "hello-world" ?basically it accepts anything that is either a list or a vector, (or more genraly, anything I can map over)
well, there's coll?
you can map over non-sequential things
hey, you can even map over a string
@U2J4FRT2T It works with anything that can be map
'd over. I believe the big thing is strings etc.
From lumo 1.9.482
cljs.user=> (for [f [coll? seqable?]](mapv f [#{:a :b} {:a :b} [:a :b] '(:a :b) :a]))
([true true true true false] [true true true true false])
What case dat seqable differs from coll?Oh, strings... Right...
Anotherday I was looking for #(or (sequential? %) (set? %))
- "Anything that turns into a json array"
maybe all I want is vector? and list? -- are there any other rodered things besodes lists and vetors?
@domingues strings and hash-maps are seqable? though, I think he wants sequential
@qqq yes, arrays for example
and queues
@qqq fyi lazy-seqs return false for list?
right
you'll find clojure itself never uses the term "lazy list" anywhere
they are lazy-seqs
so why does sequential? not work for you here?
just curious
is it a bad idea to define tests "inline" in the same namespace as the code being tested?
@noisesmith : it might work; I've just never used sequential? before
oh, that's funny because ArrayList prints as [] and HashMap prints as {}
you use /clj
@luxbock you don’t want to include tests inline. This would mean that the tests would be shipped with your packaged code. And additionally, when you write tests you want to be testing the external API, not have access to internal state or private functions of a namespace
@benjamingramlich yeah that makes sense, but I woud like to include tests as documentation, so my next question is if there's an easy way to do this without suffering from the issue you mentioned
it's a feature that I've never seen anyone use
the problem is that if you define the tests via metadata, that means if someone else uses clojure.test they run your tests
since they can't load your code without loading your tests
what is a good naming convention for functions that create lookup maps? if the map is a -> b, I would use a-to-b-map
I often just name it a->b
yeah I like that especially when a or b can contain dashes in their names, but it bothers me a little bit that this would be a lot more accurate name for the return value of the function, so I often use that as a local variable name
wait when you say functions that create lookup maps do you mean a function that is defined as a map or a function that returns an associative like a map
@bcbradley the latter
yeah the reason I asked is because I find myself liking different conventions at different times, and it feels like I should just choose one and stick to it
perhaps the larger issue is that I have a bad habit of fixing styling stuff while I procrastinate on a difficult problem
I've solved this before but never liked my solution. What is the best way to do a "stateful map" in clojure? Regular map is: (a -> b) -> list of a -> list of b Stateful map is: (s -> a -> [s, b]) -> s -> list of a -> [s, list of b]
@bcbradley : is that in response to @luxbock or my question ?
(a -> b) -> list a -> list b means given a function f :: a -> b and a list of a we generate a list of b
in stateful mpa, we change f from f :: a -> b to f :: s -> a -> [s, b] so our f now (1) takes a state, (2) takes an 'a', and (3) returns a new state + a 'b'
let the map hold all state, if you want to "add" a new state, then generate a new map with that state added by using assoc
probably not, the solution I have at the moment is:
(defn smap [f s lst]
(reduce
(fn [[old accum] x]
(let [[new v] (f x)]
[new (conj accum v)]))
[s []]
lst))
what you are describing is a classic reduce, and it looks like that is what you are using
also looks like a monad as designed by Rube Goldberg
honestly i find that my clojure code becomes magnitudes simpler if i just be honest with myself about where state is and how it got there
its usually a bad idea to use the "the whole world -> the whole new world" pattern at a high level in almost every language i can think of, but because of clojure's design I can honestly say that it actually produces some fairly clean clojure code and I haven't had any issues yet
look at the unification part of https://github.com/halgari/odin
i still stand by what i said, there is no reason you can't use a transducer in a macro
I think this is the second time you have, without understanding the problem I'm working on, just assume that whatever idea you have in mind works better. I don't quite appreciate that, and will leave the conversation at this. 🙂
@tbaldridge Do you know if anyone’s compared odin to datascript for perf? It seems like they have comparable querying. Currently, I have nested maps that I’m turning into flattened facts so that datascript can query it (a la intension, if you’ve seen that). odin claims it’ll probably be faster than set-based approaches if you can use its laziness, but slower if you need all the results. I need all the results, but turning that map into a db isn’t free either 🙂
so with flat maps, suppose you're adding a new entity with 10 items, it's a single assoc!
with any form of indexing, if you're now touching an index for every kv paif of the entity; then there's stuff for foreign keys, unique key, etc ...
right now the dbs aren’t indexed at all, I’m querying [[:deeply :nested :flat :fact 0 "value"] ...]
but I feel like it should know more about the structure it’s querying because it’s a pretty deep tree
If I could get cheap unification out of specter I’d be pretty happy; maybe the real answer is going to be something along the lines of: use specter to select possibly-relevant facts instead of eagerly selecting all of them, and then use datascript once the set is small enough i don’t care about the size
@lvh: does it sound like I'm misunderstanding your question? (in my experience, datascript auto idnexs everything; and I don't understand why you have deeply nested maps in a database)
@qqq datascript will also query seqs of facts for you that don’t live in a db, don’t have BTSet indices, &c
what is "cheap unification"? unification is about 100-200 loc to implement; [ in fact, I'm rewriting one right now ]; if certain unification algos can speed up your dataset, it shouldnt' be hard to hack
@qqq sure; writing unifiers isn’t hard, and there are plenty of off-the-shelf ones I can use; it’s more the query language I’m worried about
I want humans to write queries that look like datalog, ideally without having to explode that nested map into a db or seq-of-facts 🙂
that’s pretty easy to do when it’s just a simple select — '["xyz" _ _ 0 _]
is easy enough to translate to a specter navigator
I do do something like that (nested group-by) but that’s more because then diffs are better
it just seems like selecting all items (via cached group-y) where first elemtn is "xyz" is better than linear search
honestly the perf of the unindexed version is mostly fine, especially if I can optimize so that it only dumps the facts it should actually care about for queries
we have exchanged many facts, which we agree on; I forgot the question we're debating 🙂
(1) took the nested data, flattened it ao a list of tuples (2) ran group-by on it many times, indexing it in all the ways I cared about (3) that sufficed for my needs
would something like this work @qqq
(defn statefully-map [f]
(fn [s]
[s (f s)]))
(defn b-seq [initial-state f]
(let [f (statefully-map f)]
(map second (reduce (comp f first) [initial-state nil] a-seq))))
i started out trying to implement the "aggregating" behavior using transducer reduction state (volatile!)
thats why statefully-map looks kind of like a transducer (minus the other two arities)
but the general idea would be to make a new transducible process that "peels out" the b-seq
I can't off the top of my head point out where we disagree, but I don't thikn these two things are the same.
(defn smap [f s lst]
(reduce
(fn [[old accum] x]
(let [[new v] (f x)]
[new (conj accum v)]))
[s []]
lst))
is definitely not equiv to (juxt identity f)basically, I wanted a very very poor man's version of https://wiki.haskell.org/State_Monad
i just took your haskel definition of f:: a->b and f:: s->a->b and turned it into statefully-map
(defn statefully-map [f]
(fn [s]
[s (f s)]))
(defn b-seq [initial-state f]
(let [f (statefully-map f)]
(map second (reduce (comp f first) [initial-state nil] a-seq))))
^^ in your above code, where is a-seq defined ?the part that confused me about your haskel definition was a of the f :: s -> a -> [s, b]
so that means given the original function f, b is (f s) or is it (f x) with some new variable x?
err, a function f would look something like:
(defn f [s a]
[(+ s 1) (+ s a)])
where (+ s 1) is the "new state" and (+ s a) is the "b"i mean its confusing when you said earlier that f:: a -> b
and yet b clearly depends on s in the derived definition
like, build up a vector of all the g's and one of all the h's, then "zip them" into the pairs that you want
in theory, it could work, I'm just stealing notation from Haskell's state monad, which does things like: s -> a -> (s, b)
@qqq Well if you really want the state monad that sort of thing does exist in Clojure. But often with a few atoms you can accomplish the same thing, while still being able to use clojure.core
functions
@tbaldridge : I have a weird aversion to using atoms for this purpose. I can't justify my dislike.