Fork me on GitHub
#beginners
<
2019-03-30
>
lepistane00:03:25

Is csrf-token needed when developing mobile app? I have backend that uses csrf written in clojure i wanted to make mobile app for it and i am thinking... do i even need csrf in this case? backend would serve as api for authenticated users. Am i missing something?

seancorfield01:03:44

Is your API going to be purely REST and stateless?

seancorfield01:03:22

(if so, you won't need that token, as I understand it) @lepistane

lepistane02:03:36

Yes pure REST, good, thank you! šŸ˜„

jumar12:03:40

It depends how you authenticate your users. If you rely on cookies you may need csrf

Greg Rynkowski01:03:49

Hi, is that fine to have in one source set two files with the same name in different namespaces, e.g. - service/grpc/api/login.clj - (ns service.grpc.api.login) and - service/domain/usecase/login.clj - (ns service.domain.usecase.login)? I know it is fine from the point of the language, but Iā€™m rather asking about good taste and best practices. I also Iā€™ve got an impression recently that same error logs doesnā€™t rely on namespaces and they operate on plain filenames. Iā€™m not sure when I got this impression, maybe it was just me tiered and hallucinating.

seancorfield03:03:15

@grzegorzrynkowski_clo I think it's fine but : it's common practice to alias namespaces to the last segment so both of those would typically alias to login so you couldn't do that if you needed both namespaces in the same file -- you'd need to use distinct aliases (maybe api-login and login).

Greg Rynkowski03:03:58

thanks @seancorfield, Iā€™m using aliases in the distinct way (actually the exact way you guessed) in the Integrant system configuration. I was just curious even though we can alias a namespace whether keeping filenames unique is recommended or entirely neutral.

elamje05:03:10

Hi all! I am mostly new to clojure (75% through Clojure for Brave and True, and Iā€™ve done some euler problems) Frustratingly, I have been wanting to start a web app project for a while, but I find myself on reddit and hacker news everyday trying to find the best full stack Clojure(script) framework for beginners. I have looked at fulcro, coast, pedestal, re-frame, and a couple others, but I really struggle knowing which one is going to be the most simple to start with. I have no clojurescript experience, so preferably the ā€œframework/lib/whateverā€ would be frontend and back end beginner-friendly. Anyone have recommendations for which full stack framework/lib would help me get going with minimal friction, and possibly have the best guides/docs/tutorials?

elamje05:03:12

For some context, I would like the app to be able to handle user accounts, emailing users, and content uploading(photo, video, audio).

seancorfield05:03:22

@j3elam My advice to someone still learning Clojure is to ignore ClojureScript for now, and look at building a simple HTML page-based (server-side rendering) app in Clojure to start with. You can start with just Ring, then add Compojure to handle routes in the app, then look at either Hiccup or Selmer to help you build the HTML pages. Then add other libraries as you need them.

seancorfield05:03:55

I think it's important to learn the basics of Clojure web app development first, before trying to tackle more "complete" templates (or, heaven forbid, actual frameworks), so you understand the underlying libraries and how they work together. Otherwise, if you try to start with a template and/or framework and something goes wrong/doesn't work, you'll be hopelessly lost šŸ˜ž

āž• 4
šŸ’Æ 4
seancorfield05:03:53

Clojure is not like Ruby and several other languages that prominent web frameworks that are geared to getting you up and running fast. There's no Rails here (and it's really sort of frowned on).

seancorfield05:03:15

Once you "get" the basics, and feel comfortable building a REST API on the back end, then you can start looking at ClojureScript to build an SPA for the front end -- but those apps are very different in style and architecture to "regular" HTML apps (the sort that you'd naturally get started with in Rails etc).

elamje06:03:39

@seancorfield Thanks for the thorough response! I will most likely work on a REST api for now! I happened to look into fulcro while I was waiting for a response, and it seems pretty nice, for when the time comes to tackle a SPA.

elamje06:03:11

I have done the pedestal API guide, however I only understood about 50% of the code because I was a little bit lost in all of the details of intereceptors and the like. I will have to go back to the basics for now and stick to ring and hiccup I guess! I need to get routing down anyways.

seancorfield06:03:23

If you want to look at a fairly simple but complete, working example of Ring, Compojure, Selmer, and Component https://github.com/framework-one/fw1-clj/tree/master/examples/usermanager

šŸ‘ 4
seancorfield06:03:39

(the main.clj is a bit more complicated than necessary since it allows you to choose at startup whether to use Jetty or http-kit as the web server, but it should give you a sense overall of a possible basic structure)

seancorfield06:03:59

It at least has database code in the mix too.

elamje06:03:56

Great, thanks @seancorfield I starred it to come back to tomorrow! Thanks for all of the input. Iā€™ll let you know how the learning goes :thumbsup:

Paul Klinkenberg10:03:21

Hi everyone, I'm working my way through Clojure for the Brave and have some trouble understanding the behavior of futures.

Paul Klinkenberg10:03:35

I suspect it has something to do with laziness but can't quite wrap my head around it

gklijs11:03:09

I already kind of asked in #sql but in general what can you do when a program gets 'stuck', not returning from a function.

victorb12:03:41

@gklijs use something like clojure.tools/trace to figure out where it gets stuck

ghadi13:03:15

@gklijs press Ctrl+\ to get a thread dump in the JVM

ghadi13:03:03

it will show you a lot of threads, including the JVM compiler and GC threads, but one of the threads is going to contain clojure.main

ghadi13:03:46

that's the REPL thread. The bottom of the stack frames is clojure.main/repl (visible as clojure.main$repl) The top of the stack is a Reader blocked waiting on user input (that's you!)

ghadi13:03:18

It's the quickest way to find out what's happening in a JVM

gklijs13:03:22

I don't use the repl as much as I should,

(trace/trace-ns `clojure.java.jdbc)
gave some insights.

hipster coder18:03:42

Does anyone have a suggestion for some design pattern to learn? Most useful for beginners?

hipster coder18:03:29

I looked at transducers but they are a little advanced

orestis19:03:39

Ohh good one @seancorfield Iā€™ve never come across that one.

seancorfield20:03:15

Mostly I say "Clojure/FP doesn't have design patterns -- it's just functions" but that's a bit flip and not very helpful. The reality is that it has different design patterns -- and the "classic" (OOP) Design Patterns are pretty much just functions and function composition. I was trying to find the blog/presentation that goes through the "Gang of Four" patterns and shows nearly all of them just as higher-order functions.

mg20:03:04

I hope it has some patterns because I've seen more anti-patterns in production Clojure code than I care to recount šŸ˜‰

didibus20:03:33

Not really Clojure patterns, but examples of most GOF patterns in Clojure

seancorfield20:03:51

Ah yes, I think that's what I was thinking of. Thanks, @didibus!

hipster coder21:03:17

yea, I think most design patterns are not really needed in functional programming. I just want to learn some useful patterns that make code more predictable when reading code.

hipster coder21:03:36

thanks for the link, I will check it out. šŸ‘

lilactown21:03:38

ā€œdesign patterns are missing language featuresā€ etc.

lilactown21:03:37

there are patterns like the ā€œcomponentā€ pattern, ā€œreloadableā€ patterns, dependency injection, big-map-of-the-world, etc. that you see pop up in a lot of functional languages

lilactown21:03:15

Lispā€™s are kind of neat in that they allow you to translate them to macros, often

hipster coder21:03:03

This is a really good blog post on dependency injection

seancorfield22:03:42

I'm not sure how I feel about that as a practice. And I get the impression Alex has also moved away from heavy use of records these days (I think he had a bit of a change of heart after his Clojure Applied book?). Stuart Sierra's Component library -- linked at the bottom of that blog post -- is definitely a reasonable practice (and has inspired several other libraries since, but Component is still solid -- and it's what we use heavily at work).

hipster coder22:03:24

Very interesting. Components holds the procedural steps needed to run... e.g. start db, open db, query db

hipster coder22:03:11

Components sounds like Domain Driven Design, but instead of business logic, it is for writing concrete procedural steps that the system must follow.

hipster coder22:03:00

It organizes the state, procedures into 1 area that can be managed

seancorfield22:03:05

Yeah, if you have a web application, there are several subsystems that need to be started up when your application begins execution: the database connection/pool, the web server, maybe your environment/configuration component, etc. The Component library lets you define start/stop "lifecycle" points for each of these, and specify what depends on what, and then it organizes the startup of everything in the right order and can shut things down in reverse.

seancorfield23:03:28

Often in an app you only think about the startup sequence, but the Clojure way is to work based on a REPL where you want to programmatically start your system from inside the REPL and to shut it down again (you often need to stop and restart your app in the REPL if you are making code or configuration changes, although there are ways not to).

hipster coder23:03:45

Instead of just injection dependencies spread all over the code?

seancorfield23:03:04

Your tests can also take advantage of this to start a minimal system for running tests and shut it down after the tests have run.

seancorfield23:03:37

(and of course you can be running your tests in the REPL too!)

hipster coder23:03:52

1 thing the article mentioned was mock testing... I watched a video on micro services. The person said mock testing never caught real world errors.

seancorfield23:03:37

"never" is a very strong claim šŸ™‚

hipster coder23:03:45

Is mock testing an accepted practice in Clojure?

lilactown23:03:08

all testing is an accepted practice in Clojure

seancorfield23:03:14

I think mocking is overrated, but I know some Clojure folks who use it heavily.

lilactown23:03:15

i donā€™t think we have a particular testing monoculture

lilactown23:03:33

people do what people do. I personally do very little unit testing; mainly integration

lilactown23:03:39

other people are very into TDD

hipster coder23:03:41

Laughing at "all testing"

hipster coder23:03:12

Yes. I have been focusing more on integration tests too.

hipster coder23:03:46

My opinion is, they usually catch bad unit code, anyway... so start with higher level testing

hipster coder23:03:15

Although clojure errors can be cryptic

hipster coder23:03:26

So that might be frustrating

lilactown23:03:32

one of the downsides of Stuartā€™s component library is the name

hipster coder23:03:16

Unit testing would have saved some NASA programs

hipster coder23:03:32

I think how much testing depends on project

lilactown23:03:33

i think itā€™s more about resource management + DI then it is about ā€œcomponentsā€ in the ā€œComponent-Oriented Designā€ sense

Lennart Buit23:03:50

I prefer a mix of unit and integration. If I would see testing as some form of proof obligation, I often use unit testing to verify my assumptions made in my integration tests

Lennart Buit23:03:11

so, that means that neither my unit nor my integration tests can stand on their own

hipster coder23:03:56

I like to ask general consensus questions. For example. Vast majority of Rails community does strict TDD

seancorfield23:03:20

I use Rich Comment Forms a lot while I've developing -- which contain proto-tests that I run via the REPL. Some of that code becomes actual (unit) tests or property-based/generative tests along the way. I love that name for them! Stu Halloway mentioned it in one of his talks about the way Rich develops code, and I realized I'd been doing it for ages -- I just didn't have a name for it.

hipster coder23:03:17

@seancorfield are you using clojure.spec property testing?

hipster coder23:03:29

It is high on my list of priorities

seancorfield23:03:50

Yes, we use test.check for some property-based and generative testing. We clojure.spec in production code heavily and for some testing as well.

Lennart Buit23:03:32

I find test.check immensely cool, but I usually struggle to find a way to apply it without telling my generators exactly what I am also testing

Lennart Buit23:03:43

any resources on practical application tips?

4
šŸ™ 4
hipster coder23:03:02

@lennart.buit would you mind posting an example when you have time?

Lennart Buit23:03:32

well, I did a test at work for some serialization code, that ā€œprovesā€ that encode/decode is identity

Lennart Buit23:03:47

and encode/decode/encode is encode

Lennart Buit23:03:39

come to think about it, this may be superfluous even

hipster coder23:03:23

It would be interesting to talk about testing in a slack channel... so I can learn most popular methodoligies to use

seancorfield23:03:49

Yeah, most of our property-based testing is around round-tripping pairs of functions. We do have a couple of more complex property-based tests where we generate sequences of valid "operations" within a system and then verify that applying those to a test system gets it into the expected state.

seancorfield23:03:58

(or at least gets it into a valid state successfully -- i.e., the random-but-valid sequences don't hit some invalid state before the end)

Lennart Buit23:03:04

right, I was hoping that I would find more ways to apply property-based testing for algorithms

hipster coder23:03:42

Does clojure.spec allow you to generate number permutations?

Lennart Buit23:03:10

it allows you to define custom generators, so by the virtue of clojure being turing complete it does šŸ˜‰

hipster coder23:03:55

That would be perfect for algorithms

Lennart Buit23:03:59

You know, the text book ā€œsort functionā€, that has as property that the resulted collection is sorted, without telling you how

Lennart Buit23:03:22

but I end up ā€¦ either not seeing these ā€œhigh levelā€ properties, or feeling like I am repeating my implementation in properties

hipster coder23:03:09

Implementation in properties?

hipster coder23:03:21

Like you are testing too many units of code instead of just checking the final result = sorted?

seancorfield23:03:12

@lennart.buit you mean your property tests end up looking like the functions you are trying to test?

šŸ‘Œ 4
seancorfield23:03:31

I think property-based and generative testing scores when used on a higher-level: when you can run series of transforms or processes and then check properties of the data/system as a whole at the end.

hipster coder23:03:09

So it's like you are just writing proofs, twice

seancorfield23:03:33

We simply couldn't do that amount of testing manually: we use property-based testing around data migrations and certain critical interactive parts of our systems.

seancorfield23:03:31

Those tests can create and run scenarios far faster than any human could. But it's true that you have to have an idea of what your end goal is, in order to test the property.

madstap23:03:35

This is a good article about which kinds of properties to test https://fsharpforfunandprofit.com/posts/property-based-testing-2/

seancorfield23:03:25

clojure.spec allows us to generate scenarios and sequences of operations as "programs" for input into property-based tests. Think "simulations".

Lennart Buit23:03:33

Oh thats really cool @madstap, I will read that

Lennart Buit23:03:46

Forgive me asking a lot ā€” but donā€™t you have the feeling that you need to be overly specific in your generators to property test with them?

Lennart Buit23:03:29

like for example in a map with dependent keys, that you need to ā€œteachā€ your generator about this dependency

seancorfield23:03:07

A lot depends on how tightly you're spec'ing things and what sort of things you're trying to generate. There's also an argument that if your data involves dependencies that make it hard to spec/generate, maybe you need to rethink your model?

Lennart Buit23:03:51

Right, thank you for your insights! Iā€™ll try harder to realise its possible applications šŸ™‚!