Fork me on GitHub
#beginners
<
2016-03-23
>
adamkowalski06:03:55

hey if I want to manage my routing on the client side, how can I make it so that on the backend ring always serves up my index.html and does not care what the url is?

martinklepsch09:03:13

@adamkowalski: implement a catch all route like "*" and respond with index.html there

martinklepsch09:03:38

not-found is probably better than * as well simple_smile

roberto13:03:40

is it possible to find the namespace a function was called from?

martinklepsch13:03:15

@roberto: I'm sure there are better ways but one option could be to throw an exception, catch it and inspect it's stacktrace.

roberto13:03:23

my problem is that I have a logger that wraps around timbre. Mostly it is there to do some calculations before we log. I want to include the namespace from where the logger function was called.

roberto13:03:01

timbre has a :?ns key I can use in the appenders, but it always defaults to my logger wrapper, which defeats the entire purpose of wanting to include the ns

roberto13:03:16

I miss log factories ala java

martinklepsch13:03:21

@roberto: ah, probably then have logging macros that pass *ns* from the callsite?

roberto13:03:24

it crossed my mind, it might be the only solution 😞

martinklepsch13:03:47

@roberto: I'd suggest asking in #C03S1KBA2 as well, not a beginners question I'd say simple_smile

roberto13:03:15

thanks, I still feel like a beginner, so I always default to this channel

roberto13:03:03

another question. I’m trying to implement a protocol that is in a different ns using extend, but it isn’t working for me. I might be missing something obvious. E.g:

(ns prots.blues
  (:require [prots.protocols :as p]))

(deftype BluesPlayer [fname lname]
  p/Speaks
  (speak [this] "HOO"))

(extend BluesPlayer
  p/Rocks
  {:rocks (fn [this] "HOOOO")})

(def wolf (BluesPlayer. "Wolfy" "Howls"))

roberto13:03:25

I can do (.speaks wolf), but (.rocks wolf) throws an exception

roberto13:03:14

if I implement p/Rocks when I declare the BluesPlayer` type, then it works. Or if I declare the protocol in the same namespace as the type declaration, then using extend works.

roberto13:03:21

I’m on clojure 1.8

lmergen13:03:20

it is normal to add a bang ! to the end of a clojure function that has side effects, right?

lmergen13:03:36

how is such a side effect defined... would I/O be considered bang-worthy?

martinklepsch13:03:59

@lmergen: I usually add it to stuff that "changes the outside world"

lmergen13:03:23

right, so indeed as I thought

lmergen13:03:57

but, that means that bangs should bubble up, right? a function calling a function with a ! should, by definition, also have a !

jmayaalv17:03:00

@lmergen @stuartsierra has a very good post about naming functions. It also discusses the ! you might find it useful https://stuartsierra.com/2016/01/09/how-to-name-clojure-functions

lmergen17:03:13

@jmayaalv: thanks! so, people basically do not know what to do and there is no real standard simple_smile

lmergen17:03:18

> If I do use an exclamation mark, it’s to signal a change to a mutable reference, not other side-effects such as I/O.

lmergen17:03:51

I think that, if you start using it for too broad a range of different function, it starts to lose its value

lmergen17:03:04

if you consider 'impure / side effects' the reason to add an exclamation mark, you basically have to add an exclamation mark whenever you would have something inside an IO Monad in Haskell simple_smile

lmergen17:03:20

as in, every Ring handler function should probably have a ! if it talks with a database / does anything useful

seancorfield18:03:39

Part of the problem with ! is that if you use it to indicate code that isn’t safe in a retry situation (i.e., you can’t just re-run a function repeatedly and get the same result), then you end up with ! all over the place — as you surmised.

seancorfield18:03:16

In java.jdbc, I took feedback from the Clojure/core folks way back and the consensus was that query was OK (even tho’ the DB could change under you and give you back different results on each call) but execute!, insert!, and delete! should indicate "unsafe" because they’re (almost) guaranteed to change the world.

seancorfield18:03:27

But it’s certainly not clear cut in most cases.

seancorfield18:03:53

In our own codebase, we have almost no ! functions because so much code ultimately depends on the database (and often modifying the database). But I’m not very happy with that and would prefer to separate out queries (of any data sources) from updates (to any data sinks). If only to make code more testable.

isaac_cambron20:03:11

We're phasing out our aggressive use ! to mean "side-effecty" or even "mutates stuff" and transitioned to "dangerous or at least destructive". we have too many idempotent database update operations to make it really useful. When everything has a !, then really nothing does

isaac_cambron20:03:05

(Though, amusingly, our internal wrapper for JDBC's query is still query! because we use for inserts where we use returning)

donaldball20:03:13

query! in jdbc is reasonably defensible as it can very much have side effects, depending on your isolation level

adamkowalski20:03:45

@martinklepsch: thanks, that is very helpful!

lmergen23:03:11

donaldball: and there we have the problem, in a language such as Haskell, this would have been exposed by an IO monad. in Clojure, there is no such thing. I think the best thing to do is to just be very conservative with using a !, because otherwise they will literally be all over the place, and we would end up with main!. simple_smile