Fork me on GitHub
#clojure
<
2015-10-12
>
Pablo Fernandez14:10:20

When using compojure-api + swagger, like in this screenshot: http://i.imgur.com/S6eQNU3.png do you know where is Body46670 coming from? can I control it?

juhoteperi14:10:25

@pupeno: You can define your schema using schema.core/defschema

Pablo Fernandez14:10:46

deraen: oh, is that because I’m passing the schema definition as a literal instead of calling defschema?

juhoteperi14:10:03

You can also set name metadata manually: (with-meta {schema} {:name "Body"}) though then you need to be careful to avoid name clashes

Pablo Fernandez14:10:50

I seen schemas using camel case instead of kebab cases. Is that the convention?

Pablo Fernandez15:10:08

I’m thinking of keeping my code grouped by object type and not function type, that is, the namespace foo.models.user contains the user schema, and validation and creation function and so on. Does this make sense or am I thinking in OO?

roberto16:10:17

what do you mean by “function type”?

juhoteperi16:10:03

@pupeno: Yes, organizing code by "object type" makes sense. I would call if organizing by topic, like one namespace for user stuff and other for groups.

juhoteperi16:10:48

@pupeno: Also, if you are doing Clj+Cljs app, you should separate your Schemas to Cljc namespace so that you can use them from Cljs.

devn17:10:41

So, pprint has the same problem as println, where you can get lines out of order

devn17:10:12

I use (pprint/with-pprint-dispatch pp/code-dispatch (pp/pprint ...))

devn17:10:36

How would I fix this so I don't get interleaved output?

devn17:10:54

like:

(defn safe-println
  ""
  [& more]
  (.write *out* (str (str/join " " more) "\n")))

ghadi17:10:02

That's Philip Greenspun of Greenspun's 10th law

Pablo Fernandez17:10:37

@juhoteperi: yes, I’m starting to use cljc.

Pablo Fernandez17:10:47

I’m finding myself moving whole namespaces from clj to cljc and putting almost everything inside a clj conditional so that some code can be shared between clj and cljs without having artificially named namespaces. Is this common?

juhoteperi17:10:35

@pupeno: I keep clj code to clj files and use conditionals pretty much only for require forms.

Pablo Fernandez17:10:08

Well, for example, I have projectx.models.user, which RegistrationSchema and registration-validator. Most of the extra code to save users to the database and so on will be clj only.

Pablo Fernandez17:10:24

Even code that could compile to both, if I’m not using it in js, I’d rather keep it out of js.

juhoteperi17:10:25

No sense to write database code to cljc files, it will never be common.

Pablo Fernandez17:10:12

deraen: yeah, but then how should I name my namespaces? projectx.models.user and projectx.cljc.mdodels.user?

juhoteperi17:10:40

I use "domain" namespaces for Schema namespaces

Pablo Fernandez17:10:56

Can you elaborate on that please?

juhoteperi17:10:16

Something like: common.domain.user, backend.user, frontend.user (or backend and frontend namespaces could be split even more: backend.user.routes, backend.user.db, backend.user.x)

juhoteperi17:10:32

and common namespace has also something like common.dates, commom.transit (for transit handlers)

chrisfarber18:10:12

Is it a bad idea to (catch Throwable …) inside of a (binding […] …) form?

ghadi19:10:00

chrisfarber: example?

chrisfarber19:10:11

This is roughly something I was doing: (binding [*bypass* (conj *bypass* id)] (try (stuff) (catch Throwable e e)))

chrisfarber19:10:08

the binding was never returning, even though (stuff) did. I refactored the try outside of the binding and it all seems to work

chrisfarber19:10:05

I suspect I’m doing terrible things simple_smile

jr19:10:00

yes that’s a bad idea

jr19:10:05

pass an exception handler down the stack or catch exceptions at the boundaries of the app

jr19:10:18

otherwise you will swallow errors by mistake

ddellacosta20:10:54

pupeno, I find that if I have a .cljc file with almost entirely Clojure or ClojureScript-specific code (i.e. a ton of reader conditional annotations) it’s a bad sign and means I probably should have just moved the small bit of code that is really appropriate to be shared to a new namespace, and leave the rest as either a CLJS or Clojure-specific namespace

Pablo Fernandez20:10:34

@ddellacosta: I sort of feel the same way, but I also feel that way about arbitrary namespaces.

ddellacosta20:10:38

I don’t know what you mean by “arbitrary” namespaces

Pablo Fernandez20:10:47

Well, let’s say I have a namespace called projectx.models.user with all the functions related to creating new users, activating users, validating fields, etc. Now, I want to re-use those validations in ClojureScript so I want to move part of it to a cljc file. What should the namespace be?

ddellacosta20:10:47

I don’t know, I’d have to understand more about what the functions are that you are moving to a cljc file

ddellacosta20:10:06

presumably they are related to each other…otherwise they shouldn’t be in the same namespace, right?

Pablo Fernandez20:10:24

Well, for example, UserSchema, UserRegistrationSchema, user-registration-validation.

Pablo Fernandez20:10:30

Yes, they are all related to users.

ddellacosta20:10:44

I’m still not getting your point—seems like there’s nothing arbitrary here

ddellacosta20:10:34

I mean, why would you need to move those in that case? if you are talking about schema validations, they can use the same code anyways

Pablo Fernandez20:10:38

Yes, having a namespace be called something like projectx.cljc.models,user would be arbitray.

ddellacosta20:10:54

it’s hard to talk about hypotheticals here—I’d have to have a more concrete example

Pablo Fernandez20:10:07

This is a concrete example.

ddellacosta20:10:26

right…but I’m not sure why you’d need to move a bunch of schema validations to a separate namespace in the first place

ddellacosta20:10:34

assuming that’s what you’re talking about re: validations

Pablo Fernandez20:10:54

I need to move them to a different file, to a cljc file, so they can be used from clojurescript too.

ddellacosta20:10:05

okay, I think we are talking in circles

ddellacosta20:10:21

I was simply suggesting that if you have a cljc file that has a ton of reader conditional annotations

ddellacosta20:10:24

that’s probably a smell

ddellacosta20:10:48

i.e., in the ideal usage of cljc you’d have a bunch of code that you don’t necessarily need to customize for CLJS or Clojure

ddellacosta20:10:59

just a few platform-specific exceptions

ddellacosta20:10:12

(that’s what I’ve found at least)

Pablo Fernandez20:10:14

Ok, let me try again. projectx/models/users.clj contains all the functions related to users. Some of the functions need to be accessed by clojurescript, so I need to move them to a cljc. What should I call thes cljc file?

ddellacosta20:10:31

I don’t know…what are those specific functions? Haha

ddellacosta20:10:45

what is the unifying concept around those functions such that they are distinct from the others and can/need to be used in CLJS?

Pablo Fernandez20:10:50

For now, schema definitions and user validation.

ddellacosta20:10:08

again, why do those need to be separated? Schemas can be written cross-platform

ddellacosta20:10:17

...and we get back to where we were before. simple_smile

Pablo Fernandez20:10:35

I want to have them crossplatform, that’s why I want to put them on a cljc file.

ddellacosta20:10:07

okay, so that’s fine then, right?

ddellacosta20:10:14

I mean, I think there is something I’m missing, I’m sorry

Pablo Fernandez20:10:23

No, it’s not fine because I don’t have a name for the cljc file.

ddellacosta20:10:24

seems like a totally reasonable use-case

ddellacosta20:10:33

how about: user validations

ddellacosta20:10:54

I dunno, it’s not arbitrary as far as I can tell—you explained it pretty clearly

Pablo Fernandez20:10:57

the schemas are not validations, they are schemas, and vice versa.

Pablo Fernandez20:10:52

For example, the helper function that builds the display name out of a user record (first name + last name) would be shared, and that’s not validation either.

Pablo Fernandez20:10:28

They are all functions related to users, but I can’t call it projectx.models.users, that’s taken.

Pablo Fernandez20:10:27

Or rather, since one file would have to use functions from the other file, and they can’t include it, I would have to use declarations.

Pablo Fernandez20:10:14

Does it make sense now?

ddellacosta20:10:39

sorry I think I’m a bit out of it today. simple_smile

ddellacosta20:10:29

but yeah, back to the point at hand, I think that it can show a potential problem in organization if you have a ton of annotations, but sometimes it makes sense—I suppose in your specific case this could be true. Or maybe it makes sense to put all the DB-specific code for a model in one place and leave the other stuff in your “…models.cljc” namespace, etc. Definitely didn’t mean to suggest it’s always going to be cut-and-dried.

ddellacosta20:10:03

sorry if I came off as argumentative, definitely didn’t intend to (seriously, think I’m out of it today…need more sleep! sigh)

jr21:10:02

@ddellacosta: I’ve seen impl namespaces used for this pattern

(ns projectx.models.user
  (:require [projectx.models.impl.user :refer [fn-1 fn-2 fn-3]]))

; Platform independent code/fns go here

jr21:10:26

where there are two files src/projectx/models/impl/user.clj and src/projectx/models/impl/user.cljs

ddellacosta21:10:20

@jr are you saying, and then the main ns is cljc?

jr21:10:22

(and src/projectx/models/user.cljc)

ddellacosta21:10:26

ah, gotcha, right

ddellacosta21:10:37

yeah, seen that pattern here and there

ddellacosta21:10:43

seems reasonable

jr21:10:59

I like it because it minimizes code reloading

ddellacosta21:10:17

dunno, I guess I also find that stuff tends to group itself together naturally too based on function—stuff that is surrounding DB insertion/extraction can be isolated, for example

ddellacosta21:10:49

but again, really probably is case-by-case, and the impl thing is a common enough idiom

redbeardymcgee21:10:52

Seems like excessive consideration just over a namespace naming issue

mccraigmccraig21:10:07

pupeno: on my current project i ended up with projectx.users.schema.cljc and projectx.users.model.clj with the schema.cljc containing schema, validation and coercion stuff and the model.clj persistence related stuff