Fork me on GitHub

Hello, have anyone here used iframe with two apps? I was trying to make this communication with postMessage, I tried to use but with no success I followed the docs and received this message: <tg://search_hashtag?hashtag=object|#object>[cljs.core.async.impl.channels.ManyToManyChannel] when I ran the command to send message but got no response on browser. Is there anything I can do to debug this problem? Or another way to solve this?


I am confused about the differences between Special Forms in Clojure and ClojureScript. While the ClojureScript docs at > state that:

The following ClojureScript special forms are identical to their Clojure cousins: if, do, let, letfn, quote, loop, recur, throw, and try.
… I have found via (doc let) in a ClojureScript REPL, that let is a Macro:
cljs.user=> (doc let)
([bindings & body])
 binding => binding-form init-expr

 Evaluates the exprs in a lexical context in which the symbols in
 the binding-forms are bound to their respective init-exprs or parts
The same seems to apply to letfn and loop as well. Can anyone here shed some light on this, please?


That should probably be considered an implementation detail. If you look at the source of let in Clojure it is also a macro:

dev=> (source let)
(defmacro let
  "binding => binding-form init-expr

  Evaluates the exprs in a lexical context in which the symbols in
  the binding-forms are bound to their respective init-exprs or parts
  {:added "1.0", :special-form true, :forms '[(let [bindings*] exprs*)]}
  [bindings & body]
     (vector? bindings) "a vector for its binding"
     (even? (count bindings)) "an even number of forms in binding vector")
  `(let* ~(destructure bindings) [email protected]))


(even tho' (doc let) says it is a special form)


letfn and loop are both macros in Clojure but, again, consider that an implementation detail -- and treat them as if they really are special forms.


@seancorfield Thank you for that. I guess my understanding of what constitutes a Special Form is a little misguided then — I took them to be “primitives” with different-from-usual Clojure evaluation rules, that could not be defined in terms of other primitives. 😕


it's not that they can't be defined in terms of other primitives, its that they aren't so defined. In a simple lisp this might be true for ease of construction but there's certainly no reason that when and if couldn't both be special forms. Also, its common for let to be a macro that expands to a closure invoked on the binding values but that can be quite slow in practice.


Thank you for the clarification. That makes sense now.


Digging a little more, it seems that there is a function called special-symbol? which says if a symbol is a Special Form, and via a Clojure REPL, I found the following interesting fact:

user=> (special-symbol? 'let)
user=> (special-symbol? 'let*)
So let* is a Special Form, and let is implemented as a Macro. I will probably need to go and read the source at


Morning everyone 🙂 I was just idly wondering what UI Libraries people are tending to go for with their Reagent / ReFrame apps these days, with options like ChakraUI, MaterialUI etc. gaining so much interest and support in the vanillaJS and TypeScript worlds I was keen to figure out what the CLJS “new hotness” is or might be and how much consensus there is on such things..?


I am huge fan of because composing tailwind classes feels a bit like composing fns from clojure.core but I don’t think it’s really a “new hotness” and did not see another CLJS project using it yet.


I'm pretty content with Material-UI and I use re-com for a couple of projects.


Thanks very much for the feedback - will add Tailwind to my research list for sure.


I am in the process of (slowly) developing my own, mostly for my own purposes:


That is an interesting angle as well @U4P4NREBY - thx 🙂


I’m trying to implement some ideas that have been floating in my head for a long time for making a UI toolkit that maps to the shape of Clojure data, that is more declarative in nature, and which can adapt to end user needs in various ways. At this point, it’s quite experimental, so I’m mostly just trying to see which directions I can take it in and how doable these things are in practice.


nods - An interesting set of challenges for sure 🙂


I've used Bulma in a couple of projects and been quite happy with it. I'd definitely look at something like Tailwind or Tachyons for a new project. I currently work on a project with 8000 lines of Clojure(Script) code, and it has 48 lines of SASS, most of which could possibly be removed. It really is a bliss not to have to maintain CSS separately.


I second Bulma - it’s a lovely thing if you don’t want to write any CSS, just use the classes and HTML structure they prescribe. It’s also JS-free, which is a plus. I’m too looking into Tailwind, though, for more control.


Hello i read that clojurescript has no :use ,i want to import all the names from a dsl. I can use (require :refer ) by hand or auto-generated. By hand its too many even if copy paste doesnt look nice,and auto-generated the IDE cant resolve the symbols. Any solution to auto-import the names,and visible to the IDE?


I'd been looking into it quite some time ago back when I was using Specter with CLJS. I ended up settling on (:require [com.rpl.specter :as s]) and using s/ namespace everywhere. In the end, I liked it enough to actually start using it in CLJ instead of :use.


thank you for the reply, but its not nice if nested calls 😞


and my dsl will have so many nested calls


In this case, you could write a macro that just transforms all call-like forms like (do-stuff ...) into (my-full-ns/do-stuff ...). You would still have to require my-full-ns though.


i dont know how to do that easily,my macro should have to find each call and rename it in the code


nested calls or even (apply myf ....) even harder


copy paste by hand i think i will go for now if no other solution ,and see in the future


That's just an opportunity to learn then. :) Your macro will have to wrap every top-level call to you library. So e.g. something like

    (my-lib/stuff args)))
could become
    (stuff args)))
(you'll just have to make sure to not use any names that are used by Clojure, like map and filter and whatnot).


thank you for your idea, i will save it as option,and when i solve bigger problems , i will re-check it

👍 3

I was thinking on what prefix I should give to specter. it deserves a single char abbrev. it deserves s, even spec already takes it.

Lauri Rutanen18:01:38

What is the typical way to structure a minimalistic project containing backend + frontend in one repository? Should I have separate entrypoints for frontend and backend?


If by entrypoints you mean directories in your src, then I'd say no.


1 git repo, 3 folders (1 for versions), 3 deps.edn (1 is versions); shared deps


FWIW I would say that it would be quite a complexity increase for what I perceive as a "minimalistic full-stack project". :)

Lauri Rutanen19:01:40

Thanks for answers! Based on your answers, I think I'll go with: • separate deps for frontend and backend (no shared) • frontend and backend have clean separation (ie. can be started/stopped separately, code & deps separated)

Fredrik Andersson19:01:05

I wonder how to "find" a entry in a array (vector?) by a value of a field in the entry

Fredrik Andersson19:01:47

in javascript i would write something like myarray.find(itm => === "hello")


In Clojure (first (filter predicate-function-here my-vector)) would do it.

Fredrik Andersson19:01:05

ah, didn't think about it that way


e.g. (first (filter #(= (:name %) "hello") my-vector))

Fredrik Andersson19:01:57

trying to get used to clojurescript little by little 🙂


And in case you are wondering, filter returns a lazy sequence, so while it might in some cases (due to a performance optimization called 'chunking') call the function on a few elements of my-vector after the first one that returns true, it will stop very soon after the first matching element.