Fork me on GitHub
#beginners
<
2020-05-21
>
mruzekw00:05:48

With deps.edn, is there a way to alias a module for another rather than just its version?

mruzekw00:05:32

I have a case where I'd like to alias react-native with react-native-web for seamless interop between native and web for a single codebase

mruzekw00:05:42

Looks like I might be able to do with via shadow-cljs https://shadow-cljs.github.io/docs/UsersGuide.html#js-resolve-npm

mruzekw00:05:17

This might work since I'd only want to change what's target in the browser. Please shout out if anybody has any other ideas. Thanks.

alidcastano00:05:25

@mruzekw yeah I do this with shadow-cljs, one sec

alidcastano00:05:20

use the :js-options :resolve field in your build config, here’s how mine looks

:js-options {:extensions [".web.js" ".js" ".json"]
                :resolve    {"react-native" {:target :npm
                                             :require "react-native-web"}}}

didibus00:05:17

@mruzekw deps.edn doesn't define anything related to the module or its name. All it does is pull down dependencies on your machine and start processes with the right paths and options setup

didibus01:05:11

Do you mean with ClojureScript?

didibus01:05:36

From a cljsjs dependency?

phoenixai208204:05:22

Hi All, I am learning Clojure(script). I just recorded screen while trying to build login form using Clojure Script, Reagent, next.jdbc, Postgresql. The video is two hour long, so you may want to speed up while viewing. I am newbie, so please pardon my Clojure(script). https://youtu.be/4gLq8K0PvTg Thank You.

yubrshen05:05:47

How to investigate and fix the error of executing clj for REPL? Just installed on Ubuntu 18.04 Clojure CLI, following the instruction below: > To install with the Linux script installer: > Ensure that the following dependencies are installed: bash, curl, rlwrap, and Java. > Use the linux-install script to download and run the install, which will create /usr/local/bin/clj, /usr/local/bin/clojure, and /usr/local/lib/clojure: curl -O https://download.clojure.org/install/linux-install-1.10.1.536.sh chmod +x linux-install-1.10.1.536.sh sudo ./linux-install-1.10.1.536.sh when executing

clj
for REPL, I got the following error trace:
[[email protected] athens-sandbox (master)]$ clj
Error building classpath. Failed to read artifact descriptor for org.clojure:clojure:jar:1.10.1
org.eclipse.aether.resolution.ArtifactDescriptorException: Failed to read artifact descriptor for org.clojure:clojure:jar:1.10.1
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.loadPom(DefaultArtifactDescriptorReader.java:255)
	at org.apache.maven.repository.internal.DefaultArtifactDescriptorReader.readArtifactDescriptor(DefaultArtifactDescriptorReader.java:171)
	at org.eclipse.aether.internal.impl.DefaultRepositorySystem.readArtifactDescriptor(DefaultRepositorySystem.java:255)
	at clojure.tools.deps.alpha.extensions.maven$eval813$fn__815.invoke(maven.clj:99)
	at clojure.lang.MultiFn.invoke(MultiFn.java:244)
	at clojure.tools.deps.alpha$expand_deps$fn__1230$fn__1231.invoke(alpha.clj:214)
	at clojure.tools.deps.alpha.util.concurrent$submit_task$task__500.invoke(concurrent.clj:33)
	at clojure.lang.AFn.call(AFn.java:18)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.eclipse.aether.resolution.ArtifactResolutionException: Could not transfer artifact org.clojure:clojure:pom:1.10.1 from/to central (): /home/yubrshen/.m2/repository/org/clojure/clojure/1.10.1/clojure-1.10.1.pom.part.lock (No such file or directory)
I Googled, haven't found any mention of the error. I suspect that my Java version or installation might have a problem:
[[email protected] athens-sandbox (master)]$ java --version
java 11.0.2 2019-01-15 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode)
Really appreciate if you could give me a pointer to investigate. Thanks in advance!

seancorfield06:05:23

@yubrshen Based on those errors, I'd say the most likely issues are either file system permissions or network/proxy access.

phoenixai208206:05:51

@yubrshen - ls -l /home/yubrshen/.m2/repository/org/clojure/clojure/ ?

paul.ekstrom.jr08:05:17

Hi! I'm have done a little elisp before (but only a little), and am now exploring the nice features and syntax of Clojure. Function argument destructuring is a fine feature, that saves a lot of tedious typing. Here is an example function, which first destructures the keymap argument into two variables must and opt . It then goes on with an assertion to check that must is not nil.

(defn foo [{:keys [must opt]}]
  {:pre  [(not (nil? must))]}
  ...
I wonder if it is possible to make the not-nil-assertion right in the destructuring, to eliminate the need for two separate lines/steps? A way to mark must as an obligatory argument so to speak, in the destructuring? I know of the :or feature, but that is not the same as an assertion which fires an exception when the condition is unmet.

noisesmith13:05:05

there is no feature that does assertions inside destructure - closest you get is :or to set defaults

endrebak8510:05:52

I want a function:

(f "abc") ; ["abc"]
(f ["abc"]) ; ["abc"]
If the argument is a string, put it in a vector, if it is a vector, do nothing. I know an (if (string? v) [v] v) will do this, just wondering if there is a different way.

kristjan.cocev12:05:28

I don't see anything wrong here, but I'm no expert...

cfeckardt23:05:42

(flatten [["abc"]]) -> ["abc"] (flatten ["abc"]) -> ["abc"]

cfeckardt23:05:21

so (fn [x] (flatten [x]))

endrebak8506:05:18

Thanks! But you need (fn [x] (flatten (vector [x]))) in case x is just "abc".

cfeckardt11:05:51

~ % clj
Clojure 1.10.1
user=> (defn foo [x] (flatten [x]))
#'user/foo
user=> (foo "abc")
("abc")
user=> (foo ["abc"])
("abc")

cfeckardt11:05:34

[x] is shorthand for (vector x)

cfeckardt11:05:02

if you must have a vector as output instead of a seq you can do:

cfeckardt11:05:13

(vec (flatten [x]))

endrebak8510:05:19

I guess there is something about checking the type that feels slightly wrong.

kraulain12:05:18

Is it safe to assume that all namespaces that start with an uppercase are probably coming from Java ? e.g. in Math/pow or Integer/parseInt

noisesmith13:05:23

To be clear, Math and Integer are not namespaces, they are classes. Clojure also uses upper case when defining classes (eg. defprotocol, deftype, defrecord, definterface, gen-class)

noisesmith13:05:37

namespaces are different, they don't exist in java

noisesmith13:05:21

(the clojure namespace construct has a representation in java, but it's not something a non-clojure java class would be likely to care about, use, or resepect)

kraulain16:05:45

Thanks @ Yeah, those are classes :face_palm: but also I thought namespaces were the same as packages in Java. 🤔

noisesmith16:05:35

It's much weirder / messier than that. If a namespace creates a class, the heirarchy of the ns is translated into the class' package

noisesmith16:05:25

but the ns itself is a data structure, and clojure keeps a mapping of all ns symbols to their implementations, and each ns contains mappings describing what's visible to them and what's exported from them

kraulain16:05:42

okay, see. Thanks a lot simple_smile

ceronman13:05:30

Hello Clojurians! If I have a list of maps '({} {} {}) and I want to add something to the first map. What would be the idiomatic way of doing it? I'm currently doing this:

=> (def mylist '({} {} {}))
=> (conj (rest mylist) (assoc (first mylist) :key "value"))
({:key "value"} {} {})

ceronman13:05:49

But I'm wondering if there is a better way

alexmiller13:05:25

if the first map is special, then maybe it should really be a map of maps and you should use update-in or assoc-in

alexmiller13:05:49

it's generally weird to have such a specific need is what I'm saying

manutter5113:05:46

I might do something like (let [[h & other] mylist] (conj other (assoc h :key "value"))), which looks a little weird on its own for such a simple example, but it does reflect a pattern I use regularly.

ceronman13:05:25

Thanks for the suggestions, I like the idea of restructuring, but also might refactor things to use nested maps 😄

skiracer129214:05:05

Hello! I am new to web dev and am working on a website using Reitit for the routing. I followed https://github.com/metosin/reitit/blob/master/examples/frontend-re-frame/src/cljs/frontend_re_frame/core.cljs but I am having some troubles getting routing to work as I hoped. I define my routes like this:

(ns website.routes 
 (:require [reitit.frontend :as rf]
           [reitit.frontend.easy :as rfe]
           [re-frame.core :as re-frame]
           [website.events :as e]))

(def routes
  ["/"
   [""
    {:name :home}]
   ["posts"
    [""
     {:name :posts}]
    ["post-one"
     {:name :blank}]]
   ["projects"
    [""
     {:name :projects}]]])

(defn on-navigate [new-match]
  (when new-match
    (re-frame/dispatch [::e/navigated new-match])))

(def router
  (rf/router
   routes))

(defn init-routes! []
  (rfe/start!
   router
   on-navigate
   {:use-fragment false}))
If I navigate to localhost/ , localhost/posts or localhost/projects it works great. The problem comes when I want to have nested routes such as localhost/posts/post-one, navigating to that page does not work. Actually, navigating to localhost/posts/ with the trailing / does not work either. I have two questions: 1. How can I get nested routes to work as expected? I would like to be able to navigate to localhost/posts/post-one or localhost/posts/post-one/ and have it correctly route the user. 2. When I upload the website to github pages, how can I get it to respect the hosts address? For example, I have my website on and if a user navigates to the posts page it will not recognize the route unless it is which, as you can imagine, breaks when you try to reload or link to the page since that page doesnt actually exist.

skiracer129214:05:05

Hello! I am new to web dev and am working on a website using Reitit for the routing. I followed https://github.com/metosin/reitit/blob/master/examples/frontend-re-frame/src/cljs/frontend_re_frame/core.cljs but I am having some troubles getting routing to work as I hoped. I define my routes like this:

(ns website.routes 
 (:require [reitit.frontend :as rf]
           [reitit.frontend.easy :as rfe]
           [re-frame.core :as re-frame]
           [website.events :as e]))

(def routes
  ["/"
   [""
    {:name :home}]
   ["posts"
    [""
     {:name :posts}]
    ["post-one"
     {:name :blank}]]
   ["projects"
    [""
     {:name :projects}]]])

(defn on-navigate [new-match]
  (when new-match
    (re-frame/dispatch [::e/navigated new-match])))

(def router
  (rf/router
   routes))

(defn init-routes! []
  (rfe/start!
   router
   on-navigate
   {:use-fragment false}))
If I navigate to localhost/ , localhost/posts or localhost/projects it works great. The problem comes when I want to have nested routes such as localhost/posts/post-one, navigating to that page does not work. Actually, navigating to localhost/posts/ with the trailing / does not work either. I have two questions: 1. How can I get nested routes to work as expected? I would like to be able to navigate to localhost/posts/post-one or localhost/posts/post-one/ and have it correctly route the user. 2. When I upload the website to github pages, how can I get it to respect the hosts address? For example, I have my website on and if a user navigates to the posts page it will not recognize the route unless it is which, as you can imagine, breaks when you try to reload or link to the page since that page doesnt actually exist.

vale14:05:13

usually you'd want to write your routes starting with a slash so like

(def routes
  [["/"
    {:name :home}]
   ["/posts"
    ["/"
     {:name :posts}]
    ["/post-one"
     {:name :blank}]]
   ["/projects"
    ["/"
     {:name :projects}]]])
and to make it more flexible with the trailing slash, you can use the trailing slash handler https://cljdoc.org/d/metosin/reitit/0.4.2/doc/ring/slash-handler

skiracer129214:05:53

If I redefine my routes like this they stop working all-together. localhost/posts and localhost/posts/ both redirect to a blank page now. I notice I am using reitit.frontend and reitit.frontend.easy to define my router; should I be using reitit.ring like they are in the example?

vale14:05:42

ah sorry i can't help with frontend code. you can try asking in #reitit

yubrshen15:05:33

@seancorfield @phoenixai2082 thanks for pointing to the probable root cause of the problem. It is related to the fact that /home/yubrschen/.m2 does not exist in my setup! The moral of my lesson: I should have read the trace to find any hint related to my own environment, that is, this path, and investigate the state of this path. This is part of the learning.