This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-11-26
Channels
- # bangalore-clj (3)
- # beginners (47)
- # boot (20)
- # cljs-dev (7)
- # cljsjs (16)
- # cljsrn (3)
- # clojure (46)
- # clojure-art (4)
- # clojure-berlin (1)
- # clojure-brasil (2)
- # clojure-greece (1)
- # clojure-india (5)
- # clojure-russia (1)
- # clojure-spec (34)
- # clojure-taiwan (2)
- # clojure-uk (8)
- # clojurescript (69)
- # cursive (9)
- # datascript (26)
- # datomic (1)
- # emacs (2)
- # events (1)
- # hoplon (8)
- # leiningen (3)
- # off-topic (4)
- # proto-repl (4)
- # re-frame (3)
- # reagent (1)
- # rethinkdb (8)
- # rum (3)
- # vim (83)
is there a built-in/popular way of printing strings while maintaining a max-width like 80 chars?
pretty sure i saw line length in the pretty-printer stuff
@martinklepsch Usually called "word wrap", you'll probably find a ton in Java/Clojure I'd bet.
@robert-stuttaford there's stuff in pprint but wasn't entirely sure how applicable that is. probably you're right and it's perfectly fine though
http://commons.apache.org/proper/commons-lang/apidocs/org/apache/commons/lang3/text/WordUtils.html seems to do it properly.
Or quick and dirty: https://www.rosettacode.org/wiki/Word_wrap#Clojure
heh, just was on the same pages 😄
What's the most straightforward way to select an implementation (a Strategy, for the pattern-inclined)? My exact situation: I have multiple maze generation algorithms, and I realize that each can be expressed in terms of three functions: initial-values
, complete?
, step
, and result
. For instance,
(loop [step-values (initial-values grid)]
(if-not (complete? step-values)
(recur (step step-values))
(result step-values)))
; the result function encapsulates knowledge of the step-values structure
This is pretty easy to code! Each algorithm could have its own implementation of step
, and its own spec for the step-values
datatype. But although it's easy to :require [some-generator :refer [initial-values complete? step-values result]]
, I'm not sure how to switch behavior at runtime.For now, I'm going to predefine something like:
(def generators
{::alpha {::initial-values alpha/initial-values, ...},
::beta ...})
And then I can implement (generate-maze {::grid grid, ::algorithm ::alpha})
pretty easily. But it seems like there should be something a bit easier.My near-term goal is to provide a strategy selector for a web-based demo; the longer-term goal is to create very large mazes where different areas use different algorithms. In either case, choosing strategies dynamically will be very helpful.
@amacdougall protocols and multimethods could both work
That was my first thought—I'm just not sure how to set it up. Multimethods and protocol functions both change their behavior based on the type of the argument, right? But what would the argument be in this case? The point is that the original input to the generator (a grid with no connections between cells) is the same... it's only the linking strategy that changes. I guess there could be a strategy flag that gets passed along all the functions.
Yeah you have to pass the strategy around
If you hate that and like magical things, you probably want to store the strategy in a dynamic var
Combining a dynamic var and a protocol wouldn't be too weird
In an OO language, you'd say something like generator = new SpecificGenerator
and then not worry about the generator type from that point on. But of course that's a setting in a mutable config variable (essentially... we just call it an "object", but from a PL perspective they're kind of equivalent).
You'd still have to pass that around, right?
I'll think about it. I'm already using a multimethod to choose SVG rendering methods based on the algorithm I'm trying to animate.
Oh, of course—the convenient aspect of the OO approach would be that once you've assigned a specific generator to the generator
variable, you can call generator.foo
without further consideration of the generator's type. But then if I just make :strategy
one of the keys in step-values
, this all works fairly smoothly. I just need to declare a higher-level ::generator/strategy
keyword in a namespace accessible to everyone that uses this API.
clojure.spec seems to be leading me in the direction of using a lot of big nested hashes everywhere, because it makes it relatively easy to understand and enforce their contents. Not sure if that's good or bad overall.
When in doubt, add another (namespaced) key (which refers to a spec defined elsewhere) to the hash!
@amacdougall I think a protocol would have the same conveniences
Anyway, an end user could say, I guess...
(re-frame/reg-event-db
:step-generation
(fn [{:keys [::g/grid
::generator/strategy
::generator/step-values] :as db} _]
(if (nil? step-values)
(assoc db ::generation-step (generator/initial-values grid strategy))
(assoc db ::generation-step (generator/step step-values)))))
And the final form works because step-values
includes a ::generator/strategy
key which we use to dispatch the multimethod. Or protocol, but this seems like a more natural fit for multimethods, unless I defrecord
the different step-values
types.
The re-frame
aspect is incidental here.
You can use reify instead of defrecord
Which is something that multimethods don't have an analog for
Anyone aware of libraries designed to let you nicely print things to a terminal? Looking for something that would help visually structuring output similar to what markdown helps with. (Maybe it could even take markdown as input?)
@martinklepsch there's a clojure library called pretty I think. Boot uses it :)
I recommend looking at https://github.com/brandonbloom/fipp or http://belle.sourceforge.net/doc/hughes95design.pdf
both fipp (if I recall correctly) and that paper look at pretty printing in sort of two phases, 1. building some kind of layout document and 2. laying out that document
the paper is very nice, even if it isn't state of the art in pretty printing anymore
Hello everyone! I am a bit lost about how lein compile
works. I am trying to incorporate Java code (wsdl client) into my web application backend. I added the sources to src/java folder, and then I specified that path in the project.clj file: :java-source-paths ["src/java"]
. However, when I execute lein compile
nothing happens, and when I execute lein repl
I get a java.lang.ClassNotFoundException.
If I remove the import statement from my Clojure code (which imports the wsdl classes), lein repl
start without errors, and it also compiles the Java classes. From that point an on, I can uncomment the import statement, execute lein repl
and it doesn't throw a java.lang.ClassNotFoundException. Does anyone know why this is happening? Why doesn't lein compile
compile those classes when I execute it?
Oh, sorry, I forgot to say that I tried that too. It throws the same java.lang.ClassNotFoundException.
It seems that in order to compile the java sources, Clojure runs the user.clj (I don't know why) namespace first. And because I am using the Clojure Reloaded approach (with components), this bring all my Clojure code, including my import statement.
user.clj is special
Yeah, if I remove from my project.clj file the :source-paths
of the :dev
configuration map, lein javac
runs ok.
I found a solution! Executing lein with-profiles test javac
works because it doesn't need the user.clj namespace.
maybe too noobie, but I have to ask I’m doing my first web app using clojure and I’m not comfortable with the following code. The code is to signup a brand new user in the system
(ns user.service)
(require '[user.sql :as sql])
(require '[user.domain :as user])
(require '[web.utils :as reply])
(defn signup-user [pgsql new-user]
(if-not (user/valid? new-user)
(reply/bad-request {:message "Invalid user payload"})
(if (nil? (sql/find-by-email pgsql (:email new-user))))
(reply/success (sql/save pgsql new-user))
(reply/conflict {:message "Email already been taken"})))
------------------------
;; signup-handler
(ns user.handlers)
(defn signup-handler [request]
(user/signup-user (:database request) (:body request)))