This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-12-20
Channels
- # admin-announcements (1)
- # bangalore-clj (4)
- # beginners (176)
- # boot (38)
- # cider (9)
- # clara (1)
- # clojars (9)
- # clojure (290)
- # clojure-belgium (25)
- # clojure-berlin (2)
- # clojure-dusseldorf (10)
- # clojure-italy (1)
- # clojure-russia (141)
- # clojure-sg (1)
- # clojure-spec (40)
- # clojure-uk (38)
- # clojurebridge (19)
- # clojurescript (148)
- # code-reviews (37)
- # community-development (7)
- # cursive (27)
- # datomic (71)
- # editors-rus (3)
- # events (1)
- # heroku (1)
- # hoplon (16)
- # jobs (5)
- # lambdaisland (3)
- # lein-figwheel (211)
- # luminus (3)
- # off-topic (52)
- # om (18)
- # onyx (49)
- # overtone (3)
- # pedestal (48)
- # protorepl (7)
- # rdf (2)
- # re-frame (61)
- # reagent (3)
- # timbre (2)
- # untangled (69)
hello guys, how do i add two presistant vectors together, such as [1 2 3] + [4 5 6] = [1 2 3 4 5 6]
@pishty Take a look at concat
: https://clojuredocs.org/clojure.core/concat
thank u @chrisoakman, is the only difference between concat and into is the return type - list and vector respectively ?
concat
always returns a lazy sequence (a list), into
can convert between difference sequences types. ie: (into #{} [1 2 3])
returns #{1 2 3}
(converting a vector into a set)
Correct
And depending on what you're converting between, into
will function differently.
For example, (into #{} [1 1 2])
returns #{1 2}
conj
is typically used to add one item to a sequence, it adds to the end of a vector and to the beginning of a list
In general, most of the core library sequence functions return a lazy sequence.
So you'll have your vector / map / set data structure, you execute a couple of functions against it (during this time you are dealing with lazy sequences), then you often convert it back to whatever format makes sense.
I'm generalizing here: it doesn't always have to work in that way. But often it does.
i think i understand, so if i do an 'into' the return type isnt always a lazy sequence ?
You may find the ClojureScript cheatsheet helpful: http://cljs.info/cheatsheet/
That is accurate. With into
you can specify which return type you want.
ah ok cool @chrisoakman you are the man, thank u so much, also i think am going to bookmark that cheatsheet 🙂
It was something that took me a while to grasp when I first started. I was used to everything being "instant" in that you didn't have the lazy sequence abstraction.
I used a lot of doall
to make sure things weren't in a lazy sequence all over my code. It was unnecessary.
Also the core library is large and there is a lot of overlapping functionality. In time you get familiar with it and this stuff becomes second nature though 🙂
doall
forces a lazy sequence to evaluate, which is sometimes what you want if you need to see a results of a side-effecting function. doseq
also does this
When I was first starting CLJS I used to write a lot of side-effecting functions in my code. I don't do that as much anymore.
when u say side effecting function .... would u be so kind as to provide an example of what u just stated or a link that explains it
There are multiple ways to explain this and I have someone en route to my house, so let me see what I can do in the next 5 minutes 🙂
When you think of a pure function, you think like math functions. Inputs always yield the same outputs: https://en.wikipedia.org/wiki/Pure_function
So in your program, some functions are that way (like "add 2 and 3 together"). But others will be different depending on what time they occur. For example: save this file to disk.
Essentially, anything that has to change state or communicate with the outside world. Often in the case of CLJS it's interacting with the user or the DOM (which is a stateful thing).
So most of the core library functions are pure. They don't change any state and they always work the same way regardless of their inputs.
In Clojure it's best to isolate your non-pure functions from your pure ones. Keep things clean and separate.
When I was new to Clojure I used to combine everywhere, which is often what you do in JS (and other languages). ie: loop over this array, and update some data, but also update the DOM
Yes. Well said.
So I used to use map
to iterate and then doall
to make sure the side effects happen.
Generally speaking, use core functions to change from Data Format A to Data Format B to Data Format C (whatever you need to do), then have some other function or process that handles the end result. Don't complect the data munging and the side-effecting.
Clojure makes this easy to do, especially with core library functions.
so when u seperate pure and non pure, do you put them in different namespaces or do u just name them differently ?
Really depends on your program, but probably it's just a naming choice.
It's convention to append a bang at the end of a function name that is side-effecting. ie: delete-table-rows!
, show-login-button!
, etc
Without even seeing the function definition, I already have a pretty clear idea of what those functions do 🙂
And the !
communicates to me that that function is not pure. (again, this just a convention, it's not enforced by the compiler or anything)
Sure thing 🙂
A bit off-topic, but does anybody happen to know, geographically-speaking, where one would have the greatest likelihood for running into a clojurian/clojurescriptian? Seattle?
At a Clojure conference 😉
i just saw some on http://meetup.com
@pishty, I’m late to this discussion, but this blog post helped me understand when to use pure vs impure
Also, https://github.com/Day8/re-frame events and effects are a nice place to start if you’re doing UI stuff in Clojurescript
My index.html does this:
goog.require("screensaverninja.core"); screensaverninja.core.main();
which used to work just fine but now I’m getting: Uncaught ReferenceError: screensaverninja is not defined
on that second line.
If I run it in the console, it works.
It used to work, but I don’t know what changed. I tried going back to a good commit and they all seem to be having the same problem.
Any ideas?
does your cljs build define a :main
, @pupeno ? because that saves you from having to do this ceremony. you simply load your js onto the page
No, I don't think so. I do that for prod compilation, not dev.
Separating the require and actual call to main in two script tags solved the problem.
After reading how require works, I don't understand how this ever worked.
I'm on the go now. When I'm back I'll check about just using :main.
Thanks.
@pupeno the require and the main call need to be in separate <script>
tags in case you are not doing that
I am now.
But I wasn't. How did it ever work?
I'm puzzled.
When compiling javascript with the closure compiler, i use the option source_map_location_mapping to redirect the source map location to an internal server. Unfortunately this isn't available for the cljs compiler. How could I achieve this behavour?
@danielgrosse I think there is :source-map-path
but not exactly sure, should be in wiki
hi all, clojurescript noob question. I have the below function:
(defn config [recognition-instance grammar-list-instance level-grammar]
(.addFromString grammar-list-instance level-grammar 1)
(set! (.-grammars recognition-instance) grammar-list-instance)
(set! (.-lang recognition-instance) "en-US")
(set! (.-interimResults recognition-instance) false)
(set! (.-maxAlternatives recognition-instance) 1))
When compiled with :advanced
the .addFromString
call turns into $instance$.$addFromString …
. $addFromString$
does not exist on the object so it explodes with function is undefined
. Can I avoid google closure changing the name of that? The object is an SpeechRecognition
instance https://developer.mozilla.org/en-US/docs/Web/API/SpeechRecognition .you need to provide an externs file for those things if you want to use advanced compilation
https://github.com/cljsjs/packages/wiki/Creating-Externs can be helpful too
@dpiatek: an alternative to externs is to use string names: https://github.com/clojure/clojurescript/wiki/Dependencies#using-string-names
Quick reminder that the Clojure community survey closes Friday - would love to have your input! https://www.surveymonkey.com/r/clojure2016
how would you integrate proto-repl's nrepl functionality with boot-cljs-repl as in this tutorial? https://github.com/magomimmo/modern-cljs/blob/master/doc/second-edition/tutorial-02.md
When trying to load my app, I get the error: file:///…/screensaverninja/app_dev/app_dev/js/app/goog/base.js Failed to load resource: net::ERR_FILE_NOT_FOUND. As you can see, app_dev is there twice. Any ideas why? It should be there only once.
@bcbradley you can connect to the nREPL port boot outputs as a remote repl with protorepl
What’s the proper way to call the main function of my clojurescript app when I specify :main something.something?
@jr is that for me? cljsbuild and lein.
ClojureScript also has a :main, but it only loads that namespac, it doesn’t call any function on it. I could just call the function from the HTML, but I want to know if I’m missing something.
boot-cljs has an option where you can specify a "main function". it adds an additional goog provide that calls the main function after the rest of the deps have been required
@pupeno You can just call the main
function on the end of the namespace
In boot-cljs, the additional options exist only because Cljs :main
didn't exist back when they were added.
Currently Boot-cljs will always overwrite :main
using the generated shim namespace, but in future it will probably be possible to use own :main
namespace
juhoteperi Is calling main at the end of the namespace considered idiomatic? It sounds like every time the namespace is (automatically) reload, main would be re-run, which is not desirable.
Why it is not desirable? In my experience is needed to re-render the app (with Reagent).
To answer myself: Yeah, it does mean that if you run some expensive initialization (start loading some codesets from backend or something) code you don't want to run after every reload, you'll need to implement logic that checks if those are alreaded loaded.
But that seems fine to me.
juhoteperi: because that would re-initialize the state, clearing it.
Hi guys, I have an externs / JS interop question. I'm trying to use this externs file:
var aphrodite = {
"StyleSheet": {
"create": function () {},
"rehydrate": function () {},
"extend": function () {}
},
"StyleSheetServer": {
"renderStatic": function () {}
},
"StyleSheetTestUtils": {
"suppressStyleInjection": function () {},
"clearBufferAndResumeStyleInjection": function () {}
},
"css": function () {}
};
...but I'm not sure how to invoke what would be the equivalent of this in JS-land:
var aphrodite = require('aphrodite');
aphrodite.StyleSheet.extend([foo, bar]);
I thought it would be something like this:
(.extend (.-Stylesheet js/aphrodite) [foo, bar])
...but that's giving me a compilation failure "aphrodite not found"Can anyone see something wrong with the syntax above?
@timgilbert The most foolproof way to make sure JS code "survives" GClosure Advanced Compilation is to use strings.
I don't see that package listed in CLJSJS: http://cljsjs.github.io/
I also suspect that most CLJS users would prefer to use something like Garden for having CSS "in their code": https://github.com/noprompt/garden
Although I know that's not the question you asked; just providing some context here 🙂
If the JS engine is saying js/aphrodite
"aphrodite not found", then require
must not be putting that on the window
object.
I'm preparing a PR for CLJSJS, actually, just trying to test my work. FWIW, aphrodite does a different thing than garden (it's more about dynamic CSS construction to reduce CSS collisions, as I understand it)
Thanks for the tip, though, I'll look for that
In general, I try to wrap JS interop in a function with a nice interface. So I might try something like this: https://gist.github.com/oakmac/fba1fa8cfb0ec07b55a4a1284761c2e6
The library itself is actually written in Es6 and goes through webpack to export
I'm not 100% sure that will work, but hopefully you can see where I'm going with that.
Thanks, I'll take a look. I seem to recall that aget
is discouraged, though?
Yes; it's not officially encouraged to use aget
to access object properties.
aget
is for arrays. I still use aget
because I know that dot notation in JS isn't going to change.
There is a nifty library that creates an oget
function; I can't remember the name of it right now. It produces something like this though: https://gist.github.com/ptaoussanis/2556c56d93bde4af0415
Whatever 😉 aget
works fine for me
is there some trick to make enable-console-print! work correctly with figwheel? i’m seeing print output in the figwheel logs
@ag more details here http://clojurescript.org/community/building
uuugh ignore my question - somehow my damn console was changed to only show error messages
Why in the Quick Start does it suggest the command java -cp cljs.jar:src clojure.main build.clj
when build.clj already references the source directory to build?
@pandeiro your second version is more correct to me as well, the compiler does not build from the classpath I believe
Hello. Pretty new to cljs. What is a good lein template for regent and figwheel?
@thomassjogren devcards?
@michaellopez Interesting. Thanks