Fork me on GitHub
#beginners
<
2018-08-06
>
TC00:08:40

Hello everyone! I’m really fighting my editor (atom with https://medium.com/@jacekschae/slick-clojure-editor-setup-with-atom-a3c1b528b722) when trying to factor out a “component”. I expect ParInfer to be helpful once I understand how the workflow operates, but I do not understand how one can accomplish the following: 1. Problem: I cannot create a new line when I expect to! 2. State: I am stuck at this step:

(defn image
  [{:keys [title image]}] ; can't create newline here to return anything
)

wusticality02:08:36

try emacs mate 🙂

TC04:08:21

I just got Clojure for the Brave and True. It’s definitely on my list.

pablore00:08:39

Is it possible to require a private defn for testing purposes?

seancorfield00:08:05

@anthonychung14 there's a #protorepl channel that might be able to help with specific Atom-related questions. Are you on Windows? I've found that there seems to be no good default key binding for enter on Windows.

TC00:08:46

Hmm it seems like option + enter exhibits the behavior I want. I’m on Mac OSX. I’m going to learn a bit more about how to use parinfer. ClojureScript is my first lisp.

seancorfield00:08:48

@anthonychung14 ok, you can rebind the keys easily enough in Atom but it sounds like you're moving forward. I mostly use Atom on OS X as well, but also on Windows (and I still don't have it properly configured there).

seancorfield00:08:28

I followed Jason Gilman's "opinionated" set up guide, but turned off the three auto-reload options. I haven't tried Jacek's setup.

seancorfield00:08:08

@pablore You can't "require" a definition, only a namespace. You can access any private Var by using the #' syntax.

seancorfield00:08:33

(require '[foo.bar :as fb])
(#'fb/hidden-fn 42)

seancorfield00:08:36

(for a def rather than a defn you'd usually need @#'fb/hidden-var since you need to deref the Var which happens automatically in a function call context)

Mario C.17:08:26

Question: Is there a difference in doing this (defn example-fn (+ 1 1) (+ 2 2) (+ 3 3)) vs (defn example-fn (do (+ 1 1) (+ 2 2) (+ 3 3)))

Mario C.17:08:00

They both return the value 6. Does one just have an unnecessary do?

manutter5117:08:14

correct, and the (+ 1 1) and (+ 2 2) lines are also unnecessary since their results are thrown away as soon as they are evaluated, though I'm guessing you just had those there to ensure there were multiple lines

noisesmith17:08:17

defn has an implicit do (and don't forget that args list)

manutter5117:08:42

Heh, yeah, if you forget the args list you get a wildly obscure error message

noisesmith17:08:23

most macros that accept some "body" of code have an implicit do (defn, fn, let, doseq, dotimes, dosync, binding, when ...) - the major exception is for, because for with multiple forms in the body is almost always a bug

Mario C.17:08:11

Yea I forgot the arg list lol was just trying to get to the meat of the question

kennytilton11:08:52

When learning a new language there is little chance of us guessing right at what is “meat”. At worst we will leave out something salient, at best leave the experts burning cycles pointing out mistakes. hth.

seancorfield17:08:14

@mario.cordova.862 Just to illustrate @manutter51’s point, you'll get the same result from

(defn example-fn [] "(+ 1 1)" (if (+ 2 2) "yes" "no") (+ 3 3))
because all of the expressions are evaluated but only the last one is returned.

David Reno18:08:28

What’s the best file structure for reusability of functions? Do “real-world-apps” just require hundreds of libraries? Do people recode or cut-and-paste simple functions to prevent implementations from changing out from under you over time?

David Reno18:08:07

It seems that one would need a basic set of functions (depending on your problem domain) in a lot of the code you use. You probably wouldn’t want the full-featured library version because it would have so much capability that the semantics would be difficult to learn. So you’d probably implement basic, simple versions and put them in a “utility” library and just include that in all your projects, right?

noisesmith18:08:50

> So you’d probably implement basic, simple versions and put them in a “utility” library and just include that in all your projects, right? I've never seen this in practice

hiredman18:08:27

require is for namespaces

hiredman18:08:42

not libraries, libraries are generally a collection of namespaces

hiredman18:08:15

generally your app will also be a collection of namespaces

hiredman18:08:31

and each of your app's namespaces will require the namespaces it needs to do whatever

hiredman18:08:27

having about 20 requires is not all that uncommon, but also about the point where I get kind of uneasy about the size of the namespace (often the number of requires is kind of a proxy for the size / complexity of a namespace)

orestis18:08:17

I don’t think people worry too much about implementations changing under you. There’s a strong backwards compatibility culture and also I think the dependency management tools don’t aggressively update things...

lilactown18:08:00

I also re-write a lot of helper functions. it’s usually not that big of a deal

lilactown18:08:07

or copy + paste

lilactown18:08:12

unless it’s something that’s pretty hairy (like I wrote a seq-vec-map zipper implementation that I’d rather not do again…) I find it’s usually better to write something that’s specific to the task I’m trying to do, then have to bring in another dependency

David Reno19:08:42

So it sounds like it’s common to leverage a lot of libraries (and just learn the semantics) and as well re-write common helper functions and include them with your code.

David Reno19:08:31

Is there an idiomatic file structure? Thinking of oop, they tend to create a file per class. Does clojure lean towards a single large file? One per namespace?

jonahbenton20:08:51

I would say a clj namespace is roughly equivalent to a package in the Java OOP world, so where a package is a collection of explicitly defined data types, along with operations they support (methods on those classes), expressing some solution domain organizational/functional opinion, in clj, a namespace is a collection of functions, expressing a solution opinion on some more fuzzily-defined data shapes. Might be maps with certain specified keys, etc.

jonahbenton20:08:06

Namespaces tend to be a lot smaller in clj than packages in Java, because for the most part you're solving in one dimension- what set of functions do I need- rather than two+- what types, what operations on those types and how do those types + operations interact.

jonahbenton20:08:49

But high level, package == namespace, though namespace is a single file. A lib may have a top level namespace and then some other namespaces in subdirectories for implementation details, not intended for consumer use.

noisesmith19:08:04

doing anything but one file per namespace requires doing things in a weird way

noisesmith19:08:29

clojure.core does this sometimes (and it has some good excuses), but really one should have one file per namespace in normal code

Karol Wójcik19:08:27

Hi! What is a idiomatic way to iterate over couple of collections like in map but without creating a sequence? Was thinking previously about the map but it’s purpose is to create a new coll. Currently I am using doseq and map like so: (doseq [[x y z] (map vector colla collb collc)) but it makes my code a little hard to read because I got plenty of those collections.

Karol Wójcik19:08:05

I am also thinking about creating a macro like each which just uses map but without creating a new coll, but for now I’m looking for some other options

dpsutton19:08:12

> it's purpose is to create a new coll what is your purpose in iterating over collections?

Karol Wójcik19:08:30

I am iterating collections of channels to apply a go-loop on each channel

mg19:08:20

go-loop returns a channel that may be useful to hang on to

mg19:08:12

if you don’t care about that and you just want to iterate over the collections for the purpose of side-effects, doseq is the idiomatic way of doing that

Karol Wójcik20:08:24

What will be in the go-loop's channel after the loop is over?

Karol Wójcik20:08:44

Ok it will receive the value of the body 😛

Karol Wójcik20:08:51

That's nice I must say 🙂

mg20:08:43

you can also use it to determine if the go-loop is still running