Fork me on GitHub
#beginners
<
2021-01-27
>
Marco Pas09:01:12

I am trying to use a custom deps.edn in my ~/.clojure/ folder.

{
 :paths ["src"]
 :aliases
 {

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  ;; Creating projects from templates

  ;; clj-new - 
  :new {:extra-deps {seancorfield/clj-new {:mvn/version "1.1.234"}}
        :exec-fn clj-new/create
        :exec-args {:template "app"}}}
}
https://github.com/seancorfield/clj-new According to the documentation it states that i can use the alias to create a new project. But whenever i try to execute the command clojure -X:new :name myname/myapp i get an error message
Execution error (FileNotFoundException) at java.io.FileInputStream/open0 (FileInputStream.java:-2).
-X:new (No such file or directory)
When i make a typing error in the deps.edn it states the error, so i am sure the custom deps.edn is used. Any pointers what i am doing wrong?

delaguardo09:01:14

which version of clojure cli you using?

GJ15:02:27

This rings a bell... I followed the direction for the aliases and it didn't work.

GJ15:02:00

(Checking my notes) The first command to use is clojure -A:new app practicalli/simple-api-server which doesn't work, because we have to install the clj-new project. This is done by updating ~/.clojure/deps.edn and adding an alias Note that copying and pasting the example from the readme doesn't work {:aliases {:new {:extra-deps {seancorfield/clj-new {:mvn/version "1.1.234"}} :exec-fn clj-new/create :exec-args {:template "app"}}} ...} But this does: :aliases { :deps {:extra-deps {org.clojure/tools.deps.alpha {:mvn/version "0.9.857"}}} :test {:extra-paths ["test"]} :new {:extra-deps {seancorfield/clj-new {:mvn/version "1.1.234"}} :exec-fn clj-new/create :exec-args {:template "app"}} } Sorting this out was interesting (something to do with the curly braces).

phronmophobic09:01:32

that same command and same deps alias works fine for me. the error makes it seem like there might be an extra argument being passed

phronmophobic09:01:28

it looks like it's trying to open a file named "-X:new"

Marco Pas09:01:48

Aaah so i am running an older version 🙂

delaguardo09:01:02

yes) update should fix that

Marco Pas09:01:14

Thanks!!! Was searching all over the place 🙂

Marco Pas09:01:17

Thanks a lot!!

Marco Pas09:01:42

@delaguardo It worked!!! Again thanks!

practicalli-john10:01:10

@marco.pasopas you may find this book useful when using Clojure with CLI tools http://practicalli.github.io/clojure/ I also have a well documented user-wide deps.edn configuration with a wide range of tools https://github.com/practicalli/clojure-deps-edn

👍 4
roelof10:01:59

so no free resources to learn re-frame or reagent

delaguardo10:01:01

there are plenty documentation available for both )

roelof10:01:01

also courses or tutorials where a site is build

roelof10:01:48

I have done one which works wih on-click but I see also some of them which uses subscribe so confusing

simongray10:01:01

they are excellent

roelof10:01:24

Thanks, some study to do

practicalli-john10:01:37

Any suggestions on getting started and designing apps with Clojure and Kafka streams? I've ask this in #apache-kafka so appreciate answers there. https://clojurians.slack.com/archives/CDAA5T4KZ/p1611742901000200

Marco Pas11:01:43

@jr0cket Thanks for the pointer! I already found the deps.edn collection and surely they are usefull!!

👍 4
Hagenek16:01:18

An error has occured for me a couple of times the past days (Using Vs Code and Calva). Anyone know why this is happening?

Syntax error compiling at (src/clojure_functions/core.clj:22:1). Unable to resolve symbol: defn in this context

delaguardo16:01:06

do you have :refer-clojure in your ns?

Hagenek16:01:25

No I just have (ns clojure-functions.core), how should it look and why?

delaguardo16:01:18

I’m asking because it is possible to exclude symbols from clojure.core using form like that (:refer-clojure :exclude [defn]) in ns

delaguardo16:01:55

do you mind to share the code? it is hard to guess based on exception message

Hagenek16:01:32

Yeah I understand! Here is the full code:

(ns clojure-functions.core)


(defn my-reduce
  "expects a funtion a value and a collection"
  ([f coll]
   (if (empty? coll) (f)
       (my-reduce f (f (first coll) (second coll)) (rest (rest coll)))))
  ([f val coll]
   (loop [acc val remaining-coll coll]
     (if (empty? remaining-coll)
       acc
       (recur  (f acc (first remaining-coll)) (rest remaining-coll))))))

(defn my-count
  "returns the number of items in a collection"
  ([coll] (my-count coll 0))
  ([coll acc]
   (if (empty? coll)
     acc
     (my-count (rest coll) (inc acc)))))

Hagenek16:01:11

It is working when I test the functions with Midje, so its related to the Calva I think

delaguardo16:01:19

yeah, lgtm so probably it is midje or calva

Hagenek16:01:22

Everything works again now

Hagenek16:01:38

Without me changing any code, just pressed ctrl-alt-c + enter a couple of times

dpsutton16:01:46

this can often happen if you execute (in-ns my-namespace) before requiring or executing a proper ns form

delaguardo16:01:25

right! I can reproduce

dev> (in-ns 'sample.core)
;; => #namespace[sample.core]
sample.core> (defn foo [])
Syntax error compiling at (*cider-repl xapix/clojud:localhost:49518(clj)*:2721:14).
Unable to resolve symbol: defn in this context

pez17:01:22

With Calva the easiest way is to always start with loading the file, Calva avoids loading things automatically for you. I think that is the way it should be, but it does create a Ux problem for people that are new to the dynamic nature of a Clojure program in development. I’ve tried to mitigate it some by having the https://calva.io/try-first/ article of the docs start with: > You should start with loading the file you are working with. Do this with Load Current File and Dependencies, `ctrl+alt+c enter`.

Hagenek18:01:02

Thank you so much for the answer, loving Calva btw, made me change from Emacs & Cider:v:

❤️ 3
calva 6
pez21:01:52

There is a lot of CIDER still there in Calva even after distilling. 😃

😂 3
Faris17:01:50

I’m getting this error when trying to jack-in using Cider

. Unhandled clojure.lang.Compiler$CompilerException
   Error compiling src/reader/snake.clj at (1:41)

             Compiler.java: 7526  clojure.lang.Compiler/load
                      REPL:    1  user/eval6049
                      REPL:    1  user/eval6049
             Compiler.java: 7062  clojure.lang.Compiler/eval
             Compiler.java: 7025  clojure.lang.Compiler/eval
                  core.clj: 3206  clojure.core/eval
                  core.clj: 3202  clojure.core/eval
    interruptible_eval.clj:   82  nrepl.middleware.interruptible-eval/evaluate/fn/fn
                  AFn.java:  152  clojure.lang.AFn/applyToHelper
                  AFn.java:  144  clojure.lang.AFn/applyTo
                  core.clj:  657  clojure.core/apply
                  core.clj: 1965  clojure.core/with-bindings*
                  core.clj: 1965  clojure.core/with-bindings*
               RestFn.java:  425  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   82  nrepl.middleware.interruptible-eval/evaluate/fn
                  main.clj:  243  clojure.main/repl/read-eval-print/fn
                  main.clj:  243  clojure.main/repl/read-eval-print
                  main.clj:  261  clojure.main/repl/fn
                  main.clj:  261  clojure.main/repl
                  main.clj:  177  clojure.main/repl
               RestFn.java: 1523  clojure.lang.RestFn/invoke
    interruptible_eval.clj:   79  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:   56  nrepl.middleware.interruptible-eval/evaluate
    interruptible_eval.clj:  145  nrepl.middleware.interruptible-eval/interruptible-eval/fn/fn
                  AFn.java:   22  clojure.lang.AFn/run
               session.clj:  202  nrepl.middleware.session/session-exec/main-loop/fn
               session.clj:  201  nrepl.middleware.session/session-exec/main-loop
                  AFn.java:   22  clojure.lang.AFn/run
               Thread.java:  748  java.lang.Thread/run

1. Caused by java.lang.Exception
   No namespace: examples.import-static

Faris17:01:18

I’m following an example for Programming Clojure This is the code so far

(ns reader.snake
  (:import (java.awt Color Dimension)
           (javax.swing JPanel JFrame Timer JOptionPane)
           (java.awt.event ActionListener KeyListener))
  (:refer examples.import-static :refer :all))
(import-static java.awt.event.KeyEvent VK_LEFT VK_RIGHT VK_UP VK_DOWN)

Faris17:01:41

This is from the example file itself, so I haven’t actually changed anything.

dpsutton17:01:56

got a link to where you got this from?

Faris17:01:33

The file in question is at shcloj3-code/code/src/reader/snake.clj

dpsutton17:01:44

but the error seems straightforward : "No namespace: examples.import-static". relating to your (:refer examples.import-static :refer :all) (which seems quite strange to me

Faris17:01:33

I think maybe I need to load the whole repo then?

Faris17:01:40

instead of just this file?

dpsutton17:01:26

yes. the examples.import-static is a reference to shcloj3-code/code/src/examples/import_static.clj

Faris17:01:17

I see, thank you very much!

mathpunk18:01:47

I'm trying to figure out how I can run tests for a namespace from the command line

mathpunk18:01:34

Here's something that didn't work:

(ns com.logicgate.helper.config)
...
(defn -main []
  (test/run-tests 'com.logicgate.helper.config))

mathpunk18:01:50

:test-config     {:main-opts ["-m" "com.logicgate.helper.config"]}

mathpunk18:01:03

clojure -M:test-config

mathpunk18:01:28

any thoughts on how i can do this? for context, i'm trying to run these tests in a docker container, since i bet i'm going to mess up configuring for that environment

dpsutton18:01:31

Have you looked at the cognitect test runner?

mathpunk18:01:03

reading now....

adam-james18:01:38

should the cmd be clojure -A:test-config?

mathpunk18:01:39

this is likely to sort me out, thank you!

mathpunk18:01:47

i'm pretty fuzzy on M vs A vs X, adam-james.... what i had was copypasta from my "true" main functions that do work from other ns's

adam-james18:01:58

From the code you posted, it looks as if :test-config is an alias. My understanding is that -M specifies a namespace in which a main function exists, but -A will run an Alias from a deps.edn file. I use aliases to launch dev or build depending on needs.

adam-james18:01:35

apologies, it looks like i was mixing up -M with -m. please disregard, I don't think I'm helping after all 😕

Christian19:01:06

I wonder why:

(map Integer/parseInt ["2011" "3" "21"]) ;this doesn't work

(Integer/parseInt "2011") ; but this is fine

alexmiller19:01:13

It’s a Java method, not a Clojure function

manutter5119:01:14

Integer/parseInt is a Java method, not a clojure function. To use it with map and so on, you need to wrap it in an anonymous function like #(Integer/parseInt %)

🙌 3
caumond19:01:57

@manutter51, I didnt know this limitation. I guess it is more general where else does it apply ?

noisesmith19:01:48

@caumond on the vm / bytecode level, "methods" don't exist as real things, they are something an object knows how to do and only the objects are concrete

noisesmith19:01:22

@caumond a clojure IFn is an object that only exists to carry a method (one which clojure calls if you put it in parens)

noisesmith19:01:10

so, more concretely, you can't put something that isn't an Object on the stack, and IFn is an object, so you can put it on the stack, unlike a method

noisesmith19:01:30

in order to pass something as an argument, it needs to end up on the stack

noisesmith19:01:35

you can use method call interop syntax with IFn objects

user=> (.invoke str nil)
""

caumond19:01:39

Yes. Very clear. Thanks. Im definitly not sure ive ever read something like that in the books I read.

noisesmith19:01:53

(there's the potentially misleading fact that reflection api offers "method handles", which are Objects that allow you to manipulate / use the methods on another Object, but we'd be badly off if we needed to reflect and use method handles everywhere)

Sophie19:01:13

Hey Guys, I'm kind of stuck trying to get some data from a textfile. It already worked today but I destroyed it likely.

(map #(subs % (count prefix)(clojure.string/split-lines (slurp file-name))))
#object[clojure.core$map$fn__4781 0x5f20155b [email protected]]
After converting the data I'm trying to compare them with clojure.set/difference but this works neither.
(let [proef  (set/difference (set prae) (set post)) ]
             (println proef)
        ))
Any suggestions what's going wrong?

dpsutton19:01:11

your map is only given a single argument here rather than two. i imagine you need to spit the split-lines form out of the subs form

noisesmith19:01:04

single arg map arity strikes again

dpsutton19:01:59

in the history of clojure paper (and elsewhere i think) rich mentioned that if he started Clojure again today it would be based on transducers by default rather than laziness. i wonder what that would look like

hiredman19:01:06

there are two distinct reifications of methods as objects java.lang.reflect.Method and java.lang.invoke.MethodHandle, reflect.Method is the older reflection api, MethodHandle is the new stuff built to work with (but possible to use independent of) invoke dynamic

Sophie19:01:33

😂 Ok this is the reason the first one worked earlier this day. First one solved.

Henri Schmidt19:01:21

@3samgal your second piece of code has an extra paren

Henri Schmidt19:01:37

On the 3rd line

noisesmith19:01:27

yeah - I suggest taking some time to learn normal formatting / indentation conventions, they tend to make it easier to find and fix these sorts of bugs

dpsutton19:01:58

indentation doesn't matter to the computer but properly indented code will make mistakes jump out at you

noisesmith19:01:24

it's like traffic rules or human language - at first it doesn't help, but it makes working with others a lot easier, and in theory an isolated Galapagos of coders could invent their own conventions that are equally useful in their context

noisesmith19:01:22

(I learned this lesson about math recently, upgrading from an ad-hoc rotation and mirroring of shapes to standard matrix transforms)

dpsutton19:01:48

indenting your matrices?

Sophie19:01:38

What is the common way for this in clojure? ( ( ( ) ) ) Like this?

noisesmith19:01:42

I mean much more generally than that - my ad-hoc rotation / flipping code did everything the matrix transform did, but by using the standard mathematical object (a transform matrix) I have a reference which makes finding bugs easier

noisesmith19:01:34

@3samgal we don't leave dangling braces, and split lines for clarity - eg.

(map #(subs % (count prefix))
     (clojure.string/split-lines (slurp file-name)))

noisesmith19:01:09

notice that the args for map line up (since they are at the same abstraction level)

noisesmith19:01:32

(let [proef (set/difference (set prae) (set post))]
   (println proef))
the println aligns under the let not the [binding block] - it doesn't belong as a child of the bindings, it belongs as a child of let

Sophie19:01:30

Ok thank you. In school we are learning C. There we usually use parenthesis the other way.

noisesmith19:01:55

right, that's why I compare it to traffic rules (we drive on our side of the street, they drive on theirs)

Sophie19:01:27

:rolling_on_the_floor_laughing: Nice

andy.fingerhut00:01:32

@noisesmith Reminds me of something I read once about Richard Feynman -- he reinvented / rediscovered parts of trigonometry on his own, and had a period of adjustment when he found out what notation others used for it in math classes.

noisesmith00:01:18

haha, right - as programmers we do a lot of off-roading but sometimes its useful to be able to adopt the official traffic rules and get on the freeway

noisesmith00:01:32

and the more math I learn (mostly set theory, linear algebra, group theory, category theory so far), the more I see things I used informally / in a very basic way, reformatted to be simpler and more reusable

noisesmith00:01:20

not claiming to be anything like a Feynman, I'm just fiddling with some numbers

andy.fingerhut00:01:47

I was impressed that he rediscovered parts of trigonometry on his own before learning it from others. Pretty cool.

noisesmith00:01:53

he would have been a polymath if he was born two centuries sooner, he was just that kind of thinker

Sophie19:01:03

Thanks for the hint, but the parenthesis is part of the function ahead. Any other ideas?

sova-soars-the-sora19:01:29

It's gotta be a #{set} to use clojure.set/union, clojure.set/difference https://clojuredocs.org/clojure.set/union https://clojuredocs.org/clojure.set/difference I think you could do (into #{} (distinct -vals-) since a set must have unique values only

tws19:01:43

set will take care of the dupes, no need for distinct

Sophie19:01:19

I solved it. Thank you so much.

upside_down_parrot 3
roelof20:01:33

Am I right that subcribe is re-frame where on-click is reagent and on both something happens ?

noisesmith20:01:58

the :on-click function of an html element is the function that gets called if you click it - this is a direct translation of an html feature subscribe is an abstraction over reagent r/atom r/atom is a data structure that will cause your page element to be re-rendered if the data you access changes

noisesmith20:01:10

instead of specifying a change to the DOM in order to change what renders, you provide a function that uses application data (via r/atom or subscription), and then the framework promises to call your rendering code if the data you used changes

noisesmith20:01:50

on-click is one popular way to trigger an app data change that would lead to a re-render, but there are a few steps in between

noisesmith20:01:01

the "something" that happens is that your template function gets called again with new data

Mno20:01:17

you can think of it as a way to get data, but also as a way of telling your app to reload “this specific part of the html” when the data changes. for example this one has both:

(defn home-page []
  (let [form-data @(re-frame/subscribe [::subs/form-data])]
    [main-layout
     [:div.card>div.card-content
      [:div.field.has-addons
       [:label.label "What's your name?"]
       (form-input "text" :name form-data)
       [:button.button.is-info.is-light {:on-click #(re-frame/dispatch [::events/push-state :quizzes/index])} "Select Quiz"]]]]
    ))

Mno20:01:32

so in this case if the form-data changes, this part of the dom gets reloaded, and if you click the button, it dispatches an event (in this cases changes the “route”

roelof20:01:47

so on both I can use subscribe or on-click ?

noisesmith20:01:42

:on-click is typically used to turn user actions into data changes

noisesmith20:01:52

then subscribe is used to turn data changes into content changes

noisesmith21:01:30

(other things can cause data changes too, eg. data coming back from an api, or just landing on a new route)

roelof21:01:35

hmm, on the reagent course I followed I never used subcribe and on the re-frame course of the same person ` subscribe is used

roelof21:01:40

still very confusing

noisesmith21:01:02

reagent doesn't have subscribe, it's something re-frame introduces

noisesmith21:01:33

in fact you could say that re-frame is reagent + subscribe (plus a few nice widget definitions you can use)

roelof21:01:50

oke, maybe I stay then with reagant because the only thing I need is to show a modal when a user clicks on a painting

roelof21:01:22

but then first convert some html template to a reagent template

noisesmith21:01:23

yeah, the basic big picture of a reagent version is that the atom would have a key for the data the modal uses, and the click would fill in data under that key

roelof21:01:40

because I do not need subscribe. I solved the problem with fetching from api wth pre-loading

noisesmith21:01:43

then the template decides whether to output the markup for the modal, based on whether it sees the data

noisesmith21:01:17

right - this example is probably small enough that re-frame doesn't become especially useful yet, and you can always add re-frame to a reagent project later

roelof21:01:56

hmm, I thought with a click could first fetch he data from the apio because I cannot know which pianting a user wants to see some info

noisesmith21:01:37

1. user click makes a fetch start 2. fetch completes, r/atom gets filled in with new data 3. reagent runs your template again with the new data

noisesmith21:01:20

one advantage of re-frame is its subscriptions make that flow more explicit, but it's still probably more than you need for this case

noisesmith21:01:18

just remember that most UI changes start with changing contents of an r/atom

roelof21:01:35

that is clear

roelof21:01:46

and maybe later I could try re-frame to instead of the pre-loading that the user sees a empty painting whcih is switched to the real image as soon as the url is returned

roelof21:01:20

for now time to sleep . Thanks for the lessons

roelof21:01:02

but one change at the time

Christian21:01:03

It's not possible to destructure in the arguments, right? Example might explain better:

(defn decomp-test [[a b c]]
  (+ a b c))

(decomp-test [[1 2 3]]) ; so this can be 6?
here a simple apply would work, it's more of a thought experiment, because it's perfectly fine in prolog

Mno21:01:14

that would work, but with one more set of []

Mno21:01:31

so:

(defn decomp-test [[[a b c]]]
  (+ a b c))

Christian21:01:14

why do I need the triple?

noisesmith21:01:18

NB nested destructuring (or mix of map and sequential destructure) is usually better done in a let block

Mno21:01:51

the first one is just the arguments that come in, the second one is the first vector, and the third one is the second vector

noisesmith21:01:51

@christiaaan because you are passing a one element vector of vectors, so your destructure needs to match the shape

Christian21:01:16

can I have named arguments?

noisesmith21:01:28

destructure gives you named arguments

noisesmith21:01:48

maybe I misunderstand that question

Christian21:01:11

no, you are right. I was just stumbling over the [[[ thing, as it looks not that idiomatic

noisesmith21:01:44

@christiaaan right, the part that is weird is that you'd define operations on single item vectors of vectors

Mno21:01:53

well it’s not common you pass a vector in a vector

Mno21:01:23

especially when it’s a 3 item vector in a 1 item vector.

Mno21:01:37

oddly specific

Mno21:01:57

Lemme see if I can give a nice example with the repl

Christian21:01:27

my function gets a sorted list, and I wanted to avoid apply, I guess apply is prettier

Mno21:01:18

Here you can run this and see all the stages of destructuring that you went through

(let [first [[1 2 3]]
      [second] first
      [[a b c]] first
      [a2 b2 c2] second]

  (prn (str "first=" first))
  (prn (str "second= " second))
  (prn (str "sum of a b c= " (+ a b c)))
  (prn (str "sum of a2 b2 c2= " (+ a2 b2 c2))))

Mno21:01:49

also it’s an example of how to use let to test destructuring a bit easier

Christian21:01:29

Thank you, that helps indeed

noisesmith21:01:02

I would have had [a b c] second on that last binding line (same result)

Mno21:01:31

that’s a good idea

Christian21:01:44

I think it's easier to understand with the let

(defn is-valid? 
  "Checks the three sides of a would be triangle."
  [a b c]
  (let [[shortest short longest] (sort [a b c])] 
    (and (< 0 shortest)
         (> (+ shortest short) longest))))

noisesmith21:01:39

@christiaaan also consider (< 0 shortest longest (+ shortest short))

Christian21:01:14

Right! I had this thought but could not reconstruct it

Mno21:01:14

that’s amazing

noisesmith21:01:23

I guess that needs to be <= maybe...

Christian21:01:38

0 length edges are not okay for a triangle

noisesmith21:01:27

@christiaaan my mental model for < is that it takes a series of numbers whose line graph rises like the top half of the symbol 😄

noisesmith21:01:40

it's like a stonks emoji

📈 3
😄 3
Christian21:01:09

at this point we shoud probably not make fun about wsb stonks

noisesmith21:01:09

it appears that we have no :stonks: or :line_goes_up:, which is probably for the best

Mno22:01:19

Malik knows emojis 💹

Malik Kennedy22:01:08

Couldnt let this go un-STONKS'd

📉 3
📈 6
Christian21:01:38

I remember why I ditched the idea. That would eliminate equilateral triangles

noisesmith21:01:18

right, shortest and longest could be equal

noisesmith21:01:51

of course you could have (< 0 shortest (inc longest) (+ 1 shortest short)) but that's weird

evocatus22:01:37

Hi! I finally made fast binary exponentiation algorithm. Could you review it? https://github.com/reflechant/binary-pow/blob/main/src/binary_pow/core.clj

noisesmith22:01:24

so powers isn't the powers of x, it's x, square x, square(square x) etc?

noisesmith22:01:05

I don't know this algorithm off the top of my head, but with a name like powers I expected powers of x

noisesmith22:01:21

ins)user=> (take 10 (iterate #(*' % %) 2))
(2 4 16 256 65536 4294967296 18446744073709551616N 340282366920938463463374607431768211456N 115792089237316195423570985008687907853269984665640564039457584007913129639936N 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096N)
(ins)user=> (take 10 (iterate #(* % 2) 2))
(2 4 8 16 32 64 128 256 512 1024)
• - edit, that last step's a doozy

evocatus22:01:45

@noisesmith it depends on whether the power is even or odd

evocatus22:01:53

was trying to write a tail-recursive version and failed

noisesmith22:01:25

oh, it is a sequence of squares, super surprising but I see