This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-05-13
Channels
- # announcements (5)
- # babashka (35)
- # beginners (65)
- # braveandtrue (3)
- # calva (20)
- # cider (6)
- # clara (11)
- # cljs-dev (36)
- # cljsrn (64)
- # clojure (65)
- # clojure-europe (6)
- # clojure-germany (13)
- # clojure-italy (14)
- # clojure-nl (22)
- # clojure-spec (16)
- # clojure-sweden (6)
- # clojure-uk (81)
- # clojurescript (71)
- # conjure (120)
- # cursive (3)
- # datomic (10)
- # events (4)
- # figwheel (4)
- # figwheel-main (5)
- # fulcro (36)
- # ghostwheel (1)
- # graalvm (8)
- # helix (9)
- # jobs (4)
- # jobs-discuss (12)
- # kaocha (33)
- # leiningen (5)
- # luminus (1)
- # off-topic (24)
- # pathom (7)
- # rdf (4)
- # re-frame (3)
- # reagent (15)
- # reitit (11)
- # remote-jobs (1)
- # shadow-cljs (97)
- # slack-help (3)
- # spacemacs (23)
- # vim (15)
- # xtdb (35)
I am developing a small app. However, I discover that the API supports JSON-LD, therefore you receive data that is similar to {"answer1!: "ans", "@type": "somevalue"}. This @ reflect the linked data. I have worked around the @type for now however this is not suitable. What do folks do? Anyone have a view or point me in the right direction? BTW the only clojars JSON-LD is for OWL implementations
What's the goal & problem? Based on a quick scan of the idea of JSON-LD it's a form of sending links. Depending on your goal, you could just ignore the links. e.g i ask for a persons name and it sends + name = "john" + person = some-unique-url
Hi @U0DJ4T5U1, this is a part of a larger JSON-LD, when map is prepared as part of json/read-str, the map is faulty as included is the {:@type spmevalue} One cannot use the map as the REPL complains due to the @type symbol. S I did a hack, however is there a better way of dealing with this as in some industries have gone JSON-LD mad (driven by MongoDB for instance) and will be more prevalent in due course.
Json-ld is valid json right? > One cannot use the map as the REPL complains due to the @type symbol. > json/read-str, the map is faulty as included is the {:@type spmevalue} are you using clojure.json/read-str with the key convertor function to a clojure keyword. eg
(json/read-str "{\"a\":1,\"b\":2}"
:key-fn keyword)
;;=> {:a 1, :b 2}
if so, then maybe dont include :Key-fn keyword and let it remain a string.strings are valid keys in a clojure map so {"@type" <some-value>} is valid clojure.
That is what I did; I processed the string and substituted the @keys and then continued. Nevertheless, this will happen more and more as companies adopt JSON-LD
strings are valid, however to maniplate or search a complex structure keywords as strings are problematic
the keyword function happily makes a keyword out of any string
scratch=> (keyword "@anything")
:@anything
any string can be a key in a hash-map, you don't need to create keywords
the only actual problem is attempting to use invalid keyword literals in your code, but nothing forces you to do that
keywords aren't magic, they are a convenience, you can simply not use them in cases where they cause complexity
I have had problems when search complex structures which have maps and vectors in them - then it is a problem
you can sue the get
and get-in
functions with strings, you don't need keywords
the json conversion doesn't need to create keywords, that's optional
yes, I used get-in but have experienced problems - change to keywords (not incl :@type) then OK
you don't need keywords
scratch=> (get-in {"a b c" {"d e f" 2}} ["a b c" "d e f"])
2
I agree you can use strings for keywords
for me just makes it more unreadable in complex structures
Thanks
Hi folks, I’m wondering if this is the right place to ask about something I’m not understanding that seems really basic. Please let me know if this is the wrong place for my question. I wrote a tiny bit of clojure that crawls a directory and converts markdown files to html files, and it works fine. I decided to try to write a test for it and I was surprised by what I’m seeing. Calling the code from the test doesn’t appear to write all the files. Am I missing something obvious about how clojure tests work? I was thinking maybe the test is finishing before the whole directory is crawled? I was thinking waiting a bit in the test would give me expected results if that was the case, though, which it doesn’t. I’m having a hard time debugging it to see what’s going on. I’m assuming I’m misunderstanding something about how clojure works with files. I’m not looking for someone to figure out exactly what my problem is, but would appreciate any insight in case this is a problem that is immediately obvious to experienced clojurists. I’ll add code to this thread in case that’s helpful.. I’m not always great at explaining things with words!
This is the code:
(ns site.core
(:gen-class)
(:require [datoteka.core :as fs]
[site.markdown :as md]))
(defn- process-content [content]
(md/->html content))
(defn- mirror-input-to-output [{:keys [input-dir output-dir]} node]
(->> input-dir
(fs/relativize node)
(fs/path output-dir)))
(defn- process-file [context node]
(->> node
slurp
process-content
(spit (mirror-input-to-output context node))))
(declare walk)
(defn- process-directory [context node]
(->> node (mirror-input-to-output context) fs/create-dir)
(map (partial walk context) (fs/list-dir node)))
(defn- walk [context node]
(if (fs/directory? node)
(process-directory context node)
(process-file context node)))
(defn generate-site [context]
(walk context (:input-dir context)))
(defn -main [context]
(generate-site context))
And this is the failing test I was expecting to pass:
(ns site.core-test
(:require [clojure.test :refer [deftest testing is]]
[site.core :as sut]
[ :as io]))
(def input-dir "test/site/resources/content/")
(def output-dir "test/site/resources/site/")
(deftest copies-files-to-the-right-place
(testing "for now just copies everything into the output directory"
(sut/generate-site {:input-dir input-dir :output-dir output-dir})
(let [result (->> output-dir io/file file-seq (map str)) ]
(is (= ["test/site/resources/site"
"test/site/resources/site/a-file.md"
"test/site/resources/site/a-directory"
"test/site/resources/site/a-directory/another-file.md"]
result)))))
Hi @kiraemclean, drop a snippet here and I'll have a looksee. I'm not the most experienced, but definitely happy to help.
Amazing, thank you! I added a snippet in the thread. I’m realizing that’s a painful way to view code, though. Snippet incoming..
its readable.
in process-directory
you want to put a doall
around your call to map
-- map returns a lazy sequence so it won't be fully realized (and won't perform any side effects) until you do something with all the values it produces. It works fine when you return it from -main
because that forces it to realize the lazy seq
That's probably it. This would be confirmed by the test failure output right?
Ah makes sense! I am constantly getting bitten by laziness. It’s obviously a great thing, just need to adapt to it.
That works, thanks so much for your help! Also glad it was obvious!
yeah, it's very common to use (doall (map ,,,))
for side effectful stuff, just becomes something you get used to seeing and writing 😄
Makes sense.. I need to mentally adjust to the concept of side effects being fundamentally separate from how data flows through a clojure program.
It’s really cool that it works this way, but takes some getting used to.
you may want to separate file processing from directory traversal @kiraemclean
yeah that seems like a good idea.. at first I had a collection of something like [{:path ,,, :content …}]
and writing them all at once at the end but went with this way instead because it seemed simpler. But I’m already seeing complications from mixing the two things.. testing would be much simpler if I were just checking a data structure like that.
Anyway, thanks everyone for the help, can’t believe how fast you are! So far I’m really loving clojure, a big part of it is the community.. have only encountered friendly and helpful folks so far 😄
Hope you all enjoy the rest of your weeks!
I’m having a bit of a hard time wrapping my head around zippers. I want to model my part of my application state as a literal dialogue tree that the user can navigate in back and fourth by a pointer to the data structure, ie, sound like a case where zippers would work very well. In the example https://i.imgur.com/tZy4YrU.png the current pointer to the tree is highlighted in black, and the view would display the current node along with its ancestors. But I’m having some troubles building the tree from nothing. All of the writing I can find on the subject deals with navigation and manipulation of existing trees, not construction of one. I want to make a zipper from a base ["prompt"]
and then append three children of some string, but using append child
seems to add them to the same level. I’m guessing I’m having some troubles with my conceptualisation of zippers, but if someone has any pointers i would really apprech!
Not sure if anyone replied to you, but arguably the best way would be to just have nested vectors and then call vector-zip over it like
[:prompt [:route-1 ...]
[:route-2 ...]
[:route-3 ...]]
You could use keywords, and then map them to dialogue options, accompanying image, etc. like so:
{:prompt ["Welcome to my RPG" image1.jpg]
:route-1 ["Antagonist: Oh... you're approching me?" image2.jpg]
:route-2 ["Love interest: It.. It's not like I'll miss you, or anything" image3.jpg]
:route-3 ["Hero: Just who do you think I am?" image4.jpg]}
Hello! I am new to clojure! I have a background in JavaScript using libraries like Ramda and Crocks. I am trying to branch out into other functional languages in the hopes of someday being able to use one in my day job.
Welcome! I started from a similar background, using Ramda in JS made me look for more functional languages and I ended up with Clojure
The idea of being able to use clojurescript is on the front end and clojure on the back end is very appealing to me
You can run clojurescript on the backend too: https://macchiato-framework.github.io/
Oh, interesting. What would be the reason to do that?
I guess using some javascript library you really need and has no alternative on the clojure world
If you are a NodeJS dev and want to explore what cljs has to offer on the server side
Could also seeing it being useful in the AWS lambda world where you want JS as your runtime language for a cold-start sensitive endpoint
What is the current best-practice for telling lein
to depend on a git repo (a temporary fork of the real dependency)?
https://github.com/technomancy/leiningen/blob/master/doc/TUTORIAL.md#checkout-dependencies
Thank you @U0510902N
Hi all. Sorry for a beginner question, but in clojure.spec.alpha, I was expecting explain-data to include the path of missing keys, in order to highlight the appropriate HTML elements in a form. As per the example on https://clojure.org/guides/spec
(s/explain-data ::person
{::first-name "Bugs"})
=>
{:cljs.spec.alpha/problems ({:path [],
:pred (cljs.core/fn [%] (cljs.core/contains? % :cljs.user/last-name)),
:val {:cljs.user/first-name "Bugs"},
:via [:cljs.user/person],
:in []}
{:path [],
:pred (cljs.core/fn [%] (cljs.core/contains? % :cljs.user/email)),
:val {:cljs.user/first-name "Bugs"},
:via [:cljs.user/person],
:in []}),
The :path is empty. Is there an idiomatic way of identifying missing keys programmatically? It would seem very wrong to try to parse the predicate. I guess I could merge a map without missing keys but with nil values and that would give me the paths of missing keys (empty fields), but that feels very wrong too! It does at least mean I can drill into the problems.path and get a list of the problem keys…. Is there something in the API I am missing? All advice much appreciated! Thank you!
(s/explain-data ::person
(merge {::last-name nil ::first-name nil} {::first-name "Bugs"}))
=>
{:cljs.spec.alpha/problems ({:path [],
:pred (cljs.core/fn [%] (cljs.core/contains? % :cljs.user/email)),
:val {:cljs.user/last-name nil, :cljs.user/first-name "Bugs"},
:via [:cljs.user/person],
:in []}
{:path [:cljs.user/last-name],
:pred cljs.core/string?,
:val nil,
:via [:cljs.user/person :cljs.user/last-name],
:in [:cljs.user/last-name]}), ......
Thank you. I suppose it is unlikely that the auto-generated predicate would change for a (contains?) check anyway. I suppose it is a self-inflicted problem as a proper old fashioned HTTP POST would send nil values to a server generating the next page while instead this new-fangled front-end cljs ‘fake submit’ malarkey generates a map with missing keys unless the user does something to trigger on-change actions. Thank you for your help.
Also, there is absolutely no reason to apologize for asking beginner questions on the #beginners channel -- you are in the right place 🙂
There is also a tiny library, phrase, that makes parsing of those preds easier
And Expound is another one that turns explain-data
into human-readable messages...
Thank you - I’ll check them both out! Might have known that it’d already be solved!
Hi all, I'm doing a talk Thu night (US Central time) at our local Java user group about Clojure. This is intended for people new to Clojure, particularly those coming from Java. RSVP here if interested to get access: https://www.meetup.com/GatewayJUG/events/266496097/ Note - if you are familiar with Clojure already, you will not find this useful and the number of spots is limited, so please let others join instead