This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-06-16
Channels
- # aws-lambda (1)
- # bangalore-clj (2)
- # beginners (121)
- # boot (23)
- # cljs-dev (165)
- # cljsrn (8)
- # clojars (2)
- # clojure (164)
- # clojure-berlin (6)
- # clojure-chicago (3)
- # clojure-italy (5)
- # clojure-nl (1)
- # clojure-russia (4)
- # clojure-serbia (32)
- # clojure-sg (1)
- # clojure-spec (8)
- # clojure-uk (55)
- # clojurescript (94)
- # cursive (21)
- # datomic (30)
- # events (1)
- # hoplon (6)
- # jobs (1)
- # keechma (1)
- # liberator (2)
- # luminus (8)
- # off-topic (48)
- # om (12)
- # onyx (24)
- # parinfer (15)
- # pedestal (8)
- # re-frame (4)
- # sql (18)
- # test-check (31)
- # unrepl (70)
- # untangled (21)
How would you code the following function in clojure?
def print_statement(operation_list):
last_date = ""
for operation in operation_list:
if operation.date != last_date:
print(operation.date)
last_date = operation.date
print(operation.description)
definitely a reduce
(reduce (fn [last-date operation] …) "" operation-list)
the part in the ..
should be pretty simple
what?
with reduce you decide what to pass as the next first arg
so you’d have (fn [last-date operation] .... (:date operation))
(with the if etc. of course)
so you only get the date for the next one, as expected
All right, yes of course, my mistake. But what if I need to return a string, instead of printing?
send to who?
so you also need a collection of strings?
{:last-date “..” :statements […]}
then you construct the hash map to return at each step
def statement(operation_list):
statement = ""
last_date = ""
for operation in operation_list:
if operation.date != last_date:
statement += operation.date
last_date = operation.date
statement += operation.description
it receives whatever you want it to - yes - so you can use a hash-map if you need to track multiple values
or you can use loop with rest, but if I am consuming a coll one item at a time I prefer reduce
I know it can receive whatever I want, but I wanted to know the right 'clojurian' way to do it 🙂
the trade off is that loop can have separate bindings without a collection, and reduce doesn’t make you step through the collection by hand
noisesmith: Indeed, but since hash-maps are pretty efficient, it's more or less the same
right - I think most people would choose reduce, just mentioning loop can make sense here
yeah - and it’s not just lower level, it’s also slower than reduce, believe it or not
(for consuming collections at least)
this is one reason I like OCaml not having polymorphic arithmetic - it’s a pain in the ass but you always know exactly which numeric conversion is happening where
@noisesmith: I got caught out by Clojure’s promotion/demotion behavior around Double
/`BigDecimal` just the other day 😞 @victora
cough threads cough 😸
https://github.com/clojure/clojure/blob/clojure-1.9.0-alpha14/src/clj/clojure/core.clj#L976
(type (+ 1.0 1.0M))
=> java.lang.Double
which I think is very surprising…
this should be done directly in byte code the same way java would do it - for better or worse
Number is a java type, and it’s the superclass for all possible args to +
wait, which code do you think would return a long?
Clojure never converts floating point to integer types implicitly.
(but it does convert BigDecimal to Double implicitly, it seems)
@noisesmith the + code i linked at the top
adding a long to a double returns a double - whether java or clojure
devil’s advocate: why would you use floating point data anywhere in your calculation if it needed to be precise?
Pretty stupid question I couldn't find on google: how can I "include/import" another file?
@victora I refer to this frequently: https://8thlight.com/blog/colin-jones/2010/12/05/clojure-libs-and-namespaces-require-use-import-and-ns.html
note: if you are using protocols, a fact that surprised me is you have to use import with them
I have two files balance/db.clj balance/handler.clj in handler.clj I'm using (:require [balance.db :as db]) I get a 'not found' error, why?
so I assume the balance directory is on your classpath?
what specific error do you get?
Exception in thread "main" java.lang.Exception: namespace 'balance.db' not found after loading '/balance/db', compiling:(balance/handler.clj:1:1)
so that means that it loaded your file, but there was no (ns balance.db)
form in the file
and require doesn’t like that
if you just want to load a file, there’s load-file, but require really wants to know if a namespace exists already, and keep track of what’s loaded
that’s not how it works
if you called (require [balance.db ...])
it needs (ns balance.db ...)
- you can highlight inline with `
thanks again @noisesmith
yeah, directories are meant to map to namespace substrings and visa-versa, and things fall apart if they are not in sync
though when experimenting I’ll often make /tmp/foo.clj and then run (load-file "/tmp/foo.clj")
in the repl
What would you guys use to run a background task that should run every day at 00:00am ?
I use one of these https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ScheduledThreadPoolExecutor.html
it’s a straightforward api
wherever it asks for Callable
you can pass in a clojure function
same with Runnable
yeah, it’s not complicated to use thanks to those facts
the only part that is mildly annoying is the TimeUnit arg required, but that’s tiny as java inconveniences go
scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) If I read the API right, I only need to call this method
well, you need an instance of the scheduler, but yes, that’s it
and it returns a handle to your scheduled thing
Do you have example code lying around? That could help. First time doing heavy java/clojure integration heh
(def scheduler (ScheduledThreadPoolExecutor. 12))
(defn schedule [f delay-ms period-ms] (.scheduleAtFixedRate f delay-ms period-ms TimeUnit/MILLISECONDS))
yeah, I just prefer to use the API when using it is two lines of code