Fork me on GitHub
#clojure
<
2019-09-02
>
jumar04:09:33

A follow-up to the discussion in #off-topic : Is there any practical difference between bound-fn and binding-conveyor-fn?

jumar05:09:31

Apart from bound-fn being public

jumar05:09:08

I guess I don't understand why their implementations are different.

dominicm07:09:42

based on impl, I'd bet that binding-conveyor-fn is faster

jumar07:09:06

I'd say so too but then don't know why bound-fn just doesn't use binding-conveyor-fn under the hood

pepas05:09:31

I’m trying to nail down exactly what a “symbol” can be in clojure.

Alex Miller (Clojure team)12:09:23

Edn is a subset of Clojure syntax - Clojure code is read with LispReader

pepas05:09:18

But either I don’t understand Java regex syntax, or it doesn’t seem to match my understanding.

pepas05:09:50

symbols seem to be officially described here: https://github.com/edn-format/edn

hiredman05:09:04

That also only defines what things the reader can read as a symbol

hiredman05:09:56

You can construct symbols from arbitrary strings using the symbol function

pepas05:09:59

based on the official description, I came up with this mental model (which is a bit of short-hand):

pepas05:09:02

- a (alpha): [a-zA-Z] - n (num): [0-9] - s special: [\.\*+!\-_?$%&=<>] - / slash: \/ a symbol can be: - single-char name: [as/] - multi-char name: [as][ans]+ - single-char prefix, single-char name: [as]/[as/] - multi-char prefix, single-char name: [as][ans]+/[as/] - multi-char prefix, multi-char name: [as][ans]+/[as][ans]+

pepas05:09:30

so, substitute in the charset wherever you see a, n, s

pepas05:09:19

i.e. the first rule is read as “a symbol can be a single-character name: [a-zA-Z\.\*+!\-_?$%&=<>\/]

hiredman05:09:54

Because the set of symbols the reader can construct, and the set of all symbols is not the same, you cannot use the reader to determine what a valid symbol is

pepas05:09:14

for (the set of all symbols) - (symbols the reader can construct), can you help me imagine what those are? or where they come from?

hiredman05:09:22

The symbol function will take arbitrary strings and make them symbols

hiredman05:09:24

For example the reader won't read 1 as a symbol, but (symbol "1") will construct such a symbol

pepas05:09:47

user=> (symbol "///")
///
user=> (symbol "0")
0

hiredman05:09:05

Similar with keywords

pepas05:09:59

user=> (def (symbol "1") "foo")
Syntax error compiling def at (REPL:1:1).
First argument to def must be a Symbol

hiredman05:09:08

I think there is some special handling of the / character when calling the symbol function for creating namespaced symbols

pepas05:09:15

hmm, ok, so since def is a special form, the second arg is never evaluated.

hiredman05:09:33

You can use intern

pepas05:09:36

so you can create invalid symbols at run-time, but you can’t actually def them to anything?

hiredman05:09:57

You could also programmatically construct a form containing the 1 symbol and pass it to eval, bypassing the reader

ahungry05:09:03

`(def ~(symbol "0") "aaaahhhh")
 (def 0 "aaaahhhh")

pepas05:09:13

user=> (intern 'user 'x 1)
#'user/x
user=> x
1
user=> (intern 'user (symbol "0") "foo")
#'user/0
user=> 0
0
user=> user/0
Syntax error reading source at (REPL:7:0).
Invalid token: user/0

pepas05:09:24

How would I actually refer to user/0?

hiredman05:09:06

You just can't use the reader

hiredman05:09:43

When you type anything at the reply it goes through the reader first, and the reader doesn't accept the 1 symbol

pepas05:09:00

So interesting! Thanks for indulging me

ahungry05:09:35

if you didn't have anything else in that ns

ahungry05:09:39

(deref (second (first (ns-publics 'user))))
         "foo"

👍 4
misha07:09:42

does anyone follow any naming convention for functions without "active" side effects, but potentially returning different values at different time (e.g. deref)?

vlaaad07:09:47

for refs specifically I use * prefix: (let [*id (atom 0)] ...)

misha07:09:53

that is name of a ref. I am curious about names of "getters" which are pure, but the thing they get from - is not.

vlaaad07:09:44

> which are pure, but the thing they get from - is not does not look pure to me..

vlaaad07:09:28

anyway, I don't have any naming convention for this 🙂

misha07:09:39

pure in a sense "does not modify things"

allandaviesza13:09:15

I feel like I'm missing something obvious, but has anyone set GOOGLE_APPLICATION_CREDENTIALS or any environment var for their Clojure code to use via (System/getenv) while using cider jack in?

mccraigmccraig13:09:44

@allandaviesza i always start a repl from cmdline and use cider-connect ... you could also use some configuration mechanism like juxt/aero

allandaviesza13:09:15

yea I've done that in the mean time

allandaviesza13:09:29

would be nice if I had a method to create an env var that required no work from other devs working on the project

jumar14:09:32

This depends on the "configuration tool" you use. You shouldn't really use System/getenv directly because that's difficult to manage but rather use something more flexible like https://github.com/tolitius/cprop that allows you to use variety of approaches - EDN files, System properties, Env vars

jumar14:09:48

That particular one is also used by Luminus: http://www.luminusweb.net/docs/environment.html

allandaviesza16:09:50

thanks for your suggestion 🙂

allandaviesza13:09:14

like writing it in to profiles.clj (if it was to be committed)

allandaviesza13:09:30

@vlaaad looks like it's working! For some reason I glossed over this earlier when finding it via Google, many thanks for bringing it to my attention! 😄

👍 4
Leon14:09:25

is it (and if yes, is it practical, and if yes, how) possible to do timeouts when using pmap?

Alex Miller (Clojure team)16:09:30

As a feature of pmap, no

Alex Miller (Clojure team)16:09:11

pmap is really most ideal for chunky computational tasks

Leon17:09:59

Then whats the best way to do some network calls and such in parallel without huge amounts of added complexity?

allandaviesza17:09:06

future may be of use

allandaviesza17:09:41

Something to that effect.

Leon17:09:57

How would i implement something like pmap with Futures? The whole Futures Thing is somehow really confusing for me..

allandaviesza17:09:22

a call to future returns immediately then executes the body on another thread

allandaviesza17:09:16

so you'll set up a bunch of requests that will all start at the same time

allandaviesza17:09:40

then the second map will block execution while waiting for the first future to return

allandaviesza17:09:39

(I'm referring to the code in the snippet above)

allandaviesza17:09:23

the best thing to do is to try it out using sleep

Leon17:09:04

So the first map creates a list of Futures (as i understand, a future is comparable to a promise in Javascript, correct?) And the second map then awaits their completion one after Another using deref. Wouldnt in your example the Futures get created only when attempting to deref them because of the lazyess of map?

allandaviesza17:09:18

future also returns what the body returns, the body being the expression within the call to future

allandaviesza17:09:57

yea thats a good point, so you can use mapv which is not lazy

allandaviesza17:09:29

you're correct about them being comparable to a promise

allandaviesza17:09:49

I think future is a lot more simple than a promise

Leon17:09:45

I think i got it, thanks!

shdzzl21:09:53

Is it possible to put metadata on protocol methods?

seancorfield22:09:51

No. But it is fairly common to write a regular function that wraps the protocol method implementation so that you can do "regular" stuff to it (metadata, instrumentation with Spec, etc).

alfredx04:09:15

@U04V70XH6 I did an experiment and it turns out to be Yes - you can alter metadata on protocol methods.

(ns myns)
(defprotocol CanFly
  (fly [this height])) 
(alter-meta! (get (ns-interns 'myns) 'fly) assoc :mymeta "Awesome")

alfredx04:09:10

I am running JDK 11 and Clojure 1.10.1

alfredx05:09:25

@U2ECUGHME Can I ask what’s your context in trying to inject metadata into protocol methods? Writing a framework/tool, or..

shdzzl16:09:50

Specifying :doc/format on a protocol method for codox

shdzzl17:09:45

Also, thanks to you both for your replies!