Fork me on GitHub
#clojure
<
2015-12-25
>
andy.fingerhut00:12:14

@bbloom: I think that is inherited from Common Lisp, and perhaps inherited by choice because it is useful for having a final default value that can be an arbitrary value that is neither nil nor false.

bbloom00:12:12

andy.fingerhut: does common lisp even have a false boolean value? i thought it did not

jaen00:12:39

I'd guess it's just consistency - if or returns the first truthy form, then in case no form is truthy returning last tested form seems sensible. (or whatever false) seems like a pretty neat trick though.

andy.fingerhut00:12:47

@bbloom: Having a final default value that is arbitrary is useful in both Common Lisp and CLojure.

bbloom00:12:03

fair enough

bbloom00:12:22

i guess i answered my own question then

jaen17:12:54

Hmm, I'm aware of http://clojure.github.io/clojure/clojure.core-api.html#clojure.core/*data-readers*, but how about function to write a custom tagged literal?

polymeris17:12:21

Hi How do I tell clojure I want a local binding resolved at compile-time (or only once, at least)?

(defn f [] 1)

(defn g []
  (let [x (f)]         ; result of f is a constant, call it only once, not every time I call g
    x)
I am suprised it's not the deafault behaviour, most functions being pure and all that.

jaen17:12:14

Well, you need to close over it.

jaen17:12:22

In that case you'e not closing over it

jaen17:12:41

(let [x (f)]
  (def g []
    x))

polymeris18:12:12

I don't understand that code... where did my constant (1) go?

jaen18:12:27

Yeah, I just rewrote the second function. First is left as-is.

polymeris18:12:37

it is defn g, right?

jaen18:12:52

Yeah, I typo'd

polymeris18:12:15

Thank you very much, @jaen

jaen18:12:13

No problem. Though it's rather unusual to use defn while closing something over. What's your use case?

polymeris18:12:48

The "constant" is a map of string to numbers. I could write the literal, but it is large and looks like magic. Instead I prefer to generate it programatically (clearer what it means that way), but it seems wasteful to do it everytime I call the function that uses it.

jaen18:12:56

Then why not just (def string-to-number-mapping (make-string-to-number-mapping))

polymeris18:12:18

That polutes the namespace

polymeris18:12:38

Or is that not considered an issue?

jaen18:12:48

Well, does it pollute the namespace?

jaen18:12:51

It's a constant

jaen18:12:11

If you don't want others to see it you could (def ^:private name ...) it, I suppose.

polymeris18:12:48

That would be an option as well (yeah, I don't want others to see it). Is that the idiomatic way? Your first solution seemed better at first glance, since it makes it clear that the binding is only used by that function.

jaen18:12:45

Well, that depends on your taste, I suppose.

jaen18:12:04

I would feel iffy to def not on the top level.

jaen18:12:11

Even if that's just a let.

jaen18:12:39

I'd rather def the constant at the toplevel before I use it

jaen18:12:43

And then refer to it.

jaen18:12:50

Not sure which is more idiomatic though.

polymeris18:12:14

Yeah, you are right. "`def` only at top level" is a good argument for the latter.

polymeris18:12:18

Thanks, again

jaen18:12:23

Sure thing

cigitia19:12:42

Clojure records are more efficient than regular Clojure maps, especially when you have keys that stay the same So are transients of maps, especially when you have data that are private to one process and mutated very frequently. But Clojure currently does not support transients of records (http://dev.clojure.org/jira/browse/CLJ-1459). This means that people have to choose between records and transients; we cannot have both. If we need to store private state that both mutates very frequently (e.g., for the state of a stateful transducer) yet maintains the same keys, then should we, in general, use record volatiles or map transients?

mpenet21:12:25

cigitia: you can build a record via a transient map via (map->SomeRecord (persistent! m))

mpenet21:12:18

I guess it could make sense in some scenarios