Fork me on GitHub
#beginners
<
2018-10-17
>
leandrotk10000:10:03

Does anyone know another approach to this problem? https://github.com/LeandroTk/learning-functional/pull/7#discussion-diff-225541000R6 Comment there 🙂

caio.cesar.g.souza00:10:03

You also can use partial like this:

(defn less-than? [n] (partial > n))
then use in your filter
(filter (less-than? n) lst)
I don't know if it is a better approach... But is a alternative 😄 also you can use (filter #(> n %) lst) even smaller! 😊

leandrotk10001:10:18

I really like this second approach using this type of anonymous function!

caio.cesar.g.souza01:10:02

It's a macro, he actually expands to (fn ...) at the end... look https://clojure.org/reference/reader#_dispatch

andy.fingerhut00:10:13

I am not sure I agree with this comment: "Usually filter and map use their aux fnx as a new function instead an anonymus fn." If a function is very small, especially a one-liner, and it needs to use the values of symbols from the environment, anonymous functions are perfect for the job.

andy.fingerhut00:10:41

If you want, you can give them a 'local name', e.g. like this (fn my-local-name [args] ... body ...). A potential advantage there is if that function ever turns up on a stack trace from an exception being thrown, you have a readable name to see for it.

mfiano01:10:44

Is it a limitation of the JVM that Clojure stack traces don't include local variables and arguments passed to them like Common Lisp does?

seancorfield02:10:20

@mfiano By the time you get an exception and a stacktrace, not much is available. From an exception (technically, from a Throwable), you can get an array of StackTraceElement which you can see here https://docs.oracle.com/javase/8/docs/api/java/lang/StackTraceElement.html

mfiano02:10:33

Fair enough. Thanks. I admit, that's been the biggest hurdle so far. Stack traces in CL are inspectable, where you can view locals, even change them, and jump around the stack and continue.

seancorfield02:10:26

There are Java debugging libraries that provide access to the actual stack frames (and local variables) but you need to break exception when the exception happens, not where it is caught.

seancorfield02:10:53

(and I'm not familiar with those sorts of tools -- I really don't like Java step debuggers)

mfiano02:10:06

Yeah that's probably a bit too much for someone with no prior Java experience anyhow.

seancorfield02:10:58

If you're using CIDER in Emacs there is debugging functionality around breaking-on-exceptions. I expect Cursive also provides that (being a Java IDE).

seancorfield02:10:34

http://docs.cider.mx/en/latest/debugging/ shows that you can walk through stack frames and view local variables

dfcarpenter02:10:21

I am having trouble running the repl in cursive. I keep getting an error with java.xml.bind

Error occurred during initialization of boot layer
java.lang.module.FindException: Module java.xml.bind not found

Process finished with exit code 1


ghadi02:10:16

is this your app throwing the error, or cursive?

ghadi02:10:45

jdk11 removed the java.xml.bind module and something is trying to look for it

dfcarpenter02:10:34

Ahh I am using a luminus web template. The error is thrown when I start the repl so I assume its my app throwing the error

rahul08032706:10:46

@ you can try adding [javax.xml.bind/jaxb-api "2.3.0"] to your project dependencies if you want backwards compatibility to java versions less than 11.

jumar09:10:25

btw. this happens with JDK 9 too

dfcarpenter02:10:56

I did switch from jdk 10.0.2 to 11 ( I was having issues which lein which were resolved )

leandrotk10003:10:27

Does anyone know how to solve this problem using filter function? https://github.com/LeandroTk/learning-functional/pull/10/files

jesse.wertheim03:10:45

@leandrotk100 two approaches come to mind, but I'm not sure how much I want to spoil - how much of a nudge in the right direction are you looking for? is there some part you're stuck on?

andy.fingerhut04:10:42

I would say that you should not get hung up on the word "filter" in the name of the problem, and let yourself use any Clojure functions. The Clojure function 'filter' takes a predicate that examines each input element independently of the others, with no information given to it about its position in the input collection.

cybersapiens9705:10:44

i'm reading the guide about spec on clojure website, and i'm wondering... there is s/fdef for spec'ing functions, ok. But there is a way, to take functions who has been defined with :pre and :post conditions, that uses s/valid so specify it's inputs and outputs, and use them to generate a s/fdef ? because this process would have some repetition...

cybersapiens9705:10:38

well, nvm, if you need to specify a function to use it as input, then it might be a general case, and you wouldn't have to write the function before...

jr0cket11:10:45

Am I the only one that thinks that using s as a namespace alias for spec is really confusing. I dont really get why we cant use spec as the standard namespace alias. Using spec makes it so much easier to search in projects and navigate around a codebase.

joelsanchez12:10:34

I use the spec alias too but I don't care if others don't...as long as it's not in my project?

joelsanchez12:10:42

tbh spec is quite recognizable...what else could (whatever/def ::product (whatever/keys :req [::price])) be? 🙂

kouvas15:10:17

best way to format multi line strings/text files using variable holders? can I do something similar to this python code? 'Hey {name}, there is a {errno} error!'.format(name=name, errno=errno)

llsouder15:10:00

@kouvas

(format "Hey, %s, there is a %d error!" name errno)

andy.fingerhut15:10:23

I don't recall anything built into the language that lets you put something like {name} in the format string

andy.fingerhut15:10:54

There may be some library that does so, but I don't know it. If so, hopefully someone else can chime in.

seancorfield15:10:59

@kouvas Take a look at the Selmer library which brings Django-style templates to Clojure perhaps?

seancorfield15:10:32

https://github.com/yogthos/Selmer -- we use it very heavily in production at work.

alexmiller15:10:23

you can use the built-in Formatter stuff from Java too

jarvinenemil15:10:36

anyone knows a refactoring tool which lets me change the name of my project name in Emacs?

jarvinenemil15:10:25

(example: right now its danger.core.integrations.what but I want it to be coder.core.integrations.what)

jarvinenemil15:10:40

it will do the job thanks 🙂 , was thinking of some good refactoring tool for Clojure though. I will check out clj-refactor.

joelsanchez16:10:31

I'm not an Emacs user, but I wouldn't trust either Cursive or Emacs to do this properly

joelsanchez16:10:39

be careful with .git folder

oliv16:10:49

hey guys, let-me bother you (AGAIN) I have to save an object on database and would like to verify if the object is valid or not before save ( maybe this flow is not the correct on functional way ) so what I have is something like that

-- order namespace 
  (defn build [params] (map->Order params) )
  (defn valid? [order]  "gonna check if the order has the proper values")
  (defn save [order] (order-repo/insert order))
so on my controller/handler what I’m doing is
(POST /orders request 
   (let [order (order/build (:param request))]
      (if (order/valid? order) 
           (order/save order)
          (order/errors order)))
my question is, is the correct way to do this thing ? should I put the validation inside the save ( not sure about that ) how you guys does this kind of CRUD apps ? cheers

chris54716:10:34

That's looks good to me, you're pulling out the functionality into distinct units rather then conflating them in the save function.

oliv16:10:27

I’m using monads to chain everything , my real code is not exactly the same, but you get the idea

chris54716:10:08

Ie, (save ..) isn't responsible for checking if the order is valid or not. You could make a function at a higher level that wraps the (if ..) call if you resue that exact statement many times

oliv17:10:03

yeah, exactly

oliv17:10:14

thanks for your time @

maniac19:10:26

Hi everyone! My first question here 🙂 I want to get a list (or set) of hosts from a structure like this to check for existence of a specific host:

{:spec {:rules [{:host "..."}
                {:host "..."}
                {:host "..."}]}}
And my straightforward solutions is
(let [hosts (into #{} (map :host (get-in data [:spec :rules])))]
  (hosts "my-host"))
Is there a better way?

dadair19:10:37

You can use “some” to iterate over the hosts vector to find the first match, rather than parsing the whole vector

dadair19:10:41

On phone, but something like (some #(= % “my-host”) (get-in data [:spec :rules]))

maniac19:10:31

More like #(= (:host %) "my-host) ?

maniac19:10:50

Thanks for the pointer to some!

dadair19:10:38

Yes that would be more correct!

matt.henley19:10:21

Hi fellow clojurians 👋 I’m feeling fed up with “modern” javascript development it’s become to much with a new tool/preset/framework every week to keep on top off so I started learning Elm about 18 months ago which I really enjoyed and was my first experience with FP. I’m now taking the leap into cljs and so far so good so I thought I would say hello as I’m pretty sure I’ll be here on a regular basis.

matt.henley19:10:09

I did notice there are several tools for the job in cljs as-well so I’m just wanting to check my tool-belt isn’t considered “legacy”. I’m using lein, emacs + cider, reagent and possibly re-frame going forward.

dadair20:10:58

All still considered modern!

peter.kehl19:10:29

Hello lovers of #"RegEx." I'm trying to prefix quotes and backslashes with (another) backslash. The regex #"([\"\\])" matches both a quote and an apostrophe, but $1 isn't replaced by the (parenthesised) pattern: (clojure.string/replace "a\\-\"c" #"([\"\\])" "\\$1") => "a$1-$1c". I'm expecting "a\\\\-\\\"c" instead. What am I missing, please?

manutter5119:10:38

@matt.henley I’m using the same setup (except for the editor, but I think most of my co-workers are using emacs)

matt.henley19:10:20

@manutter51 How long have you been working with clojure may I ask? I’m also seeing articles about figwheel main being the latest version of figwheel that uses clojure cli instead of lein do you believe this is this something I should worry about right now?

manutter5119:10:25

I’ve been using clojure since about version 1.2 fwiw

manutter5119:10:22

The clojure cli stuff is the new hotness, and if you want to dig into it, it’s probably worth your time. I haven’t done more than kick the tires with it so far, but I’m interested in it.

manutter5119:10:15

Most of the projects I work on have figwheel in the mix somewhere for the CLJS work, but I’m still doing everything in lein for the most part

manutter5119:10:35

@peter.kehl what output are you expecting? I know backslashes inside regex’s have a tendency to become monsters, so I tried this:

(clojure.string/replace "a\\\\-\"c" #"([\"\\\\])" "\\\\$1")
=> "a\\\\\\\\-\\\"c"

peter.kehl19:10:45

@manutter51 That works. Thank you.

andy.fingerhut19:10:19

Clojure uses different syntax for escaping inside regular strings vs. regexes.

andy.fingerhut19:10:31

Specifically because backslashes are so common in regexes.

andy.fingerhut19:10:32

I added this note in the Clojure cheatsheet section on regexes to try to convey this fact: Note: \ in #"" is not escape char. (re-pattern "\\s*\\d+") can be written #"\s*\d+"

andy.fingerhut19:10:11

user=> (def r1 (re-pattern "\\s*\\d+"))
#'user/r1
user=> r1
#"\s*\d+"
user=> (str r1)
"\\s*\\d+"

andy.fingerhut19:10:54

That last string contains 6 characters, not 8. The regex pattern also contains six characters, not 4.

peter.kehl20:10:09

@andy.fingerhut Thank you for explaining \ in regex patterns. Why does the replacement string need 4 backslashes to generate one backslash? (clojure.string/replace "ab" #"a" "R\\") Evaluation error (IllegalArgumentException) at java.util.regex.Matcher.appendExpandedReplacement (Matcher.java:1020). character to be escaped is missing

peter.kehl20:10:59

Wouldn't you expect the replacement string to act as ordinary, except for $0, $1...?

noisesmith20:10:20

@peter.kehl

Note that backslashes (\) and dollar signs ($) in the replacement string may cause the results to be different than if it were being treated as a literal replacement string. Dollar signs may be treated as references to captured subsequences as described above, and backslashes are used to escape literal characters in the replacement string.

noisesmith20:10:54

I needed to look at the source for clojure.string/replace to be sure what method it was even using though

peter.kehl20:10:10

Thanks @noisesmith. Thanks @andy.fingerhut I see your explanation in https://clojuredocs.org/clojure.string/replace#example-542692d7c026201cdc3270fe.

andy.fingerhut20:10:53

I believe the doc string for clojure.string/replace gives some clues about the different cases, depending on the types of the arguments, but sure, source code is definitive. If you see anything that looks like a mismatch between doc string and code, please do file an issue.

noisesmith20:10:09

@andy.fingerhut I guess the one detail that was missing from the doc-string was using \ to escape $, which means you need \\\\ to get \ (double escape, string syntax then substitution syntax)

noisesmith20:10:12

oh - but if I had read the doc string more carefully I would not have needed to view the source, it did indicate the right javadoc to look at

markmarkmark20:10:58

(clojure.string/replace "ab" #"a" "\\R") => "Rb"

markmarkmark20:10:12

looks like the way they handle the replacement string in Java is just strange

noisesmith20:10:04

for a replacement string, \\R is just R, because there's two levels of escaping needed

noisesmith20:10:31

clojure's own string reader would complain about it, but due to the layers, it doesn't find it there

markmarkmark20:10:32

the way they describe it in the javadoc makes sense now, but I definitely didn't get the first time I read it

noisesmith20:10:39

yeah, it's weird

noisesmith20:10:34

I forget the name, but there's a cool emacs mode that opens a string, unescaped in a new buffer, and when you save it puts the escaped version in your original

noisesmith20:10:40

it can be used recursively

markmarkmark20:10:49

it's pretty much just there so that you can put in a literal $ right? you'd think they would have just had you use $$ for a literal one. then it could have been in the same place that it handles all the other $ cases

noisesmith20:10:08

that would have made some sense ¯\(ツ)

andy.fingerhut20:10:58

If you use the regex / function version of clojure.string/replace, you can avoid that weirdness

niklos200520:10:34

hello from a starter in clojure. Could pls someone here tell me how to create a new clojure program in cursive? For example: 1. go to New file , 2. Create a new empty project etc.... [I've created one from command line with leiningen and repl but i want to see how it is gonna be created from cursive (avoiding command line)] THX!!!

dadair20:10:06

@niklos2005 I haven’t used cursive for a while, and I’m not sure how often the docs are updated, but the docs here https://cursive-ide.com/userguide/leiningen.html (see “Create a new project using Leiningen”) state that you must use the command line for now

niklos200521:10:37

@dadair Thank you very much, i will check it. I hope there is a way to create a clj project without using cmd line. Thanks again.

seancorfield21:10:09

@niklos2005 You're going to find it pretty hard to avoid the command-line working in the Clojure world. Pretty much any non-trivial bit of work is going to require familiarity with one or more of lein, boot, or clj (and deps.edn). You'll find nearly all the books and tutorial assume you are working at the command line...

niklos200521:10:39

@seancorfield Thanks for the info. I know that i cant avoid cmd line. Command line also has its beauty (old traditional way)😀

peter.kehl21:10:11

Thank you @andy.fingerhut, @noisesmith and @markmarkmark. You helped me to finish http://www.4clojure.com/problem/125. I used regex to escape " and \.