This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-02
Channels
- # admin-announcements (1)
- # aws-lambda (9)
- # beginners (161)
- # boot (1)
- # cider (3)
- # cljsrn (36)
- # clojure (245)
- # clojure-austin (2)
- # clojure-denmark (3)
- # clojure-dev (11)
- # clojure-greece (6)
- # clojure-italy (25)
- # clojure-russia (5)
- # clojure-serbia (1)
- # clojure-spec (76)
- # clojure-uk (78)
- # clojurescript (168)
- # clojurex (4)
- # community-development (7)
- # core-async (11)
- # core-logic (5)
- # css (6)
- # cursive (8)
- # data-science (6)
- # datomic (5)
- # devops (4)
- # duct (17)
- # emacs (1)
- # figwheel (8)
- # fulcro (51)
- # hoplon (4)
- # instaparse (3)
- # kekkonen (6)
- # klipse (3)
- # lein-figwheel (9)
- # luminus (2)
- # lumo (3)
- # midje (4)
- # off-topic (11)
- # om (4)
- # onyx (62)
- # other-languages (60)
- # re-frame (21)
- # reagent (63)
- # rum (1)
- # shadow-cljs (22)
- # spacemacs (22)
- # specter (23)
- # test-check (2)
- # vim (2)
- # yada (6)
1. imagine I'm editing foo.clj
I can define a macro, and use it later in the same file
2. now, imagine I'm editing foo.cljc
and I define a macro, say via
#?(:cljs (defmacro ...))
now, I should be able to use this macro in foo.cljc
on the clojure side -- but is there anyway to also use it from the cljs side?
or does cljs absolutely require macros come from other namespaces, that are pure *.clj files ?
(binding [*out* /dev/null])
Obviously /dev/null isn't a thing in Clojure, but how to supress stdout? Forgot
possibly not. resulting string wouln't be colossal, still I'd like to learn the cleanest pattern
=> (binding [*out* (proxy [java.io.Writer] [] (append [& _]) (close []) (flush []) (write [& _]))] (println "hello, black hole"))
nil
https://stackoverflow.com/questions/29914967/can-cljc-single-file-macro-definitions-to-work-with-clojurescript <-- does this trick still work ? I'm getting 'macro not found from my cljs compilation'
I’m trying to find an article I read a while ago, told as a parable about a guy named Rich in the land of boxes, about how complex objects were and how simple composable tools could be more enjoyable
and my google-fu is failing me… so, does anyone know this piece and can remember the title?
That was one of Steve Yegge's big ol' rants... http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html
no, I very specifically remember it referring to objects as some kind of blocks or boxes, and a shout-out to Rich
you wouldn't happen to mean https://feierabendprojekte.wordpress.com/2017/04/13/a-parable/ would you?
hmm, is there a plan to have https://github.com/clojure/brew-install in a apt/yum repository?
hey folks - veteran c++ game engine programmer here, emacs hacker / elisp user, getting into clojure
I was thinking about trying to do some kind of music visualizer (think g-force / milkdrop / etc) - what's the best approach to get framebuffer access and / or shader access in clojure? thanks in advance!
@iwannaseethelight making a brower UI or desktop?
for ClojureScript you can use https://github.com/thi-ng/shadergraph to get easy GLSL access
@niklas.collin I'm just doing this for fun to learn the language - I love Lisp and its derivatives 🙂
yeah, well for ClojureScript and browsers there are several options out there, less so for Clojure
I'll take a look - I mostly wondered if Clojure would even be capable of something like this given its immutable state
In this particular case I'm just doing it for fun / learning - I build game engines for a living, it's definitely not the right language for graphics, but we'll see what it can do 😉
for the performance intensive mutable data stuff your code will end up looking an awful lot like java
I remember John Carmack rewrote Wolfenstein 3D in Haskell, it was pure madness
one could write a very efficient 3d engine with immutable data structures but only if the hardware drivers and APIs supported that properly
you can also check out https://github.com/ztellman/penumbra
which is no longer developed
but maybe as a way to get started
Thanks guys, I'll take a look - I have to run to a meeting, bbs
For this toy example I'm wondering if I can just modify a framebuffer directly and blit it to the screen
I think you can do that stuff with GLSL, accessing framebuffer that is. Been a while since I last did any GPU level coding 🙂
@niklas.collin yeah, getting to shaders through the browser may help, don’t need to write the interop yourself since there’s stuff in the browser already 🙂
on other GPU related, but not graphics, Dragan Djuric has done great work on getting the compute side of GPU’s available to Clojure with http://uncomplicate.org/
I'd like to parse clojure source file. What's the good way to do this?
Using clojure.tools.reader/read-string
gives me only the first namespace form:
(r/read-string (slurp "src/clojure_repl_experiments/experiments.clj"))
;;=> (ns
clojure-repl-experiments.experiments
(:require [clojure.set :as set] [criterium.core :as c] [seesaw.core :as see]))
What I'd like to get is the list of all forms in that source file@jumar because of clojure's evaluation model it's not generally possible to read a whole namespace w/o compiling each form as you go
altho since 1.9.0-alpha<something> (or by using tools.reader) there's ways to make this work, but it's still tricky
take a look at https://github.com/clojure/tools.analyzer.jvm
You guys might appreciate this https://cacm.acm.org/magazines/2017/10/221326-a-large-scale-study-of-programming-languages-and-code-quality-in-github/fulltext
that's odd. their data suggests typescript is more likely to contain bugs than unadorned js.
Yeah, real data has a way of messing up 'intuition' and theorizing...
IIRC, the .ts extensions would also match C++ projects as they are Qt translation files
there was a long twitter thread with critique about that study, but I’m failing to find it now
for example, I’m working on TS project at the moment, and we ran into an issue that was not TS’s fault, but the JS library that did not have a type file.
and because I commit often, I committed the buggy code, but fixed it later, before the PR was made. So in a study like this, that would appear as a bug.
Especially for languages that compile to JS, it won’t catch the edge cases when you try to interact with JS libraries
Of course there are issues with it - any such study is going to have issues. But at least it is actual data and not just sitting around making goofy claims
what would be a good/easy way to disable logging when running tests?
(using leiningen)
well also setting the level to WARN is enough (probably better)
in Python for example pytest captures all the logs during tests and only display the relevant logs in case of failure
@andrea.crotti depends how you're logging, logback supports a logback_test.xml for example.
which is quite handy
just using tools.logging at the moment
@iwannaseethelight take a look at https://github.com/oakes/play-clj, it's got bindings to OpenGL etc through libgdx. I've been using it for making arcade games.
@andrea.crotti apparently the fallback is java.util.logging if nothing else is found 🙂 so you'll have to figure out how to configure that for testing.
well in theory I just need (.setLevel (Logger/getRootLogger) Level/WARN)
the only question is where to hook that up
I have something like this for lein run
mm not sure I find anything useful there
unless I make a fixture for each test namespace that does that?
which is not very convenient
I'm trying to recreate an aot behavior I've accidentally seen before, I'd like to capture a couple of environment variables at build time, so I can use version data automatically. I'm on 1.9.0-beta3, perhaps aot capture changed a bit? I've just got
(def DESCRIBE (System/getenv "GIT_DESCRIBE"))
in a file that's in the :aot lein config for the uberjar profile (and is being aot compiled, going by the output. That value is interpreted at runtime, thoughwhoops, dropped this: )
Top-level def
s are run at namespace load time (so, essentially, runtime).
@seancorfield correct me if I'm wrong, but if you AOT, doesn't that make the load time earlier? (which is why you shouldn't (launch-missiles)
at the top level)
it certainly does sometimes, because it's been a pretty common confusing deployment issue. that's where I've encountered it in the past
It loads namespaces for AOT and for running -- so it will execute both times:
(! 510)-> lein uberjar
Compiling aotit.core
I'm a top-level form
Created /Users/sean/clojure/aotit/target/uberjar/aotit-0.1.0-SNAPSHOT.jar
Created /Users/sean/clojure/aotit/target/uberjar/aotit-0.1.0-SNAPSHOT-standalone.jar
Thu Nov 02 08:28:52
(sean)-(jobs:0)-(~/clojure/aotit)
(! 511)-> java -jar target/uberjar/aotit-0.1.0-SNAPSHOT-standalone.jar
I'm a top-level form
Hello, World!
That's with (def foo (println "I'm a top-level form"))
from https://clojure.org/guides/spec: Any existing Clojure function that takes a single argument and returns a truthy value is a valid predicate spec
string?
is a predicate, (s/spec string?)
is a spec that conforms to the string?
predicate
you can use keywords that represent spec definitions in lots of places that you can use specs and predicates, but not all (and specifically it seems not in s/spec?)
I'm hitting an anti-pattern often, and wonder if there is a better approach...
I write a function, fn-a
, that takes a map of parameters and does nothing with them but pass on to fn-b
.
It could be written as (defn fn-a [options] (fn-b options) ...)
But, I want to supply useful arglist info, so I write (defn fn-a [{:keys [param1 params2 params3] :as options}] (fn-b options) ...)
But, later, fn-b gains a few more parameters. My code continues to work, but my arglist is out of date.
sounds like a job for spec, or prismatic/schema
also, as Rich Hickey eloquently argues, it's good to have an open information model - specify the keys you need, but it should be OK if other things end up in there too
@noisesmith How? I see how I could use them for checking, but I'm looking for arglist as documentation.
the fact that the check passed in dev mode (even if turned off in prod) is more useful than pure documentation that isn't executable
if all you need is documentation, we have doc strings too
I can write (defn foo [{:keys [a b c d]}] ...) and pass it an empty map - clojure doesn't care
the a b c d there isn't any more informative than text in the doc string would be, nor is it more enforcible
That just begs the issue. I would still see the doc string of fn-a. But, really, the caller of fn-a needs to know the parameters of fn-b in order to effectively use the fn-a wrapper.
which is why an executable validation that can optionally be turned off is more useful
I'm not lookinf for enforcement in the question, I'm looking for, if you will, enlightenment.
why would a name that isn't enforced in an arg map be more enlightening than a string that isn't enforced in a doc string?
When I'm writing code in emacs, I want to do a quick C-c d d
to see what parameters to type.
But, that forces me to keep the doc-string or the parameters of fn-a in lockstep with fn-b.
sounds like an emacs problem - a doc string can give you a lot more nuance and information than names in a destructure can
and an optional validation verifies that the code you are using actually works that way
When, really, fn-a's mandate is, rightly "take whatever I get and pass it to fn-b, because I have no right to care"
I would much rather spend one second when I'm typing my code, rather than one minute later, when a runtime check finds a problem. (and that's even assuming that someone did the unlikely task of writing a run-time checker for misspelled parameters in a map).
spec and prismatic/schema can both warn you about such things, and can be turned off in production
Spec can, but not naturally. As you pointed out above "specify the keys you need, but it should be OK if other things end up in there too".
But, even that is not the point. I want auto-maintained arglist documentation that I can see when I'm writing code.
emacs 4 lyfe
What is a tasteful way to document a function whose mandate is to pass a map of parameters to deeper code? The user typically knows only about this function, but needs to see an accurate list of the parameters that it expects.
he already explicitly turned down using spec or schema for this
and doc string 😄
I feel like I've made my cases so won't belabor them here
You could abuse destructuring {:as foo :keys [...]} but that d be odd if you dont use them
(def ^{:arglists (-> (var map) (meta) (:arglists))} my-map (fn [f coll] (map f coll)))
#'boot.user/my-map
(doc my-map)
-------------------------
boot.user/my-map
([f] [f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])
nil
something like this could work?@deg this is also true for prismatic.schema/defn btw
+user=> (s/defn foo :- s/Num [] 42)
#'user/foo
+user=> (doc foo)
-------------------------
user/foo
([])
Inputs: []
Returns: s/Num
nil
`@sundarj Nice idea. But, currently, does not quite work in ClojureScript because there is an open bug in the handling of some arglists.
these tools are imperfect, but they really are designed with these issues in mind
Re spec, one problem is that this forces creating a name to describe this map. For a simple set of parameters used in only a few functions, this is a bit heavy.
if it's worth describing it's worth giving a name IMHO
Some people wrote macros to work around this. But ultimately you ll grow to like this (I did)
But, agreed, spec does the heavy lifting nicely for "big" cases. And, arglist spoofing covers the remaining cases, I guess.
why does it force you to create a name? (s/fdef my-fun :args (s/cat :the-arg-map (s/keys :req-un [::foo ::bar ::bash]))) is fine
how could you use it twice without assigning it to some sort of name for any solution? 0_o
In the code, I only need to use it once. fn-b requires me to list the parameters. fn-a only needs (defn fn-a [options] (fn-b options))
Right. I'm trying to avoid any need to list the options in or near fn-a, which may well be in a different file than fn-b.
@pelletier yes https://github.com/clojure/clojure/blob/master/test/clojure/test_clojure/genclass/examples.clj - you should be able to adapt this to gen-interface
oh - if you keep reading there's a gen-interface example in the same file haha!
My functions take exactly the same parameters as each other. Only fn-b cares about them in detail. fn-a is just an exposed surface wrapped around it.
imo you're working too hard to avoid duplication here. just
(s/def ::param-list (s/cat :opts-map (s/keys ...) :other-arg ...))
(s/fdef fn-a :args ::param-list)
(s/fdef fn-b :args ::param-list)
Yes, understood, and not terrible since the duplicated code can sit next to its copy. But, this still requires:
- Repeating the param list in both the spec and fn-b (admittedly, this is no worse than any other spec, so ok...)
- Creating the name ::param-list
-- Well, more likely ::fn-b-param-list
which, again, is not terrible but adds a bit of weight.
In short. Yes, this is a reasonable answer and about the best that can be done today (with the arguable exception of the meta :arglists hack above).
But, there is still a bit of a smell here that bothers me. Sorry that I obviously can't pin down my discomfort well enough... I'm clearly in the minority here. 🙂
fwiw, I don’t think your crazy. I’ve used libraries that have similar wrapper functions and I wish that they had gone through the trouble you’re going through so I can use my C-c d d
🙂. It seems @sundarj’s recommendation is a decent fix if it worked with cljs. It looks a lot like https://docs.python.org/2/library/functools.html#functools.wraps from python
I am using at-at to schedule some functions and want to persist the schedules (preferably to datomic) - is there anything that can help with that or any pointers ?
I have some macros in a clj file (no coresponding cljs file exists). I want to import these from some cljc files. Doing a normal :require in the cljc files fails, because the cljs namespace doesn't exist:
No such namespace: common.css, could not locate common/css.cljs, common/css.cljc, or JavaScript source providing "common.css" in file src/common/pages/timesheet.cljc
I could do them in a cljc file, but the macros require java stuff, so almost everything would be reader conditionaled to clj.
I managed to get it working with (:require-macros [common.css :as css])
, but I'm very confused, because as far as I know clj files don't recognize require-macros. Could someone explain?@len I'm sure it's possible (and I've done variations on it myself) but quartzite is made for this purpose http://clojurequartz.info/
@ghopper cljc files may be compiled as clojurescript or clojure, you are compiling it as clojurescript, so clojurescript features are there
thanks @noisesmith looks like thats the option
@hiredman Except it's being compiled as clojure as well without issue.
The error message was with the normal (:require), not the (:require-macros).
There isn't any error with :require-macros.
Shouldn't there be? When it's compile to clojure and it can't find the namespace, because it doesn't recognize the require-macros method?
Yeah, same way.
the error message can only come from compiling clojurescript, if you are loading them the same way then they are being compiled the same way, so both are being compiled as clojurescript ∎
Oh... you're right. It wasn't being compiled to clojure as well. It thows a ns doesn't comform error now.
So I need a reader conditional to switch between require-macros and require?
(ns hitch.selector
#?(:cljs (:require-macros hitch.selector))
(:require [hitch.oldprotocols :as oldproto]
[hitch.protocol :as proto]
[hitch.tracking.halt :as halt]
[hitch.selector-tx-manager]))
@dpsutton Well, the second require would be only for clj, since I don't have a cljs namespace of the macros namespace.
(ns common.core
#?(:clj
(:require [common.css :as css])
:cljs
(:require-macros [common.css :as css])))
How's that?
Can I have multiple (:require) calls in a ns?I suppose that works:
(ns common.core
(:require
...
#?(:clj [common.css :as css]))
#?(:cljs (:require-macros [common.css :as css])))
A bit uglyWhat does https://clojurescript.org/about/differences#_namespaces mean by "implicit macro loading". It's not clear to me how that's accomplished.
Is there anything I use to purposely return nil from a function's tail when there's a call at the tail returning something?
yeah, just put nil at the end
I’ve run into this occasionally and don’t know of any other solution
you could write a function and wrap the validate if that was nicer looking to you
Reminds me of actual Java code I saw once, 'if (c==null) return null else return c;'
(defmacro swallow [& body]
`(do ~@body nil))
then (swallow (s/validate …))
prob a simpler way to do that
if it’s always wrapping a single expression, you could just do (def swallow (constantly nil))
i guess i prefer this alternative with constantly
, most of the time it would be used for calls at the function's tail
I had a hunch that constantly obviates the need for a macro that creates a do form
+user=> (def foo (constantly :OK))
#'user/foo
+user=> (foo (println :a) (println :b) (println :c))
:a
:b
:c
:OK
I wonder if it still works for large arg lists
oh yeah, constantly creates a functions that accepts any number of arguments. that invalidates my argument to prefer it over the macro form
and even if you could figure out how to do it implicitly... it would still be expensive