@misha The obvious solution is a "seen" map
and only put the fields you want to compare into the elements of that map
generally though, are you just doing a search?
not exactly. There is a complication of time, where state is "the same", but time (since game start) is not. Which is kind a problem for your line 92. The goal is not to do search from start state for every query. the goal is to generate all possible states for a certain time period from the initial state, and then search through those. then, since there is a bunch of those states (millions per second after some point in time) – i'd like to parallelize it too. And it is a problem for your "doseq" on line 93 part. Then, the "searching" is typically like this: - what is the earliest state/time I can have this unit/upgrade/building, and - what are steps that led to it. (tracing it back to the initial state)
if so, this might be useful
there are def. libraries and whatnot that are better examples and actually tested
you can start from a "starting game state" and go forwards from there
Good article on how one can "discover" lisp:
An Intuition for Lisp Syntax: https://stopa.io/post/265
or you could use a sorted-set with a custom comparator that dissoc's :id before comparing (or select keys :a and :b) .. you can get rid of the meta usage that way
Hello! I have some bug:
(go (def row (:body (<! (http/get "<http://localhost:5000/test>")))))
(def clean (subs row 1 (s/index-of row (last row))))
(hash-map clean)
It returns {}
in clean
some data like :id 1, :name "Ab Bc Cd", :sex "M", :birth "01.01.1999", :address "Street 1", :oms "0001"
and when i put this data in hash-map
:
(hash-map :id 1, :name "Ab Bc Cd", :sex "M", :birth "01.01.1999", :address "Street 1", :oms "0001")
It works. But why and how can i fix it?
Not sure what's going on in your code.
First of all, (hash-map clean)
would immediately fail in Clojure, no matter what the value of clean
is because hash-map
expects either no arguments or an even number of arguments. So you must be using ClojureScript.
Second of all, you're assigning the result of subs
to clean
. subs
returns a string. You cannot magically turn a string into data without explicitly converting it. If you want to read EDN strings, just use clojure.edn/read-string
.
It's in cljs but i did think there's no difference so i wrote in this channel
Either way, you have to read that EDN string first.
Thank you
It helps me
hello. I'm looking for something which behaves like an Atom, but which records a stat like 'number of tries per successful update' - anyone know of such an impl?
@henryw374 Don't know of any. Probably implementing your own variation of https://github.com/clojure/clojure/blob/cbb3fdf787a00d3c1443794b97ed7fe4bef8e888/src/jvm/clojure/lang/Atom.java#L15 ...
@borkdude cheers yeah I've been thinking of doing that ... just being lazy!
I have issues with clojure.data.csv. I am getting "Unexpected character: C". How do I find out what's causing this? The input file is a tsv file and I've told data.csv to use \tab
as separator.
read-csv will give you a lazy sequence - if you read that line by line (with loop/recur), you should be able to count lines and print or try/catch around the body to determine where the bad data is
Anyone experienced issues involving clojure.tools.logging
, threading, and try
? The following causes Can't set!: *current-length* from non-binding thread
:
(defmethod d/create! :impl/ad
[ad-inst complex-user ad-user]
(log/trace ad-user) ; fine
(try
(log/trace ad-user) ; not fine
; etc
))
Method is being called from pmap
Exception is thrown from within clojure.pprint
@hsartoris Could it be a laziness issue?
my guess would be this is an async issue.
Actually I have to amend, the try
likely has nothing to do with it; can only consistently repro with log/spy
pmap
does return a lazy sequence, and there are dynamic vars that affect clojure.pprint
's behavior. I haven't checked, but wouldn't be completely surprised if clojure.pprint
's implementation attempts to set!
one or more dynamic vars in its implementation.
Just checked, and there definitely are a couple of set!
calls within pprint's implementation.
At issue is evidently https://github.com/clojure/clojure/blob/cbb3fdf787a00d3c1443794b97ed7fe4bef8e888/src/clj/clojure/pprint/pprint_base.clj#L193
@hsartoris You could try (doall (pmap ..))
to see if it's laziness causing this
@borkdude yup that does it
Thanks! I guess the dice have just fallen in favor of not breaking for the previous iterations... weird
@hsartoris in general, be wary of mixing side effects with laziness. You'll get surprises
But it is fairly common when someone is debugging issues with laziness and side effects, debug print/log statements are a common way to do that. In this case, it is an extra bit of surprise that the function that was attempted to be used for printing, pprint, has inside of itself some implementation details that don't mix with laziness, more so than if one tried to use println
instead.
Agreed on the general recommendation you gave.
Would it be correct to say dynamic bindings are a form of side effects? You're reading from an impure environment instead of writing to it (the classic example)
dynamic vars are global mutable variables that don't combine well with the mathematical concepts of FP like laziness and purity
I worked on an application once that had a dynamic var for the Datomic db value (as of a certain date, defaulting to today). This caused tremendous confusion in combation with laziness. I refactored the entire codebase to take a db argument instead.
This was before component was a thing. Currently I work on an app where lots of functions take the system as an argument. Nice to see how things evolved during the years ;)
I have an interest in this area of Clojure software design. I could find very few write ups on the topic, and nothing in depth. According to you, should the system map contain A) as much as possible or B) as little as required ? In my app, getting passed the system map carries the implication that you are going to do something side effectful with it, like getting a record from a database. In https://www.youtube.com/watch?v=vK1DazRK_a0, R. Dittwald advocates for deferring side effects to as late as possible and using as many pure functions as can. Isn't passing the system to lots of functions some kind of design smell in that context ? I'm having trouble reconciling "system map given liberally everywhere" and "use as much pure functions as possible".
They don’t seem like side effects to me. They for sure break referential transparency though
> Despite this, the fact is that we are using functional values to simulate state. There is in principle nothing to stop functional programs from passing a single extra parameter into and out of every single function in the entire system. If this extra parameter were a collection (compound value) of some kind then it could be used to simulate an arbitrarily large set of mutable variables. In effect this approach recreates a single pool of global variables — hence, even though referential transparency is maintained, ease of reasoning is lost (we still know that each function is dependent only upon its arguments, but one of them has become so large and contains irrelevant values that the benefit of this knowledge as an aid to understanding is almost nothing). This is however an extreme example and does not detract from the general power of the functional approach. Out Of The Tar Pit, 5.2.3 Kinds of State
I don't think that is the same thing though. He is talking about pure functions (no side effects) that accepts some large mutable collection.
he's not talking about a mutable collection
at least that's not how I remember the paper
yes, the mutable part doesn't matter actually.
using dynamic scope in combination with laziness doesn't exactly introduce mutation in the normal sense, but it does introduce changes in bindings that are equally spooky and unpredictable, so as @dpsutton says they break referential transparency
to me (and for many of us I think), avoiding mutation isn't the end goal, it's a means to having referential transparency
Eventually you have to mutate something, otherwise your code isn't doing anything besides heat CPU
(unless you're writing a theorem prover or something)
right, the question is whether the calculation is reified into the explicit flow of data, or spooky
there's a massive amount of mutability in theorem provers :)
mutating the set of proven theorems and lemmas? largely like clojure namespaces?
I think the point of that quote from Out of the Tar Pit a few comments back is that even if you write pure functions, if one of the parameters is some big collection, e.g. a Clojure map with many key/value pairs, but any given function only examines a small fraction of them, then the fact that it is a pure function doesn't help a human much in reasoning about which part of that big collection is relevant for any given pure function. That is a kind of incidental complexity for a person who wants to reason about the code's behavior.
(def zorn's-lemma ...)
etc?
@andy.fingerhut that's how I understand it as well. Even more so if you pass that large collection around from function to function it complicates things even more.
It is better than reading global variables, because you know that whatever the pure function accesses is somewhere in that big collection, rather than outside of it, but it isn't localizing things very much if that collection is large.
and why I said it is different is that if a function refers to an ear-muffed variable it isn't pure at all
so it is a different case altogether
If you read a dynamic variable's value, one that is in the environment and not a parameter, then yes, to that extent you are reading global variables.
Note that pretty much every Clojure function you write depends upon the current definitions of other Clojure functions that you name inside of its body, and those are mutable variables (via def
). It is just very very uncommon practice to mutate those vars, except during interactive development.
and also in this particular case we're talking about printing functions so I don't think it is claimed they are side-effect free
nah I meant the implementation of theorem provers usually makes use of a lot of mutability internally
in order to be efficient