This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-01-11
Channels
- # aleph (38)
- # announcements (6)
- # aws (1)
- # beginners (47)
- # calva (21)
- # cider (47)
- # cljs-dev (18)
- # clojure (40)
- # clojure-europe (7)
- # clojure-india (2)
- # clojure-italy (9)
- # clojure-nl (11)
- # clojure-norway (2)
- # clojure-sanfrancisco (1)
- # clojure-spec (17)
- # clojure-sweden (2)
- # clojure-uk (73)
- # clojurescript (10)
- # cursive (6)
- # datascript (12)
- # datavis (2)
- # defnpodcast (1)
- # duct (5)
- # emacs (36)
- # figwheel (2)
- # figwheel-main (10)
- # juxt (12)
- # leiningen (1)
- # midje (1)
- # nrepl (9)
- # off-topic (25)
- # pedestal (3)
- # portkey (3)
- # quil (2)
- # re-frame (45)
- # reagent (1)
- # ring (3)
- # ring-swagger (36)
- # rum (1)
- # shadow-cljs (48)
- # spacemacs (1)
- # speculative (50)
- # testing (2)
- # tools-deps (27)
- # yada (4)
Is it a know bug/limitation? (works on clojure, but not in clojurescript)
I searched in jira but I did not find anything.
In cljs throws Can't recur here at line 1 <cljs repl> {:file "<cljs repl>", :line 1, :column 73, :root-source-info {:source-type :fragment, :source-form (myloop [] (recur))}, :tag :cljs/analysis-error}
clj -Srepro -Sdeps '{:deps {org.clojure/clojure {:mvn/version "1.10.0"} org.clojure/clojurescript {:mvn/version "1.10.439"}}}' -m cljs.main --repl-env node -e '(defmacro myloop [bindings & body] `(loop ~bindings ~@body)) (myloop [] (recur))'
@souenzzo You aren't getting a macro, but a function there. So, in Clojure it would essentially be like
user=> (defn foo [x & y] 1)
#'user/foo
user=> (foo [] (recur))
Syntax error (UnsupportedOperationException) compiling recur at (REPL:1:9).
Can only recur from tail position
I don't know if this is a good idea, but I started thinking "what if clojure.core.protocols/coll-reduce
was extendable via metadata"?
All the sequence functions in core - when used in a reduce - could get called as transducers. Allowing us to write code that nest sequence functions instead of explicitly calling functions that take transducers, and still get the benefits of transducers...?
See this implementation of map:
(defn map
([f]
;; transducer implementation
)
([f coll]
(with-meta
(lazy-seq
(when-let [s (seq coll)]
(cons (f (first s)) (map f (rest s)))))
;; Implementing coll-reduce via metadata.
{`p/coll-reduce
(fn [_ rf init]
(reduce ((map f) rf) init coll))})))
Implementing coll-reduce
would look similarly for filter, partition, et. al.
Now think about the how the code (reduce + 0 (map inc (filter even? (range 10))))
would get called. More on this in the thread.The transducers would compose.
Example:
The form:
(reduce + 0 (map inc (filter even? (range 10))))
would reduce over the collection returned from range
as:
reduce
would call coll-reduce on the value returned from map
via metadata,
-> map's reduce call would call coll-reduce on value returned from filter
via metadata,
-> filter's reduce call would call reduce on the coll (range 10)
.
I don't know if there's any real performance gain here, but it should avoid allocating all the extra collections when they are being reduced over. It'd be fun to test this against the coal-mine :man-shrugging:
I find the coll-reduce
version of concat
oddly satisfying for some reason 🙂
(defn concat
([])
([x])
([x y])
([x y & zs]
(let [cat-fn (fn [xys zs]
;;; cat impl..
)]
(with-meta
(cat-fn (concat x y) zs)
;; implementing concat with reduce
{`p/coll-reduce
(fn [_ rf init]
(reduce (cat rf) init [x y (eduction cat zs)]))}))))
I think reduce is too performance-sensitive to use the metadata extension
^ That's what I wonder too, whether adding the ability to implement coll-reduce
via metadata would decrease performance too much.
you’re just taking the generic seq implementation that already exists in coll-reduce and copying it over N functions with a slower dispatch mechanism
that seems worse in two dimensions
and better in none
well I guess it’s not the same implementation since you’re using the transducer
but I think you’re changing how the system works in ways that could be subtly surprising
I took a stab at documenting the new "Truthy-Induced" Inference feature that landed: https://github.com/clojure/clojurescript-site/blob/news-next/content/news/2019-01-04-release.adoc#truthy-induced-inference
The examples really helped me understand what this meant. Nice! I think there's a typo in this sentence:
meaning that the either a number of nil can be returned.
where it should be "number or nil", instead of "of". And remove the "the", making it:
meaning that either a number or nil can be returned.