This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-05-13
Channels
- # beginners (202)
- # boot (7)
- # cider (14)
- # clara (2)
- # cljs-dev (7)
- # clojure (56)
- # clojure-italy (9)
- # clojure-spec (6)
- # clojure-uk (12)
- # clojurescript (40)
- # core-async (3)
- # datomic (6)
- # duct (1)
- # editors (10)
- # emacs (5)
- # fulcro (24)
- # off-topic (16)
- # onyx (4)
- # pedestal (1)
- # planck (8)
- # portkey (2)
- # re-frame (31)
- # reagent (23)
- # tools-deps (8)
- # vim (3)
Hey there, I'm learning clojure right now and I'm trying to figure out why the following doesn't work as expected:
Heya clojurians, I'd like to take a structure like [1 3 2 1 1 3 1 1 1 2]
, and return a nested structure with all runs of equal data in their own vector, like [[1] [3] [2] [1 1] [3] [1 1 1] [2]
. I'm struggling with the best way to do this. Ideas?
A lot of the inbuilt functions like split-by
or take-while
, which is what I'd think of using for this, won't work because I need to compare elements with previous elements. Which implies using reduce
, but I was hoping their would be a cleaner way, especially since updating nested data is kind of confusing.
That produces a sequence of sequences, so you'd need to (mapv vec ...)
if you really want a vector of vectors...
(this is just one of those cases where years of exposure to Clojure gradually teaches you more and more of the core functions ๐ I'm still learning after eight years!)
Reminds me that someone created some code where you could give example inputs and outputs that you want, and if there was a known existing function that could do it, it would tell you. Anyone remember where to find that?
Found what I remembered, but haven't tried it out yet to see if it would answer the question above: https://github.com/Raynes/findfn
Are there any libraries that implement common specโs? e.g. email telephone postcode?
How do people feel about the use of :as
vs :refer
in a require expression these days?
in our team we tend to :as
everything, as it makes it easy to know where things are from, visually
the fact that you add :as
or :refer
has no performance impact, the namespace has already been required
Say (require clojure.string :as str)
. Is the entire clojure.string namespace loaded or only the functions you use
(don't do it that way, it's bad style, but there's no way to "partially load" an ns, it's all or nothing)
what I'm saying is partially loading an ns doesn't exist, it's not a clojure feature
:as creates aliases with a prefix, :refer creates aliases to specific symbols, neither changes what's loaded
So if we are in agreement that import * from foo
is bad practice, how is Clojure loading the entire namespace good practice? It's the same thing
@whoneedszzz in java you can load classes separately, in clojure you can't load parts of a namespace separately
like literally, in java, you only load the classes in a package that have been referenced
if you just mean creating aliases within a different scope, that's different - the whole thing is loaded, it's just that only certain aliases are made
it might be a bad choice? I can't think of any language that loads up only parts of a file - in java each class is one file so that's the modularity of loading
And it would be impossible to determine statically which parts of a namespace would or could be used
right, your ns file would need to have some kind of database format maybe, with metadata about granular dependencies? not sure how it would work
I guess I'm just not understanding how Clojure can load the entire namespace and not have the same problems Java has with import * from foo
because we avoid refer (or only use it for specific symbols) and we use :as to qualify the names, we avoid implicit scoping - but that's not a loading issue, that's a naming and scope issue
:refer mititages it slightly by only bringing in a small list of symbols and not everything
loading is taking a resource outside the program and turning it into part of your program
Ok so if you corrected me on the word from the start we would be on the same page
import is for classes, it has nothing to do with other namespaces, it creates an alias to a class in the current ns
alias is for namespaces, it creates a prefixed alias for each public var in the target into the current ns, and yes, it does this for all of them
in practice, refer is worse than as in terms of explicitly knowing where things come from, because as makes it clear via the prefix that something is external
So if you are only using 1-2 vars in a namespace that has 20 vars why would you want to use :as
then
but, sometimes refer is worth it because you use something enough that the prefix is too noisey
when I'm down further in the ns, I need to remember the names of all referred items and where they came form
then if you are right, clojure uses poor naming. It works out for me. Best of luck!
no, status-bar isn't the full namespace, that's a shitty namespace name, it's the alias
why would you prefix all vars inside a namespace with the name of that namespace?
inside the com.whatever.app.status-bar
namespace, of course everything is related to status-bar
, so you can have an update
fn there, and refer to it as status-bar/update
, with :as
(:require [foo.bar.status-bar :refer [update-status-bar]])
means I can now do (update-status-bar ...)
and know exactly where it came from and what it does
Why would you want to repeat "status-bar" in the name? It's already there in the namespace?
So what you guys are talking about means that you must use :as
because they are both called update
Generally I don't do my naming with accommodating people who use :refer too much as a concern
Stylistically, it's probably best to only use :refer for things that are repeatedly used in a ns, and I also strongly disfavor :refer-ing in anything that's domain-related
we don't have to argue about naming, I doubt anyone here is going to change their mind
it's a beginners channel for learning clojure, we can tell you what's normal, idiomatic
The point is to help beginners. I posed the question in case any beginners were wondering the same thing and if I asked it in #clojure they would likely never see it
@whoneedszzz It's also possible to rename symbols that you refer in, if you prefer to do things in your style but are dealing with symbols that don't have prefixes in their names. require
supports a :rename flag
just for clarity, this is how the discussion started
07:54:26 WhoNeedszZz | How do people feel about the use of `:as` vs `:refer` in a require expression these days? โ
07:55:27 joelsanchez | in our team we tend to `:as` everything, as it makes it easy to know where things are from, visually โ
| (edited) โ
07:55:47 WhoNeedszZz | But are there any performance differences? โ
07:56:01 WhoNeedszZz | Does `:as` load the entire namespace or does it simply create an alias? โ
07:56:15 joelsanchez | it's just an alias, the namespace is loaded by requiring it
it was understood and answered - there's no performance difference, it's a naming alias
I was drawing a comparison to Java where using import wildcards imports everything in that package and causes multiple issues because of that. One of them is a performance issue because the compiler has to search through the entire package of any wildcards to find the occurrence of the reference
require
will cause the namespace to be compiled and instantiated if it's not already, regardless of :as or :refer
Another benefit to using :refer
is that you can look at the top of the file and know exactly which functions and/or macros are being used in that namespace at a glance
Iโm using lein-figwheel and trying to write a pixi.js application in clojurescript. I canโt get hot-reload to work correctly. If I mount my application to the dom using replaceNode, I have to do a hard browser refresh in order to see changes
(dom/replace-node
(oget js/document "body")
(oget app "view"))
On the other hand, if I mount it using appendChild, then every time I save a change, another canvas is appended to the page without removing the previous. Why does figwheel work so well with reagent and how can I make it work better for pixi?are you doing the replace-node at the top level of the ns? figwheel has to load your full ns so anything in a top level form will run
usually there's a specific callback for figwheel that you tell it to call after each reload
the reason things work so nicely with reagent is that you set up a piece of data that will cause a re-render of the mounted node when chaned
(which means figwheel needs no special callback - if the data changes when reloading the code, the page refreshes)
Ah, I am using it in the top-level. I think the figwheel templateโs default name for that callback is on-js-reload
. So, it sounds like I should put my reload logic in there
right, and whether in cljs or clj, doing things that have side effects at the top level of a normal ns will cause problems
clojure doesn't have a "compile only" mode, if there are side effects in your ns outside something like fn or delay that defer them, they run when your ns loads
@grierson that really depends on what you are trying to do - there's no direct analog as clojure doesn't enforce types during compilation
but depending on what you are attempting, it could be a multimethod extended to multiple keywords, or a protocol extended to multiple records, or a multimethod extended to multiple values of a magic key in a hash-map
@grierson another important difference is that clojure doesn't really do "closed types" - so the natural solution to most things involving datatypes is going to leave it open to runtime extension
@noisesmith Iโm watching โThe Power of Composition - Scott Wlaschinโ presentation now. https://youtu.be/vDe-4o8Uwl8?t=1456
if you try to apply ml patterns to clojure (beyond the very basics) you'll learn a lot, but you'll end up with very weird clojure code - ml and clojure have some incompatible base assumptions
Have ocaml got their threading model done yet? Last I heard it was essentially single threaded with one or two proposals of how to accomplish it but nothing official yet
as far as I know there's already a proposal that's been accepted which is under active development (multicore under ocaml-labs). Looks like there's been a lot of thought put into it which is why it's taking a long long time.
It is dependent on other things like the addition of typed effects as well from what I remember/understood
yeah, that is a problem with ocaml - it has good ipc so for a pool you can viably use a fixed number of instances on one machine, but it doesn't have shared-resources threads
but f# (which is what was specifically being referenced) can use c# threading and is based on ocaml - I don't have experience with it though