Fork me on GitHub
#clojure
<
2016-09-30
>
eraserhd01:09:20

So, I want a kind of inverse of defmulti, in order to preserve Open/closed principle. defmulti allows one to extend how values are consumed, but I want to extend how they are produced, allowing each module to register additional producers. There are clearly many ways to do this. Anyone have experience with this sort of thing?

eraserhd02:09:25

For example, not sure whether I should use atoms or alter-var-root! to register things as namespaces are required. I guess threads could be an issue.

pesterhazy09:09:50

I've noticed this to be a common pattern for me:

(defn update-some
  "Like clojure.core/update but returns `m' unchanged if `k' is not already a
  key of `m'"
  [m k & args]
  (if (contains? m k)
    (apply update m k args)
    m))
Anyone else?

dominicm09:09:32

@pesterhazy Not myself, but I can see the utility, particularly if you don't want nils in your map.

pesterhazy09:09:26

@dominicm, also if your update fn doesn't handle nil well

dominicm09:09:38

@pesterhazy Yep, but that might indicate problematic code. I was under the impression that functions should generally handle nil. Even though that isn't particularly true.

pesterhazy09:09:39

no, a lot of interop-related code doesn't like nil, e.g. clojure.core/name, clojure.string/*, clojure.core/inc

pesterhazy09:09:54

also number, string fns

dominicm09:09:55

That's true, yes. I wonder when you are supposed to handle the nil case. I've found myself solving the general nil/update problem via a function I called nilf - it checks if the argument is a nil, and just skips if so. Doesn't work so well in multi-argument cases though (which to check!)

joost-diepenmaat09:09:13

@dominicm that sounds a lot like clojure.core/fnil

dominicm09:09:43

@joost-diepenmaat It's similar, but different. fnil is a default argument in place of the nil, this just skips the f altogether

tcoupland09:09:33

@eraserhd big question! but i think your looking at atom to be honest, if your looking for a 'fan out' kind of solution. Also worth looking at core.asyc/mult, that's a nice way of fanning stuff. Then add a dash of Component so your namespaces have a life cycle where they can register them selfs in the atom/tap the mult. enjoy!

credmp11:09:22

has anyone ever run into this error while running migratus: clojure.lang.PersistentVector cannot be cast to clojure.lang.Named? It happens when there is not schema_migrations table anymore...

credmp11:09:34

seems a dependency issue with hugsql

yogthos12:09:05

the issue is with the API change in clojure.java.jdbc

yogthos12:09:27

if you have a dependency that's pulling in an older version, then it will conflict

credmp12:09:03

Hi Yogthos… I needed to upgrade java.jdbc indeed

credmp12:09:08

and that solves the problem

credmp12:09:29

love the work you do btw… thanks!

grzm12:09:14

I've got some clojure tests that tests code that generates error messages which are logged. The tests aren't failing, it's expected that the code will log errors. This makes for noisy output when running tests. Any strategies for quieting this down? Sometimes I do end up adding other log messages while debugging, so I'd rather not disable logging entirely during testing.

credmp12:09:53

you can always exclude the namespace from your logging solution

yogthos12:09:05

@credmp thanks, and glad to hear everything's working 🙂

grzm12:09:04

credmp that would be the namespace of the code that's got the log statements, correct? Not the test code.

credmp12:09:16

yeah, that makes 2 of us :)… I was doing a live coding broadcast earlier today and it failed miserably… luckily it was at the end, so I could take some time

credmp12:09:37

so say my.namespace is generating all these extra messages, exclude my.namespace

grzm12:09:54

thanks for the suggestion. I'll give it a try

manenko13:09:35

@credmp > I was doing a live coding broadcast earlier today and it failed miserably Well there is a workaround. You should always say “See? An error! And in the next episode I will explain the cause of it and how to fix it. See ya!” 😛

credmp13:09:16

That is exactly what I did, as it was the end of the episode :)

credmp13:09:24

One of the mottos of the cast is to tune in to watch me fail, which more then often works bananadance

lwhorton13:09:56

this really feels like a problem that clojure has already solved somewhere, but i’m not sure where to look. can someone point me in the right direction? I’m trying to write functions that operate on either a single set of data ’(…) or a collection of datasets ’( ‘(…) ‘(…) ). Surely there is a better abstraction to handle this case that is not just “write specific helper functions to check seq? versus not-seq? at each step"?

ul13:09:08

perhaps clojure.walk will help

dominicm13:09:19

@lwhorton the obvious solution is to let the caller decide whether they need to map or not?

lwhorton13:09:22

for example, if i’m trying to sample a dataset, say naively take every-other item in the dataset, is there a clojure-ey way to write this sample-data function that accepts both a single dataset or multiple?

lwhorton13:09:51

i suppose I didnt think of that @dominicm .. and also great reference, thanks

mpenet13:09:04

@nathanmarz with specter can you write a tree walker/transform that's also able to expand/resolve some branches? ex a tree that contains keyword values that need to be replaced/expanded by another tree as you walk it.

nathanmarz14:09:30

@mpenet yes that's easy, use stay-then-continue

mpenet14:09:48

thanks, I ll look it up

nathanmarz14:09:52

here's an example:

(def TreeVals
  (recursive-path [] p
    (if-path vector?
      [ALL p]
      STAY)))

(def TreeExpander
  (recursive-path [] p
    [TreeVals
     (stay-then-continue p)]
     ))

(transform TreeExpander (fn [v] (vec (range v))) [4])
;; => [[[] [[]] [[] [[]]] [[] [[]] [[] [[]]]]]]

grzm15:09:50

@credmp the logging tip works well. Thanks!

kkruit15:09:30

So i'm new to clojure and now of course I want to break the rules. I'm using jna which allows me to call a system function that takes a Structure and mutates it. I'm not sure how to allow this to happen and then return the mutated object. I've looked at atoms and refs but they don't seem to allow you to use a function to mutate the object unless it returns that value. Where should i look?

kkruit15:09:27

I'm not too worried about the mutation because I'm creating the object being mutated inside the same function that calls the mutator so it can be a "black box."

dominicm15:09:35

@kkruit Look at doto 🙂

kkruit15:09:56

Will do. Thanks!

kkruit15:09:26

@dominicm so a simple example of my problem is that the function i'm using is basically like the anonymous function here and I cant change it. I kinda wanna pass the hashmap by reference.

kkruit15:09:32

so pretend like i cant change that lambda function

kkruit15:09:26

how do i get the modified hashmap

dominicm15:09:40

Does (doto (java.util.HashMap.) f) work?

dominicm15:09:58

That should return the original HashMap reference, after f has been run against it

kkruit15:09:15

it's returning a empty hashmap because the mutated one isn't a method on the hashmap

dominicm15:09:23

🙂 That's not it.

dominicm15:09:37

There's a subtle bug in your code, I'm not sure why it doesn't throw, but it's a mistake

dominicm15:09:52

Try this ^^

dominicm15:09:06

With the threading macros (`->`, ->>, doto, etc.) there's a behaviour that sometimes people run into. It's a little confusing. I'll try my best to explain it.

(-> m
       (fn [m] (do-thing-to m)))
Actually expands to:
(fn m [m] (do-thing-to m))
So you have to wrap it twice, so you get:
((fn [m] (do-thing-to m) m)
Does that make sense at all?

kkruit15:09:20

cool, Thanks!

quoll16:09:55

@dominicm double-wrapping is cool, thank you! It’s obvious when I think about it, but it never occurred to me. I always defined the function (in a let or letfn) before starting the threading block.

dominicm16:09:58

@quoll Unless it's for debugging, I'd generally recommend against it from a stylistic point of view. I find it harder to read. You might find your letfn is significantly clearer as you spend time giving names to your actions.

dominicm16:09:18

Another alternative is to turn your entire threading macro into an as->

quoll16:09:32

I’m typically happy with it, yes, but sometimes it’s a trivial wrapper that’s not worth it

quoll16:09:16

anyway, thanks. You’re right… I wouldn’t use it much, but it’s handy to remember

bcbradley16:09:38

holy crap i just wrote a one hit wonder function xd

bcbradley16:09:43

that took a long time

bcbradley16:09:46

use it like

(concurrently {+ [- /] * [/ + inc] dec [*]} (constantly 5) (constantly 10))

witek17:09:54

Hi, as an experienced Java developer I find it difficult to solve problems the functional (recursive) way. Which books would you recommend? I have already read Brave-Clojure and Joy-of-Clojure. Now I am looking for something what focuses even more on recursive algorithms, etc. Or do you know any other good learning resources for this purpose?

bfabry17:09:51

@witek the little schemer maybe

bfabry17:09:29

short and mind opening. not very clojure specific, but iirc most of it uses recursion

bfabry17:09:51

SICP is also always a good choice to read, but that's a lot of book just to get better at thinking recursively

dpsutton17:09:09

sicp site with downloadable ebooks and other things: https://sicpebook.wordpress.com/

bcbradley17:09:40

I'm trying to convince my classmates to use clojure on our undergraduate capstone project

bcbradley17:09:05

we are in teams of four with different industry mentored projects

blueberry17:09:12

@witek IMO, if you've already read The Joy of Clojure, I don't think what you need is more reading. I'd throw myself into coding a real project and applying what I'd learned if I were you.

bfabry17:09:18

I'd probably agree with that. just try and solve normally iterative problems using for loop, and then see if they would be a good fit for reduce. the little schemer is nice though because you can burn through it in a plane ride

bcbradley17:09:44

every time anyone says "little schemer" i get a picture in my mind's eye of some mischievous cartoon character rubbing his hands together and grinning menacingly.

bcbradley17:09:11

that evil little elephant

bcbradley17:09:28

gonna build something evil...

kuzmin_m18:09:04

Hi! I created bidirectional routing library based on core.match. I'll be glad to hear any feedback. https://github.com/darkleaf/router

zilti19:09:20

Is there a way to tell clojure.data.xml to stop throwing errors because of "Unknown xmlns for clj ns"?

zilti19:09:48

I'm coding a WebDAV implementation, and apparently I'm supposed to handle XML with unknown XMLNS.

achesnais21:09:33

I’m using agents in my code for the first time. Any recommendations/best practices/ things to watch out for? 🙂

bcbradley21:09:39

does anyone have any good introductory learning material for ring?

bcbradley21:09:52

i just read the wiki on github but feel a little lost

bcbradley21:09:10

i've hardly done any web programming, in any language

bcbradley21:09:37

i'm super comfortable with functional programming ideas, but I don't know anything about the web

bridget21:09:22

You might want to take a look at Luminus @bcbradley. http://www.luminusweb.net/

bcbradley21:09:34

i was hoping for something less "all-in-one"

bcbradley21:09:51

i'm afraid if i concentrate too much on a single framework, i won't understand the principles or concepts that make it work

bcbradley21:09:02

so i'll just forced to use that framework because I don't understand anything else

bfabry21:09:21

imo you've probably got that right there

bridget22:09:19

I was thinking more that it might have the intro learning material about ring you were looking for

bcbradley22:09:39

I looked through it and it seemed too specific to the application

bfabry22:09:42

sadly I don't know much about the clojure http world, but what web app experience I have started with rails, and it definitely meant that it was a much longer time before I really understood how all the pieces worked than it should have been

bcbradley22:09:14

i'm looking more for like "what is a cookie" "what is a session" "whats the standard workflow between server and client" etc

bfabry22:09:15

(but we did get our app out there, and I was being paid, so on the whole it was still the right thing to do)

bcbradley22:09:48

for a senior software engineering undergrad i'm embarassingly ignorant of the web

bcbradley22:09:15

the only networking i've ever done is with low level sockets

bcbradley22:09:28

and every time i've ever had to do some kind of networking, i did it with low level sockets

bcbradley22:09:47

i never saw a need for anything else

zilti22:09:27

Well, that probably saved you a lot of trouble. I always did my own stuff, too, and now I have to implement WebDAV. Dear gods!

bcbradley22:09:56

whats WebDAV?

bcbradley22:09:52

i mean atleasti can get a gist of the workflow

bcbradley22:09:08

then i'll know exactly what questions to ask google about in context of that workflow

bcbradley22:09:12

about sessions, cookies etc

bfabry22:09:05

if I wanted to learn web apps from the ground up personally, I'd implement a todo list app that had users with login and sessions in just ring, then ring+compojure, then ring+compojure+hiccup, etc etc

jrheard22:09:05

bcbradley - a good place to start imo would be to learn about http - you’ll want to learn about the http request/response cycle, and see some examples of what http requests and responses look like

jrheard22:09:41

the curl command might be a surprisingly good learning tool - if you do man curl you should be able to find various knobs that let you see real live http requests and responses

jrheard22:09:15

once you have a good understanding of what requests and responses look like, the rest of it will hopefully be a little more easy to grok

jrheard22:09:07

see also the Network pane (and others) in chrome devtools

jrheard22:09:25

just like take a look at http://yelp.com or whatever using devtools and curl

jrheard22:09:42

oh lol you’re already well past that, aren’t you? didn’t see you’ve already done things with rails

bcbradley22:09:36

i wanted to give back to the clojure community but i didn't even know it existed 6 months ago. I've been spending all my free time learning as much about it as I can, making dinky little programs and trying to compare the ideas Rich has about what makes program development difficult with my own experiences. I can confidently say that I have become more enlightened in the short time I've had with clojure than I had in the 5 years I had with java or 8 years with C before then.

bcbradley22:09:15

Don't get me wrong, I can make stuff in plain old c. But it doesn't feel to me like i have control over how complicated the project can become. I feel like I don't have many tools at my disposal for managing incidental chaos or complexity

bcbradley22:09:36

I've learned so much from clojure. A lifetime of wisdom to be frank.

jrheard22:09:51

gotcha - pardon me for my lines above, i was very confused

bcbradley22:09:31

I've fully embraced the functional way of thinking, but I don't know alot about the web. I figured I could both give back to the clojure community and learn about the web by making something the clojure community doesn't have yet

bcbradley22:09:43

I figured a library for the Discord API

jrheard22:09:52

sounds like a great idea!

bcbradley22:09:11

I guess my biggest road block right now is it feels like everyone who's in the business of making web apps knows how web apps are made and can't imagine anyone not knowing how they are made 😕

bcbradley22:09:25

There is very little quality learning material out there

bcbradley22:09:22

your suggestion about learning http is a good one. I'll start there

bcbradley22:09:54

Is there anything else that seems fundamental? Something that doesn't change? I don't wanna learn about some technology that is just "today's soup of the day"

bcbradley22:09:18

I am quite comfortable with udp / tcp and the idea of sockets

bcbradley22:09:50

and assume I know how computers and networks work at the physical or data link layer

jrheard22:09:56

heh, that’s a super great question but unfortunately 95% of web programming is “soup of the day"

bcbradley22:09:28

I've seen some stuffs about ipv6

bcbradley22:09:33

I don't know what that is, is it important?

bcbradley22:09:49

someone told me it isn't mandatory

jrheard22:09:56

yeah i wouldn’t worry about it right now

bcbradley22:09:13

what is a websocket?

jrheard22:09:15

a fundamental thing in web programming is making http requests to a url and getting a response back

bcbradley22:09:15

is it a true socket?

jrheard22:09:19

so that’s what i’d start with

bcbradley22:09:27

What is a css?

jrheard22:09:49

websockets are a bit advanced, i’ve never used them myself, you can put them off - css is fundamental so that’s a great question

jrheard22:09:58

(if this is the wrong room for this, someone please speak up and i’d be happy to take this elsewere)

jrheard22:09:29

web programming basically involves (at least) three fundamental pieces of tech - html, css, and javascript

jrheard22:09:27

you’re likely familiar with html already, or at least have seen a few html tags - the html is basically the static content of the page, the words and some hints about the semantics of those words (these words are a paragraph, these other words are a large heading)

jrheard22:09:52

css - cascading style sheets - is a piece of tech that can be used to make your html document look pretty when viewed in a web browser

jrheard22:09:10

css is the reason that you see pretty colors and nice layouts when you view web pages

bcbradley22:09:20

so like html is the car and css is the paint?

bcbradley22:09:23

what would javascript be?

bcbradley22:09:43

i'm assuming, since i know javascript is programmable

jrheard22:09:04

hm, that’s a good question

jrheard22:09:41

i haven’t yet mentioned the distinction between the frontend and backend of your web app

jrheard22:09:16

the three pieces of tech i mentioned - html, css, and js - are used in the frontend portion, and if the frontend portion of your webapp is a car, then js is likely the engine

jrheard22:09:26

html is content, css is layout/style, js is behavior

jrheard22:09:44

it lets you write code that says “when the user clicks on this thing over here, make some side effect happen over there"

jrheard22:09:32

if you’ve used, for instance, a web email client like gmail, and you’ve been able to do a ton of things - send emails, view emails, etc - without leaving the web page you’re on, you’ve been using javascript

bcbradley22:09:48

When javascript does what it does

bcbradley22:09:54

does it simply modify the html programmatically?

jrheard22:09:05

it certainly can, yes!

jrheard22:09:15

that’s a great question and the answer is definitely yes

jrheard22:09:22

through the DOM, the document object model

jrheard22:09:24

that’s worth learning about

jrheard22:09:43

it’s an (oft-maligned) API that lets javascript code modify the contents of the html page it’s running on

bcbradley22:09:21

so if i'm understanding this all correctly, html is like the "state" of the program in one sense-- the layout and scaffolding

bcbradley22:09:34

css is the "state" in another sense, the colour

bcbradley22:09:43

I assume its more than just colour

bcbradley22:09:49

other aesthetic stuff?

gfredericks22:09:59

it can affect layout quite a lot

bcbradley22:09:10

I thought layout was html's job

jrheard22:09:44

css is quite often used for layout

jrheard22:09:12

it’s.. sort of a long story

bcbradley22:09:18

so it looks kind of like both css together make up the "state" of the page in a certain sense

jrheard22:09:25

but definitely css is a fundamental piece of web tech that’s worth learning about

bcbradley22:09:37

so javascript is responsible for managing the state?

jrheard22:09:07

there are perhaps several categories of state in this context, i don’t want to commit to saying that html/css are your page’s state

jrheard22:09:24

it’s a great question though

jrheard22:09:37

because yes, the page’s html is definitely a kind of state, it’s the current set of words, tags, etc that you’ve got on your page

bcbradley22:09:38

Why seperate state like this? Is it just a coincidence in how the internet browsers developed?

jrheard22:09:04

here’s something you might find useful - go to http://www.csszengarden.com/

jrheard22:09:13

and click on some of the links on the right

jrheard22:09:30

if i remember correctly, each page you are taken to has the exact same html, but is decorated / laid out by using different css files

jrheard22:09:55

i guess the idea is about separation of concerns - html for content, css for describing how it should be laid out / etc

jrheard22:09:19

html documents can also be read by screen readers - tools that folks who can’t see well use, which read web pages to them out loud

bcbradley22:09:49

You said javascript can generate html and css

bcbradley22:09:53

and access the DOM

bcbradley22:09:01

does that mean it can generate an entire webpage?

bcbradley22:09:06

all the css and all the html?

jrheard22:09:20

definitely, yeah - you can write arbitrary code in javascript that does whatever it wants to the webpage’s html and css

bcbradley22:09:37

If you can do that in javascript, does that mean you can do it in clojurescript?

jrheard22:09:40

absolutely

bcbradley22:09:05

So instead of learning 3 syntaxes and 3 semantics, I could learn 1 syntax and 3 semantics

jrheard22:09:15

one thing to know about is that historically, pages whose html is generated entirely by javascript have been hard to find via e.g. http://google.com

jrheard22:09:33

i think that that’s no longer as true as it used to be, but who knows

jrheard22:09:02

(there’s this whole category of thing called SEO, search engine optimization, where you try to do certain things to your html and css to get your web page to rank highly in google)

jrheard22:09:55

i can definitely see the attraction of just learning JS and using it to generate all your html and css, but i don’t think i’d recommend that - html, css, and js are fundanental to web programming, it’s best to learn them all, they’re sort of first principles and understanding them / being comfortable with them will make the rest of it go easier for you

bcbradley22:09:15

thankyou this is the kind of info i need

jrheard22:09:27

so you’ve got html, css, and js on the frontend - the stuff that’s going on in your user’s web browser

jrheard22:09:51

and on your backend, you’ve got arbitrary programming languages doing whatever you want, talking to databases, doing whatever - you can use clojure for this, or java, or python, or php or whatever you like

jrheard22:09:08

and the bridge that connects your frontend and backend is HTTP

bcbradley22:09:15

so the HTTP API for discord

bcbradley22:09:23

is a bridge between the backend of discord's servers

bcbradley22:09:28

and the frontend of your webapp

bcbradley22:09:35

or in my case, a library for building discord bots

jrheard22:09:14

hm, again that’s a good question but i’m not sure i’d quite put it that way - let’s set discord aside briefly but return to it in a second

jrheard22:09:32

so i worked at yelp for a while, and what happens if you type http://yelp.com into your browser and hits enter is: your browser sends an HTTP GET request to http://yelp.com

jrheard22:09:59

it eventually gets routed to a particular machine that yelp controls that’s running the yelp “webapp"

jrheard22:09:15

it runs some python code, talks to databases, does whatever else it wants, and then eventually responds to your browser with an HTTP response

bcbradley22:09:24

when it sends the http response

bcbradley22:09:32

does that mean it serves the html and css?

jrheard22:09:33

the response has some headers and then a bunch of HTML, and your browser uses this to draw pictures / etc on your screen

jrheard22:09:40

great question

jrheard22:09:02

you’re likely familiar with the fact that html documents make heavy use of tags, like <p>hello there</p>, etc

bcbradley22:09:10

yeah i've seen that

bcbradley22:09:16

its kind of annoying xd

bcbradley22:09:26

xml was never my favorite dsl

jrheard22:09:43

html documents can also contain tags that say: hey web browser, i’d like you to also go get some css and javascript, and it lives over here

jrheard22:09:55

those tags look like e.g. <link rel=“stylesheet” src=“foo.css” />

jrheard22:09:02

or maybe it’s href=, i forget

jrheard22:09:10

and for js, <script type=“text/javascript” src=“foo.js></script>

bcbradley22:09:15

wait a second

jrheard22:09:26

when the browser encounters one of these tags while processing your HTTP response’s html, it’ll kick off another http request to fetch that resource

bcbradley22:09:29

so the server serves a html page in response to the http get

bcbradley22:09:38

and the html itself contains some kind of link to the other resources

jrheard22:09:46

yes exactly

bcbradley22:09:49

does the browser automatically follow those links back to the server?

jrheard22:09:08

yup! and sometimes (often) it’s not even to the same server, it’s to some other sever somewhere else

bcbradley22:09:16

thats convenient

jrheard22:09:25

yeah, the browser does a lot of work for you

jrheard22:09:58

(this reminds me, you’ll encounter the concept of a “CDN” at some point, look that up at some point, it’s a pattern used to mitigate the speed of light in this context and help make web pages load more quickly)

bcbradley22:09:06

so is this "link" to be interpreted and treated sort of like a pointer in the c memory model?

bcbradley22:09:12

in other words, a type of thing all on its own

bcbradley22:09:33

or is it to be interpreted like "inline command" where, the browser parses the command and injects whatever it got from whatever server

bcbradley22:09:40

ie a c macro

jrheard22:09:09

i have very little c experience, so i’m hesitant to commit to one of those, but the second one sounds more like it

bcbradley22:09:37

i assume you have clojure experience

bcbradley22:09:54

then what i'm asking is if the link is like a ref, or is it like a macro

bcbradley22:09:10

does it generate something (perhaps using data from another server somewhere)

bcbradley22:09:20

or is it something that has to be derefed

jrheard22:09:24

ah interesting

jrheard23:09:18

your analogy questions are good but i worry that i’m going to give an answer when the analogy isn’t actually a precise fit and i’ll have sent you down a wrong path

bcbradley23:09:43

i'm just wondering whether the browser can be made to "not deref the links"

bcbradley23:09:51

in other words, don't download the images / whatever inline stuff

jrheard23:09:00

ah, good question

bcbradley23:09:04

if not, then i know its more like a macro rather than a ref

jrheard23:09:37

then it’s more like a macro than a ref, i suppose 😄

jrheard23:09:39

here’s what i recommend

jrheard23:09:52

in a web browser (i use chrome, but obviously you can use whatever), go to https://clojure.org/

jrheard23:09:38

if you’re using chrome, go to your menu bar and go to view -> developer -> view source

jrheard23:09:46

this’ll let you see the page’s html

jrheard23:09:22

just, like, look at that html for a while, see the different types of tags in it, click on whichever ones look like links, notice that the page uses a bunch of different css files

jrheard23:09:51

then go back to http://clojure.org and (again, this is in chrome), go to view -> developer -> developer tools

jrheard23:09:05

and click on the “network” tab, and refresh the page

jrheard23:09:39

this’ll let you see all the (many, many) subsequent http requests that your browser kicks off after it gets back the initial http response from http://clojure.org, the one that has all the html you saw in view-source mode

jrheard23:09:57

you’ll see things like “Method”, with values like GET, POST, etc - learn about what those are, what their semantics are

jrheard23:09:05

status codes, like 200, 304, etc - learn about those, what their semantics are

bcbradley23:09:40

gosh this is a powerful tool

jrheard23:09:52

absolutely! webdevs spend a ton of time using developer tools

jrheard23:09:59

very very useful tool, built right into the browser

jrheard23:09:08

and if you click on an item in this network pane, you’ll be able to see info about the related http request/response

bcbradley23:09:17

i wish i could see virtual memory like this when debugging c code

jrheard23:09:51

anyway i should get back to whatever i was doing when we started talking 🙂 but i hope you’ve got a slightly better picture of what web programming looks like

bcbradley23:09:02

thankyou very much

jrheard23:09:02

the frontend has html, css, js; the backend has arbitrary code in arbitrary languages; they communicate via http

bcbradley23:09:06

you saved me weeks of searching

jrheard23:09:34

i’m @jrheard on twitter if you find yourself stuck, and also i should usually be around here 🙂

blueberry23:09:52

@bcbradley there is a recend book "Web Developmet with Clojure, 2nd edition" that could help you

bcbradley23:09:04

thanks i'll give it a look

jrheard23:09:40

(oh also learn about cookies, those are also fundamental)

jrheard23:09:49

(ipv6 and websockets you can put off for a later day though)

jrheard23:09:52

(also re: your question about why html and css are separate - imagine a website that has ten or fifteen pages, whose html is written by hand - all ten or fifteen of those pages can be made to have a consistent look-and-feel by having them all refer to the same single css file; and if two years from now you want to redesign your website’s look-and-feel, you can (ideally) do that by just changing the one css file, rather than having to modify tens or hundreds of html pages)

bcbradley23:09:15

its about branding

bcbradley23:09:20

thats understandable then

jrheard23:09:36

sort of! or about maintainability, ease of making style changes without wanting to kill yourself, etc

jrheard23:09:56

in reality your html and css often end up more tightly coupled than i’ve made it sound here, but reality’s always messy 🙂

bcbradley23:09:48

so the ideals of seperation of concerns and forcing functionality to go through interfaces still applies to this as it does to any program right?

bcbradley23:09:52

keep css doing one job

bcbradley23:09:54

keep html doing one job

bcbradley23:09:58

keep javascript doing one job

jrheard23:09:08

yeah, exactly!

bcbradley23:09:23

html is good for search indexing

bcbradley23:09:39

css is good for making it easier for you to change your company theme / brand painlessly

bcbradley23:09:48

and javascript is the engine that makes everything interactive

bcbradley23:09:29

so when servers serve as a response to a GET

bcbradley23:09:40

and you get served some html that has links

bcbradley23:09:50

does the browser turn those links into more GETS on other servers?

bcbradley23:09:00

is it all http?

jrheard23:09:02

yeah, that’s what you’re seeing in the network pane in devtools

bcbradley23:09:39

so "json through http" means instead of asking for a webpage you are making a GET request to the server for plain old text

jrheard23:09:42

although you’ll want to be careful re: “link” terminology - there’s also the <a href=“foo.com”>foo</a> tag in html, which is what users can see and click on and often think of as “links"

bcbradley23:09:43

not even html

bcbradley23:09:51

or is it json in html in http?

jrheard23:09:33

trying to find a relevant url

bcbradley23:09:31

well gateway is about websockets, but nevermind that

bcbradley23:09:45

the GET returns a json encoded response

jrheard23:09:47

aha - so the example response they give there is JSON, right, totally

jrheard23:09:50

no html is involved there

bcbradley23:09:55

but the response, is it within the http response?

bcbradley23:09:00

or is it within html within http

bcbradley23:09:32

or is html just one kind of response

bcbradley23:09:35

and json is another kind

bcbradley23:09:39

and they are both text

jrheard23:09:16

yeah, that’s more like it - there’s a field in the response called (i’m a bit fuzzy on this, please correct me anyone else who sees inaccuracies here) the MIME type, and it tells your browser (or whatever other arbitrary computer program made the http requst, eg your clojure code): “hey, you’re about to see some text, it’s JSON” or “it’s HTML” or “this blob of data you’re about to see is a jpeg file"

jrheard23:09:36

i think https://www.w3.org/Protocols/rfc1341/4_Content-Type.html is the documentation of that field, the content-type header

jrheard23:09:10

i’m less confident about the past two lines than about most of the other stuff i wrote above, though 🙂

jrheard23:09:24

https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html looks like an exhaustive list of http headers, could be useful

bcbradley23:09:47

alright i'm starting to get my head around all of this now

jrheard23:09:18

per that document, an example content-type header you might find in an http response: Content-Type: text/html; charset=ISO-8859-4

jrheard23:09:23

you could also expect to see eg text/json, etc

jrheard23:09:46

ok i’m seriously going to turn this off for a bit now, this was really fun but i should get back to what i was doing 🙂 before i forget, you’ll also want to learn about how a client can communicate information/parameters in its http requests

jrheard23:09:03

learn what the "query string" is in the context of a GET request, and what a POST body looks like

bcbradley23:09:16

given how long the web has been around, they have done a remarkable job at keeping everything from becoming a c++ish mess

jrheard23:09:17

those things are fundamental and useful, particularly in the context of talking to the discord API

bcbradley23:09:52

Well i just bought web development with clojure ebook for 24 bucks

bcbradley23:09:59

maybe that'll help me

bcbradley23:09:08

you've been super helpful too

shdzzl23:09:08

I have a case where I need to conditionally return either a seq that wraps some other forms or return those forms without the wrapping seq. I know I can do this with macros, but does anyone know of a way to do this without macros?