Fork me on GitHub
#beginners
<
2020-04-27
>
Bhougland01:04:52

I am playing around with the prepl and sending highlighted sections from kakoune to the repl for eval. How can I use libraries like pretty or glow with it?

Bhougland01:04:15

I want better formatted output

subsaharancoder04:04:49

what is a quick and easy way to convert this:

["Host: " "User-Agent: ExampleBrowser/1.0" "Accept: */*"
 "Content-Type: application/x-www-form-urlencoded" "Content-Length: 21"]
into a map with keys and values:
{:Host "" :User-Agent "ExampleBrowser/1.0" :Accept "*/*" :Content-Type "application/x-www-form-urlencoded" :Content-Length "21"}

Chris McCormick04:04:02

there is probably a simpler way but here's something you can use (into {} (map #((juxt (fn [x] (keyword (first x))) second) (clojure.string/split % ": ")) vector-of-header-strings))

Chris McCormick05:04:27

here's a slightly more concise version (into {} (map #((juxt (comp keyword first) second) (clojure.string/split % ": ")) vector-of-header-strings))

jaihindhreddy05:04:57

An alternative that avoids juxt

(require '[clojure.string :as str])
;; coll is the input here.
(->> (map #(let [[k v] (str/split % ": ")]
             [(keyword k) v]) coll)
     (into {}))

👍 8
subsaharancoder05:04:31

@U883WCP5Z small nitpick the regexp should be #": " 🙂

subsaharancoder05:04:40

thanks for the solution

jaihindhreddy05:04:01

My bad 😅. I always expect str/split to be able to split by string and character.

Steiner08:04:51

anybody can help? does my lazy-seq program has any problem?

(def primes
  (letfn [(primes-parts [part] 
            (lazy-seq
             (when-let [[p & xs] (seq part)]
               (let [cannot-div? #(not= 0 (mod % p))]
                 (cons p (primes-parts (filter cannot-div? xs)))))))]
    (primes-parts (iterate inc 2))))
here
(count (take 2000 primes)) ;; 1789

hindol09:04:51

Works on my system,

(count (take 2000 primes)) ;; => 2000

hindol10:04:59

Though I see your problem. It is possible to hit StackOverflowError.

(count (take 10000 primes)) ;; StackOverflowError
And since the def is cached, subsequent calls to count will return values till the stack overflow, so you will see the behaviour you are seeing.
(count (take 10000 primes)) ;; 4153

Steiner10:04:59

is there any way to avoid it

hindol10:04:32

The logic in your function is dense and I might be wrong, but I think you have the (iterate inc 2) running through an increasing number of filters, so after you have calculated 1000 primes, you have 1000 filters piled up. No, not unless you change your logic.

hindol10:04:06

Did that make sense?

Steiner10:04:51

I think there must be better generator for primes

hindol10:04:08

Yes, there is. One that Rich Hickey wrote.

Steiner10:04:31

can you show me that,or link

Steiner10:04:50

wow,your primes is so quick

Steiner10:04:06

did you write euler-project too?

Steiner10:04:48

here is my sieve,i think it hits the same problem

(defn divsible? [a b]
  (zero? (mod a b)))

(defn sieve [stream]
  (lazy-seq
   (cons (first stream)
         (sieve (filter #(not (divsible? % (first stream)))
                        (rest stream))))))
(def primes (sieve (iterate inc 2)))                    

hindol10:04:52

No no, I am just solving some problems from project-euler.

Steiner10:04:50

have you solve any other problem in euler-project

hindol10:04:07

I have solved close to 130 I think.

Steiner10:04:23

wow,where is your github for euler?

hindol10:04:18

The same one that I shared. I don't share solutions in the git repo though.

hindol10:04:30

It is just a collection of helper functions.

hindol10:04:47

What's your euler alias?

Steiner10:04:52

so do i ,for i always forget that

Steiner10:04:20

I'm not sure where are you from,may i ask

hindol10:04:36

Here is my key, you can add me. 68392_rXI1S5R6kIUPxgK21FELKaRqAJ8RVBVR

hindol10:04:41

I am from India.

hindol10:04:22

Nice. Add me when you get the time.

Steiner10:04:10

sure,but here I have network problem,so that i don't like github,but gitee made by we Chinese

hindol10:04:38

That's my key for project euler.

Steiner10:04:40

do you know how to make private message in slack,we talk too much useless words

hindol10:04:03

By the way, please read this section: https://clojure.org/reference/java_interop#primitives In short, Clojure uses boxed math most of the time and they are terribly slow. You will need to do primitive math and sometimes need to create Java primitive arrays to solve most of the problems fast.

hindol10:04:56

It's in a thread, so that is okay.

Chris K09:04:43

I've read articles online where they said that if Clojure (or Lisp in general) was well optimized, it can run as fast as C. At first it was a joke maybe because I've always heard that there is no faster language than C and always had this thought that Lisps are not the fastest (maybe this is due to my lack of knowledge), but can anyone verify this? I've even heard that there is a interpreter written in Lisp that can read 30000 lines of code per second too and that sounds pretty darn fast.

teodorlu11:04:15

That depends a whole lot on how you write your programs. Using Neanderthal or TVM, you can achieve great numerical performance. Also hard to decouple from the question of "is idiomatic code fast"? This is typically what you will hear from C or Rust people. https://neanderthal.uncomplicate.org/ https://github.com/techascent/tvm-clj http://clojure-goes-fast.com/

Chris K14:04:35

thxs for a great answer

noisesmith15:04:14

This is something that got argued about a lot on usenet back in the day. There are cases where fortran still performs better than c for example (where the c advocates retort that using a fortran lib if it's faster is idiomatic in c). Similar for assembler macros.

noisesmith15:04:52

I think the cases where lisp or java are faster than c come down to their GC performing better than naiive usage of malloc, and on newer hardware that difference goes away because C uses cache lines better.

noisesmith15:04:58

if you are looking for high level languages that rival c in performance (as your main criteria) check out OCaml (more high level / well designed, great perf if you don't need threads) or Rust (just plain fast, but less cleanly designed)

Steiner11:04:06

here,I want to optimize my solution for project euler,in problem 4 and 9,can anybody help me

(defn solution-4 []  ;; this solution has generator too many repetitive nums
  (reduce max
   (for [n1 (range 999 99 -1)
         n2 (range 999 99 -1)
         :let [num (* n1 n2)]
         :when (is-plalindrome? num)]
     num)))

(defn solution-9 []  ;; this solution solves too slow
  (let [rng (range 1 1000)]
    (first (for [a rng
                 b rng
                 c rng
                 :when (and (= 1000 (+ a b c))
                            (= (* c c)
                               (+ (* a a) (* b b))))]
             (* a b c))))

Alex Miller (Clojure team)13:04:43

the big thing here is remove boxing as much as possible (boxed math is about 100x unboxed math)

Alex Miller (Clojure team)13:04:27

(set! *unchecked-math* true)
(defn solution-9 []  ;; this solution solves too slow
  (let [rng (range 1 1000)]
    (first (for [^long a rng
                 ^long b rng
                 ^long c rng
                 :when (and (= 1000 (+ a b c))
                            (= (* c c)
                               (+ (* a a) (* b b))))]
             (* a b c)))))

hindol14:04:14

The output of for is still a lazy seq, so the final output will be boxed right? Just clarifying. I get that the point is to avoid boxed math and not boxing entirely.

Alex Miller (Clojure team)14:04:57

you could turn the for into a loop/recur with early exit on first success to avoid that (although I don't know that it would help you much)

Alex Miller (Clojure team)13:04:00

is probably lots faster without any other more invasive changes

hindol14:04:03

Let's take a hypothetical case. We have two boxed numbers, a and b. Which of the two is faster? 1. Multiply boxed. 2. Unbox, multiply and box again.

Alex Miller (Clojure team)14:04:36

I think the implementation of 1 is 2

bfabry14:04:24

yup ^ takes the same amount of time given std dev on my machine

Jim Newton14:04:40

what is the correct way to call map to iterate over a hashmap ?

dpsutton14:04:33

(map (fn [kv] (prn (key kv) (val kv))) {:a :b}) you can just call it. also common to destructure (map (fn [[k v]] (prn k v)) {:a :b})

Jim Newton14:04:16

iI see, I need an extra set of brackets. (map (fn [[key value]] ...) the-hash-map)

hindol14:04:57

Yeah, that's because taking a sequence over a map gives you pairs.

chaow15:04:54

hey guys how do i remove a specific key from a list of maps? if have a list:

'({:a 1, :b 2} {:a 2, :b 3}) -> '({:b 2} {:b 3})

noisesmith15:04:49

have you used map?

noisesmith15:04:20

basically what you need would be a one liner, using map and a function calling dissoc

chaow15:04:32

ah i see, thanks

Michael Stokley17:04:18

is there a conventional way to avoid shadowing? for example, in python, you append an underscore to any name that would otherwise shadow.

noisesmith17:04:11

many people shadow on purpose - you can't mutate someone else's scope out from under them except by using def (which is not used in application logic, only during development)

noisesmith17:04:55

if you want a new derived value but don't want to shadow the old one, an idiom from math is x then x' then x'' etc.

👍 4
noisesmith17:04:05

which works just fine

noisesmith17:04:01

but in most cases like these I find I can safely shadow, I no longer need the old value

noisesmith17:04:12

shadowing things like key and countand val is extremely common (many don't even know that key and val are functions in core)

noisesmith17:04:42

that's a different kind of shadowing - just using the same name for an unrelated meaning

noisesmith17:04:03

and I'd never use key' to mean a key of something for example - the semantics don't fit!

noisesmith17:04:17

I'd just use k or key and assume people realize it's not the one from core

Michael Stokley17:04:43

fair enough. in some inner scope there may not be any real stakes if you shadow, i guess.

noisesmith17:04:11

right - function calls inside the scope won't inherit your shadowing, there is little danger of invisible breakage

noisesmith17:04:30

and in idiomatic clojure nearly all our bindings should be local to some small inner scope

hindol18:04:31

reify does not accept return type hint on the argument vector? I can only make it work when I place the hint before the method name.

Alex Miller (Clojure team)18:04:11

did you read the docstring?

hindol18:04:54

I just grepped for ^ on ClojureDocs. But now that I read the whole docstring, I see it. Many other forms support hint in both places and I read hint on the arg vec is preferred. I hoped that would work.

Alex Miller (Clojure team)18:04:37

you can just (doc reify) in your repl too

Alex Miller (Clojure team)18:04:57

some parts of Clojure related to interop mimic Java's syntax by putting the return type hint before the method

Kelvin Mai19:04:28

for a deps.edn project. how do you load a .env file?

andy.fingerhut19:04:55

I am not sure what an .env file contains, or how you load it in a project that is not a deps.edn project. What other kind of project loads one?

Kelvin Mai19:04:21

I'm trying to use System/getenv to get the environment variables. but it only reads global environment variables instead of ones in my project

Lu21:04:03

Its worth to look at https://github.com/juxt/aero. Define all you need in your deps.edn by turning on profiles like dev or prod .. I find that having all your variables declared in your deps.edn simplifies things a lot .. especially when you’re trying to understand things like “oh I wonder what port is env.PORT in prod”

hindol22:04:23

.env comes with its own helper executable that reads and exports those variables. If you run java from the same shell, it will see those variables, otherwise it won't.

noisesmith19:04:29

.env is a tooling convention for things like docker, I've found that in some cases I can use env $(<.env) clj to get a repl with those settings applied

noisesmith19:04:39

depending on the values in your .env, you might need to set a custom IFS too

noisesmith19:04:01

env is a unix command that takes k/v pairs for env vars and then launches a command using those env vars

hiredman20:04:38

the idea that .env files are standardized make me so mad

hiredman20:04:47

env is the worst

noisesmith20:04:09

and I don't think .env files are even meant to work with env

noisesmith20:04:26

they just happen to, in many cases

hiredman20:04:34

good, ditching env could maybe make things better

hiredman20:04:10

having spent sometime working on shell scripts that do things like dump the environment using env and then trying to reload it, nothing works, everything is broken, and it peeves me greatly

Nassin22:04:26

better to just use files 😉

noisesmith22:04:14

problem is there's nothing that provides environment variables from a file without some other infrastructure like docker

noisesmith19:04:00

clj itself has no mechanism to set env vars, as that's something a stock jvm can't do, it's non portable

noisesmith19:04:34

(there are third party libs that can set in-process env vars, and eventually someone might make a clj task that does it... but support would be on a per OS basis)

noisesmith20:04:19

@kelvin.mai002 also, if it doesn't need to be env vars (eg. if it could be system properties instead, which have a similar API in a running vm) those can be set with jvm args which you can define in a deps.edn alias

didibus21:04:43

Ya, if you need to set configs in deps.edn, just use Jvm properties instead of env properties

hindol22:04:13

Ha! Often I reply to a thread then come out and see that the same thing has been answered outside.

theequalizer7322:04:01

Hi, I have a question about ring sessions. Do I have to assoc-in the session values everytime I render a template in my web app?

noisesmith22:04:49

you should only need to touch the session if you want to add or remove data for that user's session

noisesmith22:04:19

for the in-memory session the data won't last across reboots, for the cookie store all the normal rules for cookies apply

theequalizer7322:04:14

Oh great! I thought I had to assoc-in the values everytime I was changing pages! Thanks!

noisesmith22:04:20

the session is per-user not per-page

theequalizer7322:04:58

I was expecting it was like that, as it is in flask sessions in Python

noisesmith22:04:44

(as long as yo aren't eg. using a reverse proxy to make the page show up as coming from different hosts...)