Fork me on GitHub
#clojure
<
2017-04-01
>
mobileink00:04:26

that's a category error, sorry.

qqq01:04:31

the other nice thing about transients is that they act as a shallow state monad

qqq01:04:49

instead of having to thread the new state through all the time, we can just make modifications, and the modifications are carried through until the persistent! call

mpenet01:04:10

qqq: not true, you still have to thread, check the docstring about "bashing in place". And try yourself with say, 100 insertions. I can t recall the exact limit for every datastructure but bashing in place only "works" for a few modifications and its an impl detail.

bcbradley01:04:37

i think the more salient issue is that reality usually categorizes only approximately, so if you need exact categorization, or an exact taxonomy of something that is supposed to be a representation of reality, the more realistic you make your representation, the more often you have to revise or rethink your whole taxonomy

bcbradley01:04:20

i like to compare the ease with which mathematics can be categorized, and the ease with which simulations can be categorized against the difficult of categorizing (with exactness) biology, economy, or even something more mundane like postage stamps

bcbradley01:04:35

The crucial difference between these two classes of things is rampant chaos-- its not present in all the structures of mathematics, and can be avoided a priori in a simulation; but it is inextricably a part of our reality

bcbradley01:04:56

thus any time you try to hedge yourself against chaos by adopting rigid types, you are hedging yourself against reality

bcbradley01:04:32

(except in the cases where you aren't dealing with reality in the first place, for instance a haskel library for matrix algebra)

qqq01:04:04

"transient" is shallow right? in the sense if if we have a map of map of values, i.e. k1 k2 -> v, then in using transient, it's on the "top level of keys" that become transient, the 'inner map' of k2 -> v is still persistent

mpenet01:04:18

There s a wrong assumption that using a strongly typed lang like ocaml will be less productive. Also a huge diff with schema/spec and the like is inference. Very often with ocaml you dont even have to add any type annotation and you get whole program coverage for free. That said that language has other issues (for now) imho. But that s #offtopic material

qqq02:04:53

https://clojuredocs.org/clojure.core/definline <-- is this the right way to inline functions in clojure?

qqq02:04:58

(slightly concerned as it's marked EXPERIMENTAL)

qqq02:04:19

is there a builtin for checking whether something is a transient ?

qqq04:04:28

(doseq [:let [x 20]]
  (println x))
this code works. Can I rely on some spec guaranteeing this works, or is the first element of a doseq supposed to be a (var, seq) pair ?

elena.poot04:04:48

The doc string indicates the latter, the keywords are modifiers of the previous sequence. I suspect this is a pathological case, since you're binding a constant value. I guess the real surprise to me is that with an empty set of bindings, it executes the body at all. 🙂

qqq08:04:52

m = a map ks = a list of keys What is the fastets way to write (reduce dissoc m ks) ?

rauh08:04:56

@qqq (apply dissoc m ks)?

qqq08:04:05

@rauh: why would this be faster?

lincpa09:04:40

(-> amap keys set (clojure.set/difference , (set ks) ) (#(select-keys amap %))) if amap have a lot of keys.

istvan09:04:41

does anybody use this library? https://github.com/funcool/cats

fernandohur10:04:00

I do. I find it very useful for the Either Maybe and Try monads.

istvan15:04:53

I was wondering if there is any downside

danielsz09:04:31

They used it for an Either monad.

lvh15:04:20

cheshire seems to have a lot of CBORfactory annotations that it doesn’t import: https://github.com/dakrone/cheshire/blob/master/src/cheshire/core.clj

lvh15:04:28

is that a bug or am I missing something about annotations

lvh15:04:40

(also sorry I mean type hints, not annotations)

istvan15:04:36

which one is not used?

Drew Verlee15:04:56

Im reading the HN comments on https://blog.skyliner.io/fourteen-months-with-clojure-beb8b3e4bf00 Which you can find here: https://news.ycombinator.com/item?id=14006242#14011870 and their is a specific complaint that inexperienced clojure devs are more likely to create a single global state then inexperienced devs in other languages. Also that this single application state is bad: > I know Python doesn't come with atoms, but you could certainly stick the whole application state in a global variable. You wouldn't though if you're a working programmer with a modicum of experience on your first Python project. Do people just see some new idioms and forget everything they already knew about programming? Isn't a single application state what Om.Next does? Is the complain about how its done? Or i'm I missing something. I thought a single DB was a very common and reliable pattern in clojure because it put all the real state in one place and made sure your changes were more transnational.

lvh15:04:30

@istvan The problem isn’t that it isn’t used; the problem is that it annotates with CBORFactory but doesn’t import it

tbaldridge15:04:54

Yeah, I have to disagree with the whole one atom is bad thing.

istvan15:04:21

@drewverlee it matters if you have atomic reference in the language and you put the global state or you have python where everything is global and there is no atomic reference 😉

tbaldridge15:04:31

From what I understand, even Datomics transactor works that way

tbaldridge15:04:13

And normally Clojure programs use pure functions to mutate that state.

istvan15:04:09

my favorite python programming question for python programmers is the following:

istvan15:04:12

def addList(val, list=[]):
    list.append(val)
    return list

addList(10)
addList(10,[])
addList(10)
addList(10)

istvan15:04:27

please tell me what are these going to print out and why 🙂

istvan15:04:31

90% failure rate

Drew Verlee15:04:16

its because the list=[] isnt doing what you think

istvan15:04:27

drewverlee for one

lvh15:04:17

[10], [10], [10, 10], [10, 10, 10] when evaluated in that order

lvh15:04:40

(note: please don’t ask gotchas as interview questions unless you can demonstrate they’re predictive (and they’re probably not))

istvan15:04:49

but it is also highlights why idempotent functions are important 🙂

istvan15:04:13

lvh this is not a gotcha, this is a source of pretty serious bugs in production

istvan15:04:22

and this is by design

istvan15:04:37

if you are not aware of it you cannot write reliable code

lvh15:04:01

okiedokie

istvan15:04:35

and if cannot write reliable code you cannot deliver mission critical systems and my company is in the business of delivering mission critical systems (but we do not use python 🙂 )

Drew Verlee15:04:49

So is the real complaint isn't having global mutable state, its that you don't have good tools to deal with it?

Drew Verlee15:04:51

Scratch that, the complaint is that when people write bad code in clojure its harder then usually to figure out whats going on.

lvh15:04:57

Is there a way to get core.match to only be required at compile time? I’m trying to avoid e.g. org.objectweb.asm.* being in the resulting uberjar; that is pulled in tools.analyzer.jvm, and I think it should only be required at compile time (but i’m happy to be wrong about that)

lepistane16:04:53

i watched clj talk on clojureTV about java9 modules ( https://www.youtube.com/watch?v=4fevIDAxQAM ) i feel concerned could someone maybe shine little bit of light on the topic? are modules really a problem that affects us deeply? Will at some point clojure have to let go of it's unique philosophy to still be able to run on JVM? (btw i am beginner)

lvh16:04:36

while it’s pretty clear oracle wants modules to happen, they don’t get to comically break the ecosystem

lvh17:04:27

is there something weird about instant? that would make removing clj sources (in an :aot uberjar) fail?

Caused by: java.io.FileNotFoundException: Could not locate clojure/core_instant18__init.class or clojure/core_instant18.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.

dthurn17:04:32

question: does figwheel work for clojure, or is it clojurescript only?

qqq18:04:27

I have a list of items. Each is of the form [a b c d e] What is the fastest (runtime) way to create a 4- level map of the form {a {b {c { d e}}}} ? There's group-by, but it only does it 1 level.

qqq18:04:17

@tbaldridge: reduce + assoc-in ? this is performance sensistive

lvh18:04:28

@dthurn Pretty sure it’s ClojureScript only. Not sure what it’s even mean for clojure

lvh18:04:56

@qqq no, assoc-in knows how to build new maps

lvh18:04:58

just try it

qqq18:04:34

I have a list of [a1 b1 c1 d1 e1] [a2 b2 c2 d2 e3] [a3 b3 c3 d3 e3[ .... with assoc-in, I'd have to use reduce

qqq18:04:41

how else does it process the entire list ?

tbaldridge18:04:33

yes then assoc-in + reduce

tbaldridge18:04:03

if its too slow you can sometimes replace assoc-in with a macro

tbaldridge18:04:28

@lepistane no reason to cross post between channels. Most of us hang out in both this channel and #beginners

dthurn18:04:20

Well, I was hoping for some figwheel-like way to auto-reload files in my clojure application when I modify them. The figwheel workflow is pretty great.

schmee18:04:24

it is not auto-reload but it simplifies reloading clj code a lot

dthurn18:04:20

it looks like I could maybe get what I want by hooking that up to a filesystem watcher

danielsz19:04:57

Have a look at system. It does what you want. https://github.com/danielsz/system

dthurn18:04:33

although figwheel also avoids reloading code with warnings, which is very useful

scknkkrer18:04:09

Guys, I need a mentor. Really successful person who wants to grow another successful person. I am in Turkey, but my English is not really bad. I want to become a professional.

scknkkrer18:04:39

Is there anyone to guide me ?

qqq18:04:37

pick an open source project; start contributing patches, people will review your code

scknkkrer18:04:40

I don’t have time to weste. I need a mentor to guide me to the right way.

qqq18:04:17

then hire someone as a tutor

scknkkrer18:04:28

Yes, I need it. 😄

scknkkrer18:04:38

Do you know someone ?

qqq18:04:52

check the #jobs channel -- this is off topic here

scknkkrer18:04:56

Zach Oakes Here ?

emccue19:04:47

What's the best way to make a macro in one namespace have reference to a function in that namespace, regardless of where it is called

emccue19:04:48

Something like (defmacro a (b) (...Replace all symbol K with a call to C, a function defined in this namespace...)

emccue19:04:48

Like replacing all instances of + with a function package.core/add-ten

moxaj19:04:45

@emccue syntax quoting will namespace qualify symbols, isn't that enough?

emccue19:04:05

No, because it will namespace qualify ALL symbols

moxaj19:04:23

is that a problem?

emccue19:04:27

And I'll get clojure.core/+ passed into my functions

emccue19:04:45

Where I only want '+

moxaj19:04:57

use ~'+ then

emccue19:04:20

But the + is in a user supplied form

emccue19:04:48

So if I had the [body]

emccue19:04:14

Everything is already quoted

moxaj19:04:34

could you show an example signature with the expected return value?

emccue19:04:41

Sure one moment

emccue19:04:40

keep in mind that I am fairly new to this

emccue19:04:36

right now Im just doing simple symbol substitutions, but I want a more robust way of replacing function calls

mobileink19:04:12

just make it explicit? or wrap stuff in let to bind the sym? (let [+ package.core/add-ten] ...). (untested, guessing from memory 😉 )

emccue19:04:01

yeah, the problem there is that clojure complains if I reassign certain symbols

emccue19:04:35

I dont want to generate warnings for the user

emccue19:04:36

though im not sure if that applies in a let block

mobileink19:04:33

or "binding" or some such. i've done this sort of thing but it's been a while. pt being i don't think you need to crawl the input if you just want to rebind some syms.

emccue19:04:40

My other question would be how to bundle this into a library

emccue19:04:57

right now im just running off of the "app" template from leiningen

emccue19:04:25

which is fine, but the end goal is to have something I can just include in a project

mobileink19:04:48

clojure complaining about symbol rebinding is not unusual. you can use "refer-clojure" to deal with that.

moxaj19:04:33

@emccue here's my take on what I believe you're trying to do: https://gist.github.com/moxaj/da60985e609916361a550a5f130df11f

emccue19:04:45

clojure.walk is a good tool, so I thank you for showing me that

emccue19:04:00

but as far as keywordizing the macro, that misses the mark

emccue19:04:41

Im trying to support the functions in a literal copy paste way

moxaj19:04:23

(edited for a simpler solution, handles t -> true)

moxaj19:04:33

what do you mean by your last sentence

mobileink19:04:39

if you understand abstract algebra, and you're bordeline insane, you can study the code behind . https://github.com/mobileink/lab.clj.polymorphism/blob/master/src/clojure/multimodels/examples.clj it demonstrates among other things how to make the same group multiplication operator work for the 2 basic groups (+, 0, N) and (*, 1, N+), using clojure's binding ops.

emccue19:04:53

and im gonna be honest

emccue19:04:55

`((replacements expr expr) @exprs)

emccue19:04:00

I have no clue what that does

emccue19:04:20

the difference between ', `, , @ is lost on me right now

emccue19:04:30

i know ' does a syntax quote

moxaj19:04:34

single quote is "quote"

emccue19:04:39

and ` does a quasiquote

emccue19:04:43

and ~ unquotes

emccue19:04:51

but ~@ is completely foreign

moxaj19:04:56

~@ is unquote-splice

emccue19:04:51

and quasiquote and unquote have some wierd behaviour in clojureland that I have yet to reconcile in my head

noisesmith20:04:30

@emccue it's well documented - we call it syntax-quote and it always qualifies symbols https://clojure.org/reference/reader#syntax-quote

emccue20:04:00

Okay I'll read up

emccue20:04:07

Thank you for the reference

lxsameer20:04:37

hey guys, is there any protocol to implement a channe l?

noisesmith20:04:43

ReadPort, WritePort, Channel

noisesmith20:04:29

(well, maybe just two if you are read-only / write-only I guess)

qqq21:04:08

oh man, (empty x) and (empty? x) means very different things when x = nil

mobileink21:04:26

different than what?

mobileink21:04:31

they always mean different things. one is an expression, the other is a predicate.

qqq21:04:09

yeah; and I have now learned the difference

qqq21:04:07

(empty? (transient {}))
throws an exception -- so how do I check if a transient is empty?

mobileink21:04:43

dammed if i know. simple_smile

mobileink21:04:05

a clojure wart.

mobileink21:04:00

maybe try

(empty? (persistent (transient {})))

qqq22:04:24

@mobileink : that explains it; thanks!

mobileink22:04:58

(not that i have the slightest understandin of this stuff.)

noisesmith22:04:52

@qqq - turning a transient persistent is just a single bit flip, use persistent! with empty?

bcbradley23:04:51

clojurewest was a thrill!