Fork me on GitHub
#boot
<
2016-12-26
>
bcbradley02:12:32

boot has this thing called X.cljs.edn which is a map that contains keys like :require and :compiler-options

bcbradley02:12:18

can someone explain to me what forced boot's design to be such that I have to manually add or remove any new or old namespaces to the :require key's value (which is a vector of namespaces)

bcbradley02:12:32

what does boot gain out of that?

bcbradley02:12:05

(X above is w/e, for me its main.cljs.edn)

micha02:12:39

usually the .cljs.edn file will be generated by a program, not manually

bcbradley02:12:53

what program?

micha02:12:00

a boot task usually

micha02:12:03

but it could be anything

micha02:12:24

the only thing you need to :require there is the entry point namespace

micha02:12:39

which is not something that is likely to change often

bcbradley02:12:52

what you are saying is that this work can be automated, which is nice

bcbradley02:12:01

but you aren't saying why it is there in the first place

micha02:12:21

the .cljs.edn file is the js application descriptor

bcbradley02:12:35

ok now that makes much more sense

micha02:12:37

there is no formal specification for what a compiled cljs application consists of

micha02:12:45

so we had to invent one

bcbradley02:12:59

ok i'm happy with that response

micha02:12:13

it allows tasks to know things about the application wihtout sharing state

micha02:12:23

or knowing about each other

micha02:12:39

like the way we can use the pom.xml file to know things about maven artifacts

micha02:12:18

boot-reload for example needs to inject cljs code into your application

micha02:12:26

(the client side of the reload websocket)

micha02:12:37

the only way it can do that is via the .cljs.edn file

bcbradley02:12:00

i'm just throwing this out there, but if the point of all this is to compile into a single js file, wouldn't a pipeline oriented approach be more suitable?

bcbradley02:12:07

i mean it would be less opaque

micha02:12:21

how do you mean? isn't this way a pipeline?

bcbradley02:12:28

its almost a pipeline

bcbradley02:12:08

a true pipeline is one in which a thing goes into a machine and comes out the other end, altered

micha02:12:18

that's exactly what's happening here

bcbradley02:12:19

and obviously you can combine those sequentially in whatever order

micha02:12:01

the thing that's going in and out is the fileset

bcbradley03:12:05

what i mean is i would prefer that boot tasks just took a directory of stuff as input and produced a new directory of stuff as output

micha03:12:39

jvm stuff relies on a classpath

micha03:12:45

which doesn't work well with just random directories

micha03:12:08

and if you want to have scoped effects of tasks you can't have just directories

bcbradley03:12:15

because if you don't do that then you have to ask questions about "what stuff looks like"

bcbradley03:12:43

you start to have statefulness creep in

bcbradley03:12:47

disguised as directories

micha03:12:07

well consider a pipeline A->B->C

micha03:12:22

and A is maybe the watch task that will call the continuation many times

micha03:12:37

no effect of C should ever be visible to B

micha03:12:55

otherwise you end up with very confusing behavior

bcbradley03:12:08

alright this is where we diverge. you aren't taking it far enough

micha03:12:09

the way we achieve that "scope" is the fileset

bcbradley03:12:21

i'm saying that A, B, and C shouldn't be aware of eachother whatsoever

bcbradley03:12:26

they should all be mutually invisible

bcbradley03:12:28

like functions

micha03:12:40

right, that's the current situation as far as i know

micha03:12:53

B calls a function, wich happens to be C

micha03:12:57

but it knows nothing about C

bcbradley03:12:10

right and c doesn't know anything about b

micha03:12:16

naturally

bcbradley03:12:46

you would expect the composition of b and c to be a pure function if b and c are pure

micha03:12:56

they can't be pure and be useful

micha03:12:07

thewhole point is to build stuff

micha03:12:18

and that means mutating the classpath in the jvm

bcbradley03:12:29

this is where i'm having some cognitive thrashing with boot

bcbradley03:12:39

i feel that you CAN have purity and be useful

bcbradley03:12:44

but you have to change your perspective

micha03:12:53

boot has a sort of limited purity

micha03:12:06

sort of like the things they tried with function level

bcbradley03:12:17

lets imagine that the final packaged js app is returned by C

bcbradley03:12:27

what could C depend on?

bcbradley03:12:34

maybe some other tasks, a task like B

bcbradley03:12:49

maybe B depends on a directory of partially compiled stuff or w/e

micha03:12:50

in boot C depends only on being passed a fileset

micha03:12:59

it can't depend on other tasks

micha03:12:18

i mean other than the normal lisp dependency graph of functions that call other functions

bcbradley03:12:30

here is what i mean to be more precise:

bcbradley03:12:54

i would prefer if the output of the last boot task executed were the thing i requested

bcbradley03:12:01

and i mean that in the most literal sense possible

micha03:12:20

i don't follow, what is the thing you requested?

bcbradley03:12:40

if i requested a different thing i might need a different task

micha03:12:58

i don't see how that differs from the way boot does work

bcbradley03:12:09

alright take this for instance (inc 1)

bcbradley03:12:12

it returns 2

bcbradley03:12:18

if i call it tomorrow it will be 2

bcbradley03:12:38

i could have something like (inc (dec 0)) and it will be 0

bcbradley03:12:44

i can chain them up as a pipeline

bcbradley03:12:02

not all boot tasks have this sort of purity

bcbradley03:12:25

if you invoke a boot task, it might change something that another task depends on

micha03:12:36

like what for example?

bcbradley03:12:08

like the task that recompiles code that has be altered on disk

bcbradley03:12:05

to put it another way, are boot tasks returning values that can be altered, or are they returning immutable values?

micha03:12:16

they return immutable values

bcbradley03:12:32

if they just change the directory they are invoked from (or classpath or whatever) then you can't really make guarantees about immutability

micha03:12:33

but they also perform side effects 🙂

micha03:12:04

so do you agree that the classpath is relevant to the build process?

micha03:12:25

like for example build processes get their input from the classpath

micha03:12:35

like the java compiler for instance

micha03:12:38

or the cljs compiler

bcbradley03:12:56

i prefer to isolate myself from the particulars of whatever virtual machine is being used, if one is being used

micha03:12:18

boot is only being run on the jvm

micha03:12:30

it doesn't try to box the jvm or anything

micha03:12:39

it does what clojure does

micha03:12:08

like if you do (require 'foo) there needs to be a foo.clj file on the classpath or clojure can't compile the namespace

micha03:12:47

the classpath is what allows tools to not know or care about a lot of other concerns

micha03:12:06

such as "is this source file from a jar or from a file on the filesystem, etc"

micha03:12:17

pretty important stuff imho

bcbradley03:12:31

it boggles my mind how people can be clever enough to invent a language like clojure and still blind to the fact that organizing code into essentially arbitrary files (containers) of code that "seems useful together" obviously creates more problems than it solves

micha03:12:07

it's precisely the classpath that makes it not arbitrary

micha03:12:17

the classpath is structured

micha03:12:33

like (require 'foo.bar) means a very specific thing with respect to the classpath

micha03:12:54

at the end of the day there will be files somewhere

micha03:12:03

or you couldn't reboot your computer without losing everything

bcbradley03:12:07

what i'm saying is that having a foo.clj file and a bar.clj file is not the right way to think about programs

bcbradley03:12:15

having to depend on bar from foo

bcbradley03:12:42

or having to deal with the inane menial task of coordinating a tree of dependencies is not the right way to think about programs

bcbradley03:12:56

all you really have are a collection of functions

bcbradley03:12:02

some of the functions invoke the other ones

bcbradley03:12:23

the dependency graph is there, its no more complex than that

bcbradley03:12:27

what functions invoke which others

bcbradley03:12:36

why the hell would anyone want to stratify it into arbitrary namespaces

bcbradley03:12:21

i see a bunch of libraries on github, and everything is broken into files

bcbradley03:12:28

i see a bunch of source control, all file based

bcbradley03:12:32

people pass files around to eachother

bcbradley03:12:35

functions in files

micha03:12:37

humans need to administratively manage things

bcbradley03:12:39

its nonsense

micha03:12:57

i wouldn't want to manage versioning boot on a per function level

micha03:12:05

with compatibility matrix tests

bcbradley03:12:08

there shouldn't be versioning on a function

bcbradley03:12:14

a function should just be a function

bcbradley03:12:23

once written and pushed to a repository, it should be immortal and immutable

micha03:12:27

we fix bugs, add features and so on

bcbradley03:12:31

that way people can depend on it with confidence

micha03:12:37

this is why we have versions

bcbradley03:12:41

if you add a bug-fixed version, it ought to be a new function

micha03:12:54

but then i need to have the matrix

bcbradley03:12:54

that way people who want to use the old "crappy" function still can

micha03:12:18

i don't have time to make sure that every edge case is compatible when someone uses an older function with a newer one

bcbradley03:12:26

its not your job to do that

bcbradley03:12:29

its the end user's job

bcbradley03:12:39

if they required a function you provided

bcbradley03:12:45

it is irrelevant that you provided it

bcbradley03:12:50

because you should not have the power to take it from them

bcbradley03:12:52

thats what i'm saying

micha03:12:53

you mean your customer who is accessing your admin interface on their ipad?

micha03:12:00

that's the end user

bcbradley03:12:16

by end user i meant the consumer of your library

micha03:12:23

everyone else is in the middle, using libraries to build other libraries

bcbradley03:12:25

a software engineer or startup or company

micha03:12:51

ok consider this

micha03:12:01

i have a function make-foo

micha03:12:07

it constructs some object

micha03:12:15

and i have a use-foo function too

micha03:12:19

that does something with it

micha03:12:41

later i discover a bug in make-foo where it sometimes produces a defective foo

micha03:12:52

so i creaet a new function make-foo2

micha03:12:57

fixing the bug

micha03:12:49

now what if someone else made a frob-foo function

micha03:12:59

that relies on the defective behavior

micha03:12:09

and i do (frob-foo (make-foo2))

micha03:12:16

that's the matrix

micha03:12:19

that i want to avoid

bcbradley03:12:28

and what i'm saying is that they can avoid that

bcbradley03:12:36

by saying (frob-foo (make-foo))

micha03:12:49

but they couldn't

micha03:12:56

because their code just does this

micha03:12:14

(defn doit [f x]
  (frob-foo (f x)))

micha03:12:26

and i do (doit (fn [] (make-foo2)))

bcbradley03:12:35

you made make-foo before you made make-foo2 correct?

bcbradley03:12:35

if they required your make-foo function (maybe :as make-foo) and later determined that they wanted to "upgrade" because you fixed some issue with it to make-foo2 (:as make-foo so they don't have to refactor code), then something broke, that is on them

bcbradley03:12:39

they can rewind easy peasy

bcbradley03:12:43

just go back to requiring make-foo

micha03:12:03

i have two dependencies in my application

micha03:12:10

A produces foos

micha03:12:13

B consumes them

micha03:12:30

if A starts making incompatible foos, B doesn't have any way to know that

micha03:12:42

and if i am to be able to know that i will need a compatibility matrix

bcbradley03:12:55

we are on two different planets

micha03:12:58

of all the versions of all the functions, which one is used where, who passes what to whom

bcbradley03:12:19

i'm just saying that if a function is immutable, if you provide someone a function and guarantee that it cannot change out from under them, then thats it

bcbradley03:12:26

its done, the problem isn't more complex than that

micha03:12:40

but there is alraedy such a guarantee

bcbradley03:12:42

if you start adding "oh it can change when it changes versions"

bcbradley03:12:47

then you have a nightmare

micha03:12:51

that's what the classpath does, as i understand it

bcbradley03:12:58

well the classpath is garbage

micha03:12:12

the classpath guarantees that a name can correspond to only a single thing

bcbradley03:12:14

and so is organizing functions into arbitrary versioned containers called "files"

micha03:12:34

like when you do (require 'foo) there is only one file that can be compiled there

micha03:12:42

the foo.clj on the classpath

micha03:12:45

and there can only be one

bcbradley03:12:04

great, but that doesn't make any guarantee that that thing at that location cannot change

bcbradley03:12:09

it doesn't make an immutability gaurantee

micha03:12:10

sure it does

bcbradley03:12:16

only a uniqueness guarantee

bcbradley03:12:18

they are different

micha03:12:23

maven artifacts are immutable

bcbradley03:12:28

maven yes, files no

micha03:12:33

and the way foo.clj got there is via versioned artifacts

micha03:12:44

if you use the same version of the artifact, you will get the same foo.clj

micha03:12:02

and thus the source for the functions defined in foo.clj will also be the same

micha03:12:17

so presumably the compiler will generate identical bytecode

bcbradley03:12:31

we sort of went around the original issue

bcbradley03:12:39

having files depend on other files

bcbradley03:12:49

or having maven artifacts refer to or require other artifacts

bcbradley03:12:58

is not the way to think about programs

bcbradley03:12:06

you just end up pulling in a lot of stuff you don't need

bcbradley03:12:12

functions depend on functions

bcbradley03:12:30

files are arbitrary

micha03:12:41

protocols, multimethods, jvm system properties, so many other things

bcbradley03:12:52

protocols, multimethods are both functions

micha03:12:53

i mean in clojure world

bcbradley03:12:58

what i'm basically saying is that instead of having people duplicate half their library over and over under different names

bcbradley03:12:07

instead of having people write the same functions over and over

bcbradley03:12:12

just let the function be the atom

bcbradley03:12:17

and build your chemicals out of that

micha03:12:23

that's an idea that comes up over and over

micha03:12:29

i am personally skeptical of it

micha03:12:55

we did try such a thing once

micha03:12:05

we called it "homeworld"

micha03:12:01

it was not a success

bcbradley03:12:17

that isn't an indicator that it was flawed

bcbradley03:12:34

a know a lot of smart people who aren't successful, but they are still smart

bcbradley03:12:59

sometimes the culprit is just chance

micha03:12:18

the admin overhead of managing individual functions is immense

bcbradley03:12:42

you obviously wouldn't want people to do that manually

bcbradley03:12:57

you could have people distribute "libraries" which really are just a list of function requires

bcbradley03:12:08

in other words, take a hint from REST

bcbradley03:12:41

better yet, a set rather than a list

bcbradley03:12:46

then a person could do set logic on it

bcbradley03:12:53

like intersection

micha03:12:59

functions are not values in lisp though

micha03:12:07

that's pretty much the essence of the problem

micha03:12:17

and macros, forget about it

bcbradley03:12:32

i don't know who told you a function isn't a value but it is

bcbradley03:12:39

because a function is strictly speaking, just a list

bcbradley03:12:59

the fact that the clojure evaluator will try to evaluate the list when it runs into one, doesn't mean it isn't a list

bcbradley03:12:07

a list begins with ( and ends with )

bcbradley03:12:23

list processing

micha03:12:51

ok what i meant was that procedures are not values

bcbradley03:12:02

whats a procedure?

micha03:12:12

the thing that the list compiles to

bcbradley03:12:19

why do you need that?

bcbradley03:12:34

er, let me be a little less terse

micha03:12:36

because you can't know anything about the list without evaluating it

bcbradley03:12:38

why do you need to distribute that?

micha03:12:46

you can't distribute that

bcbradley03:12:02

you distribute the list (happens to be invokable as a function)

micha03:12:09

it is not invokable

micha03:12:18

it can be compiled to a procedure that is invokable

bcbradley03:12:30

a list that begins with the symbol defn is what you ought to be distributing

micha03:12:12

are you familiar with john backus' function level stuff?

bcbradley03:12:17

don't know him

micha03:12:59

this is the thing that backus was trying to achieve

micha03:12:02

what you are describing

micha03:12:30

he also talks about why you can't do it with lambda calculus and lisp

micha03:12:47

it's all about what it means for a function to be a value

bcbradley03:12:42

i guess if i were to just put it briefly: i want to think of software as a collection of functions. whether the functions are invoked on code (as macros) or on data is irrelevant, I just want to think of it as a bunch of functions. I want these functions to be distributed to me independently. I don't want them to change out from under me, they should be immutable. A repository should be tantamount to a map from function names to lists that start with the symbol "defn". To cut down on administrative nonsense I should be able to import a bunch of functions ala carte by requiring each from a set of remote function requirements (thats how I want to think of libraries). I should be able to process those sets, and think at a higher level of abstraction than I do currently.

bcbradley03:12:07

the clojure logic library should be a set of function names (elements in the map from name to lists that start with the symbol "defn")

bcbradley03:12:11

as should any other

bcbradley03:12:26

i can ask questions about how these libraries overlap by doing set logic

micha03:12:30

there is nothing preventing you from making this world

micha03:12:43

you can do it with current technology, like homeworld

micha03:12:23

but when you need to interact with the rest of the world it gets sticky

bcbradley03:12:39

i really strongly believe in this approach primarily because if functions are your smallest unit then you can run queries for specific functions

micha03:12:42

pods are boot's best effort there

bcbradley03:12:58

for instance, maybe a programmer could run a query for a function in a very large repository that fits a specific spec

bcbradley03:12:03

as in clojure spec

bcbradley03:12:13

thats a pretty powerful search tool

micha03:12:20

you can make a database of specs

micha03:12:28

without ditching namespaces or whatever

micha03:12:40

and you can use pods to use the things a la carte

bcbradley03:12:31

the point is that if you try to be honest with yourself about the periodic table of programming, the elements are functions, not files

micha03:12:47

i'm not a scientist or academic myself

bcbradley03:12:49

and everything else would be working around the fact that you have files

micha03:12:52

i'm a workin man

bcbradley03:12:03

sure, you could make a database of specs and refer to files

bcbradley03:12:09

sure you could use pods

bcbradley03:12:15

you could pretend files don't exist, but they do exist

bcbradley03:12:19

and you can work around them

bcbradley03:12:29

personally, if there is a stump in the way, i uproot it

micha03:12:30

someone has to build an alternative

micha03:12:38

so far there is none

micha03:12:47

at least none that will help me do real work

bcbradley03:12:56

there is but you are so accustomed to it you think its a part of nature

micha03:12:08

it is a part of nature

micha03:12:13

it's our environment

micha03:12:18

it can be terraformed probably

bcbradley03:12:28

we invented the environment we are working in

bcbradley03:12:59

the difference between nature and this, is that this is self imposed

bcbradley03:12:02

we did this to ourselves

bcbradley03:12:08

we did github to ourselves

bcbradley03:12:13

we did source control to ourselves

micha03:12:17

well i think abstraction is not the end all be all

bcbradley03:12:20

we did things to ourselves in order to undo even worse things

bcbradley03:12:35

and then we are thankful for the things we did that aren't that great but could be worse

bcbradley03:12:47

everyone is just trying to do just enough

bcbradley03:12:14

i feel like i'm the only person who can see in the dark and everyone is bumping into eachother

micha03:12:26

i work for a company that serves ads on the internet, i am happy if i can help my coworkers have good jobs and feed their kids

bcbradley03:12:55

well i don't mean to take away from that

bcbradley03:12:13

all i mean is that we put up with a lot of garbage "because we can" not because we should

bcbradley03:12:35

c++ is a heap of it

bcbradley03:12:47

i'm saying we have that garbage in a lot of places

bcbradley04:12:07

and i feel like clojure was designed with a sensitive nose

bcbradley04:12:08

and i like that

bcbradley04:12:15

but its surrounded in stink

bcbradley04:12:35

stink in the jvm, and stink in the way we think about things that we feel are "too old / established to change"

bcbradley04:12:41

like how we distribute software in files

bcbradley04:12:44

rather than in functions

bcbradley04:12:07

or to be more precise, distribute in "containers that contain functions"

bcbradley04:12:11

rather than "just functions"

micha04:12:21

i like clojure because of the practical approach rich takes

micha04:12:29

you can get work done with it

micha04:12:51

it's also a beautifully engineered programming language in so many ways

micha04:12:58

more than any other language i've seen

bcbradley04:12:08

i totally agree

micha04:12:42

i can still use all the crufty java stuff to make my company successful

micha04:12:26

the artisanal programming genius will never make a solid xml parser, i bet

micha04:12:37

beacuse it's really boring grinding work

micha04:12:49

you'd only do it if you got paid to do it

micha04:12:55

hello java

bcbradley04:12:08

the artisanal programming genius won't make a solid xml parser because xml is a terrible way to encode information

micha04:12:25

you'd end up with a monadic tower of beauty that fails in the real world

bcbradley04:12:26

and probably won't sell his time to make it

micha04:12:50

but when i have a customer who needs me to accept his xml i do it

bcbradley04:12:00

people who are just smart enough end up being super productive members of society

bcbradley04:12:07

people who are too smart end up not

micha04:12:12

and i'll use some ancient massive java abomination to get it done

bcbradley04:12:14

because they realize that they only live once

bcbradley04:12:27

and they don't want to waste even a little bit of their time doing something they won't enjoy

bcbradley04:12:37

and they don't enjoy things that aren't beautiful or elegant

bcbradley04:12:43

like xml for instance

micha04:12:10

i'm barely smart enough, i don't have that luxury

bcbradley04:12:18

its not a luxury

bcbradley04:12:30

its costly if anything

micha04:12:00

i see programming as a way to help my colleagues succeed

bcbradley04:12:29

i see it as a way to understand how I form thoughts

micha04:12:51

the things i enjoy are getting things done that bring us the money we need to live a better life

micha04:12:05

if i don't have to deal with xml that's all the better

micha04:12:10

but if i do that's ok too

bcbradley04:12:17

i just enjoy discovering things about the way I think that I didn't previously know

bcbradley04:12:42

because it allows me to discover more things more quickly

micha04:12:55

towhat end?

bcbradley04:12:02

whatever end

bcbradley04:12:04

its about exploration

bcbradley04:12:17

if we hadn't discovered all the land on the earth I would have been an explorer

bcbradley04:12:30

but we have, and there isn't any deep space exploration really

bcbradley04:12:46

and the only places in the earth that haven't been explored are extraordinarily dangerous

bcbradley04:12:50

this is as close as I can get

micha04:12:52

yeah drones do all the exploration now

micha04:12:59

and genetic algorithms

bcbradley04:12:07

yes and that is absolutely fascinating

bcbradley04:12:16

i guess software engineering attracts different kinds of people

bcbradley04:12:26

some are more like builders

bcbradley04:12:32

others more like explorers

bcbradley04:12:41

they are both helpful to the culture in their own way i think

micha04:12:03

i think explorers need to be more solitary though

micha04:12:43

an explorer can not expect the rest of the world to accept their stories of far off lands they have not seen

micha04:12:07

like the dove with the olive branch

micha04:12:14

after the flood in genesis

bcbradley04:12:31

a long time ago the earth was dominated by an era of violence and warlords

bcbradley04:12:41

then the warlord's descendants became known as kings and queens

bcbradley04:12:49

and it was an era of fealty

bcbradley04:12:31

eventually the power of the crown was undermined by the power of religion

bcbradley04:12:44

so we moved into an era of piety

bcbradley04:12:29

the news that the universe obeyed certain laws universally (gravitation) caused people to question the principles laid down by tradition

bcbradley04:12:49

and eventually people began to believe that everyone should be treated equally under the law

bcbradley04:12:04

that was enough leverage for aristocracy to be planted

bcbradley04:12:19

fast forward a bit and we move into an era of mercantilism

bcbradley04:12:43

the world right now is dominated by currency, trade, mercantilism

bcbradley04:12:48

it wasn't always this way, but it is right now

bcbradley04:12:00

and because of that, builders are prioritized above explorers

bcbradley04:12:15

if we were in a colonial era, explorers would be prioritized above builders

micha04:12:23

i don't really agree there

micha04:12:37

it's a market with competition

micha04:12:45

look at all the VC funding and whatnot

micha04:12:54

funding explorers mostly

micha04:12:01

self driving cars and all that

bcbradley04:12:43

the way i see it competition is only relevant when you have to compete

bcbradley04:12:51

if resources are so plentiful that competition is unviable

bcbradley04:12:00

then exploration is much more optimal

bcbradley04:12:14

we can't do that on the earth because we've already circled it

micha04:12:28

explorers were never really prioritized

bcbradley04:12:30

maybe a few hundred years from now, when we start populating other celestial bodies

micha04:12:37

look at captain cook for example

micha04:12:48

he was a nobody

micha04:12:06

he got the worst hand me downs from the fleet

micha04:12:12

a merchant ship basically

micha04:12:34

he was only grudgingly promoted to command rank

micha04:12:46

because nobody else wanted the job

bcbradley04:12:00

i like to think thats because the fleet was primarily a military endeavor, because throughout most of recorded history humans have had to compete with other humans

bcbradley04:12:23

although that doesn't imply that humans have always been so great in number that they have had to compete with eachother

micha04:12:31

i think it was because he was unlikely to succeed

micha04:12:38

so they chose someone disposable

bcbradley04:12:40

there was certainly a time in humanity's history during which they competed far more with nature than with eachother

micha04:12:59

most explorers meet a dead end

micha04:12:09

a few are unicorns

bcbradley04:12:13

doesn't dissuade real explorers xd

micha04:12:37

but you can see how that affects the prioritization

micha04:12:05

people who really discover things don't usually get to exploit them, too

bcbradley04:12:08

idk maybe i'm biased because i resonate with the explorer more than the builder

bcbradley04:12:29

physics is mostly exploration

bcbradley04:12:36

i was going to go into physics

bcbradley04:12:48

but i don't like the administrative nonsense that comes with it

bcbradley04:12:07

like securing grants from the government and all that

micha04:12:15

i studied physics in college

micha04:12:25

i realized that i wasn't a genius 🙂

bcbradley04:12:49

i got an associates degree in physics and decided i liked physics but didn't like the lifestyle physicsts had, so i swapped majors to software engineering

micha04:12:40

to me exploration is more like religion

micha04:12:57

you need to have some revelation that guides you, against all reason

micha04:12:11

and in the end maybe you are right

micha04:12:43

but the explorer always needs to bring back the olive branch like the dove

micha04:12:49

or it's just hot air

micha04:12:08

anyone can tell a tale of some far away island

micha04:12:33

i think you would enjoy reading john backus' turing award speech i linked above

micha04:12:42

it's about the exact thing you were talking about

micha04:12:35

also with recent advances in machine learning it might be time to revive it

iago.b2wdigital13:12:53

@micha we're working on the new push task, to deploy on maven central

iago.b2wdigital13:12:11

I'll update you once we have something 😃

nonrecursive20:12:04

hey y’all I’m running this: boot watch notify -v test and getting this when the tests run: No value supplied for key: null

nonrecursive20:12:08

has anyone else run into that?

geoffs20:12:05

yeah. you’re on a Mac right?

geoffs20:12:25

you can work around it by passing -t Boot (or something else)

geoffs20:12:37

there’s a bug in the way that notify shells out specifically on Mac’s. I have a PR up for it. Was about to look at the feedback on it actually 🙂

geoffs20:12:28

if it wasn’t clear, the -t option is for notify. So your example should be boot watch notify -v -t Boot test

nonrecursive20:12:59

that works! i’m not getting that anymore, but I’m also not seeing any visual notifications

geoffs20:12:14

do you have terminal-notifier program?

geoffs20:12:18

you can install it with brew

nonrecursive20:12:19

i think that’s from my system prefs though

nonrecursive20:12:22

do you have any tips for getting tests to run faster?

geoffs20:12:58

that is a broad question 🙂 any more context you can share?

manenko20:12:47

you can buy a faster computer, for example 😛

nonrecursive20:12:56

sorry 🙂 with watch, it takes 12s every time I make a change for my 10 tests to run

nonrecursive20:12:21

I think test run in a new pod every time?

nonrecursive20:12:38

another option would be to only run tests for namespaces affected by a change

geoffs20:12:57

hmm, that’s strange. AFAIK pods shouldn’t have that kind of overhead. These are just clojure.test tests?

geoffs20:12:27

focusing tests is definitely useful. Unfortunately watch is kind of a coarse tool in that regard. From what I understand you’d have to focus the tests when you invoke the boot pipeline.

geoffs20:12:02

Maybe you’d be better server running boot tasks from the repl instead of the command line if that’s the route you want to go. Don’t have to wait for clojure to load when you want to switch which sets of tests you’re running.

geoffs20:12:43

My only other suggestion is to make sure you’re not doing anything super slow in the tests or setup or something (like a network call).

nonrecursive20:12:46

that’s a good point

geoffs20:12:41

Sorry I don’t have anything more concrete to offer. I typically run tests through CIDER in emacs so I run one namespace at a time pretty much always.

nonrecursive20:12:28

yeah that makes sense, that’s usually what I do too

nonrecursive20:12:32

thanks for your help!

devo23:12:50

Getting Classpath conflict: org.clojure/clojure version 1.8.0 already loaded, NOT loading version 1.9.0-alpha14 on all my boot tasks where I'm using the 1.9.0 alpha. Feel like this is a simple fix but haven't been able to get this working to play with spec.

geoffs23:12:21

If you put the clojure version you want in a boot.properties file it should enforce getting that version. Like so:

BOOT_CLOJURE_NAME=org.clojure/clojure
BOOT_CLOJURE_VERSION=1.9.0-alpha14
BOOT_VERSION=2.7.1

devo23:12:13

@geoffs thanks! Does boot just default to whatever version of clojure it is using?

geoffs23:12:42

That is a good question. I think so? not totally clear on that myself 🙂

micha23:12:11

@devo @geoffs boot will use whatever is in the ~/.boot/boot.properties file, or ./boot.properties

micha23:12:20

or BOOT_CLOJURE_VERSION

micha23:12:27

environment variable

micha23:12:15

that warning is telling you that boot wasn't able to use the version you specified in your :dependencies because it was already using a different version

micha23:12:25

via the boot.properties or env var

devo23:12:17

Sweet! I had removed the BOOT_CLOJURE_VERSION from my .Bashrc but forgot to refresh. Thanks for the insight.

micha23:12:47

boot needs to choose some version of clojure before it can evaluate your build.boot

micha23:12:57

since it evaluates that in clojure

micha23:12:10

so specifying the version of clojure needs to be done externally