Fork me on GitHub
#beginners
<
2019-08-25
>
norilinoriginal01:08:45

couldn't get a functioning repl on emacs or cursive if vim doesn't work i'm making a linux partition.

jakob.durstberger10:08:37

Hello, I am trying to define a function inside a macro. I googled for a while but can't seem to search for the right thing. I tried:

(defmacro defattrs
  []
  `(defn my-function [] nil))
but I get the error: failed: simple-symbol? at: [:fn-name] spec: :clojure.core.specs.alpha/defn-args Maybe someone could help me out? Would be highly appreciated 🙂

danieleneal13:08:41

Try doing a macroexpand on your macro and seeing what it expands to. Away from computer at the moment but something like (macroexpand-1 '(defattrs)) Expansion is my first port of call with macro errors - is the macro really expanding to the code I think it is expanding to. I think here that my-function has probably become namespace qualified - some.ns/my-function which means it's no longer a simple symbol.

jakob.durstberger14:08:19

Thank you I'll try using macroexpand

danieleneal10:08:30

@jakob.durstberger

pez10:08:48

Is there a way to evaluate something at the REPL without it affecting *1 et all?

j.m.frith11:08:02

Hi everyone. I'm having a great time with spec, I'm using expound to format spec errors, and I'm using cursive for development. Following expound's docs I have (set! s/*explain-out* expound/printer) but cursive is giving me a "cannot be resolved" warning on s/*explain-out*. I have required [clojure.spec.alpha :as s]

j.m.frith11:08:36

Is there actually anything wrong, or should I just ignore the warning? Generally I like to fully understand why I'm getting warnings before ignoring them, so any explanation of why this might be happening would be gratefully received

sova14:08:53

So I'm still working on this XML -> EDN mini project interstitial bridge and i'm wondering, what is this https://github.com/thebusby/into-edn into-edn library doing at the end that cannot be done with plain vanilla zipper and xml?

neo255114:08:17

In CLJS, how can we emulate create a state variable in react? I tried to use reagent/atom and js-obj, but I was unsuccessful.

danieleneal15:08:15

How did you use reagent/atom?

neo255115:08:36

I followed this example

neo255115:08:34

But my issue I define my component in did-mount, but the component never gets the new props in component-did-update.

neo255115:08:48

Maybe I will retry to use useState from 16.8

danieleneal15:08:26

Oh are you trying to use hooks? Reagent doesn't work very well with hooks, as it has its own way of handling state

danieleneal15:08:30

The basic reagent way for local state would be to use a form 2 component - declare a reagent atom and return a render function

danieleneal15:08:20

(defn counter [] (let [n (r/atom 0) (fn [] [:span {:on-click #(swap! n inc)} @n])))

danieleneal15:08:42

The example you posted is specifically about interop with js components that may have their own non react state

danieleneal15:08:18

If you've got more hooks experience you could try the library hx

sova16:08:28

xml is melting my brain

sova16:08:36

hope you're all having a sunshiney day 😄

neo255116:08:44

@danieleneal Thanks for the tip, however I am trying to interop with a JS react component that mutates its internal states to communicate changes to its children

neo255116:08:51

I am trying to reimplement this component with CLJS

sova16:08:14

how can i turn the big clojure data structure i got from an xml file into a neat clojure map?

sova16:08:34

#clojure.data.xml.Element{:tag :entry, :attrs {}, :content (#clojure.data.xml.Element{:tag :ent_seq, :attrs {}, :content (1000000)} #clojure.data.xml.Element{:tag :r_ele, :attrs {}, :content (#clojure.data.xml.Element{:tag :reb, :attrs {}, :content (ヽ)})} #clojure.data.xml.Element{:tag :sense, :attrs {}, :content (#clojure.data.xml.Element{:tag :pos, :attrs {}, :content (unclassified)} #clojure.data.xml.Element{:tag :gloss, :attrs {:g_type expl, :xml:lang eng}, :content (repetition mark in katakana)})})}

sova16:08:58

i want to end up with a vector of entries, each entry a map,

[{:ent_seq 100000 
:reb ヽ
:sense {:gloss "repetition mark in katakana"}]

sova16:08:42

some keys of entries might end up having vectors of maps (like in the case of multiple :glosses )

sova16:08:13

it's pretty much the most basic thing to do with an xml file in clojure, make it a clojure datastructure without the fluff, but i'm trying to think of how to do it efficiently because the file is kinda big for zipping and stepping... so i'm just working with a smaller file for the moment, like i don't want to do (doseq) with conditionals, but maybe that's the best way?

alexmiller16:08:20

generically, it seems like you want to recursively convert Elements to some Clojure data

alexmiller16:08:05

you could actually do it recursively, but you'd want to be somewhat careful not to end up holding too much in memory and blowing either the stack or the heap

alexmiller16:08:46

another option might be to use clojure.walk/postwalk-replace

alexmiller16:08:52

which again, might need to be a little careful

sova16:08:46

Right on. Well it's not a big deal because I only have to do this once really

sova16:08:56

Recursively probably OK

alexmiller16:08:06

oh, well that's nothing

alexmiller16:08:11

recurse away :)

sova17:08:43

recursion is like learning to pop a bubble molecule by molecule

alexmiller17:08:25

well you only need to learn how to do the first one :)

sova17:08:57

So i get something like

sova17:08:04

#clojure.data.xml.Element{:tag :JMdict, :attrs {}, :content (#clojure.data.xml.Element{:tag :entry, :attrs {}, :content (#clojure.data.xml.Element{:tag :ent_seq, :attrs {}, :content (1000000)} #clojure.data.xml.Element{:tag :r_ele, :attrs {}, :content (#clojure.data.xml.Element{:tag :reb, :attrs {}, :content (ヽ)})} #clojure.data.xml.Element{:tag :sense, :attrs {}, :content (#clojure.data.xml.Element{:tag :pos, :attrs {}, :content (unclassified)} #clojure.data.xml.Element{:tag :gloss, :attrs {:g_type expl, :xml:lang eng}, :content (repetition mark in katakana)})})} #clojure.data.xml.Element{:tag :entry, :attrs {}, :content (#clojure.data.xml.Element{:tag :ent_seq, :attrs {}, :content (1000010)} #clojure.data.xml.Element{:tag :r_ele, :attrs {}, :content (#clojure.data.xml.Element{:tag :reb, :attrs {}, :content (ヾ)})} #clojure.data.xml.Element{:tag :sense, :attrs {}, :content (#clojure.data.xml.Element{:tag :pos, :attrs {}, :content (unclassified)} #clojure.data.xml.Element{...

sova17:08:37

I can invoke (first j-coll) and (rest j-coll)... but when I do (first j-coll) I get a sequence of vectors

dpsutton17:08:20

not sure what j-coll is but if its the data xml that's a record so you probably don't want to interact with it with first and rest

sova17:08:35

right thank you

sova17:08:55

i don't know which spoon to use on this melon

dpsutton17:08:07

what do you want to do?

dpsutton17:08:28

the docs say its a defrecord but its actually a custom deftype

sova17:08:59

I want to parse this xml japanese dictionary file called jmdict and create a vector of clojure maps for each entry

sova17:08:09

the tags are pretty simple <entry><ent_seq>###</ent_seq><k_ele><keb>~</keb></k_ele><sense>...</sense></entry> but i'm having a hard time accessing the first content child because i'm not sure what to do to recurse over xml.Element

dpsutton17:08:25

i think you essentially have that. you have a "map" with a key :content which is a seq of nodes, each of which is a map. is pretty 1-1 with "vector of clojure maps for each entry"

sova17:08:20

I want to spit it out into clojure consumable data so that i can mess with it more for this web app

sova17:08:51

yeah, so aside from first and rest ... should I check if the node is typeof xml.Element and then attempt to access content?

dpsutton17:08:47

i think you want to write a function of xlm.Element -> clojure map?

sova17:08:24

yeah i think so

dpsutton17:08:39

#clojure.data.xml.Element{:tag :entry, :attrs {}, :content (#clojure.data.xml.Element{:tag :ent_seq, :attrs {}, :content (1000000)} #clojure.data.xml.Element{:tag :r_ele, :attrs {}, :content (#clojure.data.xml.Element{:tag :reb, :attrs {}, :content (ヽ)})} #clojure.data.xml.Element{:tag :sense, :attrs {}, :content (#clojure.data.xml.Element{:tag :pos, :attrs {}, :content (unclassified)}
would this turn into?

sova17:08:02

Something like

[{:entry {:ent_seq "100000"
                   :r_ele {:reb   "ヽ"}
                   :sense { :pos "unclassified" }}]

sova17:08:50

Let's do another one that's actually a word...

sova17:08:00

<entry>
<ent_seq>1000130</ent_seq>
   <k_ele>
       <keb>N響</keb>
   </k_ele>
   <r_ele>
    <reb>エヌきょう</reb>
   </r_ele>
   <sense>
     <pos>&n;</pos>
     <misc>&abbr;</misc>
     <gloss>NHK Symphony Orchestra</gloss>
   </sense>
</entry>

sova17:08:27

is the native XML

sova17:08:53

#clojure.data.xml.Element{:tag :entry, :attrs {}, :content (#clojure.data.xml.Element{:tag :ent_seq, :attrs {}, :content (1000130)} #clojure.data.xml.Element{:tag :k_ele, :attrs {}, :content (#clojure.data.xml.Element{:tag :keb, :attrs {}, :content (N響)})} #clojure.data.xml.Element{:tag :r_ele, :attrs {}, :content (#clojure.data.xml.Element{:tag :reb, :attrs {}, :content (エヌきょう)})} #clojure.data.xml.Element{:tag :sense, :attrs {}, :content (#clojure.data.xml.Element{:tag :pos, :attrs {}, :content (noun (common) (futsuumeishi))} #clojure.data.xml.Element{:tag :misc, :attrs {}, :content (abbreviation)} #clojure.data.xml.Element{:tag :gloss, :attrs {:xml:lang eng}, :content (NHK Symphony Orchestra)})})}

sova17:08:14

desired:

[{:entry {:ent_seq "1000130"
                   :k_ele {:keb "N響"}
                   :r_ele {:reb   "エヌきょう"}
                   :sense { :pos "&n;" 
                                 :misc "&abbr;" 
                                 :gloss "NHK Symphony Orchestra"}}]

sova18:08:31

Anyway don't stress to much about it, i'll figure it out ^^

sova18:08:44

not to mention this file is full of landmines like &n;

sova18:08:48

i'm one of those people who abhors reading the manual

sova18:08:59

but when i finally sit down and do things end up being clearer

sova19:08:40

how would I set jdk.xml.entityExpansionLimit = 0 in :jvm-opts []?

andy.fingerhut19:08:04

Maybe something like ["-Djdk.xml.entityExpansionLimit=0"]

sova19:08:49

o.o Caused by: java.lang.OutOfMemoryError: GC overhead limit exceeded

sova20:08:00

now that i've increased the jvm available mem i think it 'll go now ^_^

norilinoriginal20:08:07

Has anybody on windows encountered this error message? >lein deps java.io.IOException: Cannot run the program clojure in directory xyz. CreateProcess error=2 The system cannot find the file specified at java.lang.ProcessBuilder.start (ProcessBuilder.java:1128)

norilinoriginal20:08:15

I'm testing my setup by trying to get a functioning repl inside of a clone of overtone

andy.fingerhut20:08:53

If no one here knows the answer, there is also a #leiningen channel where someone may

sova20:08:14

Hmmm... How to deftly manipulate a deftype?

sova20:08:02

@norilinoriginal Cannot find clojure? hmm that's a weird one...

norilinoriginal20:08:29

Yeah, I've added clojure explicitly to the $PATH and to the :user profiles.clj

norilinoriginal20:08:34

It's accompanied by Caused by: java.io.IOException: CreateProcess error=2, The system cannot find the file specified at java.lang.ProcessImpl.create (ProcessImpl.java:-2)

norilinoriginal20:08:36

it's worth mentioning that I can create a repl in , I just can't in /_dev/overtone

norilinoriginal20:08:41

I can connect to the REPL I create from ~, but then it can't find the classes I reference.

sova20:08:48

@norilinoriginal Try creating a shortcut link to your global clojure executable

sova20:08:03

and drop it into ~/_dev/overtone

sova20:08:33

i don't play on windows much with clojure ;x but maybe that can help

sova20:08:54

(defn recurse-over-jmdict [element]
	(cond
        (instance? clojure.data.xml.Element element)
          (do
              (println element)
              (recurse-over-jmdict (:content element)))
							;	(string? element) (println "str: " element)
							;	(integer? element) (println "int: " element)
        :else "heyx"))
;external entry point into bubble popping recursive function (recurse-over-jmdict parsed-jmdict)` How can I "step in to" a #clojure.data.xml.Element{:tag :JMdict, :attrs {}, :content (#clojure.data.xml.Element{.......})} ? I try accessing the :content of element with (:content element) but this is apparently not the way to access the content field of data.xml.Element

norilinoriginal21:08:55

you mean this guy, right?

norilinoriginal21:08:29

it normally lives at C:\Users\noril\Documents\WindowsPowerShell\Modules\ClojureTools

sova21:08:25

Did you try asking in leiningen ? hopefully somebody can help. Did you install clojure via package manager of some kind?

sova21:08:27

i feel like i'm missing something very basic about deftypes

norilinoriginal21:08:20

I asked in leinengen, yes. I did not install clojure via package manager, I installed it via clojure on windows. https://github.com/clojure/tools.deps.alpha/wiki/clj-on-Windows

sova21:08:15

clojure.xml/parse doesn't put lots of #clojure.xml.data.Element{}s everywhere so I just switched to that

sova21:08:59

you may have to reinstall with admin privs

sova21:08:04

so it's a global executable,

sova21:08:12

that's just my guess with how windows is

matt.wistrand21:08:58

If I want to test a function that creates a file, is the best approach to allow the test(s) to create files and use .deleteOnExit for cleanup after the fact? It looks like that’s how tests handle I/O unit tests?

andy.fingerhut22:08:40

I cannot think of a way to actually test the ability of code to create files, without actually letting it create a file.

andy.fingerhut22:08:13

One could imagine testing it inside of a container, or VM, etc. and then blowing away the entire container/VM after the test, but deleting a single file seems a lot quicker.

andy.fingerhut22:08:26

(or even deleting hundreds of files seems a lot quicker)

matt.wistrand01:08:59

Thanks, Andy! That’s essentially what I’ve concluded as well. I’m still trying to find a clean way to run a “delete file after test completes” for this specific situation I’m in, but I’ll get there.

andy.fingerhut01:08:46

You can do it in the finally block of a try, would be one wa

matt.wistrand13:08:46

Thanks again. I ended up with the following (although it appears the catch block is unnecessary):

(deftest generate-file-test
  (testing "generate file"
    (let [filename (create-file "hello-world")]
      (is (re-matches #"resources\/files\/\d+-hello-world\.edn$" filename))

      (try
        (let [contents (slurp filename)]
          (is (= contents "generated contents")))
        (catch Exception e
          (throw e))
        (finally
          (.delete (io/file filename)))))))

zhuxun221:08:33

Hi all, beginner here. How do I tell if a name represents a function or a macro?

zhuxun221:08:10

(programmably)

norilinoriginal21:08:14

@zhuxun2 functions and macros don't possess any distinctive symbolic identifiers or attributes to my knowledge.

norilinoriginal22:08:37

Functionally, you can consider them to inhabit the same category of 'function'.

zhuxun222:08:50

@norilinoriginal Thanks, so you are saying it's impossible to programmably tell them apart by design?

zhuxun222:08:12

But interestingly syntax highlighters seem to be able to color them differently

zhuxun222:08:25

for example, the rebel-readline

norilinoriginal22:08:24

>>>macroexpand-1 function Usage: (macroexpand-1 form) If form represents a macro form, returns its expansion, else returns form. Added in Clojure version 1.0

norilinoriginal22:08:03

>macroexpand function Usage: (macroexpand form) Repeatedly calls macroexpand-1 on form until it no longer represents a macro form, then returns it. Note neither macroexpand-1 nor macroexpand expand macros in subforms. Added in Clojure version 1.0

norilinoriginal22:08:44

@zhuxun2 Those two functions appear to be able to programmatically identify macros when they're not inside subforms.

andy.fingerhut22:08:20

@zhuxun2 Something like this may work for you:

user=> (:macro (meta #'let))
true
user=> (:macro (meta #'str))
nil

andy.fingerhut22:08:45

That is for Clojure/Java, at least. It is probably different in ClojureScript, where macros are a bit different than Clojure/Java.

zhuxun222:08:16

Is there a way for me to run some code before I open up my clojure repl (I mean the $ clojure repl)

zhuxun222:08:35

I mostly wanna add some shortcut functions

zhuxun222:08:10

I guess something like .vimrc would be nice

norilinoriginal23:08:45

I reinstalled Clojure as admin and I still get the same error messages.

norilinoriginal23:08:35

I added the new path to the PATH and tried >clj and I got Copy-Item : Cannot find path 'C:\Users\noril\Documents\WindowsPowerShell\Modules\ClojureTools\example-deps.edn' because it does not exist. At C:\Users\noril\Documents\WindowsPowerShell\Modules\ClojureTools\ClojureTools.psm 1:196 char:5 + Copy-Item "$InstallDir\example-deps.edn" "$ConfigDir\deps.edn" + + CategoryInfo : ObjectNotFound: (C:\Users\noril\...xample-deps.edn:S tring) [Copy-Item], ItemNotFoundException + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.CopyItemC ommand

norilinoriginal23:08:07

Then I cleaned up the PATH so I can clj from that directory but not lein.

seancorfield23:08:02

@norilinoriginal maybe take this to #clj-on-windows -- the Powershell installer is basically pre-alpha and still be actively worked on. The folks in that channel will be more knowledgeable about what works and what doesn't, as well as asking the right questions to help you debug the problem.

norilinoriginal23:08:15

thanks for linking, i didn't know how to get there

seancorfield23:08:23

(just bear in mind it is Sunday and the channel may be quiet today)

norilinoriginal23:08:42

I got here via link from the clj on windows github page, idk where to find all the channels here though.

seancorfield23:08:50

@norilinoriginal There's a #slack-help channel (which you should be auto-joined into?) where you can ask how to use/navigate Slack 🙂