Fork me on GitHub
#beginners
<
2021-08-31
>
finchharold13:08:37

It returns an error: Execution error (IOException) at sun.tools.attach.HotSpotVirtualMachine/ (HotSpotVirtualMachine.java:75). Can not attach to current VM

finchharold13:08:53

I've added in another project.clj! Sorry and thank you 🙂

sova-soars-the-sora13:08:17

How can I replace a plus sign via regex? I am getting a weird error when I try to do #"+"

delaguardo13:08:14

try this #"\+" or (re-pattern "+")

alexmiller13:08:03

#"\+" maybe?

1
sova-soars-the-sora13:08:18

Amazing that worked 😄 thanks

alexmiller13:08:22

+ means "1 or more" in regex so it's a character with semantics and needs escaping

popeye13:08:51

(defprotocol Dog
  (bark [dog] [dog x] "dog barks")
  (eat [dog] "dog eats"))

(defrecord Pitbull [name]
  Dog
  (bark [dog] (println (str name "goes woof woof")))
  (bark [dog n] (repeatedly n #(bark dog)))
  (eat [dog] (println (str name "eats and grunts"))))

(defn calling-function [x]
  (eat (Pitbull. "Pete")))

popeye13:08:30

When does it will call "dog barks" which is in defprotocol

delaguardo13:08:30

only when you explicitly call bark

popeye13:08:09

I called with

(defn calling-function1 [x]
  (bark "hi"))

popeye13:08:24

No implementation of method: :bark of protocol: #'com.clojure.core/Dog found for class: java.lang.String

alexmiller13:08:50

you didn't pass it a dog instance

alexmiller13:08:25

(bark (->Pitbull "Pete"))

alexmiller13:08:53

(it is better to use the constructor function than the Java interop to create a record instance)

popeye13:08:19

constructor function ? defmulti ?

alexmiller13:08:01

not Pitbull.

popeye13:08:03

I am trying to call bark [dog] [dog x] "dog barks") which is in defprotocol , when it will print "dog barks" ?

alexmiller13:08:15

when you call it with a dog

alexmiller13:08:26

(bark (->Pitbull "Pete"))

popeye13:08:36

this on i got, I wanted to call, (bark [dog] [dog x] "dog barks") which is in defprotocol, how can I call directly

alexmiller13:08:31

I feel like I'm saying the same thing over and over, but when you call it with a dog

alexmiller13:08:10

(bark [dog] [dog x] "dog barks") is not a function

alexmiller13:08:40

it's a method declaration. "dog barks" here is a docstring

popeye13:08:37

oh, sorry I should have gone through documentation first, Thanks anyway, it helped

alexmiller13:08:53

sorry if I was misunderstanding the question

popeye13:08:11

nope, you are right!

popeye13:08:32

have a cross question, when to use defprotocol and when to use defmulti

emccue14:08:55

If you are asking how to have a "default" implementation of stuff you can reference - somewhat like inheritance - then the simplest answer is to make your default stuff its own functions

emccue14:08:20

but as far as when to use a protocol over a multimethod

emccue14:08:52

if you have a dispatch mechanism that isn't just the type of a thing (you choose bark because its a pitbull) then a multimethod is more appropriate than a protocol

emccue14:08:25

but truthfully its best to start out just only using plain functions with defn until you have a concrete use for doing dynamic dispatch like this

emccue14:08:26

most uses of records and protocols (with some caveats) would be served just as well with regular functions and regular, untagged, maps

Joshua Suskalo16:08:46

You can also extend a protocol to java.lang.Object and that'll act as a default

finchharold13:08:19

How to check the sampler?

finchharold13:08:40

Especially to target one function that is currently ran?

jjfine13:08:00

one way is to take snapshots before/after the fn runs and compare them

finchharold13:08:51

Of Heap Histogram or Per thread allocations? And they're constantly changing in seconds

jjfine13:08:40

ah i was assuming you were looking to catch a memory leak. yeah i don't think this will help

delaguardo13:08:20

those measures might be inaccurate because of GC

finchharold13:08:55

Find the amount of memory consumed by a function which is fetching some data.

delaguardo13:08:49

during computation or after it returns?

delaguardo13:08:28

and what is the reason for that? optimisation?

finchharold13:08:50

Yes. To see if the function takes more/less memory based on the stuff it does. Ex. It fetches the records and converts them to the camel and etc. So, want to know if removing these stuff changes anything or not by comparing the memory consumed.

delaguardo13:08:43

not sure if I follow. The function suppose to do what it suppose to do. If you remove something from it — outcome might bring some unexpected side effects like broken program’s logic

finchharold13:08:50

It fetches the record and converts that data into a camel case and adds some other content to it. Can edit this to only fetch the records and nothing else. But first have to see if there is any change in doing so.

delaguardo13:08:34

and what about outer code which is using that function? is it expected to not have camel cased data?

delaguardo13:08:02

if yes - then just remove that conversion

delaguardo13:08:37

but I’m guessing right now. Could you share the code of the function?

finchharold13:08:44

How much does it make a difference?

Dan Lucas16:08:56

Day 3 and I'm struggling to understand how to reference libraries in Clojure. I was able to use pdfboxing in a project without any issues after including it in the dependencies. As well as extracting text from a PDF, I need to save a page of the PDF as an image. (The alternative would be adding images and text to an existing PDF file - creating a new one isn't an option - and I can't find a Clojure library that will allow me to do that.) Thinking I would try pdf-to-image (https://github.com/pablocastromontero/pdf-to-image), which wraps PDFBox, I included it in the dependencies and ran lein deps. It now shows up in the repository, but this ns form:

(ns pdf-test.core
  (:require [pdfboxing.text :as text])
  (:require [pdf-to-image])
  (:gen-class))
gives a "Could not locate pdf_to_image__init.class, pdf_to_image.clj or pdf_to_image.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name." Looking at the repository the path and the file names use dashes rather than underscores, e.g. "C:\Users\dan\.m2\repository\pdf-to-image". Do I have to manually change these to use underscores? Or do I have to qualify the imported function in some way e.g. 'pdf-to-image.convert', or is it something else altogether?

dpsutton16:08:12

pdf-to-image.core is the namespace you want

noisesmith16:08:52

@clojure529 by the way "lein deps" is only needed in exceptional circumstances - every lein task (repl, run, compile, check, test ...) will run it implicitly as a subtask. "installing a dep" is how you get libraries in other ecosystems but that's not how lein works really . You declare a dep and on running a task the deps are either found in cache or retrieved and cached.

noisesmith16:08:37

I mention these things because lein becomes a lot less frustrating and more useful when you internalize this model

dpsutton16:08:00

also you don't need multiple :require forms. you can just do (:require [pdfboxing.text :as text] [pdf-to-image.core :as image]) (i'd use newlines as well but just doing inline here for brevity

sheluchin16:08:27

https://purelyfunctional.tv/article/100-most-used-clojure-expressions/ I'm looking to run a similar analysis to determine most frequently called functions in a codebase. Does anyone know how I could accomplish this? Is there a library or something that would make it easy?

Dan Lucas16:08:30

Thanks @dpsutton and @noisesmith for those tips. So the part after the dot is a reference to the actual module in the original? That would make sense. The namespace now works, but I get:

Syntax error (ClassNotFoundException) compiling at (pdf_to_image\core.clj:3:1).org.apache.pdfbox.util.PDFImageWriter
Investigating, it seems that there have been https://pdfbox.apache.org/2.0/migration.html in PDFBox since this lib was written and PDFImageWriter has been removed. I will take a look at PDFRenderer class that replaces it, but given my lack of Java that might be a bridge too far at this stage. Ostensibly back to square one, but I learned a couple of things.

noisesmith17:08:45

@clojure529 it should be possible to access the version of PDFBox that pdf-to-image needs by declaring the right deps in your project.clj > the part after the dot is a reference to the actual module in the original? modules are something completely different (and not relevant here). require asks for a namespace to be loaded if it was not loaded already, the . is part of the namespace (when looking up namespaces, foo.bar.baz is looked for in the directory foo/bar/ in the file baz.clj)

🙏 1
noisesmith17:08:53

for example, it's valid to have both a.b.c and a.f.c - both end in c, but they are not otherwise related, and the full name includes the prefix

noisesmith17:08:07

or as a more concrete and common example, many libs have namespaces with a .core suffix, and foo.core and bar.core are unrelated, they likely come from totally different libraries

popeye17:08:35

I have seen the code (server/run-server #'app-routes {:port port}) while practising rest api in clojure, Why do we need to use #' to app-routes ? As per my reading these var is used for those symbol which will change in the future, correct me if I am wrong!

alexmiller17:08:44

that's correct - it gives you a point of indirection to support reloading while running the app

popeye17:08:32

While running the web application, which scenario it needs an update?

popeye17:08:31

will take a look @U04V70XH6, Thank you

popeye13:09:25

This helped @U04V70XH6, Tkanks

👍 2
alexmiller17:08:19

invoking a var derefs the var and invokes the function it refers to

Apple19:08:05

From https://www.youtube.com/watch?v=gIoadGfm5T8 this (require '[clojure.tools.deps.alpha.repl :refer [add-libs]]) no longer works as repl is not there anymore. What's the new way to use add-libs? Does this work https://github.com/lambdaisland/classpath?

seancorfield19:08:51

@UP82LQR9N In particular, pay attention to all those caveats about breaking/changing/alpha/work-in-progress. It's a case of "here be dragons" and not something I'd recommend to folks who just want a simple, reliable workflow.

Apple19:08:58

repl was in this commit

alexmiller19:08:27

the latest tools.deps.alpha branch is add-lib3

alexmiller19:08:45

(btw, #tools-deps is probably better for this specific question in the future)

alexmiller19:08:09

latest commit there is 83a477b305839c697666401508c395cfed29506a

Apple19:08:53

sorry that i totally missed that it is a different branch. thank you all.

alexmiller19:08:43

should really probably be moved into its own repo as its an additive thing

1
Ryan19:08:48

In a reframe app, if I have some mock data with components (e.g. [mention "<mailto:[email protected]|[email protected]>"], and I prevent resolving the symbol in the mock data with ', how do I get a subsequent 'get' to resolve it? Presently, its just plopping <mention><mailto:[email protected]|[email protected]></mention> into the html but its never resolving to the component

Jonor20:08:28

I've started a fighweel.main repl from CIDER in Emacs on Windows, is there a ready option or template, or recommended workflow to make a production build for deploy?

noisesmith20:08:30

if you are using lein the standard thing is to use lein uberjar to create a deployable artifact, I'm confused by your question though because I'm not sure how that relates to your REPL

Jonor20:08:43

I'm trying to learn to create a ClojureScript web application, I could start a figwheel.main browser REPL, but I'm not sure about the workflow to create the optimized version for deploy

noisesmith20:08:35

OK, then see above, if your template was set up properly lein ubjarjar should set you up

noisesmith20:08:05

that gives you *something*-standalone.jar which you can then run via java

Jonor20:08:31

I think I'm looking for a way to run this from my environment (docs example): "clojure -m figwheel.main -O advanced -bo cruel", probably I should set up or find a build configuration to refer from the IDE ...

noisesmith20:08:00

OK so you aren't using lein, in that case you need to check your deps.edn to see if a packaging task is set up, if not I recommend depstar https://github.com/seancorfield/depstar

Apple20:08:59

Add this to project.clj :aliases {"fig" ["trampoline" "run" "-m" "figwheel.main" "-b" "dev" "-r"] "bo" ["trampoline" "run" "-m" "figwheel.main" "-O" "advanced" "-bo" "dev"]} then you can lein bo to compile

Apple20:08:27

lein fig to continuously watch and compile. this is good for dev.

noisesmith20:08:47

@UP82LQR9N they use clojure to run the app, they are not using lein

Jonor20:08:16

I use lein, the clojure line was an example from http://figwheel.org

Apple20:08:27

clj is similar. add to :aliases :bo {:main-opts ["-m" "figwheel.main" "-O" "advanced" "-bo" "dev"]} then you can do clj -M:bo

noisesmith20:08:36

@ULD86RW5N than once agian, if you are using lein all you need is lein uberjar, that makes a jar, use java to run the jar

noisesmith20:08:53

that's literally the whole thing

Jonor20:08:02

Isn't that for creating a Java app? I want to compile to JavaScript.

noisesmith20:08:35

if your project was set up properly then it will compile to javascript as part of the packaging

Jonor20:08:23

Ok, it says "Created C:\...\hello-world.core\target\hello-world.core-0.1.0-SNAPSHOT-standalone.jar"

noisesmith20:08:25

the jar is an archive, that should run a server which servers your app to a browser

Jonor20:08:31

@UP82LQR9N Yes there is an alias called "fig:min" in project.clj, so that would perhaps be lein fig:min to create the build from the command line

noisesmith20:08:38

or you can use the js files from the archive in another context

Jonor20:08:00

Ok, so the Cljs app is packaged inside the jar? I did not intend to deploy a Java web app but that could be good to know about

noisesmith20:08:54

the cljs app is comprised of the js files plus the html template plus server side code (if any) - if all you need is the html and the js files that's all there, but how to use that is very much dependent on how you plan to run the app, it doesn't have a generic solution as far as I know

Jonor21:08:37

I was a little confused about the ":profiles" concept, there is only a ":dev" profile present in the project.clj, but maybe that is relevant for the release build also.

noisesmith21:08:28

the project.clj is merged over all the built in default configs, each lein task has a profile (repl, compile, jar, uberjar, test ...) and lein plugins will usually add one or more profiles as well

Apple21:08:14

cljs/figwheel can give you one compiled/optimized .js file you also need other html/css files. if your web server is written in .clj then it makes sense to package everything into one .jar file

Apple21:08:30

otherwise html/css/js files are just files you need to deploy to your web server specific folders

Jonor21:08:14

Thanks. Yes that is the next step to transfer the page and scripts to the remote server.

Jonor21:08:34

So figwheel is a plugin maybe, and the :aliases are tasks? The :dev profile declares a dependency of figwheel-main, is that profile merged always or when running certain tasks.

noisesmith21:08:33

the :dev profile is merged for most tasks, other than compile or run

noisesmith21:08:07

lein help sample shows an annotated project.clj with info about what each part is for / how to use it

Jonor21:08:58

Thanks 👀

noisesmith21:08:18

lein help profiles also has a lot of content

Apple21:08:25

figwheel is the cljs->js app written in clojure, succeed by figwheel-main, and lein-figwheel is the lein plugin which enhances lein support for figwheel.

Jonor22:08:08

Ok, so the :aliases are shorthands for lein arguments to run the fighweel.main app then, and the app is an extension of the regular cljs compiler. What is the :dev :dependencies [[com.bhauman/figwheel-main "0.2.12"]] for?

noisesmith22:08:41

because you shouldn't need any figwheel code during your app runtime - it's a dev tool

noisesmith22:08:57

and that profile ensures you can use it in dev tasks but it doesn't get packaged

Jonor22:08:31

So :dev is a lein concept to merge a configuration for certain tasks in that category.

noisesmith22:08:59

well, that's what profiles are, and the :dev profile is the one for dev specific tasks

noisesmith22:08:18

but yes, precisely

Jonor22:08:56

There are two jar files in the target directory, one named "-standalone" which is larger.

noisesmith22:08:24

right - the standalone contains all the recursive deps needed to run the jvm clojure code

noisesmith22:08:51

they are both zip files (jar is a type of zip), you can use a zip tool to look inside (or even an editor if your editor is any good)

Jonor22:08:42

Yes I think I found the compiled javascript in public/cljs-out/dev-main.js, there is also a "dev" folder there with a lot of dev-related files

Jonor22:08:41

So it looks like a dev build inside the jar, maybe there is not a release build configuration defined or/and I should run some kind of cleanup before.

practicalli-john02:09:27

@ULD86RW5N https://github.com/bhauman/figwheel-main-template is the template I use to set up a figwheel-main project. The template includes a dev and min build profile. The min profile creates a single javascript file using advanced compilation and minification. I typically add a live profile that is similar to min which creates the JavaScript file in the docs directory. I publish the resources files and the JavaScript file on GitHub pages, so do not need to create an uberjar (as there is no server-side component). https://practical.li/clojurescript/web-design-basics/clojurebridge-london-website/github-pages-deploy.html

practicalli-john02:09:26

I have started using a GitHub action to deploy the artifacts to GitHub pages, although I haven't documented this yet https://github.com/practicalli/practicalli.github.io/blob/live/.github/workflows/deploy.yml

Jonor19:09:28

Thank you, that sounds like the scenario I had in mind currently, publishing a simple web app to a static page server. I'll look more into the figwheel-main-temple and also the GitHub automations feature sounds interesting. I'm still confused about the profile semantics and evaluation but maybe it will get clearer.

Jonor20:09:37

In the usage example for figwheel-main template the project folder is named hello-world.core? What does the .core suffix in the project name tell?

lein new figwheel-main hello-world.core -- +npm-bundle --reagent # or --rum, --react or nothing

noisesmith20:09:53

core is an arbitrary name, it's a default when you don't give a multi part namespace to lein on project creation

noisesmith20:09:38

that is, if you do lein new some-template foo you get src/foo/core.clj containing foo.core, if you do lein new some-template foo.bar you get src/foo/bar.clj with foo.bar

noisesmith20:09:37

this is because single segment namespaces are a bad habit (and also cause weird bugs)

Jonor20:09:08

Yes, but following the usage example that would be lein new some-template foo.core

noisesmith20:09:27

why would you want foo.core? it's a default that's there because it's generic, it was picked because it doesn't carry meaning

Jonor20:09:22

It was just because the example said that on https://github.com/bhauman/figwheel-main-template

noisesmith20:09:48

right - that's for doc / walkthrough purposes. saying hello-world.core is the same as saying hello-world as far as lein is concerned, but it might help the reader know that something other than core could be picked

Jonor20:09:05

Ok, so the project folder gets the name of the main namespace then

Jonor20:09:39

Of course the instructions say "already an expert?" which I'm not

practicalli-john20:09:39

Leiningen project typically used project-name.core as the default namespace, possibly as a tribute to clojure.core namespace (and some Lisp tradition). It not essential to change it, but it's encouraged to have meaningful names, e.g landing-page or website, etc. This is the GitHub repository I use for the Practicalli landing page https://github.com/practicalli/practicalli.github.io

👍 2
Jonor20:09:26

Could you select the min build in Spacemacs/cider to create a release version from the IDE

Jonor20:09:31

I can run lein fig:build and fig:test, but the fig:min gives a Compile Exception Illegal char <:> at index 2 .... lein uberjar seems to work. Could be a path name problem?

Jonor21:09:53

Guess it's the index of the third char in the "/C:/Users/..." string

Jonor21:09:34

Ok, I had to delete resources\public\cljs-out\ folder manually before doing the fig:min build

Jonor21:09:22

So the development build and the production build are mixed into the same output folder, and also into to the uberjar

Jonor21:09:02

Maybe I would have expected some automatic cleanup or isolated packaging

Jonor21:09:37

Still not a single bundle, but maybe it's deployable.

Jonor21:09:38

Ok, it actually works to load the page from a plain web server. The cljs-out/dev folder with 2.5 MB worth of script files was a bit frightening but it does not seem to be used by the dev-main.js script.

Jonor21:09:31

So it is a single dev-main.js file then

practicalli-john03:09:25

The large number of files created by the dev build allows figwheel-main to selectively load in just the parts that change. I haven't needed to delete these files, as the min build creates a self-contained file. In the Practicalli project repository, I created a live build, based on min, that outputs the file to a different location

practicalli-john03:09:14

The readme explains how to generate the builds from the command line. I only run the dev build in the editor, other builds are on the command line

👍 2
Jonor19:09:01

I see. The min build produced the cljs-out/dev folder also, I don't know what the content is used for in that case. To output the production build to a separate location would feel more tidy and make it easier to understand what to deploy.

Jonor19:09:36

The need to delete the cljs-out folder seems to be a Windows issue.

az20:08:24

Any ideas on what would be causing this after moving a lein project to deps.edn. Exception in thread "main" Syntax error compiling . at (aleph/http/core.clj:251:3). Found an old thread on this from last year and the person fixed by using clojure:openjdk-8-tools-deps-1.10.1.502 I’ve tried to switch java versions but that hasn’t resolved it. Any thoughts?

seancorfield20:08:58

I found a similar error reported (by searching the Zulip archive) and the "solution" was "I believe this is on Aleph’s side and I can resolve by excluding aleph and just specifying the latest aleph 0.4.6 dep on my own. So it’s like it’s just an issue with the version of Aleph that Yada depends on. The other thing that seems to resolve it is just using the alpha version of Yada. Would the preferred solution be to just use alpha?" (it was in the context of Yada).

seancorfield20:08:32

So I think I would ask: What version of Aleph are you using? What version of JDK are you using? What version of Clojure itself and what version of the CLI?

seancorfield20:08:58

Also: are you using a library that depends on Aleph or are you using Aleph itself directly?

az20:08:02

Hi @U04V70XH6, I’m going to play with this and see how I can exclude aleph (using it through luminus-aleph).

az20:08:45

Seems to be using 0.4.6, I see aleph is up to 0.4.7

seancorfield20:08:56

I remember looking into this for someone else who had the exact same error (I have never used Aleph myself) but unfortunately I don't remember what the solution was...

az20:08:10

Java - I’ve tried open jdk 8, 11, 14, 16. Currently on 11.0.11

az20:08:12

That’s using the solution I saw you posted: clojure -M -e ‘(println “Java” (System/getProperty “java.version”) “Clojure” (clojure-version))’

az20:08:28

Java 11.0.11 Clojure 1.10.3

az20:08:24

Lastly: org.clojure/clojure {:mvn/version "1.10.3"}

seancorfield20:08:17

The stacktrace from that error might provide more insight as to what is behind the error -- look for a "Caused by" line further down.

az20:08:57

Doing this fixed the error

{aleph/aleph {:mvn/version "0.4.6"}
  luminus-aleph {:mvn/version "0.1.6" :exclusions [aleph/aleph]}

az20:08:59

Thanks so much for the help @U04V70XH6

1
Ryan20:08:50

In general, how do I resolve a symbol if it was stored in edn unresolved with a '

noisesmith20:08:58

in general there's no guarantee it can be resolved, but you can start with the resolve function

noisesmith20:08:18

user=> (resolve '+)
#'clojure.core/+

noisesmith20:08:46

there's also requiring-resolve if you want the compiler to look up and require the namespace too

Ryan20:08:11

What Im trying to do is store a map with vectors representing messages

dpsutton20:08:33

sounds like a fine use of data. why do you need to resolve anything?

Ryan20:08:51

e.g. :foo ['who " kicks the ball"], then sort of hydrate them with variables in context of a log message

Ryan20:08:03

because some log messages don't need 'who at all

dpsutton20:08:28

we're using resolve in a technical sense. how do you mean resolve?

dpsutton20:08:27

oh i see. you are using it the same way. can you write out a form with how you would use it? a bit more concrete of an example?

hiredman20:08:40

resolve and friends only work with vars, which are only the top level global names created with def

hiredman20:08:21

names bound via let, or via function application are "locals" and don't have any kind of first class queryable representation

Ryan21:08:53

that puts a wrinkle in it

Ryan21:08:20

(def messges 
  {:login ['who " has logged in at " 'time]
   :logout ['who " has logged in at " 'time]
   :changed-password ['who " has logged in at " 'time]
   :app-restart ["The application has restarted at " 'time]
   })

(def log-message {:who "ryan" :type :login :time #inst "2020-02-02T02:02:32Z"})

(defn humanize-log-message [log-mesage]
  (get messages (get log-message :type)))
That's the jist of what I'm shooting for

Ryan21:08:07

excuse some copy-paste laziness on the sample content 🙂

noisesmith21:08:26

so what you actually want is templating

Ryan21:08:04

precisely

noisesmith21:08:53

I'd break this into two tasks, the first one (use :type to pick a template) you basically have already

noisesmith21:08:59

the second part, using the keys of the data to fill in that template, can be done via simple walk/replace code in your case, or you could pull in a logging lib like selmer if you think you'll want full featured templating

hiredman21:08:12

clojure.walk/prewalk-replace

noisesmith21:08:39

(apply str (map #(get log-message % %) (get messages (:type log-message))))

"ryan has logged in at Sat Feb 01 18:02:32 PST 2020"

noisesmith21:08:52

I considered walk, but there's a guarantee of no depth here

Ryan21:08:09

thats awesome thanks for pointing me in the right direction!

noisesmith21:08:29

I changed your definitions slightly to make that work:

(def messages
  {:login [:who " has logged in at " :time]
   :logout [:who " has logged in at " :time]
   :changed-password [:who " has logged in at " :time]
   :app-restart ["The application has restarted at " :time]}) 

Ryan21:08:42

right use some keywords

noisesmith21:08:00

of course symbol / keyword conversion is also trivial

Ryan21:08:27

yeah still glad I didnt do all of them before I made sure the first few worked! 🙂

noisesmith21:08:07

@rdonahue since this is #beginners I'll point out that the key thing that makes it work (get coll key default) works since only things you want substituted will be keys in that map

noisesmith21:08:45

and in this case of course both the key and default are the same value

Ryan21:08:34

yes thanks for pointing everything out

noisesmith21:08:04

oh, and of course, the always useful apply

🙏 1
Ryan22:08:46

Ok, sooooo if I wanted to do one little thing extra, say make the inst's a little more compact, is my best bet to transform the map on the way in to that function? Maybe with specter, which I'm already using for nested map traversal?

Ryan22:08:11

like, rather than go with like selma or something more intense on the templating front

noisesmith22:08:31

the inst is a data type that has its own dedicated formatter

noisesmith22:08:11

you can replace the current replacement function (the one using get) to a more complex thing that also does conversions based on data type

Ryan22:08:11

sweet, I'll start on that first thing in the morning! Thanks for all your help!

closure-is-overrated23:08:01

beginner question, how do people get a value from a map. currently i always do (get map :key) . is there an “idiomatic” way?

noisesmith23:08:25

both (map :key) and (:key map) work

noisesmith23:08:38

of course naming anything map is pathological

closure-is-overrated23:08:55

for context in this code `

(not (= "labeled" (get params :action))
that’s how i do it all the time. is there a better way

noisesmith23:08:19

(not= "labeled" (:action params))

closure-is-overrated23:08:33

oh so interchangeably works

noisesmith23:08:47

well - this is specific to keywords / symbols but yes

closure-is-overrated23:08:55

ok i see. that’s simpler

noisesmith23:08:59

hash maps invoke get when used as functions, as do keywords and symbols

noisesmith23:08:30

so (params :action) would also work, but if one of the two is a data literal, I prefer to put that one in the calling position

noisesmith23:08:04

but ("foo" {"foo" "bar"}) would blow up - strings are not callable

closure-is-overrated23:08:29

but if one of the two is a data literal, I prefer to put that one in the calling position &lt;-- can you pls give an example?

noisesmith23:08:22

({:a 0} foo); returns 0 if foo is :a, otherwise nil
(:a foo) ; attempts to look up :a

noisesmith23:08:02

that way you don't get a dumb "can't be cast to IFn" error if foo isn't an expected datatype

closure-is-overrated23:08:23

so {:a 0} is the data literal in ({:a 0} foo)right? sorry new to programming

closure-is-overrated23:08:13

and if you do this ({:a 0} foo) it will return nil because there is no foo key in the dictionary right?

noisesmith23:08:28

well who knows what foo is

noisesmith23:08:30

sorry, I shouldn't have specified "data literal" but the more general "if the binding is obvious and visible"

noisesmith23:08:51

so foo here stands for some value that gets passed in, or could change, or otherwise isn' t immediately resolved and visible

noisesmith23:08:17

so maybe it's a function arg or a ring map parameter we destructured or whatever

closure-is-overrated23:08:20

oh ok so foo in that code is a placeholder

noisesmith23:08:53

right - the convention is that foo, bar, baz, quux are used as placeholders where the actual named thing is not the important aspect

noisesmith23:08:00

"metasyntactic variables"

closure-is-overrated23:08:02

ah yeah get it now, cause of course you have to pass in a key e.g. :foo and not foo

noisesmith23:08:06

adult way of saying "thingy"

👍 1
😄 2
souenzzo02:09:16

btw

(replace {:who  "you"
          :food "cake"}
  [:who " ate my " :food])
=> ["you" " ate my " "cake"]