This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-09-15
Channels
Hello! In coordination with the original authors, I am writing a Clojure Version of the legendary "Structure and Interpretation of Computer Programs" (SICP) since about one year. I expect to finish the first draft in a few months. Is anyone willing to review early versions? / Where should I ask this question? 🙂
I think https://clojureverse.org and clojure mailing list may also be good places to ask
I may be interested!
great! I add you as well
Me too, thanks.
Me too!
i would love to review it ...just recently started reading SICP, but would be fun to do it in clojure 🙂
I will notify you on the progress 👍
For a while now. Is the next question, how I handled TCO in Chapter 1.2? 😅
By coincidence, I am totally enjoying the MIT course on this right now https://www.youtube.com/playlist?list=PLE18841CABEA24090
did you see the Readings section of the ocw. It provides a link between the videos and the book. Its great! https://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-001-structure-and-interpretation-of-computer-programs-spring-2005/readings/
Hey guys, I want to extend a protocol I have for some classes in case the person who loaded my library loaded also some other library
I used (Class/forName ...
to check if the other library is present
but the problem is that my (extend-protocol
sentence has direct references to the classes
which fails to compile
@roklenarcic you'll need to use a macro, clojure.core has examples of doing this.
it's called "when-class" and is private, but you could copy the implementation yourself.
I've noticed that generally (not= (class (reify)), (class (reify)))
. I find this desirable behavior.
However, certain contrived reify returned by a defn always returns the same class. It's as if the underlying reify's class was cached.
Wondering what triggers this and how to control it?
I haven't seen anything in reify's doc string that mentions the class of the returned objects, so it seems to promise nothing in that regard. Did you see anything about it?
Funnily enough, the docstring doesn't say what reify is/does at all 🙂 I've always taken it as "make a class+object in runtime", but yeah, sure, there's no such contract.
I suspect if it had a sentence or three added saying what it does (yes, weird that is not there), it might be "make an object", but not mentioning class.
@emccue yes, but evaled code cannot access the let
bindings. I tried to hack it with binding
, but the bindings will be gone after reify
evaluation (i.e., reify methods cannot access the eval-time binding)
The class returned by reify is generated at compile time, functions compiled once and invoked multiple times, so the class will always be the same
The class returned by reify is generated at compile time, functions compiled once and invoked multiple times, so the class will always be the same
is the ^int
type tag deprecated in favor of ^long
?
user=> (defn foo [^int x])
Syntax error (IllegalArgumentException) compiling fn* at (REPL:1:1).
Only long and double primitives are supported
I would say that it's not deprecated, since you still can need ^int
for avoiding reflection elsewhere
defn
primitive annotation has the stated constraint (`Only long and double primitives are supported`). That doesn't deprecate all the entries you can see in https://clojure.org/reference/java_interop#TypeAliases
It is still mentioned here: https://clojure.org/reference/java_interop#TypeAliases
and as primitive return types.
and although the docs are a little lacking on this minor detail, you can only get in compiled code long or double primitives for loop-bound symbols. If you try to make it int, you get long instead. If you try to make it float, you get double instead.
The same as there always have been @emccue 🙂
It's "OK" to do AOT on everything as the last step when building an uberjar if you want the startup time improvement it can bring, but most other cases can introduce problems so it's best avoided unless you must do some AOT (`gen-class` for example).
And even for gen-class
, the advice I seem to hear most is "use a Java shim instead" if you can (and use Clojure's "Java API" from that shim to load Clojure code).
I have one project that relies on gen-class
for one namespace and that has no dependencies outside clojure.core
and clojure.string
, and my deps.edn
file looks like this
{:deps {org.clojure/clojure {:mvn/version "1.8.0"}}
:paths ["classes" "src"]
:aliases
{:compile {:main-opts ["-e" "(compile,'cfml.struct)"]}
:test {:extra-paths ["test"]
:extra-deps {expectations/clojure-test {:mvn/version "1.1.1"}
org.clojure/test.check {:mvn/version "0.10.0-RC1"}}}
:runner {:extra-deps {com.cognitect/test-runner
{:git/url ""
:sha "3cb0a9daf1cb746259dc8309b218f9211ad3b33b"}}
:main-opts ["-e" "(compile,'cfml.struct)"
"-m" "cognitect.test-runner"
"-d" "test"]}
:build {:extra-deps {seancorfield/depstar {:mvn/version "0.2.3"}}
:main-opts ["-e" "(compile,'cfml.struct)"
"-m" "hf.depstar.jar" "cfml-interop.jar"]}}}
so it explicitly compiles that one ns for each top-level path in the aliases.(it's an implementation of clojure.lang.APersistentMap
that has case-insensitive keys... because CFML...)