This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-02
Channels
- # adventofcode (5)
- # arachne (2)
- # bangalore-clj (1)
- # beginners (8)
- # boot (195)
- # cider (28)
- # cljs-dev (35)
- # cljsrn (4)
- # clojure (295)
- # clojure-brasil (5)
- # clojure-gamedev (2)
- # clojure-greece (2)
- # clojure-korea (13)
- # clojure-russia (60)
- # clojure-spec (58)
- # clojure-uk (92)
- # clojurescript (31)
- # clojurex (4)
- # css (1)
- # cursive (13)
- # datomic (40)
- # devcards (2)
- # emacs (17)
- # events (1)
- # flambo (3)
- # garden (9)
- # hoplon (31)
- # jobs (3)
- # klipse (1)
- # lein-figwheel (1)
- # london-clojurians (1)
- # luminus (2)
- # mount (36)
- # off-topic (13)
- # onyx (8)
- # pamela (1)
- # pedestal (1)
- # planck (3)
- # proto-repl (16)
- # protorepl (11)
- # re-frame (78)
- # reagent (4)
- # rethinkdb (6)
- # ring-swagger (1)
- # specter (8)
- # untangled (10)
- # vim (1)
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?generally -main takes an arg like [& args] is the moral equivalent of c's argc and argv
so I have a directory structure like this:
classes/
zero_project/
first_file_init.class
// other class files
which is why I wrote it like this classes:clojure-1.8.0.jar
thinking it start in that directory
I am following this one http://www.flyingmachinestudios.com/programming/how-clojure-babies-are-made-lein-run/
so the reason the text didn't change, almost definitely, is because you didn't recompile the class from the clojure code
good question, I don't know off the top of my head. the documentation for compile doesn't really say
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
if you are looking at some sort of beginners guide and it is using compile, drop it, it is junk
or use a more full featured repl from a tool like lein, or boot, or something built in to your editor
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
jar them up, then java -cp clojure.jar:my-jar clojure.main -m my-main-namespace.core/-main will run it
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)
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
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
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
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?
Should I just map over the order list and pick values from the map, or is there a nicer way?
Is this a good way to organize a small project of 2 pages : http://clojure-doc.org/articles/tutorials/basic_web_development.html
@kzeidler Let me know how it goes 🙂 Have you seen this example for sente: https://github.com/danielsz/system-websockets
@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
@kzeidler If you want to load clj dependencies at runtime, you have a facility in Boot that allows to do that (via pomegranate).
@kzeidler I'm not aware of a guide, I think people learn with the examples. A guide will be welcome, of course.
@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)
@kzeidler System doesn't have semantics of its own. To understand it means to understand Component and Boot.
@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
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) ?
@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
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
@roelofw: it seems like a good starting place :)
thanks , @clojuregeek
I have this code :
(ns paintings.views
(require paintings.api-get :as api)
(defn homepage)
(api/do-both-in-parallel (api/read-numbers))
)
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
@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)))
it seems that (defn name doc-string? attr-map? [params*] prepost-map? body)
is the same as (def name (fn [params* ] exprs*))
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)))
now I see this error from ring : ' Wrong number of args (1) passed to: views/homepage '
time to choose a template engine I think and look if I can print something on the screen
at this moment, I want to display the json request that it processed by do-both-in-parallel on the browser
I doubt between selmer and hiccup. what is a better one when dealing with a big html template ?
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))
I try it with (render ( api ..... )) but that does not work , I see then a argument error
Selmer's render
expects a template (string or file) and a map of data.
(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)
You need an HTML template that has appropriate substitutions in it.
Selmer has constructs to display sequences, by looping over HTML fragments.
{% for item in data %} {{item}} {% endfor %}
So you'd pass a map to Selmer with a key :data
that is your sequence of values.(selmer/render my-template {:data my-data})
Yes, that's in a file that you could slurp
in or use Selmer's render-file
(from memory, we just use render
)
(yes, hence why we slurp
in the file first!)
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 %}
@dominicm Yes, we slurp and cache the templates.
@seancorfield ah, you cache yourselves. Selmer has built-in caching. Any reason you don't use render-file?
@roelofw For reference, you should be able to do (selmer/render "{{ data|json }}" {:data {:key :val}})
to get something basic working.
Yes, complex reasons 🙂 We have a cascading algorithm for selecting a template, based on locale and various other considerations.
We have one code base supporting nearly 100 different web sites in over a dozen locales (including RTL languages!).
so I can do (selmer/render "{{ (api/do-both-in-parallel (api/read-numbers)) |json }}" {:data {:key :val}})
(selmer/render "{{ data|json|safe }}" {:data (api/do-both-in-parallel (api/read-numbers))})
Thanks, I will try it out. Later I have to make a real template but I have not found a nice one
Selmer is great, once you get used to it 🙂
Wierd, I now see this error : Unable to resolve symbol: ???? in this context, compiling:(paintings/views.clj:6:1)
Django figured out the perfect compromise to templating — Jinja2 perfected what is available and better defaults.
@roelofw My comment was in response to @seancorfield, Jinja2 is a Python library, inspired by the same thing as Django
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))}))
(ns paintings.views
(:require [paintings.api_get :as api]))
I don't think Clojure namespaces can have an underscore in the nameit's the other way around, you can't have dashes in filenames, but you certainly can have underscores as namespace names
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)
ah, so that's definitely not it then. I figured it might be a misc bug creating some confusion further down.
@roelofw is there more to your stacktrace that you can share? The suggestion seems to be that (defn homepage
is the problem
here is a repheap of the whole output : https://www.refheap.com/124075
And what's on line 6 of paintings/views.clj?
(sounds like you have non-ascii characters in the code -- did you copy'n'paste it from a web page?)
Oh, you have (use 'selmer.parser)
which will only make render
available at runtime, not compile-time.
That works in the REPL, but not in a Clojure file.
You need to have [selmer.parser :refer :all]
in your :require
clause in ns
instead.
Most readme files show REPL usage.
They assume you'll do the mental mapping to ns
when you write code outside the REPL.
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))}))
(ns paintings.views
(:require [paintings.api_get :as api]
[selmer.parser :refer :all]))
(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
)
Rule of thumb: in Clojure, symbol names never contain _
, only filenames have _
.
The file will be api_get.clj
but the namespace should be api-get
.
Is that now producing the correct result?
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...
@ezmiller While running in Node, yes. You can just call (def Foo (js/require "foo"))
Well, when you run the application in node
No, you'd write ClojureScript application that is compiled to Node compatible JS
This might be interesting read: http://yogthos.net/posts/2016-11-30-Macchiato.html
@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…
There is JGit for Java: https://eclipse.org/jgit/
For example Boot uses that: https://github.com/boot-clj/boot/blob/master/boot/worker/src/boot/jgit.clj
And there seems to exist a clj wrapper for jgit: https://github.com/clj-jgit/clj-jgit
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?
@dpsutton is still fails with the same error : Unable to resolve symbol: ???? in this context, compiling:(paintings/views.clj:5:1)
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))}))
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
tomorrow I will try to make a template which displays a record instead of a big clojure object
@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
@prakhar that's a common problem with the short-hand fn syntax. Your first example is saying "create a vector, then call it"
try this instead: (map #(vector % 0) '(1 2 3 4 5))
ah nice! thanks a lot @tbaldridge. I’m a big fan of your videos! Thank you 😃
hrm....not sure why the second one worked though....
@roelofw Most folks put the templates in the resources
folder instead of src
. That should be on your class path at runtime too.
oke, I have to find out how to do that , Thanks @seancorfield
@roelofw You can do (slurp (
and it will read in resources/path/to/template.html
.
Leiningen will automatically put resources
on your classpath along with src
as I recall...
Im now looking for a nice portfolio layout which can work with different layouts. Some paintings are landscape and some are not
I'm no front end guy and certainly no designer so I'll resist offering advice on that part 🙂
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.
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.
@fiddlerwoaroof That can also be but I do not know what format ( landscape or not) the paintings are
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.
oke, for another site I have used this template : http://themes-pixeden.com/landing/urku/portfolio-masonry.html
But, I'm not a designer, so don't listen to me 🙂
Can't it be that there will be space between images when there are 7 landscape and 3 non landscape
I guess I was thinking that the extra space may not matter and will, in fact, help showcase the paintings better.
@fiddlerwoaroof you mean something like this : http://jeremycowart.com/portfolio/
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
@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"
@seancorfield when you had it about the resources directory for selmer templates , you mean that one or resources/public ?
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.
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.
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.
That's probably the ordering mechanism needed in contrast to SHAs. I wonder how that plays with forks? Hmm.
I couldn't help but wonder if he had a certain Javascript ecosystem's left-pad debacle in mind with all this.
@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.
You're suggesting that swap! should throw too?
Maybe? There are performance ramifications
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 || [];