Fork me on GitHub
#beginners
<
2019-09-02
>
borkdude07:09:53

@gisf You may be interested in https://re-find.it/ if you want to find a function for an example to an example: e.g. 1 => "1" https://re-find.it/?args=1&amp;ret=%221%22

❤️ 1
hamid tsh08:09:36

hi. how can i use http request between clojure as a server and clojurescript as a client?

Mno08:09:01

have you tried with: https://github.com/r0man/cljs-http If you're more used to ajax maybe: https://github.com/JulianBirch/cljs-ajax I'm not great at cljs, so if someone recommends something take their opinion first.

Mno08:09:14

if it isn't what you're looking for you can also check in or post the question on: https://ask.clojure.org 😄

hamid tsh08:09:24

thanks for your answer. I tried the first link for client but it did't sync with clj-http library for clojure.

Vesa Norilo10:09:41

just using the javascript fetch api from cljs isn't too bad either

hamid tsh11:09:30

can you give me an example?

Leon11:09:59

back to my macro-question from yesterday: it worked! but there is one big problem: i now can only use concrete values in my forms, and nothing that needs to be calculated (especially nothing that is dependent on locals stuff) is it even possible to avoid this problem? i tried things like eval-ing the rest of each form and quoting the first, but then i get cannot eval locals errors, which obviously make sense. any ideas? (my problem was the following: i need a macro that can get called like this:

(foo
  [+ 1 2]
  [str 123]
)
(vararg) and return a structure like this:
['(+ 1 2) '(str 123)]
without giving me the function-objects, but the actual symbols of the functions. i know realized that i might need a different return structure...)

Leon11:09:03

wait i think I got it... altough it seems ugly:

(defmacro foo [& forms]
  (let [lists# (for [[func & args] forms]
                 (list 'apply 'list
                  (apply vector
                    (list 'quote func)
                    args)))]
    `[[email protected]#]))

Leon11:09:36

okay what could cause: Caused by: java.lang.RuntimeException: Unable to resolve symbol: apply in this context ? getting it somewhere related to my macro-definition from before, but the line-number doesn't help at all...

henrik11:09:39

Could it be from elsewhere in the code? I get no such error:

henrik11:09:49

(foo (str "hello" "world") (str "dog" a))

henrik11:09:59

[(str "hello" "world") (str "dog" 9)]

henrik12:09:17

(where a is (def a 9))

Leon12:09:01

ill try to reproduce it in the most simple way

Leon12:09:14

it could be related to me using that macro within a generated namespace or something, maybe i need to somehow first include core stuff in generated namespaces?

Leon12:09:37

haha wow that seems to have been it.... i just added [clojure.core :refer :all] to my requrie thing in the namespace and now it seems to work

Felix Linker12:09:39

I updated my java recently and started to get this warning in one of my projects:

ARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by clojure.lang.InjectedInvoker/0x0000000801368040 (file:/C:/Users/felix/git/smvtrcviz/target/uberjar/smvtrcviz-0.1.0-SNAPSHOT-standalone.jar) to method com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl.parse(org.xml.sax.InputSource,org.xml.sax.helpers.DefaultHandler)
WARNING: Please consider reporting this to the maintainers of clojure.lang.InjectedInvoker/0x0000000801368040
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
After digging around a bit I found a way to debug it and managed to pinpoint the source of the warning to clojure.xml$startparse_sax.invokeStatic(xml.clj:76). Is this an issue that is worth reporting? And if so: Is it right to do it here https://groups.google.com/forum/#!forum/clojure? Or is there something I could do about this.

alexmiller12:09:08

There is a ticket for this, really it’s just a warning from use of reflection in clojure.xml (which really no one should use anyways)

👍 1
Felix Linker12:09:54

So I just should wait and pray? 😇

alexmiller12:09:49

To understand more, this faq entry is helpful https://clojure.org/guides/faq#illegal_access

alexmiller12:09:34

In this particular case, the Clojure code in clojure.xml is intentionally reflective in ways that are difficult to fix. clojure.xml is very old and really superseded by libraries like clojure.data/xml

alexmiller13:09:25

This warning is just a warning - it can be safely ignored

alexmiller13:09:13

There are various flags you could pass to make this particular reflective access valid but I’m not sure it’s worth doing so

alexmiller13:09:05

I presume the usage is in smvtrcviz - that lib could be changed to use a better api

Felix Linker13:09:27

Well, just changed the xml parser to clojure.data.xml but that also has an illegal reflective access. Thanks for all the information, though!

alexmiller13:09:26

Are you using the latest? I thought these issues were fixed in clojure.data.xml

alexmiller13:09:14

0.2.0-alpha6 is latest

Felix Linker13:09:34

No, I was using stable. Will try latest as well.

alexmiller13:09:43

despite the name, latest is very stable

alexmiller13:09:52

(and prior is pretty old now)

Felix Linker14:09:43

Works fine with latest! Thanks for the hint on that library 🙂

Patrick P.12:09:11

this.tempWorkingPath = this.cfg.autoImport.tempWorkingDir.replace('$MANDANT$','M' + mandantNr);

sova-soars-the-sora14:09:44

Hey everyone, i'm using Rum to generate a japanese grammar quiz. It's cool, a fragment is hidden from you, it shuffles the fragment correct response with some faulty ones and renders them as buttons

sova-soars-the-sora15:09:47

And I thought I had a problem with react keys but... i just fixed it 😄

sova-soars-the-sora15:09:53

amazing what fresh eyes can do

alberson17:09:06

Hi friends. I just came by the function eduction that takes some transducers, a list and apply them. My question is: when should I prefer eduction over ->>?

alberson17:09:49

(->> (take 10) (filter odd?))
;; over
(eduction (filter odd?) (take 10))

alexmiller17:09:18

eduction is pretty specialized in that it is a delayed eager evaluation

alexmiller17:09:33

the most common use case is to set up a reduction over an external resource (file, db result, etc) and hand that to a caller, who can a) decide when to invoke it and b) know that since it's eager the resource use is complete

alexmiller17:09:53

vs lazy sequences which are also delayed (but throughout, not just at the beginning) but are harder to catch and handle the "end" for resource control

alberson17:09:57

So opposite to ->>, eduction applies the transducers to the given list lazily?

alexmiller18:09:28

I'd say that's wrong on both counts. ->> creates a lazily computed sequence which will produce values as needed. eduction creates a pending computation. when you ask for the first value, it will compute the entire collection eagerly at that point.

1
alberson18:09:41

Oh, now I get it. Thanks for the explanation

jumar11:09:24

@alexmiller I got confused by your statement that eduction computes the whole collection eagerly when you ask for the first value. Trying something like this shows that it only consumes a "chunk" of a lazy seq:

(def cnt1 (atom 0))
(let [res (eduction (map #(do (swap! cnt1 inc) %)) (range 100))]
  (conj (rest res) (first res))
  @cnt1)
;; 66 (2 x 33 - chunked seqs?)
Am I misinterpreting you?

1
kenj17:09:31

out of curiosity, any idea how the name “eduction” came to be?

alexmiller18:09:14

it's a real word. transduce means "to lead across". educe means "to draw out" or "to lead out"

kenj18:09:11

huh, TIL… thanks!

Vachi21:09:26

hi guys, I'm having hard time to figure out how to go from this :

(def test-a [{:tag :categories}
             {:tag     :associations
              :content [{:tag     :categories
                         :content '()}
                        {:tag     :products
                         :content [{:tag :product}
                                   {:tag :product}
                                   {:tag :product}]}]}]) 

Vachi21:09:45

to this:

[{:tag :categories}
 {:tag     :associations
  :content [{:tag     :categories
             :content '()}
            {:tag     :products
             :content []}]}] 

Vachi21:09:06

which is set the : content inside of {:tag : products } to empty a vector

schmee21:09:28

you can use assoc-in for this:

(assoc-in test-a [1 :content 1 :content] [])

👏 1
Vachi21:09:13

thanks!

👍 1
Vachi21:09:04

@schmee i'm trying to use the same for a lazy seq , but it don't seem to work , what is the alternative for lazy seqs?

schmee21:09:24

you can’t access lazy-seq elements by index (only using first/`rest`) but you can convert the lazy seq to a vector with vec

Vachi22:09:32

many thanks! it worked!

Vachi22:09:20

(let [remote-categories (remote-get categories)
      cat1              (remote-get (str categories "/12"))
      xml               (->xml cat1)]
  (as-> (:content xml) v
        (vec v)
        (update-in v [0 :content] vec)
        (update-in v [0 :content 16 :content] vec)
        (update-in v [0 :content 16 :content 1 :content] vec)
        (update-in v [0 :content 16 :content 1 :content 1] vec)
        (assoc-in v [0 :content 16 :content 1 :content] ()))) 

Vachi22:09:48

is there a nicer way? , I had to convert all the nested lazy seqs to vec in order to get it work

schmee22:09:16

where is the data coming from? is it clojure.data.xml?

seancorfield22:09:58

@vachichng You don't need as-> there -- plain -> will work (and then omit v in all those expressions). as-> is intended to be used inside a -> pipeline rather than at the top-level.

👍 1
David Pham22:09:01

@vachichng did you try to write a recursive function?

David Pham22:09:20

Or use use clojure.zip?

seancorfield22:09:01

Overall tho', it looks like you might be better served by transforming this to some data structure that would be more amenable to processing -- can you explain in more detail what end result you're trying to achieve?

Vachi22:09:37

@seancorfield yeah, I'm consuming a webservice from prestashop, which serves xml data , what I'm trying to do , is get a xml from one instance and do a post to another instance ( migrate data ) with some fields changed

seancorfield22:09:16

Ugh! That's an unpleasant task. In that case, I think the suggestion to use zippers is probably going to be your best approach so you can convert XML to data, modify it with zippers, and convert it back to XML.

👍 1
👏 1
Vachi22:09:04

@neo2551 I will have a look at clojure.zip , thanks!

Vachi22:09:26

so, zippers are the recomended way to do xml transformation?

Ian Fernandez22:09:45

hey guys, I didn't understood this error

Ian Fernandez22:09:47

class clojure.lang.Keyword cannot be cast to class java.lang.String (clojure.lang.Keyword is in unnamed module of loader 'app'; java.lang.String is in module java.base of loader 'bootstrap')

Ian Fernandez22:09:27

I made this error using environ

Ian Fernandez22:09:44

(->> environ/env (reduce-kv (fn [m k v] (assoc m (keyword "env" k) v)) {}))

Ian Fernandez22:09:48

and doing this

dpsutton22:09:09

(keyword "bob" :bob) -> ClassCastException clojure.lang.Keyword cannot be cast to java.lang.String clojure.core/keyword (core.clj:595). You need to use strings not kewords. But what are you putting these with an env namespace?

Ian Fernandez22:09:31

I'm mixing another file into environ and calling this with another function that I use (let [:env/keys [...] ... )

johnjelinek23:09:45

do I need to run spec/explain on this to find out what the problem is?

(ns hello-cdk.hello-stack
  (:gen-class
   :extends software.amazon.awscdk.core.Stack
   :constructors {[software.amazon.awscdk.core.Construct String] [software.amazon.awscdk.core.Construct String nil]
                  [software.amazon.awscdk.core.Construct String software.amazon.awscdk.core.StackProps] [software.amazon.awscdk.core.Construct String software.amazon.awscdk.core.StackProps]}
   :init "init")
  (:import (software.amazon.awscdk.core Construct Stack StackProps)
           (software.amazon.awscdk.services.s3 Bucket BucketProps)))

Syntax error macroexpanding clojure.core/ns at (REPL:1:1).
((:gen-class :extends software.amazon.awscdk.core.Stack :constructors {[software.amazon.awscdk.core.Construct String] [software.amazon.awscdk.core.Construct String nil], [software.amazon.awscdk.core.Construct String software.amazon.awscdk.core.StackProps] [software.amazon.awscdk.core.Construct String software.amazon.awscdk.core.StackProps]} :init "init") (:import (software.amazon.awscdk.core Construct Stack StackProps) (software.amazon.awscdk.services.s3 Bucket BucketProps))) - failed: Extra input spec: :clojure.core.specs.alpha/ns-form
class clojure.lang.Compiler$CompilerException

seancorfield23:09:25

*e will print the entire exception and stack trace but I don't think it will help you...

seancorfield23:09:07

I think the problem is that you omitted the :name option -- which is the only mandatory option for :gen-class if I'm reading the docs correctly...

seancorfield23:09:17

Hmm, well, that's not the only problem... let me read the docs more closely...

johnjelinek23:09:05

added :name:

Syntax error macroexpanding clojure.core/ns at (src/hello_cdk//Users/johnjelinek/Documents/code/hello-cdk/src/hello_cdk/hello_stack.clj:1:1).
((:gen-class :name hello-cdk.hello-stack :extends software.amazon.awscdk.core.Stack :constructors {[software.amazon.awscdk.core.Construct String] [software.amazon.awscdk.core.Construct String nil], [software.amazon.awscdk.core.Construct String software.amazon.awscdk.core.StackProps] [software.amazon.awscdk.core.Construct String software.amazon.awscdk.core.StackProps]} :init init) (:import (software.amazon.awscdk.core Construct Stack StackProps) (software.amazon.awscdk.services.s3 Bucket BucketProps))) - failed: Extra input spec: :clojure.core.specs.alpha/ns-form

johnjelinek23:09:25

I tried wrapping this in an (s/explain .. didn't add any extra info

seancorfield23:09:34

Like I said "not the only problem" 🙂

seancorfield23:09:54

I almost never use :gen-class and I wrestle with it every time I do... 😞

johnjelinek23:09:04

*e
#error {
 :cause "Call to clojure.core/ns did not conform to spec."

seancorfield23:09:22

Yeah, exactly. I said it wouldn't help 😐

johnjelinek23:09:00

:data #:clojure.spec.alpha{:problems [{:path [], :reason "Extra input", :pred (clojure.spec.alpha/cat :docstring (clojure.spec.alpha/? clojure.core/string?) :attr-map (clojure.spec.alpha/? clojure.core/map?)

johnjelinek23:09:56

wat ... it got fixed when I remove nil

seancorfield23:09:07

:init init not :init "init" as well I think?

johnjelinek23:09:12

this evaluates:

(ns hello-cdk.hello-stack
  (:gen-class
   :name hello-cdk.hello-stack
   :extends software.amazon.awscdk.core.Stack
   :constructors {[software.amazon.awscdk.core.Construct String] [software.amazon.awscdk.core.Construct String]
                  [software.amazon.awscdk.core.Construct String software.amazon.awscdk.core.StackProps] [software.amazon.awscdk.core.Construct String software.amazon.awscdk.core.StackProps]}
   :init init)
  (:import (software.amazon.awscdk.core Construct Stack StackProps)
           (software.amazon.awscdk.services.s3 Bucket BucketProps)))

seancorfield23:09:28

And, yeah, nil is not a class name. I was just about to point that out.

johnjelinek23:09:37

the thing is .... for the first constructor, it needs to pass nil to the third param of the superclass

seancorfield23:09:47

You need the type there.

seancorfield23:09:59

software.amazon.awscdk.core.StackProps

johnjelinek23:09:25

ya, that evals ... but, how do I tell it to pass null to that? does it happen automatically since there's only 2 params passed to the constructor?

seancorfield23:09:41

You write the constructor.

johnjelinek23:09:38

(defn -init
  ([parent id] ,,,)
  ([parent id props] ,,,))
replacing the body with what to tell it to pass to super? I thought gen-class handled that part

seancorfield23:09:01

The :constructors part tells Clojure what signatures to use for the generated Java code -- but you still write the code.

seancorfield23:09:46

At least, that's my understanding... but, like I say, I don't use :gen-class very often.

seancorfield23:09:37

The init function is weird. It returns a pair of values -- the first value is the list of values to pass to the super constructor, the second value is any state your class needs.

seancorfield23:09:49

So based on your example, I'd expect something like:

(defn -init
  ([parent id] [[parent id nil] ,,,])
  ([parent id props] [[parent id props] ,,,]))

seancorfield23:09:23

So in the two-arg case, you return a triple that is used to call the super constructor, passing nil as the third arg.

seancorfield23:09:31

Does that help @johnjelinek?

👀 1