This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-05-02
Channels
- # aws-lambda (5)
- # bangalore-clj (1)
- # beginners (96)
- # boot (66)
- # cider (39)
- # cljsjs (2)
- # cljsrn (5)
- # clojure (265)
- # clojure-android (1)
- # clojure-france (1)
- # clojure-greece (32)
- # clojure-italy (4)
- # clojure-russia (2)
- # clojure-sg (1)
- # clojure-spec (27)
- # clojure-uk (25)
- # clojurescript (88)
- # cursive (4)
- # datomic (31)
- # emacs (96)
- # hoplon (10)
- # immutant (14)
- # jobs (2)
- # luminus (1)
- # lumo (66)
- # off-topic (128)
- # om (8)
- # om-next (2)
- # onyx (9)
- # parinfer (5)
- # re-frame (37)
- # reagent (16)
- # rum (9)
- # schema (3)
- # specter (34)
- # unrepl (8)
- # yada (21)
I have some string parameters that I want to pass from my server (Django templates) to the clojurescript app. In Elm there is a way to pass parameters to initialize an app. I don’t see this pattern in any of the tutorials or docs for cljs (that I’ve found). Is there a standard way to bootstrap a cljs app with parameters after the document has loaded?
Kind of a related note, but I used a lein template to create this project, and I’m unclear where it is determined that core/init! is called on load.
that should be in the :cljsbuild config in the project.clj
Ah, thanks @noisesmith. I tracked it down to env/cljs/. I wasn’t looking there before.
But I still have the question about bootstrapping cljs with config passed in from the html page. I’m using re-frame if that matters.
@noisesmith @donaldball @tbaldridge @mobileink it really kept me going in my sleep, the relationships between the multimethod system, records and protocols. In my perspective, the core differences lie in what kind of abstraction one has in their head and different ways of making one's code extendible by others through a shared mental model. And I learned of some performance differences and mild syntactic ones. I also learned of the type hierarchies model, mostly related to the multimethod system. The historical aspect of why one mechanism was introduced before the other seemed to mainly emphasize how eschewing Java concepts was initially more important than devising the later mechanisms, thusly admitting one hammer misses a lot of nails. It also spoke to the anthropology of speaking to people through differences from prior art (Java) before making time to address well-roundedness.
@noisesmith @donaldball @tbaldridge @mobileink you don't really have to read that, it is sometimes just helpful to recap on learnings, and I just don't have time left now, to make a blog post or something 🙂
Which library has scan
function? (scan + [1 2 3])
?
I don't know, seems used in parallel programming, I found it in this video: https://www.youtube.com/watch?v=eRq5UBx6cbA
The talk is a bit high level, there is no built-in function called scan
in Clojure. The concept of a scan
is a reduce but with every intermediate result included in the final result. It is not used for parallel programming, in fact the point he made in the talk was that parallelizing scan
results in more work being done than in the serial case.
While the is no function named scan
in Clojure, we have reductions
which produces the same result (and has a clearer name):
(reductions + [1 2 3]) ;=> (1 3 6)
@U0J30HBRS Thanks for your explain.
If somebody have experience with clojure - electron app generation, please drop me a line, about how to setup successful an icon. Many thanks. I tried with --icon app creation but in this case I see just an empty icon.. any other idea?
So this was bound to happen sooner or later: I have (1) a function of mine which I use in some places, and I wish for (2) a macro of mine, to use it in some other places. In use I mean either bring it along with it, or literally embed inside of it. Or anything else idiomatic to reuse the function also "by" the macro, making the macro safe to call from whatever namespace?
Now for some reason I'm against embedding it literally.
As is, the function is not found at runtime where my macro is expanded, because it is coming from a different name space in my code (a util
namespace of mine). So I use
my util namespace wherever I call my macro. Which won't scale very elegantly for the general case the more I write and use macros...
So two questions about this:
• This has been a curiosity for me for a while ― is there some way of telling clojure to not only use
or refer
a namespace in the current namespace, but to also expose it to those that consume the latter namespace? sort of a transitive use
if you must.
• Best practice for this use case?
I don't recommend using use
at all, and instead use (:require [foo.bar :as fb])
and then fb/qux
. This way you don't pollute the local namespace with names from another namespace. Also it's easier to track down where a symbol came from because you can go lookup what fb
means and that takes you to the namespace where qux
was defined.
@matan it sounds to me like your problem is caused by not using ` for your macro, and instead embedding raw, unnamespeced symbols, in your macro generator
@noisesmith think you are right, let me first see how I can rewrite it
the unnamespaced symbol might be valid in the namespace which defines the macro, but it won’t be valid in the namespace in which the macro is expanded
this kind of issue is why ` was invented
your fix is usually to literally replace ‘foo with `foo
(and later consider using ` to create the whole form)
and as an aside, can require
d symbols somehow propagate along with the namespace where they are require
d?
so that namespace A
refers a symbol foo
from namespace B
, and when A
is require
d in some other namespace C
, C
can use the symbol foo
?
there’s re-export macros out there, but I consider it a sign of bad design
sometimes I think it might be helpful though, e.g. I have this ceremony in some of my namespaces:
now that's because the authors of the library split it all in two, fair enough, modularity, they chose not to encapsulate under one name
well, you hopefully don’t have two require blocks in one ns form
specifying both explicitly is a feature
I should be able to see from my ns form exactly which file to look at to see what is up for a function
implicit requires, implicit refers, all break this
so point being, I am tempted to merge them in a proxy namespace, making my ns definitions more concise
and you turn something simple, direct and declarative into a treasure-hunt when someone has to find the code
(which is why we don’t tend to do this, and why clojure doesn’t support it directly)
an intentional one
No, it's about simplicity. The more ns magic you try to do, the harder it is for the next programmer to track down where a given var comes from.
Language (maybe) could have been designed to make it seamless, but I accept the limitation
If we had namespace require propagation (as Python does), it then becomes as @noisesmith said a treasure hunt of "where is this thing actually defined?
I used that model in Python, it's a major pain
@matan I don’t want to need to start a program in order to edit its code - the text itself should suffice for understanding
well that's a statement @noisesmith let me see how much it fulfills as I grow my clojure 😉
of course I need to run the code to know my own changes work - but we should strive for code to be a human-first document
noisesmith: kind of breaks apart the moment you do tinker defmethods and other dynamic stuff.... reading code is oftentimes the equivalent of compiling and running it in your head, unless you code to simple reading rather than good execution.
I'd say most people strike some balance in between, but that's not a scientific saying on my part 🙂
the difference is that dependency injection (including defmethod and protocol usage) should be top-down if done well - that means that you know which implementation is pulled in based on either static config, or the concrete instance created at a high level of abstraction before calling into internals. and the internals by their nature should work regardless of which implementation flows through (and if they don’t that’s a testing and debugging problem of course)
for example I use conj everywhere, I rarely need to think about which of clojure’s dozen or more concrete persistent collections I am conj-ing too, at most I need to remember if the thing is list-like or associative
maybe those are two very different examples, dep. injection and using a function like conj. I'll think about it again after running through some stack traces. Or you think of conj
as a dependency in your code, then it is kind of the opposite, you don't care where it comes from as long as you guess the "contract"
conj uses an interface, the actual collection you conj to is effectively an injected dependency
(and even could literally be one if you use a lib that extends the persistent collections)
I think you mean this at some higher level of code, like in namespaces or dependency injections. But at the micro, this "principle" might mean a lot of dumbing down of code.
oh, it’s not a stir-up, it’s just something I’m strongly opinionated about (and a big part of why I love clojure)
@matan oh it can, I’m telling you why I don’t think you should
there’s at least one popular library out there where none of its namespaces have code for the functions you can call in those namespaces because all the code is generated by macros
@noisesmith i can think of a library that does exactly that as well
@dpsutton thanks for not mentioning names 🙂 eventually I'm gonna get a drive to mimic it just cause it is forbidden https://www.youtube.com/watch?v=RnqAXuLZlaE
i'm not sure why we're tiptoeing around naming a library. the library explicitly says these are experimental ideas
Yeah, go ahead and name it. Criticizing code is different than saying "X is a fool for writing this..."
IMO it's fine to discuss the shortcomings of software, just don't project those shortcomings onto the author.
In scala (where I came from) you don't discuss shortcomings Everyone pretends everything is fine: case classes are fine, lack of concurrency idioms outside akka is fine. the horrendous build tool DSL is fine. etc.
@tbaldridge since were OK with it, this is the lib in question - notice how empty these files are, it uses reflection to build functions for each method on a java api https://github.com/mcohen01/amazonica/tree/master/src/amazonica/aws
Yeah it's an interesting trade-off, and one I've had to make in some libraries. The other option, which personally I'm a fan of, is to expand those macros into thousands of lines of CLJ code. That way you get static analysis and auto-generated code.
rauh: declaring the var before importing it makes cursive happy
this i the alternative: https://github.com/halgari/fn-fx/blob/master/src/fn_fx/controls.clj
1000 lines of auto-generated boiler-plate (honestly it should be generating more), so you get static analysis at the cost of having giant blocks of machine generated code
at least that way if I don’t get a function (or why it’s behaving the way it is) it takes me a lot less time to figure out what exactly it is
agreed, and that's why I prefer code generation over macros at times. With macros you loose line numbers, "jump to symbol" etc. But macros are more "lispy". So i've done it both ways from time to time.
can't one do "code generation" by somehow saving the outputs of macro application? doesn't the compiler support that? one nice thing in Scala is the compiler plugin architecture
sure you could do that with macros. And we have a plugin system for our compiler....it's called "macros" 🙂
core.async doesn't touch the compiler.
@tbaldridge oh I meant can you tell the compiler to dump the result of the macro evaluation phase to disk, or expose it as data, rather than write macros that take care of that? anyway I hope it can be gracefully accomplished, ignore ... 🙂