Fork me on GitHub
#clojure
<
2016-12-02
>
hl2zip00:12:30

Hi. I am running through some beginner guides and I noticed that even if I create the -main function like this

(defn -main
  []
  (println "hello"))
I still have to call the program with an argument for it to work:
java -cp classes:clojure-1.8.0.jar zero_project/first_file 0
does the -main function just always need an argument?

hiredman00:12:42

technically it is always passed an argument though

hiredman00:12:21

and that wouldn't work anyway

hiredman00:12:34

java needs to be passed a class name

hiredman00:12:45

zero_project/first_file is not a valid class name

hl2zip00:12:04

The above calls my program though...is something wrong still?

hl2zip00:12:20

For example, I call it and it returns hello to the console

hiredman00:12:31

generally -main takes an arg like [& args] is the moral equivalent of c's argc and argv

hiredman00:12:51

you think it does, but something else is happening

hiredman00:12:17

if you change "hello" for "hello world" what happens?

hl2zip00:12:39

def' something else happening

hl2zip00:12:46

it still prints hello

hl2zip00:12:27

hmmm so what is wrong with the above syntax?

hiredman00:12:13

that command wouldn't run

hiredman00:12:33

'java' would complain about the misnamed classfile you are passing it

hl2zip00:12:05

so I have a directory structure like this:

classes/
    zero_project/
        first_file_init.class
        // other class files

hl2zip00:12:51

which is why I wrote it like this classes:clojure-1.8.0.jar thinking it start in that directory

bfabry00:12:52

lol, was gunna say that may have happened

bfabry00:12:35

@hl2zip are you using leiningen?

hl2zip00:12:59

Yes, I was trying to understand at a lower level what it would look like without lein

bfabry00:12:10

oh ok cool, there's a tutorial just for that

bfabry00:12:42

haha ok that's what I was looking for

bfabry00:12:09

so the reason the text didn't change, almost definitely, is because you didn't recompile the class from the clojure code

hl2zip00:12:36

wait, do you always have to run load and then compile?

bfabry00:12:06

good question, I don't know off the top of my head. the documentation for compile doesn't really say

hiredman00:12:58

and you shouldn't run both

hiredman01:12:07

compile implies load

hiredman01:12:27

and you never have to run compile

hiredman01:12:13

if you really want to start bare bones, start with a repl and copy and paste forms in, or pass a whole file as a script to the clojure jar

hiredman01:12:23

don't touch compile

hl2zip01:12:48

so how would I build my .clj file without compile?

hl2zip01:12:02

(I am assuming the guide I was reading is more or less on the right path)

hiredman01:12:03

if you are looking at some sort of beginners guide and it is using compile, drop it, it is junk

hl2zip01:12:19

Its the above

hiredman01:12:06

the load then compile call

hiredman01:12:21

and this isn't a beginner's guide

hiredman01:12:39

ignore, and forget anything you read there 🙂

hiredman01:12:59

java -jar clojure.jar will launch a repl

hiredman01:12:05

copy and paste code in to the repl

hiredman01:12:29

it isn't a very full featured repl, so you might want to pair it with rlwrap

hiredman01:12:50

or use a more full featured repl from a tool like lein, or boot, or something built in to your editor

hiredman01:12:55

but that is the way to start

hl2zip01:12:10

fair enough. Out of curiosity - how do I build manually without lein

hiredman01:12:21

it depends what you are doing

hiredman01:12:27

I wouldn't build at all

hiredman01:12:31

you don't need to

hiredman01:12:51

that blog post is conflating "building" with aot compilation

hiredman01:12:58

which is what "compile" does

hiredman01:12:45

which is not required at all, and generally will make your life more difficult for yourself if you do it all the time, and is only useful in some specific situations which you are unlikely to encounter for some time

hiredman01:12:12

java -cp clojure.jar clojure.main my-file.clj

hiredman01:12:21

will run your clojure file

hiredman01:12:30

if you have a bunch of clojure namespaces

hiredman01:12:03

jar them up, then java -cp clojure.jar:my-jar clojure.main -m my-main-namespace.core/-main will run it

hiredman01:12:29

clojure code is always compiled to jvm bytecode before it is run

hiredman01:12:45

compile and just loading the clojure file are no different in that regard

hl2zip01:12:23

sorry, what is the command for jarring up the files?

hl2zip01:12:32

And thank you!

hl2zip01:12:42

this clears everything up

hiredman01:12:59

but just use lein

hiredman01:12:03

lein is great

hiredman01:12:54

my first clojure project that required a "build" step used makefiles

hiredman01:12:18

my first clojure job used maven multi module build when I started

hiredman01:12:26

(this was all before lein was written)

bfabry01:12:23

if you want a clojure build tool that's a bit more explicit about what's happening then there's boot (I have not use boot)

hiredman01:12:23

my current job is using boot, and it is fine, but I am particularly impressed enough to move away from lein for my personal stuff

hl2zip01:12:42

haha that was my next question - boot

hl2zip01:12:15

Thanks, all!

kzeidler07:12:16

To piggyback on @hl2zip 's earlier question about build tools: I ran into this cool-looking library today called 'System' while trying to bootstrap a Sente server https://github.com/danielsz/system

kzeidler07:12:11

Has anyone used this? Is it a nice way to bootstrap a new project?

kzeidler07:12:59

I haven't quite wrapped my head around how to use it, but it seems possibly like a solution to the problem I've been having with static project.clj dependencies -- namely that it's hard to swap dependencies in/out

grav08:12:50

If I have a list of keys defining a sort order, how can I sort a map (into a list of pairs) according to the order in the list?

grav08:12:54

Should I just map over the order list and pick values from the map, or is there a nicer way?

roelofw08:12:26

Is this a good way to organize a small project of 2 pages : http://clojure-doc.org/articles/tutorials/basic_web_development.html

grav08:12:08

@grav ok, I guess it’s just (map #(get m %) order)

danielsz09:12:47

@kzeidler Let me know how it goes 🙂 Have you seen this example for sente: https://github.com/danielsz/system-websockets

kzeidler09:12:53

@danielsz Oh goodness, I feel almost starstruck. 🙂

kzeidler09:12:28

@danielsz: Is there a comprehensive guide to setting up a dev environment with System? I've checked out the individual examples and I'm having a bit of trouble figuring out how to use them to get the "runtime loading of clj dependencies" idea up and running

spacepluk09:12:24

hi, is there a leiningen template for nrepl middlewares?

danielsz09:12:12

@kzeidler If you want to load clj dependencies at runtime, you have a facility in Boot that allows to do that (via pomegranate).

danielsz09:12:01

@kzeidler I'm not aware of a guide, I think people learn with the examples. A guide will be welcome, of course.

kzeidler09:12:58

@danielsz: Gotcha. So Boot + Pomegranate for loading of actual dependency files at runtime, but System can (if I'm reading the docs correctly) initialize and bind those dependencies to the project on demand? (Correct me if I have the wrong idea, I'm comparing a few different libs right now and trying to keep them sorted in my head)

danielsz09:12:18

@kzeidler No, System will reload your code, not third-party libraries.

danielsz09:12:46

@kzeidler System is a component system + a live coding environment.

danielsz09:12:45

@kzeidler System doesn't have semantics of its own. To understand it means to understand Component and Boot.

danielsz09:12:03

@kzeidler And both have good guides and READMEs.

cfleming11:12:20

@achesnais A little late, but recently I’ve been creating PDFs using https://github.com/whamtet/cljs-pdfkit. I created a simple version of http://cljs-pdfkit.herokuapp.com/ which allows me to develop PDFs using Figwheel

cfleming11:12:24

It’s really nice

kah0ona12:12:17

that's awesome

kah0ona12:12:30

I really needed this 2 months ago 😉

kah0ona12:12:32

but i managed

kah0ona12:12:40

will try this out soon for something else i need to do

roelofw13:12:53

no one who can help me ?

rcanepa13:12:55

Hi everyone! ... Does anyone knows why select-keys returns an unsorted-map when the vector of keys is big (big in comparison with the map) ?

bronsa13:12:17

@rcanepa if you look at m it will be unordered in the same way as your last one. maps are not ordered in clojure, it just so happens that for performance reasons, small maps maintain insertion order but that's not something you should rely on

rcanepa13:12:10

You are so right ! ... thanks @bronsa !

kah0ona13:12:47

i have a (deftest ...) which calls a function, which i want to debug. but println statements are not showing. what is the best way to go about this? I just call (run-tests.. ) from the repl

clojuregeek14:12:06

@roelofw: it seems like a good starting place :)

roelofw14:12:38

I have this code :

(ns paintings.views
  (require paintings.api-get :as api)

  (defn homepage)
  (api/do-both-in-parallel (api/read-numbers))

  )  

roelofw14:12:48

but when I want to run it , I see this error message : Exception in thread "main" java.lang.IllegalArgumentException: First argument to defn must be a symbol, compiling:(paintings/views.clj:1:1) What is wrong with my view file

dpsutton14:12:30

your defn form is malformed

dpsutton14:12:07

and these cant go inside a ns form

dpsutton14:12:37

and i think you want the (:require [dep :as alias]) form

roelofw14:12:44

@dpsutton this better :

(ns paintings.views
  (:require [paintings.api-get :as api]))

(def homepage
  "makes the homepage"
  []
 (api/do-both-in-parallel (api/read-numbers)))
 

dpsutton14:12:06

look up differences in def and defn

roelofw14:12:16

if so, then I have to find out why both api calls cannot be found

roelofw14:12:35

@dpsutton changed, and im diving into the docs to find the differences

roelofw14:12:08

it seems that (defn name doc-string? attr-map? [params*] prepost-map? body) is the same as (def name (fn [params* ] exprs*))

dpsutton14:12:27

and yours is neither

roelofw14:12:34

so with def you do not use a docstring

roelofw14:12:22

oke, changed it to :

(ns paintings.views
  (:require [paintings.api-get :as api]))

(defn homepage
  "makes the homepage"
  []
 (api/do-both-in-parallel (api/read-numbers))) 

roelofw14:12:39

still both api calls cannot be resolved in cursive

roelofw14:12:31

oke, after a invalided caches it seems to work

roelofw14:12:14

I have this into my handler.clj : (GET "/" [] views/homepage)

roelofw14:12:26

so homepage does not have arguments

mpenet14:12:58

it does, it gets the request by default

roelofw14:12:04

now I see this error from ring : ' Wrong number of args (1) passed to: views/homepage '

roelofw14:12:14

aha, that is the 1 argument

roelofw14:12:45

so I must change it to [req] ? @mpenet

mpenet14:12:03

(defn homepage [request] ....)

roelofw14:12:51

time to choose a template engine I think and look if I can print something on the screen

roelofw14:12:43

at this moment, I want to display the json request that it processed by do-both-in-parallel on the browser

roelofw15:12:28

I doubt between selmer and hiccup. what is a better one when dealing with a big html template ?

roelofw16:12:43

How can I make it work that this function is executed and the outcome is displayed with selmer :

(api/do-both-in-parallel (api/read-numbers))  

roelofw16:12:17

I try it with (render ( api ..... )) but that does not work , I see then a argument error

seancorfield16:12:33

Selmer's render expects a template (string or file) and a map of data.

seancorfield16:12:10

(off the top of my head -- I'd have to check how we use it... but we use Selmer to create millions of HTML emails every day)

roelofw16:12:15

oke, so back to the manual.

roelofw16:12:47

I want to display at this moment, only the outcome of that function on my web page

seancorfield16:12:24

You need an HTML template that has appropriate substitutions in it.

roelofw16:12:55

oke, so I cannot display the whole object or do I misunderstood you

roelofw16:12:44

web development with clojure is much harder then the 4clojure challenges

seancorfield16:12:48

Selmer has constructs to display sequences, by looping over HTML fragments.

dpsutton16:12:28

if you just want proof of concept you can just call (str)on your object

dpsutton16:12:36

should spit out something and you can make sure that your endpoint is being hit

seancorfield16:12:42

{% for item in data %} {{item}} {% endfor %}
So you'd pass a map to Selmer with a key :data that is your sequence of values.

seancorfield16:12:03

(selmer/render my-template {:data my-data})

roelofw16:12:38

oke, so if I understand you right, the template is the {% ..... } part

seancorfield16:12:06

Yes, that's in a file that you could slurp in or use Selmer's render-file (from memory, we just use render)

roelofw16:12:24

and must the template also be in the views directory

dominicm16:12:50

render takes the contents of a template file, not the path to the file.

seancorfield16:12:09

(yes, hence why we slurp in the file first!)

dominicm16:12:19

^^ No caching? 😛

seancorfield16:12:41

Here's an example from one of our Selmer templates:

<p>Dear {{user.userName}},</p>
	<p>Thank you for posting your photo on {{site.title}}.</p>
	
	{% if not data.accepted-photos|count-is:0 %}
		{% if data.accepted-photos|count-is:1 %}
			<p>The following photo has been approved by our Quality Control Team and is now showing on your profile.</p>
		{% else %}
			<p>The following photos have been approved by our Quality Control Team and are now showing on your profile.</p>
		{% endif %}
		{% for photo in data.accepted-photos %}
			<div>
				<a href="{{data.photo-url}}/{{photo.photo-name}}.{{photo.photo-ext}}{{data.clicker}}"><img src="{{data.photo-url}}/{{photo.photo-name}}_small.{{photo.photo-ext}}"></a>
			</div>
		{% endfor %}
	{% endif %}

seancorfield16:12:04

@dominicm Yes, we slurp and cache the templates.

dominicm16:12:44

@seancorfield ah, you cache yourselves. Selmer has built-in caching. Any reason you don't use render-file?

dominicm16:12:24

@roelofw For reference, you should be able to do (selmer/render "{{ data|json }}" {:data {:key :val}}) to get something basic working.

seancorfield16:12:25

Yes, complex reasons 🙂 We have a cascading algorithm for selecting a template, based on locale and various other considerations.

dominicm16:12:57

There are 2 hard problems in computer science...

seancorfield16:12:31

We have one code base supporting nearly 100 different web sites in over a dozen locales (including RTL languages!).

roelofw16:12:49

@dominicm and data is the outcome of the function ?

roelofw16:12:50

so I can do (selmer/render "{{ (api/do-both-in-parallel (api/read-numbers)) |json }}" {:data {:key :val}})

dominicm16:12:48

(selmer/render "{{ data|json|safe }}" {:data (api/do-both-in-parallel (api/read-numbers))})

roelofw16:12:01

Thanks, I will try it out. Later I have to make a real template but I have not found a nice one

seancorfield16:12:48

Selmer is great, once you get used to it 🙂

roelofw16:12:13

Wierd, I now see this error : Unable to resolve symbol: ???? in this context, compiling:(paintings/views.clj:6:1)

dominicm16:12:21

Django figured out the perfect compromise to templating — Jinja2 perfected what is available and better defaults.

roelofw16:12:35

but there are no ??? in the template to be found

roelofw16:12:11

@dominicm so I can use ninja2 also als template engine ?

dominicm16:12:15

@roelofw My comment was in response to @seancorfield, Jinja2 is a Python library, inspired by the same thing as Django

roelofw16:12:31

oke, one of you two know why I see the resolve symbol: ??? with this code :

(ns paintings.views
  (:require [paintings.api_get :as api]))

(use 'selmer.parser)

(defn homepage
  "makes the homepage"
  [req]
  ⁠⁠⁠⁠(render "{{ data|json|safe }}" {:data (api/do-both-in-parallel (api/read-numbers))}))  

dominicm16:12:21

(ns paintings.views
 (:require [paintings.api_get :as api]))
I don't think Clojure namespaces can have an underscore in the name

dominicm16:12:54

file src/paintings/api_get.clj should be required as paintings.api-get

bronsa16:12:58

it's the other way around, you can't have dashes in filenames, but you certainly can have underscores as namespace names

bronsa16:12:09

both foo.bar-baz and foo.bar_baz will match foo/bar_baz.clj (but only the namespace that's defined in bar_baz.clj will actually load, obviously)

dominicm16:12:26

ah, so that's definitely not it then. I figured it might be a misc bug creating some confusion further down.

dominicm17:12:17

@roelofw is there more to your stacktrace that you can share? The suggestion seems to be that (defn homepage is the problem

roelofw17:12:40

here is a repheap of the whole output : https://www.refheap.com/124075

seancorfield17:12:08

And what's on line 6 of paintings/views.clj?

roelofw17:12:35

(defn homepage

seancorfield17:12:07

(sounds like you have non-ascii characters in the code -- did you copy'n'paste it from a web page?)

roelofw17:12:28

Nope, I typed it myself

dpsutton17:12:18

can you show us the whole input?

seancorfield17:12:30

Oh, you have (use 'selmer.parser) which will only make render available at runtime, not compile-time.

seancorfield17:12:40

That works in the REPL, but not in a Clojure file.

roelofw17:12:07

oke, then I misunderstood the readme of selmer

seancorfield17:12:07

You need to have [selmer.parser :refer :all] in your :require clause in ns instead.

seancorfield17:12:21

Most readme files show REPL usage.

seancorfield17:12:43

They assume you'll do the mental mapping to ns when you write code outside the REPL.

roelofw17:12:19

oke, the view file looks now like this :

(ns paintings.views
  (:require [paintings.api_get :as api])
  (:require [selmer.parser :refer :all])
  )


(defn homepage
  "makes the homepage"
  [req]
  ⁠⁠⁠⁠(render "{{ data|json|safe }}" {:data (api/do-both-in-parallel (api/read-numbers))})) 
 

roelofw17:12:28

is is now good ?

dpsutton17:12:59

look at a file online to see how to format your ns form

dpsutton17:12:04

you shouldn't be using two requires

seancorfield17:12:13

(ns paintings.views
  (:require [paintings.api_get :as api]
            [selmer.parser :refer :all]))

seancorfield17:12:07

(and having that _ in the namespace is really jarring... in paintings/api_get.clj I'd expect the ns to be paintings.api-get not paintings.api_get)

seancorfield17:12:41

Rule of thumb: in Clojure, symbol names never contain _, only filenames have _.

roelofw17:12:54

oke, I was naming it like that because the file gets data from a external api

roelofw17:12:10

any suggestions how I can name it better ?

seancorfield17:12:34

The file will be api_get.clj but the namespace should be api-get.

seancorfield17:12:59

Is that now producing the correct result?

ezmiller17:12:31

is it possible to have interop with a npm Javascript library? for example, if i wanted to write an application that makes use of the nodegit library...

juhoteperi17:12:35

@ezmiller While running in Node, yes. You can just call (def Foo (js/require "foo"))

ezmiller17:12:31

can you elaborate a bit about what “while running in node” means?

juhoteperi17:12:53

Well, when you run the application in node

ezmiller17:12:23

interesting. so you’d write a node application that would load up a clojure jar?

ezmiller17:12:38

is there an example repo somewhere of what that’d look like?

juhoteperi17:12:10

No, you'd write ClojureScript application that is compiled to Node compatible JS

ezmiller18:12:42

@juhoteperi very interesting. thank you. this all because i want to write something that serves files stored in git(hub), using nodegit or js-git. didn’t see anything like this for clojure…

juhoteperi18:12:35

And there seems to exist a clj wrapper for jgit: https://github.com/clj-jgit/clj-jgit

ezmiller18:12:29

Oh, promising. Thanks!

dpsutton18:12:11

i know i've seen some guides for how to contribute to the clojure jira, about formatting patches and other things. does anyone know where i can find that again?

roelofw18:12:25

@dpsutton is still fails with the same error : Unable to resolve symbol: ???? in this context, compiling:(paintings/views.clj:5:1)

dpsutton18:12:41

still haven't seen the input text you are using so don't know how to help

roelofw18:12:45

I will try to re type that part ahain

dpsutton18:12:48

don't type it

roelofw18:12:07

what do you mean with the input text ?

dpsutton18:12:15

your file paintings/views.clj

dpsutton18:12:27

just upload the file here

roelofw18:12:59

views.clj :

(ns paintings.views
  (:require [paintings.api_get :as api]
            [selmer.parser :refer :all]))

(defn homepage
  "makes the homepage"
  [req]
  ⁠⁠⁠⁠(render "{{ data|json|safe }}" {:data (api/do-both-in-parallel (api/read-numbers))}))   

roelofw18:12:48

and still on the (defn homepage line 😞

dpsutton18:12:16

can you delete the defn and in its place put

dpsutton18:12:15

you just want to see if the endpoint is working

dpsutton18:12:25

and if there's any weird characters in there get rid of them

roelofw18:12:23

That displays the text on the webpage

roelofw18:12:30

so its working

dpsutton18:12:44

now put this function

roelofw18:12:29

Then I see this as message on my webpage : [email protected]

dpsutton18:12:59

try (defn homepage [req] (str (doall (api/...)))

roelofw18:12:40

yes , that is schowing the whole clojure object so my first step is working

roelofw18:12:51

Thanks a lot

dpsutton18:12:56

so now try to put it back in the render stuff

roelofw18:12:08

when I do : (defn homepage [req] (render "{{ data|json|safe }}" {:data (api/do-both-in-parallel (api/read-numbers))})) . I see the same output as with doall

roelofw18:12:14

thanks a lot

roelofw18:12:09

tomorrow I will try to make a template which displays a record instead of a big clojure object

roelofw18:12:20

@dpsutton one question: Must I make a directory templates in the src directory or can it be in the same directory as the views code file

tbaldridge18:12:46

@prakhar that's a common problem with the short-hand fn syntax. Your first example is saying "create a vector, then call it"

tbaldridge18:12:04

try this instead: (map #(vector % 0) '(1 2 3 4 5))

prakhar18:12:29

ah nice! thanks a lot @tbaldridge. I’m a big fan of your videos! Thank you 😃

tbaldridge18:12:45

hrm....not sure why the second one worked though....

prakhar18:12:07

(map (fn [x] [x 0]) '(1 2 3 4 5))

prakhar18:12:11

sorry, it should be this

seancorfield19:12:22

@roelofw Most folks put the templates in the resources folder instead of src. That should be on your class path at runtime too.

roelofw19:12:28

oke, I have to find out how to do that , Thanks @seancorfield

seancorfield19:12:06

@roelofw You can do (slurp ( "path/to/template.html")) and it will read in resources/path/to/template.html.

seancorfield19:12:50

Leiningen will automatically put resources on your classpath along with src as I recall...

roelofw19:12:10

oke, I will try it tomorrow

roelofw19:12:07

Im now looking for a nice portfolio layout which can work with different layouts. Some paintings are landscape and some are not

roelofw19:12:26

So im thinking about a masonary template

seancorfield19:12:49

I'm no front end guy and certainly no designer so I'll resist offering advice on that part 🙂

roelofw19:12:58

im also not

roelofw19:12:21

Im get a better feeling with just making back ends

fiddlerwoaroof19:12:39

If it's for artwork, I'd be a bit hesitant about a masonry template. I'm not really a designer, but it seems to me you want something that gives each painting enough room to be appreciated.

fiddlerwoaroof19:12:35

So, maybe a simple grid of with some padding in between and then a way to popup an individual painting to get a better view.

roelofw19:12:57

@fiddlerwoaroof That can also be but I do not know what format ( landscape or not) the paintings are

roelofw19:12:12

I read them from a external api

fiddlerwoaroof19:12:50

If you make a bunch of squares and then set their background-image to the image and then set background-size to contain and use margin for padding, it doesn't matter whether the image is portrait or landscape.

fiddlerwoaroof19:12:03

But, I'm not a designer, so don't listen to me 🙂

roelofw19:12:36

Can't it be that there will be space between images when there are 7 landscape and 3 non landscape

roelofw19:12:52

O, I listen and try to see what you mean

fiddlerwoaroof19:12:13

I guess I was thinking that the extra space may not matter and will, in fact, help showcase the paintings better.

roelofw19:12:27

oke, I can always try

nha22:12:05

just watching clojure conj videos (or starting to watch them). I read them basically as "write immutable code". Which sounds perfectly sensible. I have been waiting for that to happen in a way. But we need more than conventions. We need tooling to enforce these conventions. hint: that is still missing

nha22:12:00

(and I think clojure is especially well suited to tackle this problem)

tbaldridge22:12:06

@nha I think most people agree that tooling needs to catch up. Spec (as Rich mentioned) is the first step. After people start using Spec more it's rather trivial to say "You said function X took foo before and now it requires foo and bar...can't do that, better rename"

roelofw22:12:57

@seancorfield when you had it about the resources directory for selmer templates , you mean that one or resources/public ?

fellshard22:12:50

Close - not so much 'write immutable code' as 'write migratable specifications'. In fact, he even noted early in the talk that code is by definition not immutable. What matters more is that the guarantees - the specification of what the code requires and provides - should be open for expansion, whether that be requesting less of the user or providing more.

fellshard22:12:02

Code can be used to generate immutable artifacts, but if those artifacts share the same 'name', they still ought to maintain a specification that is at least as strong.

fellshard22:12:24

Notably, the one benefit I see from his discussion of using temporal labeling for a namespace is that it gives you guarantees for progression - if you move forward in time, you should have a guarantee that future versions of the same namespace are at least a strong as prior versions.

fellshard22:12:04

That's probably the ordering mechanism needed in contrast to SHAs. I wonder how that plays with forks? Hmm.

fellshard22:12:40

I couldn't help but wonder if he had a certain Javascript ecosystem's left-pad debacle in mind with all this.

misha23:12:04

@alexmiller is this intentional?

user=> (dosync (alter (ref 0) inc))
1
user=> (dosync (alter (ref 0) (io! inc)))
java.lang.IllegalStateException: I/O in transaction
but
user=> (swap! (atom 0) inc)
1
user=> (swap! (atom 0) (io! inc))
1
given that
(swap! a f). Note that f may be called multiple times, and thus should be free of side effects.

Alex Miller (Clojure team)23:12:34

You're suggesting that swap! should throw too?

misha23:12:04

not should, but I expected it to, yes

misha23:12:27

though pure function and tx function - are not exactly the same, yes

Alex Miller (Clojure team)23:12:43

Maybe? There are performance ramifications

misha23:12:47

would have made io! so much more useful

tdantas23:12:45

what is the common way to default an array/seq js snippet

// if the coll is nil we are going to default to empty array
coll = coll || [];

olslash23:12:08

(or col []) i guess, but cant most functions that expect a list handle nil (returning an empty list)?

tdantas23:12:53

geez, why I didn’t try that ! sorry to bother you guys !