Fork me on GitHub
#beginners
<
2018-04-20
>
decim03:04:39

So basically PersistentList is akin to a LinkedList while cons follows the lisp rules for a list where you have the head and rest (1(2(3(4))))… it’s sort of coming together now in my mind.

bronsa08:04:44

@decim right, and a PersistentList is counted in O(1) and never lazy, Cons is countable in O(n) and can hold lazy tails

reborg08:04:23

Also, PersistentList has a custom reduce and reduces faster. In theory you could create pure cons-cell lists (with cons = clojure.lang.Cons), but their main focus is as building blocks for lazy sequences. Clojure consed-lists are not intended as general purpose data structures. PersistentList instead has the typical usage scenarios of linked lists (head mainly operations list stacks for example).

rowanharg13:04:36

Hi all, I was wondering if it is a "code smell" to use large numbers of vars within a let. Sometimes I feel like I have so many vars in a let that depend on each other that the code is turning into procedural code. What solutions are there to this? Is it just refactor to functions?

schmee13:04:06

IMO, don’t think about it in terms of “I don’t like the way this looks, it has too many variables”. Instead, ask “does having so many variables in a let make the code harder to understand/extend/test”

schmee13:04:18

if it doesn’t, then no reason to change

gklijs13:04:48

@rowanharg I don’t think it can always be fixed. I have some function generating different image formats and saving them, and it has a large amount vars in the let. I could remove some by moving them to specific functions, but it’s such a procedural thing I still have a lot.

rowanharg13:04:16

@schmee @gklijs Thanks for the replies! Yes, I have exactly the same thing where I am doing some side effects - in this case saving some intermediate calculations to disk. I guess the only way to avoid this would be to build up some data structure (probably a map) with all the results in and then perform the side effect (save) at the end?

rowanharg13:04:35

This would be akin to pushing side effects to the outside of the "app" - like in The Clean/Hexagonal Architecture.

gklijs13:04:51

You have several options, you might also use destruction to make it a bit cleaner. I moved on function out, and let it return a vector of two, and in the let I use something like [a c] for the first argument.

rowanharg13:04:39

Yeah, I thought of that, but then the function names for the compound return values felt a little contrived.

mailmeupinside14:04:41

hey guys. I often need a disposable function that I'll only use once (in a bigger function), but it's too big for an anonymous function. though I don't want it to clutter the namespace, as it only makes sense in that bigger fn. can I somehow group them? is doing (let [foo (fn .. a bad idea?

mailmeupinside14:04:25

looking good, thanks

danielsouzasevero14:04:27

if it will be used only once

clojurians.net14:04:27

@rowanharg I think it's a powerful pattern to push side effects to the edge, for example: https://github.com/Day8/re-frame/blob/master/docs/EffectfulHandlers.md Makes things much more robust.

mailmeupinside14:04:18

@danielsouzasevero it gets unreadable after putting in a reader macro, I don't want people who'll read it later (namely me) suffer

dpsutton14:04:34

Just put it in a let binding surrounding the defn form

mailmeupinside14:04:14

like this?

(let [foo (fn [x] (inc x))]
  (defn inc2 [x] (foo (foo x))))

dpsutton14:04:15

Yeah. It's "out of the way" in the body so it doesn't clutter but it can't be reference else where

dpsutton14:04:47

Letfn is broken is cljs too if you're on that platform

danielsouzasevero14:04:26

@dpsutton broken?

clojurians.net14:04:30

@mailmeupinside @danielsouzasevero Sometimes I'll also write a let binding for a single-use anon function if it's more than a one-liner. If it's not immediately obvious at a glance what it does, naming it can make the code much more readable.

clojurians.net14:04:52

@dpsutton Working fine for me too, what do you think is broken?

dpsutton14:04:32

The js code it emits names a variable with what you called your var but it's not munged into the namespace. It's a global var called whatever you called it

clojurians.net14:04:17

Huh. Is there an open issue for this?

sveri14:04:44

@clojurians.net thanks for the link. The re-frame docs are awesome, that framework should have its own course at university. It would be self teaching.

clojurians.net14:04:29

@dpsutton Brilliant. Or not. But thanks for the link.

dpsutton14:04:48

So if you use letfn twice with the same name it just replaces the first. Not good :)

dpsutton14:04:04

Use let unless you need them to refer to each other

danielsouzasevero14:04:05

compiler totally missing the point, lol

dpsutton14:04:14

Yeah my coworker found that when his code didn't work

dpsutton14:04:25

Sucks when your code lies to you

rowanharg15:04:20

@clojurians.net - thanks for the link, it was a very good read ... now just need to code up my own event-loop framework.... 🙂