This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2020-07-18
Channels
- # beginners (17)
- # calva (1)
- # clara (1)
- # cljs-dev (12)
- # clojure (151)
- # clojure-france (11)
- # clojure-uk (6)
- # conjure (4)
- # datomic (32)
- # duct (42)
- # emacs (2)
- # fulcro (20)
- # lambdaisland (4)
- # malli (5)
- # meander (32)
- # pathom (8)
- # reagent (1)
- # reitit (7)
- # shadow-cljs (2)
- # sql (6)
- # tools-deps (2)
- # vim (17)
- # xtdb (1)
The existing from-java
function has not changed (although I found and fixed a small bug with from-java-shallow
while working on this). This is therefore backward compatible, by using a new name for the correct behavior.

Are there any methods or tools for detecting if a lazy seq gets realized at wrong time. For example I have a large finite lazy seq which I’d like to realize at specific point in the program. The lazy seq goes through complex processing where items are modified etc. And then there is some code like (count lazy-seq)
which realizes the lazy seq by mistake before the right place.
Possibly lazy seq could contain something that throws exception when realized, unless it is gets realized after certain point in program?
it honestly sounds like you are misusing lazy-seqs here
if it depends on side effects, and needs to be realized at a specific time (no sooner), it's better to use a procedural / side effecting low level tool, because that's what your domain actually requires
of course a redesign that doesn't make your domain side effects (or minimizes the part of your code using that domain) is often an improvement, but that's a bigger design problem
In my case the side effects are HTTP GET requests that fetch data which will be part of the final the datastructure.
And the problem is running out of memory if the lazy seq is realized fully at the wrong point.
Is there a special term when in a tree graph you transfer [node->leaf] edges from children to the root?
its a kind of flattening
I mean, "flatten" as we usually know it is a simpler subset of this operation for directed, non-looping graphs which disallow a node having two parents
thanks! if I called it lift – do I miss?
that also works I think - it might be confused with the concept from monadic / functor programming in ML family languages though(?)
in haskell or OCaml etc. you can use an operator to "lift" a function on x to a new one on (functor x)
eg. map
lifts a function to operate on the seq monad in clojure
got you, thanks!
Hi guys, I get clojure.lang.Compiler$CompilerException Syntax error compiling at
when using lein test
, but when I send (run-tests)
to the REPL all works: {:test 8, :pass 16, :fail 0, :error 0, :type :summary}
, any ideas?
(run-tests) doesn't find and compile test files, it only runs the ones that are already loaded
try (re)loading the test namespace that lein errored on
(require 'some.ns :reload)
(or whatever the equivalent is for your tool integration of choice)
there is just one test namespace, let me try
what's important, to be pedantic, is how many test files there are, for lein test, because it finds and loads test files, (including ones the repl would never load because eg. they are shadowed)
it's file tree oriented where clojure is classspaath oriented
I need that lein test
command works without problem
right, of course, I'm just trying to be more clear about reasons lein test would fail and a repl wouldn't
also, which file does it fail to compile, the test file?
yes test file
if so, the require with :reload should replicate the error in the repl
or (load-file "test/path/to/file.clj")
to even more directly do what lein test does
which is explicitly load files by path, not symbolically
(load-file "test/path/to/file.clj") returns nil
which is odd
what is the syntax error you get from lein test, can you show the full output?
you need to look at the entire error and analyze it @ertucetin
ERROR in (lower-upper-dual-bound-test) (Compiler.java:6808)
expected: (= "TEST_LEVEL := POSITIVE" (eval-from-fn-call (quote {MEASURED_VALUE? true, X 12}) (data->code data)))
actual: clojure.lang.Compiler$CompilerException: Syntax error compiling at (/private/var/folders/gs/dtdlkj7551vbd_d7jl8dxfb80000gn/T/form-init14550509181402349056.clj:1:6420).
Caused by: java.lang.RuntimeException: Unable to resolve symbol: ccase in this context
OK - which file has ccase
in it? grep could find it
some tests are failing not all of them
but works on REPL, which seemed to me weird 😕
probably because you haven't reloaded the file after typoing ccase
This is the ns that test is using: x-mind-report-parser.core
(ns x-mind-report-parser.core-test
(:require [clojure.test :refer :all]
[ :as io]
[clojure.edn :as edn]
[x-mind-report-parser.core :refer :all]
[x-mind-report-parser.util :as util]
[x-mind-report-parser.queries :as q]))
all required all
what I'm saying is ccase
is not a clojure function, you either failed to define it properly or misspelled case
that's your error
nope it's a custom macro
OK then why didn't you require it?
if you had required it, it would resolve
it's inside of x-mind-report-parser.core
which is required in x-mind-report-parser.core-test
are you trying to use it without the correct prefix?
Shouldn't it work after requiring in test file [x-mind-report-parser.core :refer :all]
?
I think leiningen has some weird thing, don't know
oh yeah if it's recursive and didn't namespae the self call properly I could see this issue coming up
yeah it's actually
you might be able to replicate by loading the test ns from user
instead of your default starting ns
@dpsutton restarted new REPL session, loaded files to the REPL and ran run-tests
all worked without problem
@ertucetin if you use lein run -m clojure.main
you can get a new repl with no readline etc. and nothing but clojure.core preloaded, from there try loading your test ns via require
that might reproduce the error in a repl
wow, this was fun
Clojure 1.10.1
(ins)user=> (apropos "special")
(clojure.core/special-symbol?)
(ins)user=> (->> (all-ns) (mapcat (comp keys ns-publics)) (filter special-symbol?))
(& def)
(ins)user=> (source special-symbol?)
(defn special-symbol?
"Returns true if s names a special form"
{:added "1.0"
:static true}
[s]
(contains? (. clojure.lang.Compiler specials) s))
nil
(ins)user=> (pprint (. clojure.lang.Compiler specials))
{& nil,
monitor-exit
#object[clojure.lang.Compiler$MonitorExitExpr$Parser 0x4bd1f8dd "clojure.lang.Compiler$MonitorExitExpr$Parser@4bd1f8dd"],
case*
#object[clojure.lang.Compiler$CaseExpr$Parser 0x7ec3394b "clojure.lang.Compiler$CaseExpr$Parser@7ec3394b"],
try
#object[clojure.lang.Compiler$TryExpr$Parser 0x278bb07e "clojure.lang.Compiler$TryExpr$Parser@278bb07e"],
reify*
#object[clojure.lang.Compiler$NewInstanceExpr$ReifyParser 0x625abb97 "clojure.lang.Compiler$NewInstanceExpr$ReifyParser@625abb97"],
finally nil,
loop*
#object[clojure.lang.Compiler$LetExpr$Parser 0xa4ca3f6 "clojure.lang.Compiler$LetExpr$Parser@a4ca3f6"],
do
#object[clojure.lang.Compiler$BodyExpr$Parser 0x3543df7d "clojure.lang.Compiler$BodyExpr$Parser@3543df7d"],
letfn*
#object[clojure.lang.Compiler$LetFnExpr$Parser 0x3b2c0e88 "clojure.lang.Compiler$LetFnExpr$Parser@3b2c0e88"],
if
#object[clojure.lang.Compiler$IfExpr$Parser 0x549949be "clojure.lang.Compiler$IfExpr$Parser@549949be"],
clojure.core/import*
#object[clojure.lang.Compiler$ImportExpr$Parser 0x6da00fb9 "clojure.lang.Compiler$ImportExpr$Parser@6da00fb9"],
new
#object[clojure.lang.Compiler$NewExpr$Parser 0x3a3e4aff "clojure.lang.Compiler$NewExpr$Parser@3a3e4aff"],
deftype*
#object[clojure.lang.Compiler$NewInstanceExpr$DeftypeParser 0x3e10dc6 "clojure.lang.Compiler$NewInstanceExpr$DeftypeParser@3e10dc6"],
let*
#object[clojure.lang.Compiler$LetExpr$Parser 0x5a7005d "clojure.lang.Compiler$LetExpr$Parser@5a7005d"],
fn* nil,
recur
#object[clojure.lang.Compiler$RecurExpr$Parser 0x4189d70b "clojure.lang.Compiler$RecurExpr$Parser@4189d70b"],
set!
#object[clojure.lang.Compiler$AssignExpr$Parser 0x1a7288a3 "clojure.lang.Compiler$AssignExpr$Parser@1a7288a3"],
.
#object[clojure.lang.Compiler$HostExpr$Parser 0x4044fb95 "clojure.lang.Compiler$HostExpr$Parser@4044fb95"],
var
#object[clojure.lang.Compiler$TheVarExpr$Parser 0x62e6b5c8 "clojure.lang.Compiler$TheVarExpr$Parser@62e6b5c8"],
quote
#object[clojure.lang.Compiler$ConstantExpr$Parser 0x1af146 "clojure.lang.Compiler$ConstantExpr$Parser@1af146"],
catch nil,
throw
#object[clojure.lang.Compiler$ThrowExpr$Parser 0x4c398c80 "clojure.lang.Compiler$ThrowExpr$Parser@4c398c80"],
monitor-enter
#object[clojure.lang.Compiler$MonitorEnterExpr$Parser 0x60641ec8 "clojure.lang.Compiler$MonitorEnterExpr$Parser@60641ec8"],
def
#object[clojure.lang.Compiler$DefExpr$Parser 0x75390459 "clojure.lang.Compiler$DefExpr$Parser@75390459"]}
nil
(ins)user=> (pprint (keys (. clojure.lang.Compiler specials)))
(&
monitor-exit
case*
try
reify*
finally
loop*
do
letfn*
if
clojure.core/import*
new
deftype*
let*
fn*
recur
set!
.
var
quote
catch
throw
monitor-enter
def)
nil
wow - so load-file definitely isn't in that list of specials, but it's definitely not normal at all
(ins)user=> (source load-file)
Source not found
nil
(ins)user=> (source clojure.core/load-file)
Source not found
nil
(ins)user=> load-file
#object[clojure.lang.RT$3 0x64a8c844 "clojure.lang.RT$3@64a8c844"]
also the back-story on clojure.core/import
being a namespaced special form is fun
when it was upgraded from a macro to a special form, they registered the form as fully qualified, so old code that used the full name to resolve it wouldn't break
@noisesmith (require 'x-mind-report-parser.core-test)
returns nil if I move to run-tests
to comment block, if move out, works and returns: Ran 8 tests containing 16 assertions. 0 failures, 0 errors.
what about (run-tests)
from the repl
from your own ns
@noisesmith also works, here:
I have no idea what that tool is or what namespace it is using to load your code, or what middleware it might be using
I suggested running the command I did because for behavior this strange getting layers out of the way helps
i think you want to be in a namespace where ccase is not defined in that ns. your test file :refer :all
so its defined there
right, thus my initial suggestion of lein run -m clojure.main
to create that set of conditions
then you'd use (clojure.test/run-all-tests)
after requiring the test ns but not switching to it
lein run -m clojure.main -> (require '[clojure.test :refer :all]) -> (clojure.test/run-all-tests) -> {:test 0, :pass 0, :fail 0, :error 0, :type :summary}
you didn't require your test ns
also don't :refer anything
the symbol not being mapped to this ns is part of what we are trying to recreate
lein run -m clojure.main -> (require 'x-mind-report-parser.core-test) -> (clojure.test/run-all-tests) -> {:test 8, :pass 11, :fail 0, :error 5, :type :summary}
got: clojure.lang.Compiler$CompilerException
OK - so we've recreated the conditions of the failure, and it's likely what @dpsutton thought
somewhere yo have 'ccase
where you should have ccase` for example
hmm let me update
being in a namespace that refers ccase (like the original ns, or your test ns) hides the error, as the symbol is referred during expansion if you are in the ns, but the error will occur if you have some other active ns when the code is expanded I bet
makes sense
wow that was hard one 😄
thank you so much @noisesmith @dpsutton, I'll try to update the code and make it work
will do thanks
(let*
[x__1019__auto__ 1]
(if x__1019__auto__ (clojure.core.cache/my-and 2) x__1019__auto__))
you see the my-and
there. if it was an unqualified my-and
that would be the bug. the expansion would only work in an environment where that symbol was definedis arcadia (unity for clojure) abandonware?
last merge was april, that doesn't sound fully abandoned to me
@bitpadawan also in my experience, mainstream clojure coding style (and the compatibility levels maintained by the vm and clojure itself across releases) means that libraries actually get "finished", or only change as features come in, not as an endless series of red-queen scrambling ot keep up with everything else's changes
arcadia is still alpha or beta, but it's being worked on
also it helps that nobody writes the security software in clojure, you get those updates via the vm or downstream deps
i've noticed that, but as a beginner it's hard to tell the difference. it's also that i don't see much/anything on reddit, here, etc, and also few beginner-friendly resources etc
it's pretty cool that it exists
that's fair - I don't know if arcadia is a very beginner friendly project (yet at least)
@bitpadawan the tooling scenario for the clr port of clojure is in a meagre state
it seems like you have people who are used to the clojure/cljs tooling who simply give up, and people who are used to the normal clr tooling, who have nothing new to document and they just work as usual
that's what it looks like from here at least, I've only played with clojure-clr lightly
it doesn't have its own package manager for example
people just use the standard clr tools, or do deps by hand(?)
you can of course use the executable to launch a repl (just like you can with jvm clojure), but most devs don't use that kind of workflow
maybe that's part of what makes getting into unity odd?
@bitpadawan the last time I saw the arcadia devs they were excited about a DSL for performant hot loop game code compiled from clojure
called "magic" iirc
but that's definitely not a newbie friendly project
you may be right, i haven't actually installed it yet, just poked around online. what confused me more was the unity-specific code examples, it's like it's assumed the reader already has done unity in c#
i sort of get the same vibe with cljs and react native, like you're supposed to know rn already and then things would make sense
@bitpadawan yeah, jvm clojure is slightly better about this, but Rich does talk about intentionally making a tool for people who are already experts, rather than one whose use is obvious to a beginner
which is definitely an unconventional approach these days
yes, the beginner-friendly documentation for clojnure has improved a lot over the last 1.5 yrs or so
when i got into it,most of it was very hard to follow
for a complete lisp beginner
right, but it's not just a question of docs, there's a series of architectural choices you make differently if your intended audience are beginners
like seamless platform interop - killer feature, not novice friendly at all
most languages hide it behind hard to use syntax on purpose IMHO
true,, i've learned more than i ever wanted about java already in order to expand my clojure horizons
the same thing seems to be shaping up now about js / cljs in the journey
yeah, it's really useful in terms of maximizing the time of the core team of devs, and making something that doesn't put a brick wall in your way once you need to do something a little odd
but it's also not newcomer friendly at all
it's the search space being so huge and so many tools from other environments that makes it difficult to pick up i think, when you don't already have the background knowledge
yup, agreed
frankly i've only stuck with it because i find clj/cljs so elegant
for a beginner it's harder than it should be, but it is what it is right now
the fact that i could in theory use clj/cljs to make mobile apps, desktop apps, backends, and SPAs/frontends is extremely appealing though
I think Clojure/Script occupies an unusual space: complete beginners can pick up the core language very easily but struggle with the ecosystem as a whole (regardless of the host platform) -- and experienced developers can pick up the ecosystem fairly easily but can struggle with idioms (depending on how much "bad OOP" is entrenched in their background).
it offers a great path to lead you forward to skill though (in my experience / opinion)
it contains the right things to bootstrap yourself into better decisions
fwiw, you oldtimers with the skills, don't be shy about writing tutorials .. 😛
the more the merrier 🙂
that's a good observation @seancorfield
Yes, and it can be a long, slow "climb". I was very familiar with the JVM when I got into Clojure a decade ago and even with past experience in FP and Lisp, it took me a long time to shake off decades of OOP practices and get comfortable with the idioms (I got started with C++ in '92 and Java in '97). And I'm still learning 🙂
@bitpadawan The difficulty for me in writing tutorials is that I find it very hard to know what I'm assuming for an audience of beginners -- I've had several folks tell me I seem to skip over a lot of stuff that's important to them 😐
Question on the canonical way to package a cljc library… I have a library I’m working on that is pure cljc with the exception of needing a priority map. My project.clj depends on org.clojure/data.priority-map in the main dependencies block and tailrecursion/cljs-priority-map in the :cljs profile and the code uses reader conditionals to bring in the right code. Upon deployment, the concept of profiles are gone - it’s just a jar. Is there a “right” way to declare dependencies in this case? I could see a few options: 1. Making both :provided and explicitly state in the docs that you must require the one you need depending on your deploy target. 2. Depend on the jvm version and mark the cljs one as provided. 3. Make the both required dependencies. In this case your jvm uberjar target would bring in the cljs version as well. Thoughts?
The dependencies you've mentioned here both seem pretty small which means I would lean towards option 3. For this particular case, it seems like the cost of including both dependencies is small (relatively small extra dependencies) and that the benefit of including both dependencies is reasonable (less setup, less documentation explaining how to get started). If the dependencies were larger, I think the other 2 options would be worth considering. However, I'm also interested in how other clojurians think about this.
Thanks for the advice. Think I’m gonna go with #3.
> it's a bit of an art @seancorfield , thinking with a beginners mind, putting yourself in their shoes and from the vantage point of experience, cover the distance .. from a certain point onwards, for example assuming the reader has at least mastered the basics of the language
@bitpadawan Yeah, not an art I've been able to master much, unfortunately. I'm better at writing documentation now than I used to be, but I'm not good at writing beginner-focused/introductory material...