Fork me on GitHub
#beginners
<
2016-12-06
>
roelofw06:12:24

a destructing problem in selmer. When I do paintings.tiles I see this output :

[{:x 0, :y 0, :url ""}]  

roelofw06:12:18

how do I get the url out of it. I tried {{ % get-in paintings [0] % }} {{ % get-in paintings 0 % }} {{ first {{ data.paintings }} }} ` but no luck

agile_geek09:12:49

It's hard to help without more context. Need to see what data structures are called what in your template and I've no idea what paintings.tiles is. However, given the shape of the data (a vector containing a map with url in it) you need to get the first (0 indexed) item in the vector to get the map and then the value associated with the :url keyword. So something like: (get-in paintings [0 :url]) assuming paintings has that shaped data and I don't know if it does from the information you've given.

roelofw11:12:46

@agile_geek , yes, I know that part. But my question is how to convert that so selmer can do it

agile_geek11:12:39

No idea - look at selmer docs

agile_geek11:12:28

I suspect you need to destructure the data in Clojure and then set a variable using Selmer's fn's then reference that variable in the template

roelofw11:12:05

I found this in the docs :

"Accessors are separated by dots like {{ foo.bar.0 }}

which gets translated into (get-in context-map [:foo :bar 0]). So you

can nest vectors and maps in your context-map.  

agile_geek11:12:02

That's extracting data from the Selmer context-map. Is your data in the context map

roelofw11:12:15

nope, in a normal map

agile_geek11:12:22

So that won't work

roelofw11:12:27

nope, Im rewrite my code so the url has it own keyword

agile_geek11:12:30

I would extract the url from the map in clojure and pass it to the selmer template as a variable using render

agile_geek11:12:41

do the extraction using Clojure

roelofw11:12:05

That is what I try now

agile_geek11:12:21

Anyway I've work to do so good luck

roelofw11:12:29

and I have to think how to solve it when there are more then 1 url for bigger images

agile_geek11:12:41

I've only used Selmer once three years ago so I wont be much help but it does have things like for tags so if you have multiple urls that all need to render in the same way in sequence you could pass the for tag a vector of URLs

agile_geek11:12:06

If each image needs to go in different places they probably need unique names anyway

agile_geek11:12:22

But if you want to render the details and images of several paintings on a page the for tag could wrap a html and tags for a collection but then you would need to figure out how to destructure the individual details from each map

agile_geek11:12:29

I think if you for loop over a vector of maps where each map is your painting details you can name each map in the vector something e.g. painting and then use dot notation to get the contents {{painting.url}}

agile_geek11:12:02

Really do need to get back to work now 😉

roelofw11:12:13

Im doing that way but for the url I needed another way

roelofw11:12:25

but now it worked I think, Thanks for the help

kyle_schmidt14:12:44

I am requiring ring but when Clojure compiles I receive an error

[ring.util.http-response :refer [response]]

kyle_schmidt14:12:04

java.lang.IllegalAccessError: response does not exist

tokenshift14:12:55

ring.util.http-response doesn’t define its own response, it uses the one from ring.util.response

kyle_schmidt14:12:20

thanks! that’s good to know! But when I re-run it with:

[ring.util.response :refer [response]

kyle_schmidt14:12:30

I get:

No such namespace: response

tokenshift14:12:09

What’s your whole ns/require block look like?

kyle_schmidt14:12:46

(ns guestbook.routes.home
  (:require [guestbook.layout :as layout]
            [guestbook.db.core :as db]
            [bouncer.core :as b]
            [bouncer.validators :as v]
            [compojure.core :refer [defroutes GET POST]]
            [ring.util.response :refer [response]]))

dominicm14:12:21

Do you have ring-util as a dep?

dominicm14:12:34

Ring util isn't in the minimal core lib

kyle_schmidt14:12:04

I thought it was, that’s probably my error

dominicm14:12:14

[ring/ring-core "1.5.0"] <-- minimal dep [ring "1.5.0"] <-- core, util, jetty, devel

kyle_schmidt14:12:25

:dependencies [[bouncer "1.0.0"]
                 [cljs-ajax "0.5.2"]
                 [com.h2database/h2 "1.4.192"]
                 [compojure "1.5.1"]
                 [conman "0.6.2"]
                 [cprop "0.1.9"]
                 [luminus-immutant "0.2.2"]
                 [luminus-migrations "0.2.8"]
                 [luminus-nrepl "0.1.4"]
                 [markdown-clj "0.9.91"]
                 [metosin/ring-http-response "0.8.0"]
                 [mount "0.1.10"]
                 [org.clojure/clojure "1.8.0"]
                 [org.clojure/tools.cli "0.3.5"]
                 [org.clojure/tools.logging "0.3.1"]
                 [org.clojure/clojurescript "1.7.228" :scope "provided"]
                 [org.webjars.bower/tether "1.3.7"]
                 [org.webjars/bootstrap "4.0.0-alpha.5"]
                 [org.webjars/font-awesome "4.7.0"]
                 [org.webjars/jquery "3.1.1"]
                 [org.webjars/webjars-locator-jboss-vfs "0.1.0"]
                 [reagent "0.5.1"]
                 [ring/ring-core "1.5.0"]
                 [ring-middleware-format "0.7.0"]
                 [ring-webjars "0.1.1"]
                 [ring/ring-defaults "0.2.1"]
                 [selmer “1.10.0”]]

kyle_schmidt14:12:40

cool! Thank you!

dominicm14:12:00

I usually just use the full ring, else I'm not sure what I have.

dominicm14:12:17

But I might be wrong, because looking at the source on github, core should include the utils

kyle_schmidt14:12:41

Hm yeah I got the same error

dominicm14:12:42

At the REPL does (require 'ring.util.response) work?

dominicm14:12:09

And also (require '[ring.util.response :refer [response]])?

kyle_schmidt14:12:36

I am not able to launch a repl in this project because my code won’t compile due to this requirements issue

dominicm14:12:13

Oh, derp. You've fixed the require issue already.

dominicm14:12:25

No such namespace: response This means you're doing response/response something, or something like that.

dominicm14:12:47

[ring.util.response :as [response]] maybe you meant this?

kyle_schmidt14:12:13

I want the function that is under ring.util.response that is called response

kyle_schmidt14:12:56

I figured it out

kyle_schmidt14:12:22

I was doing

response/ok
which was thought to be a namespace just as you’ve mentioned

kyle_schmidt14:12:54

Thank you for your help!

dominicm14:12:17

Sorry I was so blind at first 😄.

sooheon17:12:27

Hey guys, is this blog about select-keys (http://blog.jayfields.com/2011/01/clojure-select-keys-select-values-and.html) out of date? Does it now return a map with keys in the order of supplied keys-vector every time? I don’t know if I can depend on that.

donaldball17:12:34

I don’t believe you can. As an impl detail, I believe small maps are implemented as array maps and do preserve insertion order, but that is not a contract on which you should rely.

donaldball17:12:25

If you need a logically ordered map, sorted-map is there for you.

sooheon17:12:45

How about if I try to rewrite it with something like for k in ks … get map k … into {}

sooheon17:12:54

would that preserve the order of ks?

dpsutton17:12:04

i believe you can't go into {} and want order

donaldball17:12:08

no, you’re dumping the values into a map at the end

dpsutton17:12:11

you need to go into (sorted-map)

sooheon17:12:37

hm I can’t concisely describe a comparator

sooheon17:12:46

I want pretty much arbitrary ordering of keys

sooheon17:12:53

to be preserved

donaldball17:12:06

Can you live with dumping the ordered values into a vector?

donaldball17:12:22

You’ll have to maintain key uniqueness yourself, of course

dpsutton17:12:29

is that not what ordered-map gives you?

sooheon17:12:07

I only see sorted-map fn, not ordered map

donaldball17:12:08

sorted-map sorts the map by a comparator fn on the keys

donaldball17:12:22

There is no ordered-map in clojure core of which I’m aware

sooheon17:12:47

so I could dump it into a vector of vector pairs [[a 1] [b 2] … ]

dpsutton17:12:23

oh sorry, array-map

dpsutton17:12:23

> An array-map maintains the insertion order of the keys. Look up is linear, which is not a problem for small maps (say less than 10 keys). If your map is large, you should use hash-map instead. > When you assoc onto an existing array-map, the result is a new array-map with the new key as the first key. The rest of the keys are in the same order as the original. Functions such as seq and keys will respect the key order. > Note that assoc will decide to return a hash-map if the result is too big to be efficient.

donaldball17:12:49

Yeah, that’s also a fine idea, but the assoc land mine is just waiting to defy your expectations 🙂

sooheon17:12:51

that assoc behavior seems to no longer be true

sooheon17:12:08

(keys (assoc (array-map :foo 10 :bar 20) :baz 30)) gives me (:foo :bar :baz) in my repl

donaldball17:12:21

I think the threshold is 16 values

donaldball17:12:42

(type (assoc (apply array-map (range 1000)) :foo "bar"))
clojure.lang.PersistentHashMap

sooheon17:12:43

whaaat so my 20th assoc or something will definitely be at the front?

donaldball17:12:20

No, you’ll just lose the “seq is in insertion order” property

sooheon17:12:31

ah ok it becomes a hash map

sooheon17:12:47

so this ordered map thing, am I likely to be just modeling the problem wrong?

sooheon17:12:03

It’s really annoying, there arent built in things like order by val

sooheon17:12:01

I feel like since I’m trying to build up a ordered list of k-v pairs just as an intermediate step to a final calculation, maybe a reduce is better?

sooheon17:12:11

but that’s more confusing

donaldball17:12:18

Hard to say, ennit. There are certainly cases where you need to preserve an arbitrary ordering, but those cases don’t tend to be also those where you require unique values by some other key.

dpsutton17:12:21

wait, what are you trying to acomplish?

dpsutton17:12:43

and if this is an intermediate step, why not just use [[k1 v1] [k2 v2] ...]

sooheon17:12:00

yeah that was the idea above, sounds best!

dpsutton17:12:10

you'll never see the data yourself

dpsutton17:12:18

and also, just reduce the collection if possible

sooheon17:12:36

yeah i’m just habitually wanting to build data to see in the repl

sooheon17:12:58

thanks for the help :)

Lone Ranger20:12:47

hi there 🙂 was wondering if I could get any guidance on setting :source-paths in project.clj for a cljs project

Lone Ranger20:12:17

(defproject hello_world "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url ""
  :license {:name "Eclipse Public License"
            :url  ""}
  :dependencies [[org.clojure/clojure "1.8.0"]]
  :source-paths ["src"
                 "src/hello_world"
                 "."])
eh?

Lone Ranger20:12:22

attempting to run lein run -m clojure.main repl.clj and getting some nasty error messages... the tutorial guidance suggests it might have something to do with :source-paths but it doesn't specify how it should be structured

gdeer8120:12:30

@goomba can you DM me the stacktrace?

Lone Ranger20:12:41

abs, thank you!

noisesmith20:12:41

goomba : putting "." in source-paths is a bad idea, because it results in your entire repo being in your jar

noisesmith20:12:54

(if you ever make jars)

Lone Ranger20:12:40

was just trying various things to attempt to get it to run 😛

noisesmith20:12:45

haha, fair enough

noisesmith20:12:16

also in general if "foo" is in src-paths, then "foo/bar" probably shouldn't be there too (I assume that too was shotgun debugging of course)

Lone Ranger20:12:41

yes indeed 😄

Lone Ranger20:12:15

it's cool got it mostly running... will probably just wipe it and start a clean slate having the benefit of hindsight

Lone Ranger20:12:43

and by "it" I mean my harddrive and change careers 😂

gdeer8120:12:05

This is an import because this is on Clojurescript's quickstart guide. If we're confusing people this early into their journey, it's going to turn some people off

Lone Ranger20:12:45

if they got past the parenthesis it's probably fine 😛

noisesmith20:12:49

oh, that project was copied from an example?

gdeer8120:12:46

towards the end of it the tutorial mentions Leiningen and gives a lein command to run

Lone Ranger20:12:05

you said "we're" confusing people 😄 I heard clojurians were awesome

Lone Ranger20:12:28

yeah I'm a Python guy but I've fallen for Clojure ❤️. I'm trying to backdoor it into my work with ClojureScript, hopefully using it on the backend via node.js, and then magically one day it will just be real Clojure 😄

Lone Ranger20:12:11

also anything I can do to spend less time writing JavaScript T.T

gdeer8121:12:19

@goomba then I suggest heading over to the #mentoring channel and see if anyone has bandwidth to get you started down a more productive track

Lone Ranger21:12:39

thank ya thank ya!

noisesmith21:12:51

regarding the leiningen section on that page, the suggestion to run lein classpath if you have questions is so stupid it's funny

noisesmith21:12:15

"oh, I see, a list of 1000 files all on one line, now I understand"

Lone Ranger21:12:15

anyway got to clojure conj??

Lone Ranger21:12:22

ehhh I'll take it to #off-topic

curlyfry21:12:40

@goomba Welcome! How much Clojure have you done so far? Everyone learns differently, but I personally like using a template for starting out a ClojureScript project (where I can explore for a bit without worrying about the project building at all). I'm not sure which one is best for beginners, but https://github.com/bhauman/figwheel-template is a pretty cool barebones template with automatic code reloading and https://github.com/reagent-project/reagent-template is popular if you want to use the Reagent react wrapper.

curlyfry21:12:32

(The second one has the code reloading too)

Lone Ranger21:12:46

fantastic 😄 I'm very "old-school" ... If I had it my way I'd work from JVM byte-code out (I suppose can say assembly for a different day) but there's only so much time in the universe! It's obviously a ton of value to see some projects put together with best practices

noisesmith21:12:02

@goomba if you really want to see byte code / assembler, no.disassemble with jvm clojure is pretty awesome

Lone Ranger21:12:16

reallllly 😄

noisesmith21:12:33

you hand it a function, it shows you the assembly for the byte code generated

Lone Ranger21:12:34

that is awesome! I'm a big fan of language design in general so I love that stuff

noisesmith21:12:43

it even knows how to return disassmbly data as a data structure so that you can write code that works with it

Lone Ranger21:12:49

so it goes past byte code and to assembly?? wow

noisesmith21:12:04

well "disassemble" as in get pseudo-code for the byte-code

noisesmith21:12:14

there's no direct access to the assembly for machine code

Lone Ranger21:12:14

that's even better

Lone Ranger21:12:25

yeah I was wondering how that worked!

Lone Ranger21:12:33

@curlyfry thanks for the warm welcome 🙂

noisesmith21:12:01

goomba: clojure contains a copy of asm.java which is a project that directly emits jvm bytecode without using javac - it's pretty neat

Lone Ranger21:12:18

man... this language is so magical

Lone Ranger21:12:51

It's also absolutely perfect for AI

dpsutton21:12:08

check out core.logic and have a good time

Lone Ranger21:12:16

and not that machine learning nonsense everyone calls AI I'm talking real AI 😄 😄 😛 😛

Lone Ranger21:12:36

@dpsutton Will do! So much to learn

gdeer8122:12:11

@goomba post specific questions here

gdeer8122:12:47

Om uses reify to create React classes

Lone Ranger22:12:47

bit confused about the purpose of reify

Lone Ranger22:12:57

is it om specific?

gdeer8122:12:45

no, it's in clojure core and clojurescript core

Lone Ranger22:12:44

okay. I'm not totally comprehending the doc string or examples... it seems like the purpose has something to do with working with objects?

gdeer8122:12:32

here is a really contrived example

Lone Ranger22:12:26

I'm good with contrived examples 😄

gdeer8122:12:43

what does this return?

(.toString (Object.))

gdeer8122:12:51

some nonsense about "java.lang.object@<some hash>"

gdeer8122:12:33

but what about this?

(.toString (reify Object (toString [_] "Oh Hai!")))

gdeer8122:12:45

so in the Om example you posted in the other channel it is returning a "reified" instance of IRender with a modified implementation of render

gdeer8122:12:30

It's the reason that some people find Reframe more "beginner friendly"

gdeer8122:12:22

also, in my example above I'm calling toString on a reified instance of an object with a modified implementation of toString. my version returns "Oh Hai!" so that is what gets returned

gdeer8122:12:24

definitely not a beginner topic

Lone Ranger22:12:33

so the [_] is pointing to the "this" of the object and you denote it as an underscore because it is unimportant

Lone Ranger22:12:02

okay, I understand now. there is a similar function in Python... just needed to connect the dots, thank you

Lone Ranger22:12:55

so the second argument of reify is instructions for how you want to perform the "reification"?

Lone Ranger22:12:15

interesting... just trying to draw comparisons, I assume reify is primarily for Java objects? In Python objects have the ability to define how they wanted to be reified... called repr in python

Lone Ranger22:12:52

do Java objects do the same? like if I call an object that has some kind of defined method for reifying itself does it need the protocol argument?

gdeer8122:12:26

it's not just a java interop thing. you can also use it to create a one-off instance of a protocol

jjfine22:12:46

it's for more than just the string representation of an object

Lone Ranger22:12:10

what's the difference? could be any kind of valid form, not just string?

gdeer8122:12:31

so if you had

(defprotocol Cat (speak [this]) (scratch [this person]))
you do
(def nice-cat (reify Cat (speak [_] "mew") (scratch [_ _] "I don't scratch, I good kitty")))

Lone Ranger22:12:49

ahhhh interesting

Lone Ranger22:12:46

defprotocol is new to me (guess I'm in the right room)

gdeer8122:12:02

it's the same as in python

Lone Ranger22:12:24

except my guess is it's smarter and doesn't let you mutate state and screw your coworkers 😛

Lone Ranger22:12:48

it's what they call an interface in Java? like a class with just methods and no data?

gdeer8123:12:29

if I had a java interface named Cat.java on my classpath my nice-cat def also works

Lone Ranger23:12:09

gotcha 😄 thanks guys!

dpsutton23:12:07

name it rand10

dpsutton23:12:24

you may have started the parsing for number and thrown it off when you switched to 10rand

dpsutton23:12:42

don't have a repl open right now to check though

dorianc.b23:12:33

Awesome yea that worked. note to self don’t start variables with numbers

dorianc.b23:12:47

I was just messing around trying to understand destructuring I didn’t think about the variables names.

gary23:12:23

Did you get a delimiter error?

dorianc.b23:12:05

so I was looking for a missing () but I knew my parens were correct so it was a bit frustrating

dpsutton23:12:03

same thing happens in maps if you have an odd number of terms or you put the : at the end of the keyword, it signals parse error for unmatched delimiters and such