Fork me on GitHub
#clojure
<
2017-12-30
>
jeff.terrell00:12:58

FWIW, git has some affordance for ignoring whitespace changes—see the -b and -w options to git diff, for example. (GitHub and GitLab have the same feature in diff view, although it's not always obvious how to toggle it.) That's not meant to disagree about alignment though.

vemv01:12:20

"Note: there is no support for inline value specification, by design." https://clojuredocs.org/clojure.spec/keys wondering if someone has a cool keys drop-in that supports them (I agree with the spec principles btw... but sometimes I just know what I'm doing ;))

vemv01:12:14

Not excessively hard to implement... syntax would be :req [int? ::foo ::bar ::baz] where int? means a predicate for the following keyword, :foo. Similar to metadata syntax (note that kws aren't IMetas) will give it a shot someday

arrdem01:12:48

One day we'll all use fully AST aware editors and argument / binding alignment will be a UI option 😛

rymndhng05:12:25

has anyone used refs and STMs in production code? I’m struggling to sea use case where it is favorable to use over one big atom

arrdem05:12:59

If it's possible to partition the problem you're trying to solve into several effect scopes (say several queues such that most STM is only between two of N queues), the STM tools Clojure includes can be useful and meaningfully reduce contention between multiple threads.

arrdem05:12:07

In general they tend to be rarely used especially in library code because that's a super application-specific property which requires global knowledge of your system and its state update behavior to leverage.

arrdem05:12:06

It's also easier (makes fewer fragile assumptions) to structure your application as a bunch of computation followed by a big-bang swap! using some comparatively cheap state merging function.

seancorfield06:12:35

@rymndhng FWIW, we have 75,000 lines of Clojure and only a small number of atoms and a few agents. We have no refs. I think that out in the real world, STM is rarely used -- but can be very valuable in the (very) few edge cases where it is actually appropriate. So, yeah, what @arrdem said 🙂

qqq06:12:27

actually, I can't think of a single situation where I have seem STM used; most concurrency problems seems solvable via: build new data structure, do a pointer swap at the last moment

seancorfield06:12:23

i.e., atoms, yes.

seancorfield06:12:41

I wonder if the rise of core.async headed off a lot of what refs might have otherwise been used for?

rymndhng07:12:49

thanks for the thoughts folks.

dominicm09:12:02

@rymndhng one place I do see STM constructs (although not many) is clojurescript.

fmnoise11:12:47

and cljs doesn't support it 😕

rymndhng19:12:03

^ are the two comments not contradictory?

fmnoise19:12:57

I think @dominicm meant that it would be better to have STM in cljs than in clojure 🙂

fmnoise19:12:35

and sad but true it's not supported there

dominicm09:12:09

I have a question, if I have a project based on clj cli, how can I build a jar from that?

dominicm09:12:40

I wondered if I needed to collect up the classpath, and add each one to the fat jar.

qqq09:12:28

are you looking for lein uberjar, or am I misunderstanding the question?

dominicm10:12:32

@qqq clj cli, I'm looking to replicate that

hansw11:12:10

I think leiningen can do this for you

dominicm11:12:17

I'm not using leiningen though 🙂 I'm trying to do it without leiningen.

hansw11:12:59

You don't want to use a build tool?

hansw11:12:56

then there is no hope 🙂

viesti15:12:33

@dominicm I think you could trace what Leiningen does, my first guess would be to figure out how to get the list of jars and copy their contents into a new zip/jar https://github.com/technomancy/leiningen/blob/master/src/leiningen/uberjar.clj

dominicm15:12:29

That's what I've started to look at @U06QSF3BK. It's all quite roundabout, I'm surprised there's no library to go from classpath->jar.

viesti15:12:25

Yes, and there are a lot of options on that route. In portkey (https://github.com/portkey-cloud/portkey) Cristophe Grand did a tree-shaker that packages the minimum needed deps starting from a var :)

viesti15:12:48

thinking that such a deployment package creation from inside the repl could be quite awesome (like push the thing into AWS/Lambda, or into a container)

dominicm15:12:58

@U06QSF3BK if this is something of interest to you, I've just got a jar that contains clojure & a helloworld.clj built, and I don't think it will be difficult to hook in tools.deps.alpha to this system.

hansw11:12:45

hmm ok, so I have a java.util.Iterable<Map<String, Object>> representing a huge file and I know i can treat this as a clojure seq, and I have done so succesfully, for example by using take and processing the item.

hansw11:12:03

think of the file as a big csv file (except it's json)

hansw11:12:29

I can't load all of the file's contents in memory, so i have to take slices.

hansw11:12:07

How would one take n items from the seq until it is empty?

hansw11:12:07

Or, I should say 'returns no more items'

dominicm11:12:59

@hans378 I think partition-all is lazy, so you could use that.

hansw11:12:33

@dominicm i'll check that out

mindenaaron13:12:38

Hello All! I have a very frustrating problem, because it should be obvious, but I cannot pass. How can i set a scheduler (exactly hara.scheduler) to a smaller period than 1 second. "/1 " means 1 second, but "/0.5 " doesn't work. Even if i set the "truncate" parameter to :millisecond, cannot use milliseconds. The documentation also silent about the topic. Do not I understand the capabilities of a scheduler? O.o Happy New Year to our glorious Community!

danboykis14:12:40

clojure's functions are java.lang.Runnable

danboykis14:12:54

so you can just pass a function to scheduleAtFixedRate

mindenaaron14:12:45

I can also use core.async, but i really wanted to use a real clojure scheduler, but cannot understand why I am not able to schedule something with milliseconds. Thanks anyway. 🙂

mindenaaron14:12:59

At first I just want to execute a function periodically, it is a few lines with core.async.

taylor14:12:38

@mindenaaron there’s this wrapper over the Java executor service stuff too https://github.com/overtone/at-at

mindenaaron14:12:45

Yes, there are several clojure scheduler. i did my research and choosed hara.scheduler

fmnoise19:12:37

manifold is also worth trying

vemv14:12:05

re STM, it depends of the application type. most of us write server-side web backends, STM is almost inherently unsuitable for that (b/c you want servers to scale horizontally, and STM is per-server) but that

vemv14:12:27

's not the only type of application out there!

vemv14:12:55

STM seems a good fit for simulations, desktop apps, games maybe

mbjarland15:12:42

assume I have the following data structure:

[{:delim ["┌─" :F]} {:align \─} {:delim [:F "─┬─"]} {:align \─} {:delim ["─┬─"]} {:align \─} {:delim ["─┐"]}]
what would be the most idiomatic / concise way of counting the number of :Fs? I do a:
(count (keep (comp #(some #{:F} %) :delim) data-structure))
now, but I have the distinct feeling I’m missing some more direct route

mbjarland15:12:23

and nathan, I assume specter can do this more succinctly but I’m trying to avoid dependencies in this particular scenario

souenzzo16:12:24

@mbjarland it's trivial with #specter (count (select (walker #{:F}) data)) (walker afn) will recursively "walk" in your data, search by something that satisfies afn. walker is a "navigator", then you need to say "what to do with this data" In this case, I use select, that just return a list of "what navigator find". But you can use (setval navigator :new-value data) to REPLACE "what navigator find", for example.

nathanmarz17:12:14

@mbjarland best way with specter is (count (select [ALL :delim ALL (pred= :F)] data))

nathanmarz17:12:59

walker is not appropriate for this use case, as it traverses parts of the data structure you don't care about (which reduces performance and can cause bugs)

bronsa17:12:15

he explicitely said he's not looking for a specter solution, I'd say what he has is not bad in pure clojure

nathanmarz17:12:17

the highest performance way with specter is something like (transduce (map (constantly 1)) + (traverse [ALL :delim ALL (pred= :F)] data)), which doesn't materialize any intermediate data structure

nathanmarz17:12:25

@bronsa if I see bad specter guidance, gotta correct it ;)

mbjarland18:12:21

@bronsa @nathanmarz and @souenzzo thank you. If I end up pulling in specter I know what to do now. Indidentally: (count (select [ALL :delim ALL (pred= :F)] data)) is not that much terser (not at all in fact, though arguably easier to grok) than my original pure-clojure: (count (keep (comp #(some #{:F} %) :delim) data)) so I guess I’ll consider the clojure version decent (as a side note, the fact that you can use specter as a reference point for terseness I think speaks to the beauty of specter)

qqq23:12:50

is there an official clojure grammar somewhere? somethng detailed enough to write an actual production clojure parser from it ?

tbaldridge23:12:25

EDN is close, but there are differences

andy.fingerhut23:12:04

tools.reader is a Clojure implementation of a reader that can read Clojure source code. Many tools that analyze Clojure source code use it.

andy.fingerhut23:12:51

It isn't a grammar, but an implementation in code of a reader. Unlike the one in clojure.core (implemented in Java), it is implemented in Clojure. Not sure if that makes it any more useful for your purposes.

arrdem23:12:38

Yeah. I've written a bunch of clojure-like grammars and own most of the git-blame for the clojure.g4 you'll find around. Don't go down that road unless you have a good reason to, tools.reader and the ecosystem around it (rewrite-clj etc.) is very good.

arrdem23:12:34

Getting a Clojure-like grammar right is surprisingly hard 😕

andy.fingerhut23:12:02

Just a side note: The most official docs for Clojure syntax on http://clojure.org do not allow symbols that the Clojure reader allows in symbols. For example, on this page: https://clojure.org/reference/reader you will find no mention that the character '=' is allowed in symbols, but it is allowed by the implementation. Clojure is in many ways defined by its implementation, not some English spec.

arrdem23:12:22

Yup. To the point that there's some reader behavior such as : being legal inside of keywords that Alex has said is unintended but won't be removed for compatibility.

arrdem23:12:31

There's an antlr-grammars repo around which contains what purport to be grammars for a variety of languages and data formats. I did a bunch of work on the clojure grammar in that repo at one point.

arrdem23:12:53

.g4 is the antlr4 file extension

andy.fingerhut23:12:11

I found it via a quick Google search after asking: https://github.com/antlr/grammars-v4

arrdem23:12:29

the parser for my Ox language is written in antlr4 using a derivative of the clojure.g4 grammar and I know https://github.com/venantius/glow uses an unattributed copy of clojure.g4 as well.