diff --git a/content/guides/async_walkthrough.adoc b/content/guides/async_walkthrough.adoc index 3b0cdf7f..6f084f49 100644 --- a/content/guides/async_walkthrough.adoc +++ b/content/guides/async_walkthrough.adoc @@ -18,7 +18,7 @@ To use core.async, declare a dependency on Clojure 1.10.0 or higher and the late [source, clojure] ---- {:deps - {org.clojure/clojure {:mvn/version "1.11.3"} + {org.clojure/clojure {:mvn/version "1.12.0"} org.clojure/core.async {:mvn/version "1.6.673"}}} ---- diff --git a/content/guides/deps_and_cli.adoc b/content/guides/deps_and_cli.adoc index f1932944..800f58f6 100644 --- a/content/guides/deps_and_cli.adoc +++ b/content/guides/deps_and_cli.adoc @@ -34,7 +34,7 @@ After you download and install the tools, you can start a REPL by running the `c [source,shell] ---- $ clj -Clojure 1.11.3 +Clojure 1.12.0 user=> ---- @@ -75,7 +75,7 @@ Restart the REPL with the `clj` tool: $ clj Downloading: clojure/java-time/clojure.java-time/1.1.0/clojure.java-time-1.1.0.pom from clojars Downloading: clojure/java-time/clojure.java-time/1.1.0/clojure.java-time-1.1.0.jar from clojars -Clojure 1.11.3 +Clojure 1.12.0 user=> (require '[java-time.api :as t]) nil user=> (str (t/instant)) @@ -271,7 +271,7 @@ Apply that classpath modification and examine the modified classpath by invoking $ clj -A:test -Spath test: src: -/Users/me/.m2/repository/org/clojure/clojure/1.11.3/clojure-1.11.3.jar: +/Users/me/.m2/repository/org/clojure/clojure/1.12.0/clojure-1.12.0.jar: ... same as before (split here for readability) ---- @@ -326,7 +326,7 @@ It can be helpful to experiment with a library without adding it to an existing [source,bash] ---- $ clojure -Sdeps '{:deps {org.clojure/core.async {:mvn/version "1.5.648"}}}' -Clojure 1.11.3 +Clojure 1.12.0 user=> (require '[clojure.core.async :as a]) nil ---- @@ -370,7 +370,7 @@ You can then tell the CLI to prep using this command (this is a 1-time action fo $ clj -X:deps prep Prepping io.github.puredanger/cool-lib in /Users/me/demo/needs-prep $ clj -Clojure 1.11.3 +Clojure 1.12.0 user=> ---- @@ -520,7 +520,7 @@ To https://clojure.github.io/tools.deps.cli/clojure.tools.deps.cli.api-api.html# ---- % clj -X:deps list clojure.java-time/clojure.java-time 1.1.0 (MIT) -org.clojure/clojure 1.11.3 (EPL-1.0) +org.clojure/clojure 1.12.0 (EPL-1.0) org.clojure/core.specs.alpha 0.2.62 (EPL-1.0) org.clojure/spec.alpha 0.3.218 (EPL-1.0) time-lib/time-lib ../cli-getting-started/time-lib @@ -533,7 +533,7 @@ If you want to understand the https://clojure.github.io/tools.deps.cli/clojure.t [source,shell] ---- % clj -X:deps tree -org.clojure/clojure 1.11.3 +org.clojure/clojure 1.12.0 . org.clojure/spec.alpha 0.3.218 . org.clojure/core.specs.alpha 0.2.62 time-lib/time-lib /Users/alex.miller/tmp/cli-getting-started/time-lib diff --git a/content/guides/install_clojure.adoc b/content/guides/install_clojure.adoc index 889ae5e1..cafc870f 100644 --- a/content/guides/install_clojure.adoc +++ b/content/guides/install_clojure.adoc @@ -15,7 +15,7 @@ Clojure (the language) is provided as a Java ARchive (JAR) file, available in th This page concerns the command-line tool (the Clojure CLI). This tool (used by the commands `clojure` and `clj`) can download Clojure itself and other Clojure or JVM-based libraries. **Any version of the Clojure CLI can download or use any version of the Clojure language itself (they are independent).** -The version numbers of the language and the CLI are separate but related. The Clojure language has a 3 part-version (like `1.11.3`) and the Clojure CLI has a 4-part version (like `1.11.3.1456`). The leading 3 parts of the CLI version indicate which version of the Clojure language will be used by default in a REPL, unless you specify otherwise in the <> configuration file. +The version numbers of the language and the CLI are separate but related. The Clojure language has a 3 part-version (like `1.12.0`) and the Clojure CLI has a 4-part version (like `1.12.0.1456`). The leading 3 parts of the CLI version indicate which version of the Clojure language will be used by default in a REPL, unless you specify otherwise in the <> configuration file. == Mac OS instructions diff --git a/content/guides/spec.adoc b/content/guides/spec.adoc index 7a7cc651..80a59d48 100644 --- a/content/guides/spec.adoc +++ b/content/guides/spec.adoc @@ -17,7 +17,7 @@ To use spec, declare a dependency on Clojure 1.9.0 or higher: [source, clojure] ---- -[org.clojure/clojure "1.11.3"] +[org.clojure/clojure "1.12.0"] ---- To start working with spec, require the `clojure.spec.alpha` namespace at the REPL: diff --git a/content/news/2024/09/05/clojure-1-12-0.adoc b/content/news/2024/09/05/clojure-1-12-0.adoc new file mode 100644 index 00000000..771d4224 --- /dev/null +++ b/content/news/2024/09/05/clojure-1-12-0.adoc @@ -0,0 +1,165 @@ += Clojure 1.12.0 +Alex Miller +2024-09-05 +:jbake-type: post + +Clojure 1.12.0 is now available! Find download and usage information on the <> page. + +## 1 Compatibility + +### 1.1 Java 8 - Compatiblity EOL notice + +Clojure 1.12 produces Java 8 bytecode (same as Clojure 1.10 and 1.11), but this is expected to be the last release using a Java 8 baseline. Future releases will move the bytecode and minimum Java compatibility to a newer Java LTS release. + +### 1.2 Java 21 - Virtual thread pinning from user code under `synchronized` + +Clojure users want to use virtual threads on JDK 21. Prior to 1.12, Clojure lazy-seqs and delays, in order to enforce run-once behavior, ran user code under synchronized blocks, which as of JDK 21 don't yet participate in cooperative blocking. Thus if that code did e.g. blocking I/O it would pin a real thread. JDK 21 may emit warnings for this when using `-Djdk.tracePinnedThreads=full`. + +To avoid this pinning, in 1.12 `lazy-seq` and `delay` use locks instead of synchronized blocks. + +### 1.3 Security + +Fix https://nvd.nist.gov/vuln/detail/CVE-2024-22871[CVE-2024-22871] detailed in https://github.com/advisories/GHSA-vr64-r9qj-h27f[GHSA-vr64-r9qj-h27f]: + +### 1.4 Serialization + +https://clojure.atlassian.net/browse/CLJ-1327[CLJ-1327] explicitly sets the Java serialization identifier for the classes in Clojure that implement Java serialization. In Clojure 1.11.0 this changed for two classes unnecessarily and we reverted those changes in Clojure 1.11.1 - this completes that work for the rest of the classes. + +Clojure data types have implemented the Java serialization interfaces since Clojure 1.0. Java serialization is designed to save graphs of Java instances into a byte stream. Every class has an identifier (the serialVersionUID) that is automatically generated based on the class name, it's type hierarchy, and the serialized fields. At deserialization time, deserialization can only occur when the available class has an identifier that matches the class id recorded in the serialized bytes. + +Clojure has never provided a guarantee of serialization consistency across Clojure versions, but we do not wish to break compatibility any more than necessary and these changes will give us more control over that in the future. + +### 1.5 Dependencies + +Updated dependencies: + +* spec.alpha dependency to 0.5.238 - https://github.com/clojure/spec.alpha/blob/master/CHANGES.md[changes] +* core.specs.alpha dependency to 0.4.74 - https://github.com/clojure/core.specs.alpha/blob/master/CHANGES.md[changes] + +## 2 Features + +[[add_libs]] +### 2.1 Add libraries for interactive use + +There are many development-time cases where it would be useful to add a library interactively without restarting the JVM - speculative evaluation, adding a known dependency to your project, or adding a library to accomplish a specific task. + +Clojure now provides <>, without restarting the JVM or losing the state of your work: + +* https://clojure.github.io/clojure/branch-master/clojure.repl-api.html#clojure.repl.deps/add-lib[add-lib] takes a lib that is not available on the classpath, and makes it available by downloading (if necessary) and adding to the classloader. Libs already on the classpath are not updated. If the coordinate is not provided, the newest Maven or git (if the library has an inferred git repo name) version or tag are used. +* https://clojure.github.io/clojure/branch-master/clojure.repl-api.html#clojure.repl.deps/add-libs[add-libs] is like `add-lib`, but resolves a set of new libraries and versions together. +* https://clojure.github.io/clojure/branch-master/clojure.repl-api.html#clojure.repl.deps/sync-deps[sync-deps] calls `add-libs` with any libs present in deps.edn, but not yet present on the classpath. + +These new functions are intended only for development-time interactive use at the repl - using a deps.edn is still the proper way to build and maintain production code. To this end, these functions all check that https://clojure.github.io/clojure/branch-master/clojure.core-api.html#clojure.core/%2Arepl%2A[\*repl*] is bound to true (that flag is bound automatically by `clojure.main/repl`). In a clojure.main REPL, these new functions are automatically referred in the `user` namespace. In other repls, you may need to `(require '[clojure.repl.deps :refer :all])` before use. + +Library resolution and download are provided by https://github.com/clojure/tools.deps[tools.deps]. However, you do not want to add tools.deps and its many dependencies to your project classpath during development, and thus we have also added a new api for invoking functions out of process via the Clojure CLI. + +[[tool_functions]] +### 2.2 Invoke tool functions out of process + +There are many useful tools you can use at development time, but which are not part of your project's actual dependencies. The Clojure CLI provides explicit support for https://clojure.org/reference/clojure_cli#tools[tools] with their own classpath, but there was not previously a way to invoke these interactively. + +Clojure now includes https://clojure.github.io/clojure/branch-master/clojure.tools.deps.interop-api.html#clojure.tools.deps.interop/invoke-tool[clojure.tools.deps.interop/invoke-tool] to invoke a tool function out of process. The classpath for the tool is defined in deps.edn and you do not need to add the tool's dependencies to your project classpath. + +`add-lib` functionality is built using `invoke-tool` but you can also use it to build or invoke your own tools for interactive use. Find more about the function execution protocol on the https://clojure.org/reference/clojure_cli#function_protocol[CLI reference]. + +### 2.3 Start and control external processes + +For a long time, we've had the `clojure.java.shell` namespace, but over time Java has provided new APIs for process info, process control, and I/O redirection. This release adds a new namespace https://clojure.github.io/clojure/branch-master/index.html#clojure.java.process[clojure.java.process] that takes advantage of these APIs and is easier to use. See: + +* https://clojure.github.io/clojure/branch-master/clojure.java.process-api.html#clojure.java.process/start[start] - full control over streams with access to the underlying Java objects for advanced usage +* https://clojure.github.io/clojure/branch-master/clojure.java.process-api.html#clojure.java.process/exec[exec] - covers the common case of executing an external process and returning its stdout on completion + +[[method_values]] +### 2.4 Method values + +Clojure programmers often want to use Java methods in higher-order functions (e.g. passing a Java method to `map`). Until now, programmers have had to manually wrap methods in functions. This is verbose, and might require manual hinting for overload disambiguation, or incur incidental reflection or boxing. + +Programmers can now use <> as ordinary functions in value contexts - the compiler will <>. The compiler will generate a reflective call when a qualified method does not resolve due to overloading. Developers can supply <> metadata on qualified methods to specify the signature of a single desired method, 'resolving' it. + +[[qualified_methods]] +### 2.5 Qualified methods - `Class/method`, `Class/.method`, and `Class/new` + +Java members inherently exist in a class. For method values we need a way to explicitly specify the class of an instance method because there is no possibility for inference. + +Qualified methods have value semantics when used in non-invocation positions: + +* `Classname/method` - value is a Clojure function that invokes a static method +* `Classname/.method` - value is a Clojure function that invokes an instance method +* `Classname/new` - value is a Clojure function that invokes a constructor + +Note: developers must use `Classname/method` and `Classname/.method` syntax to differentiate between static and instance methods. + +Qualified method invocations with #26-param-tags-metadata[param-tags] use only the tags to resolve the method. Without param-tags they behave like the equivalent https://clojure.org/reference/java_interop#_the_dot_special_form[dot syntax], except the qualifying class takes precedence over hints of the target object, and over its runtime type when invoked via reflection. + +Note: Static fields are values and should be referenced without parens unless they are intended as function calls, e.g `(System/out)` should be `System/out`. Future Clojure releases will treat the field's value as something invokable and invoke it. + +[[param-tags]] +### 2.6 :param-tags metadata + +When used as values, qualified methods supply only the class and method name, and thus cannot resolve overloaded methods. + +Developers can supply <> metadata on qualified methods to specify the signature of a single desired method, 'resolving' it. The `:param-tags` metadata is a vector of zero or more tags: `[tag ...]`. A tag is any existing valid `:tag` metadata value. Each tag corresponds to a parameter in the desired signature (arity should match the number of tags). Parameters with non-overloaded types can use the placeholder `_` in lieu of the tag. When you supply :param-tags metadata on a qualified method, the metadata must allow the compiler to resolve it to a single method at compile time. + +A new metadata reader syntax `^[tag ...]` attaches `:param-tags` metadata to member symbols, just as `^tag` attaches `:tag` metadata to a symbol. + +### 2.7 Array class syntax + +Clojure supports symbols naming classes both as a value (for class object) and as a type hint, but has not provided syntax for array classes other than strings. + +Developers can now refer to an <> using a symbol of the form `ComponentClass/#dimensions`, eg `String/2` refers to the class of a 2 dimensional array of Strings. Component classes can be fully-qualified classes, imported classes, or primitives. Array class syntax can be used as both type hints and values. + +Examples: `String/1`, `java.lang.String/1`, `long/2`. + +### 2.8 Functional interfaces + +Java programs emulate functions with Java functional interfaces (marked with the https://docs.oracle.com/javase/8/docs/api/java/lang/FunctionalInterface.html[@FunctionalInterface] annotation), which have a single method. + +Clojure developers can now invoke Java methods taking <> by passing functions with matching arity. The Clojure compiler implicitly converts Clojure functions to the required functional interface by constructing a lambda adapter. You can explicitly coerce a Clojure function to a functional interface by hinting the binding name in a `let` binding, e.g. to avoid repeated adapter construction in a loop, e.g. `(let [^java.util.function.Predicate p even?] ...)`. + +### 2.9 Java Supplier interop + +Calling methods that take a https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html[Supplier] (a method that supplies a value) had required writing an adapter with reify. Clojure has a "value supplier" interface with semantic support already - `IDeref`. All `IDeref` impls (`delay`, `future`, `atom`, etc) now implement the `Supplier` interface directly. + +### 2.10 Streams with seq, into, reduce, and transduce support + +Java APIs increasingly return https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html[Stream]s and are hard to consume because they do not implement interfaces that Clojure already supports, and hard to interop with because Clojure doesn't directly implement Java functional interfaces. + +In addition to functional interface support, Clojure <> to interoperate with streams in an idiomatic manner, all functions behave analogously to their Clojure counterparts: + +* `(stream-seq! stream) => seq` +* `(stream-reduce! f [init-val] stream) => val` +* `(stream-transduce! xf f [init-val] stream) => val` +* `(stream-into! to-coll [xf] stream) => to-coll` + +All of these operations are terminal stream operations (they consume the stream). + +### 2.11 PersistentVector implements Spliterable + +Java collections implement streams via https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html["spliterators"], iterators that can be split for faster parallel traversal. `PersistentVector` now provides a custom spliterator that supports parallelism, with greatly improved performance. + +### 2.12 Efficient drop and partition for persistent or algorithmic collections + +Partitioning of a collection uses a series of takes (to build a partition) and drops (to skip past that partition). https://clojure.atlassian.net/browse/CLJ-2713[CLJ-2713] adds a new internal interface (IDrop) indicating that a collection can drop more efficiently than sequential traversal, and implements that for persistent collections and algorithmic collections like `range` and `repeat`. These optimizations are used in `drop`, `nthrest`, and `nthnext`. + +Additionally, there are new functions `partitionv`, `partitionv-all`, and `splitv-at` that are more efficient than their existing counterparts and produce vector partitions instead of realized seq partitions. + +### 2.13 Var interning policy + +https://clojure.org/reference/vars#interning[Interning] a var in a namespace (vs aliasing) must create a stable reference that is never displaced, so that all references to an interned var get the same object. There were some cases where interned vars could get displaced and those have been tightened up in 1.12.0-alpha1. If you encounter this situation, you'll see a warning like "REJECTED: attempt to replace interned var #'some-ns/foo with #'other-ns/foo in some-ns, you must ns-unmap first". + +This addresses the root cause of an issue encountered with Clojure 1.11.0, which added new functions to clojure.core (particularly `abs`). Compiled code from an earlier version of Clojure with var names that matched the newly added functions in clojure.core would be unbound when loaded in a 1.11.0 runtime. In addition to https://clojure.atlassian.net/browse/CLJ-2711[CLJ-2711], we rolled back a previous fix in this area (https://clojure.atlassian.net/browse/CLJ-1604[CLJ-1604]). + +## Detailed changelog + +See the https://github.com/clojure/clojure/blob/master/changes.md#changes-to-clojure-in-version-1120[official changelog] for a complete list of all changes in 1.12.0. + +## Contributors + +Thanks to all the community members who contributed patches to Clojure 1.12: + +* Ambrose Bonnaire-Sergeant +* Christophe Grand +* Frank Yin +* Nicola Mometto +* Ray McDermott +* Steve Miner diff --git a/content/reference/java_interop.adoc b/content/reference/java_interop.adoc index 5c18776b..5f26dade 100644 --- a/content/reference/java_interop.adoc +++ b/content/reference/java_interop.adoc @@ -455,6 +455,7 @@ Since Clojure 1.12, all `IDeref` impls (`delay`, `future`, `atom`, etc) implemen * Many people seem to presume only the unchecked- ops do primitive arithmetic - not so. When the args are primitive locals, regular + and * etc do primitive math with an overflow check - fast _and_ safe. * So, the simplest route to fast math is to leave the operators alone and just make sure the source literals and locals are primitive. Arithmetic on primitives yields primitives. If you've got a loop (which you probably do if you need to optimize) make sure the loop locals are primitives first - then if you accidentally are producing a boxed intermediate result you'll get an error on recur. Don't solve that error by coercing your intermediate result, instead, figure out what argument or local is not primitive. +[[streams]] == Java Stream Support Clojure collections implement the Java collection interfaces, which provide https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html[Stream] and https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html[Spliterator] access. Clojure persistent vectors implement a custom Spliterator that supports parallel streams. diff --git a/content/reference/repl_and_main.adoc b/content/reference/repl_and_main.adoc index df5d5662..fe04ba6d 100644 --- a/content/reference/repl_and_main.adoc +++ b/content/reference/repl_and_main.adoc @@ -54,7 +54,7 @@ The simplest way to launch a Clojure _repl_ is to use the < ---- diff --git a/content/releases/download_key.adoc b/content/releases/download_key.adoc index f9fba025..e0f5405e 100644 --- a/content/releases/download_key.adoc +++ b/content/releases/download_key.adoc @@ -14,21 +14,21 @@ A typical url in Maven Central will look something like: [source] ---- -https://repo1.maven.org/maven2/org/clojure/clojure/1.11.3/clojure-1.11.3.jar +https://repo1.maven.org/maven2/org/clojure/clojure/1.12.0/clojure-1.12.0.jar ---- Your dependency manager / build tool will download that file to your local Maven cache, usually: [source] ---- -~/.m2/repository/org/clojure/clojure/1.11.3/clojure-1.11.3.jar +~/.m2/repository/org/clojure/clojure/1.12.0/clojure-1.12.0.jar ---- You can append .asc to any jar or pom url in Maven to obtain the signature for that file: [source] ---- -curl -O https://repo1.maven.org/maven2/org/clojure/clojure/1.11.3/clojure-1.11.3.jar.asc +curl -O https://repo1.maven.org/maven2/org/clojure/clojure/1.12.0/clojure-1.12.0.jar.asc ---- == Verification @@ -42,7 +42,7 @@ The Clojure key used to sign all jars is registered in the MIT key server (pgp.m You can check this by verifying the jar with the signature: ---- -$ gpg --verify clojure-1.11.3.jar.asc ~/.m2/repository/org/clojure/clojure/1.11.3/clojure-1.11.3.jar +$ gpg --verify clojure-1.12.0.jar.asc ~/.m2/repository/org/clojure/clojure/1.12.0/clojure-1.12.0.jar gpg: Signature made Thu Jun 6 08:43:47 2019 CDT gpg: using RSA key 8D06684A958AE602 gpg: Good signature from "Clojure/core (build.clojure.org Release Key version 2) " [unknown] diff --git a/content/releases/downloads.adoc b/content/releases/downloads.adoc index 88197dfd..8d93c2c6 100644 --- a/content/releases/downloads.adoc +++ b/content/releases/downloads.adoc @@ -15,7 +15,7 @@ These tools allow you to start a REPL for interactive use, download Clojure libr ==== [[stable]] -== Stable Release: 1.11.4 (Aug 3, 2024) +== Stable Release: 1.12.0 (Sep 5, 2024) Include the release in your project using the following coordinates: @@ -23,24 +23,24 @@ deps.edn coordinate: [source,clojure] ---- -org.clojure/clojure {:mvn/version "1.11.4"} +org.clojure/clojure {:mvn/version "1.12.0"} ---- Leiningen dependency: [source,clojure] ---- -[org.clojure/clojure "1.11.4"] +[org.clojure/clojure "1.12.0"] ---- === Dependencies -Clojure 1.11.4 depends on the following core libraries: +Clojure 1.12.0 depends on the following core libraries: - * `org.clojure/spec.alpha {:mvn/version "0.3.218"}` (https://repo1.maven.org/maven2/org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar[jar]) - * `org.clojure/core.specs.alpha {:mvn/version "0.2.62"}` (https://repo1.maven.org/maven2/org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar[jar]) + * `org.clojure/spec.alpha {:mvn/version "0.5.238"}` (https://repo1.maven.org/maven2/org/clojure/spec.alpha/0.5.238/spec.alpha-0.5.238.jar[jar]) + * `org.clojure/core.specs.alpha {:mvn/version "0.4.74"}` (https://repo1.maven.org/maven2/org/clojure/core.specs.alpha/0.4.74/core.specs.alpha-0.4.74.jar[jar]) -Including Clojure with a tool like `clj` or `Leiningen` will automatically include these libraries as transitive dependencies. +Using Clojure with a tool like the Clojure CLI or Leiningen will automatically include these libraries as transitive dependencies. === Java compatibility @@ -55,8 +55,9 @@ Clojure depends on Java and all Clojure code is compiled to Java 8 compatible by Read the https://github.com/clojure/clojure/blob/master/changes.md[Changelog] for detailed release information. [[dev]] -== Development Release: 1.12.0-rc2 (Aug 28, 2024) +== Development Release: none +//// Include the release in your project using the following coordinates: deps.edn coordinate: @@ -79,6 +80,7 @@ Leiningen dependency: ** `org.clojure/spec.alpha {:mvn/version "0.5.238"}` ** `org.clojure/core.specs.alpha {:mvn/version "0.4.74"}` * Requirements: Java 8 or higher (recommended: Java 8, Java 11, Java 17, Java 21) +//// == Older Releases @@ -86,7 +88,7 @@ Leiningen dependency: == Clojure Source -Clojure source code is hosted at https://github.com/clojure/clojure[github.com/clojure/clojure]. Builds of the very latest version of Clojure's master branch are available at https://oss.sonatype.org/content/repositories/snapshots/org/clojure/clojure/1.12.0-master-SNAPSHOT/[oss.sonatype.org]. +Clojure source code is hosted at https://github.com/clojure/clojure[github.com/clojure/clojure]. Builds of the very latest version of Clojure's master branch are available at https://oss.sonatype.org/content/repositories/snapshots/org/clojure/clojure/1.13.0-master-SNAPSHOT/[oss.sonatype.org]. == Get Clojure @@ -97,7 +99,7 @@ Specify the version of Clojure that you want in your deps.edn: [source,clojure] ---- {:deps - {org.clojure/clojure {:mvn/version "1.11.4"}}} + {org.clojure/clojure {:mvn/version "1.12.0"}}} ---- === Via Leiningen @@ -106,7 +108,7 @@ Modify the dependencies and repositories sections of your https://leiningen.org/ [source,clojure] ---- ; under dependencies, select the release of clojure that you want -:dependencies [[org.clojure/clojure "1.11.4"]] +:dependencies [[org.clojure/clojure "1.12.0"]] ---- == Using Clojure SNAPSHOT releases diff --git a/content/releases/downloads_older.adoc b/content/releases/downloads_older.adoc index 1dbaa68e..965d0b18 100644 --- a/content/releases/downloads_older.adoc +++ b/content/releases/downloads_older.adoc @@ -9,6 +9,7 @@ ifdef::env-github,env-browser[:outfilesuffix: .adoc] == Older Clojure Releases +* https://repo1.maven.org/maven2/org/clojure/clojure/1.12.0/[Clojure 1.12.0] (Sep, 2024) - https://clojure.org/news/2024/09/05/clojure-1-12-0[release notes] * https://repo1.maven.org/maven2/org/clojure/clojure/1.11.4/[Clojure 1.11.4] (Aug, 2024) - https://clojure.org/news/2024/08/03/clojure-1-11-4[release notes] * https://repo1.maven.org/maven2/org/clojure/clojure/1.11.3/[Clojure 1.11.3] (Apr, 2024) - https://clojure.org/news/2024/04/24/clojure-1-11-3[release notes] * https://repo1.maven.org/maven2/org/clojure/clojure/1.11.2/[Clojure 1.11.2] (Mar, 2024) - https://clojure.org/news/2024/03/08/clojure-1-11-2[release notes]