Fork me on GitHub
#beginners
<
2019-09-01
>
calle00:09:38

ok, so if I got this right - comp given only transducers returns a transducer - comp given only functions does function composition - comp given a mixture of transducers and regular functions doesn't work

calle00:09:37

Now I don't understand why the code above with ->> works... I just saw it as doing the same as comp but in reverse.

calle00:09:12

because ->> is a macro, does it take the forms given to it and actually "physically" put the output of the previous line as the last argument in the next form?

calle00:09:24

sort of runs partial on all the forms?

hiredman00:09:26

Comp composes functions full stop

hiredman00:09:00

Transducers are functions that take and return reducing functions

seancorfield00:09:45

->> is purely syntactic rewriting. There's no semantics involved. (->> (+ a b) (let [a 1 b 2])) => (let [a 1 b 2] (+ a b))

calle00:09:56

I need to remember that (= ((comp (partial map inc)) [1 2]) (->> [1 2] (map inc)))

seancorfield00:09:30

comp with a single argument is identity

seancorfield00:09:52

((partial f a) b) => (f a b) by definition

seancorfield00:09:35

And as hiredman said @calle ((comp f g h) x) is (f (g (h x)))

calle01:09:54

I think it's this non-currying that's tripping me up

calle01:09:31

I'm so used to ((f a) b) being the same as (f a b)

calle01:09:11

that's basically the only way I use map

tjb01:09:38

just want to shout out #practicalli. truly an amazing resource for getting up and running with ring + compojure

calle01:09:41

I think I'm going to use ->> a lot...

calle01:09:47

What I'm saying is that when I see (map my-fn) in a comp and in a ->> I need to remember that they mean completely different things.

calle01:09:28

->> is not comp but reversed.

calle01:09:46

thanks for clearing things up, see you later 🙂

johnjelinek01:09:46

I wanted to change the path that aot dumps to ... seems like it doesn't like the following -- any suggestions?

{:aliases {:aot {:extra-paths ["target/classes"]
                 :main-opts ["-e" "(set! *compile-path* \"target/classes\") (compile,')"]}}}

seancorfield01:09:56

@johnjelinek Did you make sure target/classes exists before you run that?

johnjelinek01:09:06

ya, it throws an exception

johnjelinek01:09:01

{:clojure.main/message
 "Execution error at clojure.main/main (main.java:40).\nEOF while reading, starting at line 1\n",
 :clojure.main/triage
 {:clojure.error/class java.lang.RuntimeException,
  :clojure.error/line 40,
  :clojure.error/cause "EOF while reading, starting at line 1",
  :clojure.error/symbol clojure.main/main,
  :clojure.error/source "main.java",
  :clojure.error/phase :execution},
 :clojure.main/trace
 {:via
  [{:type clojure.lang.LispReader$ReaderException,
    :message
    "java.lang.RuntimeException: EOF while reading, starting at line 1",
    :data {:clojure.error/line 1, :clojure.error/column 1},
    :at [clojure.lang.LispReader read "LispReader.java" 314]}
   {:type java.lang.RuntimeException,
    :message "EOF while reading, starting at line 1",
    :at [clojure.lang.Util runtimeException "Util.java" 221]}],
  :trace
  [[clojure.lang.Util runtimeException "Util.java" 221]
   [clojure.lang.LispReader readDelimitedList "LispReader.java" 1405]
   [clojure.lang.LispReader$ListReader invoke "LispReader.java" 1243]
   [clojure.lang.LispReader read "LispReader.java" 285]
   [clojure.lang.LispReader read "LispReader.java" 216]
   [clojure.lang.LispReader read "LispReader.java" 210]
   [clojure.core$read invokeStatic "core.clj" 3766]
   [clojure.core$read invokeStatic "core.clj" 3741]
   [clojure.main$eval_opt$fn__9100 invoke "main.clj" 487]
   [clojure.main$eval_opt invokeStatic "main.clj" 487]
   [clojure.main$eval_opt invoke "main.clj" 482]
   [clojure.main$initialize invokeStatic "main.clj" 508]
   [clojure.main$script_opt invokeStatic "main.clj" 533]
   [clojure.main$script_opt invoke "main.clj" 530]
   [clojure.main$main invokeStatic "main.clj" 664]
   [clojure.main$main doInvoke "main.clj" 616]
   [clojure.lang.RestFn applyTo "RestFn.java" 137]
   [clojure.lang.Var applyTo "Var.java" 705]
   [clojure.main main "main.java" 40]],
  :cause "EOF while reading, starting at line 1"}}

seancorfield01:09:23

What exception?

johnjelinek01:09:37

I think it doesn't like my \ in there

seancorfield01:09:05

You probably need , instead of space in that string

seancorfield01:09:21

"(set!,*compile-path*,\"target/classes\") (compile,')"

seancorfield01:09:25

Does that work?

johnjelinek01:09:04

needs , between forms

johnjelinek01:09:18

but then that works, except -- the clojure.core stuff doesn't get into the directory

seancorfield01:09:20

Ah yes. That too.

johnjelinek01:09:04

not sure why the clojure.core stuff is missing

alexmiller01:09:36

it's already been compiled

johnjelinek01:09:38

nvm ... ran -A:aot again and it got it into the directory now

seancorfield01:09:48

AOT is evil 🙂

seancorfield01:09:07

(we do not use AOT at work ever)

johnjelinek01:09:46

unfortunately, I need it for my stuff

seancorfield01:09:20

Sorry man. We rely on one library that has a single namespace AOT'd. Other than that, we avoid it at all costs.

johnjelinek01:09:46

I don't know how to transpose the following without aot:

package com.myorg;

import software.amazon.awscdk.core.Construct;
import software.amazon.awscdk.core.Duration;
import software.amazon.awscdk.core.Stack;
import software.amazon.awscdk.core.StackProps;
import software.amazon.awscdk.services.sqs.Queue;
import software.amazon.awscdk.services.sqs.QueueProps;

public class HelloStack extends Stack {
    public HelloStack(final Construct parent, final String id) {
        this(parent, id, null);
    }

    public HelloStack(final Construct parent, final String id, final StackProps props) {
        super(parent, id, props);

        Queue queue = new Queue(this, "MyFirstQueue", QueueProps.builder()
                .visibilityTimeout(Duration.seconds(300))
                .build());
    }
}

seancorfield01:09:34

Concrete inheritance? Ugh 😞

johnjelinek01:09:37

To be fair, I haven't yet figured out how to transpose this in general, but I feel like my options are either proxy, reify, or gen-class

neo255107:09:13

Why is AOT evil?

andy.fingerhut08:09:30

Others with more experience can give more full answers, but I believe the gist of it is that even experienced Clojure developers can have a difficult time diagnosing subtle problems that can occur in some situations when AOT is used.

andy.fingerhut08:09:42

e.g. .class files that were compiled from different versions of Clojure source code being used, leading to code execution behavior from source code that is not what you are looking at in your editor.

d.eltzner10:09:55

I am having the most frustrating experience with ring ... I have a compojure POST route, that just pprints the request from a client I wrote. My handler is

(def app  (-> routes  wrap-json-body wrap-reload))
But wrap-json-body leads to the body always being nil. Without it its a HttpInputOverHTTP. I don't know what to do about it, it seems like noone had this problem with wrap-json-body, at least I can't find it. Content-type is application/json.

lkowarschick10:09:46

how would i go about writing a macro that can be called like this:

(my-macro
  [+ 1 1]
  [str "hello " 123]
  [inc 5])
and return the following structure:
['(+ 1 1)
 '(str "hello " 123)
 '(inc 5)]
(take vecs that would be valid forms if they were lists, and return quoted, unevaluated "eval-able" lists) (i know i can use [+ 1 1] directly using (apply (first [+ 1 1]) (rest [+ 1 1]), which is what i'm currently doing, but this stores the functions as function-objects, which isn't directly a problem, but it makes debugging these structures extremely hard, especially when everything gets wrapped with spec instrumentation stuff and is as such turned into some unreadable spec function-object thing)

d.eltzner11:09:04

Now I have slurped my input-stream manually and it yields "{\"date-range\":{\"from\":\"2019-09-10\",\"to\":\"2019-09-19\"}}" which at least according to https://jsonlint.com/?code= is valid JSON. Still when I don't slurp it (so it is not gone) and use wrap-json-body it is nil. Also wrap-json-request works fine. Can anyone help me understand this?

lkowarschick11:09:21

it works, i just needed to remove that little ' in the last line to remove double-non-evaluation ;D thanks, person who removed his/her message ^^

alpox11:09:25

@lkowarschick Why not just use a function?

(defn to-lists [& forms]
  (map (partial apply list) forms))

alpox11:09:40

I removed it because I believe this is the easier solution 😉

lkowarschick11:09:22

that doesn't fully fulfill my requirements, as it results in the following:

(([clojure.core$_PLUS_ 294690511 "[email protected]"] 1 1)
 ([clojure.core$str 439674431 "[email protected]"]
  "hello "
  123)
 ([clojure.core$inc 1883794397 "[email protected]"] 5))
(it stores function-objects instead of symbols)

lkowarschick11:09:28

the first solution works however ;D

alpox11:09:20

I see, ok 🙂

lkowarschick11:09:38

(defmacro foo [& forms]
  (let [lists# (for [form# forms]
                 (list 'quote (apply list form#)))]
    `[[email protected]#]))
gonna use this ;D

alpox11:09:24

I don't think the generation of special names is necessary here though as the code doesn't make its way in the macro at all

lkowarschick12:09:48

better be safe than sorry i guess ;D

lkowarschick12:09:28

i've got a function that can take any type of collection (it handles maps seperately, so were talking sets, lazySeq, list, vector, etc) it does stuff to that collection and should then return the modified version as the same type as it got it. how can i achieve this? map and such turn everything into a lazySeq, so i need to somehow (into (type input) output) my result.. (<- i know that doesn't work)

schmee12:09:26

I recommend Specter for this, it is specifically designed to address this issue (changing the type of the container)

lkowarschick12:09:26

really? do i actually need a additional dependency for that? then i'd rather just (cond) it on the type..

schmee12:09:09

you don’t need it, it’s just an option that’s available 🙂

lkowarschick12:09:00

so is my simplest option to write this function

(defn map-keep-type [fun coll]
  (let [mapped (map fun coll)]
    (condp #(%1 %2) coll
      vector? (vec mapped)
      set? (set mapped)
      list? (apply list mapped)
      map? (zipmap (map first mapped) (map second mapped))
      seq? (seq mapped)
      mapped)))
?

schmee12:09:27

something like that, except it doesn’t cover sorted-set, sorted-map etc

lkowarschick12:09:11

thats why i hoped there would be some kind of into that takes types and not empty collections...

schmee12:09:31

nothing like that in clojure core afaik

jackwestmore15:09:42

Hey there, would anybody be willing to help meet out setting out Emacs with Cider? Completely new to this thing and encountering a bug...

dpsutton15:09:23

I can help you out. What’s up

jackwestmore15:09:05

I'm using cider version 2019090

jackwestmore15:09:04

When I try and do cider-jack-in, I get this error:

Could not find artifact cider:cider-nrepl:jar:0.22.1 in clojars ()
This could be due to a typo in :dependencies, file system permissions, or network issues.
If you are behind a proxy, try setting the 'http_proxy' environment variable

jackwestmore15:09:38

Pretty sure the issue is that nrepl version 0.22.1 does not exist on Clojars

jackwestmore15:09:48

Latest stable version is 0.22.0, from what I can see on the web page

dpsutton15:09:50

ah understood. There was a bug in the 22.0 release and the intention was to release on clojars. But it looks like that hasn't happened yet. CIDER injects its dependencies based on its version.

jackwestmore15:09:56

I tried changing cider-required-middleware-version in cider.el to 0.22.0 (according to the Cider docs, "any nearby version will work"...). But after making this changing, restarting emacs, and running cider-jack-in, I still get the error message about 0.22.1

dpsutton15:09:09

this is set in a var cider-required-middleware-version.

dpsutton15:09:14

how did you change that var?

jackwestmore15:09:19

I edited the file

jackwestmore15:09:32

I just changed the argument to defconst from 0.22.1 to 0.22.0

dpsutton15:09:32

did you restart emacs?

dpsutton15:09:42

and that didn't work?

dpsutton15:09:46

interesting

dpsutton15:09:05

so one easy thing you can do. Normally you jack in with C-c M-j

dpsutton15:09:58

if you use a prefix C-u C-c M-j you can directly edit the jack in command and rewrite the version of the cider-nrepl version that's injected

jackwestmore15:09:13

Ah, OK. How exactly do I rewrite the command?

jackwestmore15:09:17

(Sorry, I'm completely new to this...)

jackwestmore15:09:53

OK, I can see how to do this

dpsutton15:09:55

if you try it you'll see. The prefix arg will put the jack in command in the minibuffer and you can just edit it directly

jackwestmore15:09:10

It's working now, with a warning

dpsutton15:09:10

what kind of project is this? lein or clj?

dpsutton15:09:27

you can probably ignore the warning. its just saying a mismatch but that's what we are intending to do right now

jackwestmore15:09:44

Odd that changing the argument to defconst in cider.el didn't fix this, right? I just assumed that I didn't know enough about emacs/clojure and was missing something else...

dpsutton15:09:48

i'm confused why editing cider-required-middleware-version didn't work

dpsutton15:09:13

correct. i'm gonna look into that but this should get you working until the newer artifact is released

jackwestmore15:09:48

thank you, this is really helpful

jackwestmore15:09:21

FYI I just checked cider.el after editing and restarting -- argument to defconst is still 0.20.0 (it didn't revert to anything else). So not sure where it's reading 0.20.1 from

dpsutton15:09:08

i think you're safest bet is 0.21.1 while we wait on the 0.22.1

dpsutton15:09:33

there's a clojurescript completion bug in 0.22.0 that's fixed by the .1 point fix but its not out yet

jackwestmore15:09:47

sorry, typo: I'm using 0.22.0, not 0.20.0

dpsutton15:09:05

that should be fine too but if you're doing cljs probably better for 0.21.1

dpsutton15:09:30

but to summarize the strange behavior: You edited cider.el in your elpa directory to make cider-required-middleware-version have the value "0.22.0". You restarted emacs but this version was still "0.22.1". Is this correct?

jackwestmore15:09:32

No, not quite; I edited the version number to "0.22.0", restarted emacs, the version number is still listed in cider.el as "0.22.0", but I still see the bug described above

jackwestmore15:09:06

The error message still complains about not being able to find cider-nrepl version 0.22.1

dpsutton15:09:40

hmm. I edited cider.el to "0.14.0", restarted and it was correctly seen. can you walk me through how you changed things?

dpsutton16:09:47

couple things i can think: 1) are you sure you edited the correct cider.el file? It should be ~/.emacs.d/elpa/[cider-version]/cider.el 2) Are you sure you actually restarted emacs. There's a server that can keep running and its important that you actually kill emacs rather than just kill the client connected to an emacs server

jackwestmore18:09:39

Hey -- sorry for the delay, was away from my machine for a couple of hours

jackwestmore18:09:58

Here's some terminal output in response to your questions:

Jacks-MBP:.emacs.d jackie$ rg "0\.22\.1"
Jacks-MBP:.emacs.d jackie$ rg "0\.22\.0"
elpa/cider-20190901.1056/cider-xref.el
56:  :package-version '(cider . "0.22.0"))

elpa/cider-20190901.1056/cider.el
14:;; Version: 0.22.0
90:(defconst cider-version "0.22.0"
407:(defconst cider-required-middleware-version "0.22.0"
1189:  :version '(cider . "0.22.0"))

elpa/cider-20190901.1056/cider-repl.el
150:  :package-version '(cider . "0.22.0"))

jackwestmore18:09:22

i.e. no reference anywhere in .emacs.d/ to the incorrect version number (`0.22.1`)

jackwestmore18:09:06

running cider-jack-in still produces the error above i.e. unable to find an artifact for cider-nrepl version 0.22.1

jackwestmore18:09:28

What is even more curious, is that if I then run cider-jack-in as you described (using the C-u optional argument), and set the version number to 0.21.1, I get a REPL with this warning message:

WARNING: CIDER 0.22.0 requires cider-nrepl 0.22.1, but you're currently using cider-nrepl 0.22.0. The version mismatch might break some functionality!
i.e. it reports that I am using cider-nrepl version 0.22.0, as defined in my cider.el, and not 0.21.1, which I passed in to the command "by hand"

jackwestmore18:09:30

Very strange...

dpsutton19:09:02

can you evaluate cider-required-middleware-version?

dpsutton19:09:07

and also cider-jack-in-lein-plugins

jackwestmore21:09:39

cider-required-middleware-version -- "0.22.1"

jackwestmore21:09:52

cider-jack-in-lein-plugins -- (("cider/cider-nrepl" "0.22.1"))

dpsutton21:09:01

there's your problem. where did you make your changes?

jackwestmore21:09:33

~/.emacs.d/elpa/cider-20190901.1056/cider.el

jackwestmore21:09:49

should I be making the changes somewhere else?

dpsutton21:09:55

i don't think so. I mentioned it earlier but are you sure you are restarting emacs as opposed to just closing the open windows?

jackwestmore21:09:11

What key command would I use to restart it? I've been doing C-x C-c

dpsutton21:09:30

“M-x kill-emacs”

jackwestmore21:09:20

Thanks -- I tried that, restarted emacs, ran cider-jack-in and still get the error!

joshlemer15:09:04

@lkowarschick I’m also a beginner so take with a grain of salt but maybe this will work nicely for you?

user=> (defn map-keep-type [fun coll] (into (empty coll) (map fun coll)))
#'user/map-keep-type
user=> (map-keep-type #(+ % 1) [1 2 3])
[2 3 4]
user=> (map-keep-type #(+ % 1) #{1 2 3})
#{4 3 2}
user=> (map-keep-type #(+ % 1) '(1 2 3))
(4 3 2)

joshlemer15:09:23

Only problem is that Lists will be backwards 😕

lkowarschick15:09:07

uhh i didn't know emptyexists, that shouuuld work (i'll reverse lists manually)... ill do some testing, thanks ;D

jiyinyiyong16:09:53

I can't send my pacakge to Clojars

dpsutton16:09:34

@jiyinyiyong some others with issues with clojars. perhaps related?

jiyinyiyong16:09:58

turned out they didn't figure out a solution. And the problem is not Meyvn specific.

borkdude21:09:01

@jiyinyiyong for what it's worth, my issue with Clojars was resolved

jiyinyiyong02:09:46

also saw this,

jiyinyiyong02:09:00

how did you fix that

gisf22:09:18

In Haskell we only need to type :t function_name on GHCI to see the type of output and inputs of this function. Can we do the same in Clojure’s repl? I only could do this with types like String, Long by (type 10) or (type "aa") but it doesn’t work with functions.

hiredman22:09:12

clojure doesn't have a static type system you can query type information from, what the type function returns is the runtime jvm type of a thing

hiredman22:09:21

you may want to use doc

alexmiller22:09:45

On the cli, rebel-readline can do that. Other tools (Emacs CIDER, IntelliJ Cursive) can provide this

hiredman22:09:52

user=> (doc +)
-------------------------
clojure.core/+
([] [x] [x y] [x y & more])
  Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'
nil
user=>

hiredman22:09:33

as @alexmiller suggests there are some extra tools that you can use that will do things like displaying arglists for functions as you type

gisf23:09:14

Just searched rebel-readline on github and looks great. Thanks! And i love this (doc ) will help me a lot!