Fork me on GitHub
#clojure
<
2019-11-30
>
ro600:11:16

clojure.edn/read-string uses *data-readers* right? I'm getting "No reader function for tag time/zoned-date-time" even though time/zoned-date-time => #'time-literals.data-readers/zoned-date-time is in *data-readers*

noisesmith00:11:05

@robert.mather.rmm you can provide data readers as an optional argument, otherwise only the default data readers are used, according to the doc string of edn/read

noisesmith00:11:16

I'm trying to figure out if it uses the default readers vs. the ones explicitly passed, not certain yet https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/EdnReader.java

noisesmith00:11:56

fwiw that java file has no reference to *data-readers* that it would grab, and the value also isn't passed in by clojure.edn/read

ro600:11:44

Thanks. Passing explicitly via the :readers opt worked. I was just surprised *data-readers*` wasn't used. What's that for, if not the built-in reading mechanisms? Does it only get used for core/read not edn/read?

noisesmith00:11:00

precisely that

ro600:11:34

I guess that makes some sense due to the safety issues around core/read

noisesmith00:11:17

I think this summarizes the behaviors and workaround

(ins)user=> (println (slurp "src/data_readers.clj"))
{foo/bar clojure.core/set}

nil
(cmd)user=> #foo/bar[1 2 3]
#{1 3 2}
(ins)user=> (read-string "#foo/bar[4 5 6]")
#{4 6 5}
(cmd)user=> (clojure.edn/read-string "#foo/bar[1 2 3]")
Execution error at user/eval154 (REPL:1).
No reader function for tag foo/bar
(cmd)user=> (clojure.edn/read-string {:readers *data-readers*} "#foo/bar[1 2 3]")
#{1 3 2}

dpsutton04:11:57

clojure-lsp uses org.eclipse.lsp4j and has a single java file

@JsonSegment("clojure")
public class ClojureExtensions {
	@JsonRequest
  @SuppressWarnings("unchecked")
	CompletableFuture<String> dependencyContents(TextDocumentIdentifier documentUri) {
    IFn require = Clojure.var("clojure.core", "require");
    require.invoke(Clojure.read("clojure-lsp.main"));
    IFn extension = Clojure.var("clojure-lsp.main", "extension");
    return (CompletableFuture<String>) extension.invoke("dependencyContents", documentUri);

dpsutton04:11:10

this causes in target/

├── classes
│   ├── clojure_lsp
│   │   └── ClojureExtensions.class
│   └── org
│       └── eclipse
│           └── lsp4j
│               └── TextDocumentIdentifier.class
which causes a problem. Since the lsp4j jar is signed, this other class is not signed and the jvm rejects this as a security exception

dpsutton04:11:35

:cause class "org.eclipse.lsp4j.TextDocumentIdentifier"'s signer information does not match signer information of other classes in the same package

dpsutton04:11:31

This problem seems to only happen on java > 8. Can anyone point me in a direction to understand why this TextDocumentIdentifier is being compiled? Removing this class file prevents the security error

hiredman05:11:26

I misunderstood, that is a weird one

dpsutton06:11:50

i think i have solved it with -implicit:none as a javac option but i don't know if i'm solving the root issue or solving a symptom

hiredman06:11:11

I wonder if there is something in the deps tree for lsp4j that is including the Java source that you could exclude. I have this vague idea that lsp4j is using eclispe's custom Java syntax thing, and the tooling for that somehow ends up including Java source in jars, and then lein's use of the javax tools javac results in a compiler that looks for source anywhere on the classpath, which results in compiling that class. But I don't know for sure about most of that. And I am not sure if that explains why just that one class is compiled.

dpsutton06:11:00

still digesting what you wrote but yes its using xtend, the sugar over java language

dpsutton06:11:11

that one class is the only one imported into the java file in lsp. i've been trying other java classes and no other ones end up in the output so your theory is a good starting point for me

dpsutton06:11:48

another thought. java looks for class files and source files, by default preferring whichever is newer. if the java source file is an artifact due to the sugared language, it might be older than the class file and therefore javac thinks it needs a newer version and compiles it again?

dpsutton06:11:08

whoops /s/older/newer

hiredman06:11:55

Yeah, the question is where is the source coming from, and can it be excluded

dpsutton06:11:52

the source is in the jar unfortunately

deas07:11:00

:dependencies [[org.clojure/clojure "1.10.0"]
                 [jarohen/chord "0.8.1"]
                 [cljs-ajax "0.8.0"]]
[jarohen/chord "0.8.1"] -> [com.cognitect/transit-clj "0.8.275"]
 overrides
[cljs-ajax "0.8.0"] -> [com.cognitect/transit-clj "0.8.309"]
How come order matters and the older version wins? 😲

hiredman07:11:22

Because lein uses maven's dependency resolution algorithm, and maven is basically first one wins

👍 4
hiredman07:11:29

Alex's recent conj talk goes into this some because the tools.deps.alpha code treats this kind of thing differently

👍 8
deas08:11:55

Been using maven for ages. So far, I got away assuming most recent version wins. Thanks @U0NCTKEV8!

deas08:11:28

Still pretty scary. Wonder what's best practice to make it more explicit. Using a non transitive dep?

PeterJM09:11:02

Please help me understand why my solution to problem http://www.4clojure.com/problem/39 works in the REPL but fails when pasted on to the site:

(fn f39
  [s1 s2]
  (-> (zipmap s1 s2)
      (seq)
      (flatten)))

jahson09:11:25

They want you to provide just the fns, without def

jahson09:11:45

It'll look like fn-x fn-y

PeterJM09:11:34

Sure I use fn, when I copy on to the site but still get "You failed the unit tests"

jahson09:11:04

Yeah, not helpful at all

jahson09:11:44

There might be some kind of implementation detail or unspoken deprecation.

jahson09:11:09

You should take a close look into map doc

PeterJM10:11:11

Yeah working on other implementations, was just wondering why this one doesn't work.

PeterJM10:11:43

Oh great thanks. Interesting but that exactly how i test the function in my REPL user> (= (f39 [1 2 3] [:a :b :c]) '(1 :a 2 :b 3 :c)) That returns true

jahson10:11:47

They're using the jailed version, there might be some issues with it, idk

jahson10:11:09

I've struggled myself with stuff like this a couple of times

PeterJM10:11:28

Yeah, thanks for the hints

jahson10:11:32

Just tried the source code of zipmap

(fn [keys vals]
  (loop [map {}
         ks (seq keys)
         vs (seq vals)]
      (if (and ks vs)
        (recur (assoc map (first ks) (first vs))
               (next ks)
               (next vs))
        (flatten (seq map)))))

jahson10:11:32

No luck. But if I get rid of hash-map here

(fn [keys vals]
  (loop [ret []
         ks (seq keys)
         vs (seq vals)]
    (if (and ks vs)
      (recur (conj ret (first ks) (first vs))
             (next ks)
             (next vs))
      ret)))

jahson10:11:38

Everything is ok

jahson10:11:57

Looks like it fails when I'm trying to assoc to a hash-map

jahson10:11:24

Don't know the reason though

didibus10:11:53

Weird, on the android app, the unit tests pass, but sending to the server errors saying it rejected the solution

didibus10:11:25

I wonder if zipmap isn't allowed but they forgot to mention it as a restriction just like interleave?

jahson14:11:14

> I wonder if zipmap isn't allowed but they forgot to mention it as a restriction just like interleave? I've tried without zipmap, and it seems like the issue boils down to assoc with hash-map

dpsutton15:11:57

It’s a super old clojure version and it’s possible some functions don’t exist there

dpsutton15:11:21

But I think the problem is there’s a “flatten” in zipmap which I think might be lazy. Your repl will force evaluation of these (the P in repl) but running on 4clojure doesn’t

jahson20:11:55

(fn [_ _] (flatten (seq (assoc [] 0 1 1 :a 2 2 3 :b 4 3 5 :c))))
This one works for the first test. I think there's no problem with flatten. But when I introduce a hash-map with assoc the test will fail
(fn [_ _] (flatten (seq (assoc {} 1 :a 2 :b 3 :c))))

dpsutton20:11:18

can you put a doall around it?

dpsutton20:11:09

oh, also (flatten {:a :b :c :d}) returns ()

jahson20:11:02

(fn [_ _] (doall (flatten (seq (assoc {} 1 :a 2 :b 3 :c)))))
Didn't pass the test.

dpsutton20:11:58

oh of course. maps aren't ordered. a map can't possibly work

jahson21:11:31

Yeah, good point, it's the real reason, probably.

dpsutton21:11:37

dan@pop-os:~/projects/clojure$ clj -Sdeps "{:deps {org.clojure/clojure {:mvn/version \"1.4.0\"}}}"
Clojure 1.4.0
user=> (flatten (seq (assoc {} 1 :a 2 :b 3 :c)))
(3 :c 2 :1 :a)
user=> 

👍 4
dpsutton21:11:51

4clojure uses clojure 1.4.0 and the hashmaps are a bit different

dpsutton21:11:37

recent clojures use array-maps for smaller maps under 8 (or 9, forgot whether the cutover is < or <=). So they would be ordered as an implementation detail

dpsutton21:11:28

if you want to test your solutions on older clojure the above is a good way to do that easily. lots of annoying things like update-in doesn't exist, maybe even update?

tianshu16:11:26

is it possible to build a syntax sugar like #:person[:id :name :age] ,just like the prefix for map with data_readers?

didibus18:11:04

You can do something similar, but you can't do it with that syntax

didibus18:11:32

You could do: #prefix[:person [:id :name :age]] for example.

Cameron18:11:21

hey hol' up, are you the same ghadi from the Charleston functional programming slack channel?

Cameron18:11:47

Ahaha I guess this isn't unexpected but it still feels like a small world moment! (I'm the same Cameron rambling on there like a month ago)

tianshu17:11:31

okay, I just feel there are more and more time I'm writing [:a/x :a/y :a/z]

dpsutton17:11:42

Is that for restructuring?

dpsutton17:11:50

Destructuring?

lvh18:11:32

I used core.logic to solve http://regexcrossword.com puzzles and wrote up what happened: https://www.lvh.io/posts/solving-regex-crosswords/ -- demo (if you're on linux amd64) here: https://github.com/lvh/regex-crossword/releases/tag/0.1.0

👍 20
Jack23:12:43

hey, that's super cool

jahson20:11:55

(fn [_ _] (flatten (seq (assoc [] 0 1 1 :a 2 2 3 :b 4 3 5 :c))))
This one works for the first test. I think there's no problem with flatten. But when I introduce a hash-map with assoc the test will fail
(fn [_ _] (flatten (seq (assoc {} 1 :a 2 :b 3 :c))))