New-style macro APIs and a prototype implementation for Scala 2.12.2 #1
Commits on Jun 4, 2017
-
create the build infrastructure
Our new sbt build and drone configuration are heavily inspired by scalameta 1.x. However, this infrastructure only provides very basic functionality: * Using Java 1.8 * Cross-building against 2.10.x, 2.11.x, 2.12.x and Dotty * Support for both JVM and JS backends (JS not yet available for Dotty) * Automatic calculation of pre-release versions for Scalameta * Support for validation of GitHub pull requests * Support for Bintray publishing More features will be added as necessary.
Configuration menu - View commit details
-
Copy full SHA for 9caf34b - Browse repository at this point
Copy the full SHA 9caf34bView commit details -
create the core infrastructure
This commit populates core with essential infrastructure. First, it reintroduces things that have been useful to us in scalameta 1.x, namely prettyprinters (.syntax, .structure) and classifiers (.is[T], .isNot[T]). Secondly, it introduces programmatic access to versions. Prettyprinting retained the same API, but underwent a complete redesign of the underlying implementation: * Show[T] has been removed, because we didn't really use the generality that it offered (only .syntax and .structure ended up being popular). * Prettyprinting combinators from Show have been replaced by a dumb imperative Prettyprinter class that encapsulates a StringBuilder. Denys is telling me that this works extremely well performance-wise in Scala Native + combinators were really tricky to use/maintain at times, so I'm willing to give this a try. * I'm planning to have all our data structures provide prettyprinting functionality, so I've made it as easy as possible to do that. There's now a trait called Pretty that enrolls its descendants into Syntax and Structure as long as they implement `def render`. You can check out the new Version class in this commit to see how this works. Classifiers remained as is. They are working well API-wise, and I don't expect to implement them for anything apart from trees so I didn't bother making classifiers easier on the implementation side. Versioning is going to be a big deal for scalameta, since the project aims to become the foundation for the official macro system of the lang. As a result, I've added a way to programmatically obtain important metadata about our libraries. This commit introduces `scalaVersion` and `coreVersion` into the `scala.meta.config` package. Future commits may transfer more metadata from our build to executable code.
Configuration menu - View commit details
-
Copy full SHA for 7119772 - Browse repository at this point
Copy the full SHA 7119772View commit details -
format everything with scalafmt
I was kinda wary of enabling scalafmt for the whole project in scalameta 1.x, because large parts of our codebase were written before scalafmt existed. However with the new beginnings in this project, we can start well-formatted and then make sure things stay well-formatted as we're reviving more and more scalameta 1.x modules.
Configuration menu - View commit details
-
Copy full SHA for afa5e60 - Browse repository at this point
Copy the full SHA afa5e60View commit details -
Configuration menu - View commit details
-
Copy full SHA for 9b32e16 - Browse repository at this point
Copy the full SHA 9b32e16View commit details -
Configuration menu - View commit details
-
Copy full SHA for d5b6b24 - Browse repository at this point
Copy the full SHA d5b6b24View commit details -
Configuration menu - View commit details
-
Copy full SHA for 1e2c1e9 - Browse repository at this point
Copy the full SHA 1e2c1e9View commit details -
Configuration menu - View commit details
-
Copy full SHA for cc5a2fb - Browse repository at this point
Copy the full SHA cc5a2fbView commit details -
Configuration menu - View commit details
-
Copy full SHA for 13ac40c - Browse repository at this point
Copy the full SHA 13ac40cView commit details -
Configuration menu - View commit details
-
Copy full SHA for e51fd67 - Browse repository at this point
Copy the full SHA e51fd67View commit details -
Configuration menu - View commit details
-
Copy full SHA for 605c181 - Browse repository at this point
Copy the full SHA 605c181View commit details -
Configuration menu - View commit details
-
Copy full SHA for d92bbd1 - Browse repository at this point
Copy the full SHA d92bbd1View commit details -
Inspired by liufengyun/gestalt, we express our core API in scala.reflect-like fashion. This has tangible benefits for implementing semantic macros in the short run.
Configuration menu - View commit details
-
Copy full SHA for 8502aac - Browse repository at this point
Copy the full SHA 8502aacView commit details -
In a crucial UX improvement over scala.reflect.macros, we implement the scala.macros.Universe cake in the scala.macros package object. In the previous commit, we modelled all companions using defs, not vals, and this proves to be critical, making it possible to swap universe implementations on the fly (see the sources of the package object). In comparison with liufengyun/gestalt, in order to implement Universe, we only need to implement one method. We also need just one asInstanceOf to trick the scalac/dotc typechecker.
Configuration menu - View commit details
-
Copy full SHA for 3d3f263 - Browse repository at this point
Copy the full SHA 3d3f263View commit details -
first new-style macro compiles
It's manually desugared into old-style macros which don't work in Dotty, and also it can't run yet, but that's a huge progress for today.
Configuration menu - View commit details
-
Copy full SHA for f606155 - Browse repository at this point
Copy the full SHA f606155View commit details -
Configuration menu - View commit details
-
Copy full SHA for d4ab879 - Browse repository at this point
Copy the full SHA d4ab879View commit details -
Configuration menu - View commit details
-
Copy full SHA for 3bdb60e - Browse repository at this point
Copy the full SHA 3bdb60eView commit details -
Configuration menu - View commit details
-
Copy full SHA for 350cb11 - Browse repository at this point
Copy the full SHA 350cb11View commit details -
compatibility check for expanding new-style macros
`@inline` has been renamed to `@inlineMetadata`, and it now carries coreVersion and engineVersion. Before a new-style macro is allowed to expand, the versions are compared with the corresponding versions available in the compiler plugin, and an error is reported if there are incompatibilities.
Configuration menu - View commit details
-
Copy full SHA for 6fab781 - Browse repository at this point
Copy the full SHA 6fab781View commit details -
Configuration menu - View commit details
-
Copy full SHA for f0cbcd8 - Browse repository at this point
Copy the full SHA f0cbcd8View commit details -
Configuration menu - View commit details
-
Copy full SHA for 7eff169 - Browse repository at this point
Copy the full SHA 7eff169View commit details -
Configuration menu - View commit details
-
Copy full SHA for 2ebac11 - Browse repository at this point
Copy the full SHA 2ebac11View commit details -
Configuration menu - View commit details
-
Copy full SHA for b6afefc - Browse repository at this point
Copy the full SHA b6afefcView commit details -
Sometimes we may want implDef to be called in a particular way. For instance, old-style macros trim stacktraces of macro-generated exceptions by looking for a method whose name ends with `macroExpandWithRuntime` (I remember being criticized for this particular way of arranging the macro engine, and now I understand why I was wrong). Thus, for optimal user experience on platforms that desugar new-style macros to old-style macros, we really want implDef to be named in this idiosyncratic way. However, we also want the inline module to have a method with a well-defined name that can be called in platform-independent fashion. That's why we introduce the notion of abiDef.
Configuration menu - View commit details
-
Copy full SHA for fa7c0a8 - Browse repository at this point
Copy the full SHA fa7c0a8View commit details -
Configuration menu - View commit details
-
Copy full SHA for d6b7f76 - Browse repository at this point
Copy the full SHA d6b7f76View commit details -
Configuration menu - View commit details
-
Copy full SHA for 4e74803 - Browse repository at this point
Copy the full SHA 4e74803View commit details -
first steps at implementing Universe
This commit implements abstract types in Universe. In order to achieve that, I had to apply a massive refactoring. Here are the most important changes: * Public scala.meta.XXX packages are now aliased as scala.macros.XXX, which makes it possible for clients of profiles/macros not to use names starting with scala.meta. * The scala.meta.dialects has been reorganized to work similarly to other scala.meta.XXX packages. * Universe.abstracts is now of an abstract type Abstracts, which makes it possible to keep abstracts of all slices in the same value, which in turn greatly simplifies delegation. * Universe.companions has been split into parts that can be extended in descendants on any level of the super cake. * Abstract types declared in Trees.scala are now fully overridable. Previously only the top-level abstract types were overridable. * Expansion is now part of the Universe cake and hence virtualized. Previously it wasn't, which was a mistake since Expansion depends on Tree that is part of the cake.
Configuration menu - View commit details
-
Copy full SHA for 65006a5 - Browse repository at this point
Copy the full SHA 65006a5View commit details -
Configuration menu - View commit details
-
Copy full SHA for 760fb3b - Browse repository at this point
Copy the full SHA 760fb3bView commit details -
Configuration menu - View commit details
-
Copy full SHA for b9fa194 - Browse repository at this point
Copy the full SHA b9fa194View commit details -
Configuration menu - View commit details
-
Copy full SHA for 919a10d - Browse repository at this point
Copy the full SHA 919a10dView commit details -
Configuration menu - View commit details
-
Copy full SHA for 41c7a65 - Browse repository at this point
Copy the full SHA 41c7a65View commit details -
update to the latest version of Dotty
It turns out that in the last several days Dotty cross-compilation was turned off in my scripts. When I tried to compile the tests now, I got blocked by scala/scala3#2551. Unfortunately, updating to the latest version of Dotty didn't fix the problem. Let's hope this gets resolved asap.
Configuration menu - View commit details
-
Copy full SHA for b2f6fef - Browse repository at this point
Copy the full SHA b2f6fefView commit details -
Configuration menu - View commit details
-
Copy full SHA for 5c57eed - Browse repository at this point
Copy the full SHA 5c57eedView commit details -
At the moment, we don't provide classtags for our abstract types, and, as a result, pattern matches like `case Term.This(_) => ` are going to produce unchecked warnings.
Configuration menu - View commit details
-
Copy full SHA for 834807f - Browse repository at this point
Copy the full SHA 834807fView commit details -
Configuration menu - View commit details
-
Copy full SHA for 6780b3d - Browse repository at this point
Copy the full SHA 6780b3dView commit details -
Name.Anonymous can't be erased to Name
It needs to be at least Term.Name with Type.Name.
Configuration menu - View commit details
-
Copy full SHA for e85427d - Browse repository at this point
Copy the full SHA e85427dView commit details -
Unfortunately, our recent code reorganization broke the macro ABI. The most difficult problem is scala/bug#10339, which I've barely worked around.
Configuration menu - View commit details
-
Copy full SHA for 2d27882 - Browse repository at this point
Copy the full SHA 2d27882View commit details -
first successful macro expansion
I spent about a day making myself comfortable with Trees and Abstracts before starting to implement the methods necessary for the `@main` annotation that I presented at ScalaDays NYC 2016. During that day, I refactored Trees to contain only type aliases and moved custom AST classes to `object customTrees` inside Abstracts. This makes Trees crystal clear and also obviates the need in Companions, because now the custom case classes don't have to implement Companion APIs directly. I also went ahead and added c.Template (c here stands for customTrees), because it is quite hard to encode the notion of Template via g.Template. Some time ago, Fengyun suggested that Template should be removed from the public API, so maybe it indeed should. I also took extreme care to preserve attributes when converting to/from custom trees. Namely, all custom trees inherit all attrs from their global analogues, but global trees only inherit positions from custom trees (otherwise, we run into problems with the mix of untyped and typed trees). A lot of time went into designing naming conventions. Unlike with converters, we don't have a clear-cut distinction between m.Tree and g.Tree, so it wasn't easy. After some back and forth, I settled on calling global-specific (or potentially global-specific) things with names that start from g, and left other identifiers unchanged (i.e. no m prefix). After all the guidelines were established, hacking the `@main` macro was actually very enjoyable. Unlike with converters, I only had to implement a very small portion of ???'s. This is definitely a very strong point of the extractor-based approach to macros.
Configuration menu - View commit details
-
Copy full SHA for 340becc - Browse repository at this point
Copy the full SHA 340beccView commit details -
Extends the cake with a semantic slice that features the usual structure. This design tries to combine the best features of the scalameta semantic API ca. 2015, the scalameta semantic API ca. 2017 and liufengyun/gestalt. This commit introduces Symbol and Denotation, which are both opaque entities fully defined by a concrete implementation. A Symbol is a GUID of a member (where uniqueness is defined within the limits of the definition of classpath). A Denotation is a Symbol augmented with a prefix, which enables it to compute symbol signatures. Types from syntactic API are also used to represent types in the semantic API. Fengyun was insisting that we shouldn't conflate these two concepts, but I'd like to use this pull request as an extended illustration of the idea that I tried to convey. Hopefully, this and the follow-up commits will provide arguments in favor of this approach. Semantic operations are implemented in an unusual fashion. There are a lot of methods that overlap between refs, members, symbols and denots, because e.g. it is reasonable to expect isFinal to be callable on all of the above. As a result, quite some design effort went into efficiently sharing these operations without copy/paste. I'm pretty happy with the end result. One blatant issue with the current data model is that allows performing semantic operations on unattributed trees. There is a solution for that that Fengyun has implemented in liufengyun/gestalt (separation of typed and untyped trees), and it works really well. Therefore, we don't consider this issue to be a serious problem, and we'll get to fixing it once more urgent tasks are dealt with.
Configuration menu - View commit details
-
Copy full SHA for afa8b6d - Browse repository at this point
Copy the full SHA afa8b6dView commit details -
tighter integration between syntactic and semantic API
This commit plugs a huge usability hole by allowing metaprogrammers to create types manually, exploiting the unification of type trees and types. First, we add functionality to look up symbols in the underlying symbol table via `Symbol.apply(String)` which is inspired by the recent iteration of the semantic API in scalameta 1.x. Secondly, we add new constructors to Term.Name and Type.Name. These constructors go from symbols to names that wrap them. When we combine these new facilities with the standard APIs to create type trees, we end up with a very potent mix that lets metaprogrammers to throw together non-trivial types, including type applications, type projections, etc. I believe this is a very elegant way to approach semantic APIs, because it obviates the need in maintaining a separate hierarchy of extractors and helpers for types. For example, if we separated type trees and types, we would have to add methods like `termRef` and `typeRef` to construct simple types and then methods like `appliedTo`, `project`, etc to construct more complex types. Then our users would say e.g. `Type.typeRef("scala.List").appliedTo(tpe)` In contrast, with the approach introduced in this commit, our users say `Type.Apply(Type.Name(Symbol("scala.List#")), List(tpe))`, or if we decide reuse AST-based helpers, `Type.Name(Symbol(...)).appliedTo(tpe)`. This doesn't require any additional APIs, apart from the three newly introduced ones, and those APIs are anyway core for semantic API and are usable in other scenarios, e.g. via `Symbol(...).isXXX` or for safe construction of typed ASTs.
Configuration menu - View commit details
-
Copy full SHA for 753226d - Browse repository at this point
Copy the full SHA 753226dView commit details -
Even though we went back to the reflect-like scheme of organizing things, we shouldn't regress to complete savagery of semantic APIs being powered by global state of the cake. This commit also includes a reorganization of expansions, because I realized that there's no need to have any method in Expansion if it lives inside the cake. This saves us an additional layer of abstraction. I've also applied aggressive abbreviation, replacing all reasonable occurrences of `symbol` with just `sym`. In the world of `tpe` and `denot` this seems logical. Let's see how people like it.
Configuration menu - View commit details
-
Copy full SHA for 33ce8fd - Browse repository at this point
Copy the full SHA 33ce8fdView commit details -
I've just realized that maxColumn=100 doesn't equal 100 characters per column. It means that a 100th character will trigger a line break. This seems unfair :)
Configuration menu - View commit details
-
Copy full SHA for 8e06d6a - Browse repository at this point
Copy the full SHA 8e06d6aView commit details -
Configuration menu - View commit details
-
Copy full SHA for 1a7d2e9 - Browse repository at this point
Copy the full SHA 1a7d2e9View commit details -
Configuration menu - View commit details
-
Copy full SHA for b27c093 - Browse repository at this point
Copy the full SHA b27c093View commit details -
Configuration menu - View commit details
-
Copy full SHA for f957794 - Browse repository at this point
Copy the full SHA f957794View commit details -
Configuration menu - View commit details
-
Copy full SHA for 5633dc3 - Browse repository at this point
Copy the full SHA 5633dc3View commit details -
Configuration menu - View commit details
-
Copy full SHA for ebcc3c1 - Browse repository at this point
Copy the full SHA ebcc3c1View commit details -
Configuration menu - View commit details
-
Copy full SHA for 2640f08 - Browse repository at this point
Copy the full SHA 2640f08View commit details -
Configuration menu - View commit details
-
Copy full SHA for 19ad48e - Browse repository at this point
Copy the full SHA 19ad48eView commit details -
Note that I'm adding quasiquotes to profiles/macros, not to core. That's because the expansion facilities are likely to differ between different implementations and usage scenarios of core.
Configuration menu - View commit details
-
Copy full SHA for fe39e04 - Browse repository at this point
Copy the full SHA fe39e04View commit details -
Configuration menu - View commit details
-
Copy full SHA for 6544359 - Browse repository at this point
Copy the full SHA 6544359View commit details -
Configuration menu - View commit details
-
Copy full SHA for c61dd7e - Browse repository at this point
Copy the full SHA c61dd7eView commit details -
temporarily inline the dependency on scalameta
I've been hit by a pretty hard blocker in the previous commit. When I tried to use scalameta 1.9 to parse quasiquote syntax, I discovered that there is an irreparable conflict between scala.meta classfiles from 1.9 and scala.meta classfiles from 2.0. Therefore, I did something pretty radical. I renamed `package scala.meta` in core to `package scala.macros` and then merged core with profiles/macros, so that there are no more mentions of scala.meta left. This means that our API becomes a fork of the scalameta API for now. We will need to take special care to keep these two APIs in sync until we bootstrap an implementation of quasiquotes based on core.
Configuration menu - View commit details
-
Copy full SHA for 76a489b - Browse repository at this point
Copy the full SHA 76a489bView commit details -
rename private[scala] to private[macros]
Now that we don't need to share the namespace between scala.meta and scala.macros, we can be more precise about the access boundary.
Configuration menu - View commit details
-
Copy full SHA for fbfa624 - Browse repository at this point
Copy the full SHA fbfa624View commit details -
dialects no longer have an always available implicit instance
Now that quasiquotes use a unicorn dialect for parsing, we are no longer compelled to perpetuate this really bad idea.
Configuration menu - View commit details
-
Copy full SHA for d3be42d - Browse repository at this point
Copy the full SHA d3be42dView commit details -
Configuration menu - View commit details
-
Copy full SHA for 61a9e89 - Browse repository at this point
Copy the full SHA 61a9e89View commit details -
Configuration menu - View commit details
-
Copy full SHA for b0e7ee3 - Browse repository at this point
Copy the full SHA b0e7ee3View commit details -
Configuration menu - View commit details
-
Copy full SHA for 22cab46 - Browse repository at this point
Copy the full SHA 22cab46View commit details -
upgrade the unmanaged dependency on scalameta to a managed one
I didn't have wifi on my flight from OAK to ARN, so I had to do a hacky unmanaged dependency on the scalameta quasiquote parser by putting the corresponding jars into plugins/scalac/lib. Now I'm back online, so it's time to throw away the hack and settle down on a stable reference point.
Configuration menu - View commit details
-
Copy full SHA for d72ecc0 - Browse repository at this point
Copy the full SHA d72ecc0View commit details -
scalameta/scalameta#406 still stands, since the implementation is copy/pasted from scalameta.
Configuration menu - View commit details
-
Copy full SHA for c70ed27 - Browse repository at this point
Copy the full SHA c70ed27View commit details -
Configuration menu - View commit details
-
Copy full SHA for 0856dfd - Browse repository at this point
Copy the full SHA 0856dfdView commit details -
Configuration menu - View commit details
-
Copy full SHA for 1fbeb3b - Browse repository at this point
Copy the full SHA 1fbeb3bView commit details -
simplify pattern matching logic
We don't support unlifting yet, so we don't have to extract pattern holes into temporary variables.
Configuration menu - View commit details
-
Copy full SHA for adf1966 - Browse repository at this point
Copy the full SHA adf1966View commit details -
Configuration menu - View commit details
-
Copy full SHA for 1d2871a - Browse repository at this point
Copy the full SHA 1d2871aView commit details -
Configuration menu - View commit details
-
Copy full SHA for 818db0d - Browse repository at this point
Copy the full SHA 818db0dView commit details -
Configuration menu - View commit details
-
Copy full SHA for b2410ed - Browse repository at this point
Copy the full SHA b2410edView commit details -
Configuration menu - View commit details
-
Copy full SHA for cb9561c - Browse repository at this point
Copy the full SHA cb9561cView commit details -
fix crosscompilation with Dotty
Looks like Dotty is a bit more strict than Scala when it comes to self-type annotations.
Configuration menu - View commit details
-
Copy full SHA for d1d924f - Browse repository at this point
Copy the full SHA d1d924fView commit details -
Configuration menu - View commit details
-
Copy full SHA for ee60c30 - Browse repository at this point
Copy the full SHA ee60c30View commit details -
Configuration menu - View commit details
-
Copy full SHA for 71cf005 - Browse repository at this point
Copy the full SHA 71cf005View commit details -
Configuration menu - View commit details
-
Copy full SHA for 65b96ab - Browse repository at this point
Copy the full SHA 65b96abView commit details -
Configuration menu - View commit details
-
Copy full SHA for f89271e - Browse repository at this point
Copy the full SHA f89271eView commit details -
Configuration menu - View commit details
-
Copy full SHA for 490c4bb - Browse repository at this point
Copy the full SHA 490c4bbView commit details -
The current incarnation of this test is really hard to maintain, and that really slows down the progress.
Configuration menu - View commit details
-
Copy full SHA for 876b2e7 - Browse repository at this point
Copy the full SHA 876b2e7View commit details -
Configuration menu - View commit details
-
Copy full SHA for ea6037d - Browse repository at this point
Copy the full SHA ea6037dView commit details -
Configuration menu - View commit details
-
Copy full SHA for df5b438 - Browse repository at this point
Copy the full SHA df5b438View commit details -
Configuration menu - View commit details
-
Copy full SHA for 759d529 - Browse repository at this point
Copy the full SHA 759d529View commit details -
Configuration menu - View commit details
-
Copy full SHA for 5cc9fb3 - Browse repository at this point
Copy the full SHA 5cc9fb3View commit details -
Configuration menu - View commit details
-
Copy full SHA for 2d04c63 - Browse repository at this point
Copy the full SHA 2d04c63View commit details -
Configuration menu - View commit details
-
Copy full SHA for 179a0d6 - Browse repository at this point
Copy the full SHA 179a0d6View commit details
Commits on Jun 8, 2017
-
Configuration menu - View commit details
-
Copy full SHA for f30bbd2 - Browse repository at this point
Copy the full SHA f30bbd2View commit details
Commits on Jun 24, 2017
-
Configuration menu - View commit details
-
Copy full SHA for 5b055c8 - Browse repository at this point
Copy the full SHA 5b055c8View commit details
Commits on Jul 22, 2017
-
Configuration menu - View commit details
-
Copy full SHA for ebab058 - Browse repository at this point
Copy the full SHA ebab058View commit details -
Since our quasiquotes don't require a dialect, I don't think we should. If in the future, we need dialects, we should be able to easily readd them later.
Configuration menu - View commit details
-
Copy full SHA for 2b5dfba - Browse repository at this point
Copy the full SHA 2b5dfbaView commit details -
Configuration menu - View commit details
-
Copy full SHA for d4700f6 - Browse repository at this point
Copy the full SHA d4700f6View commit details -
As @olafurpg has pointed out, we don't need this if we don't plan to have macro APIs called at runtime.
Configuration menu - View commit details
-
Copy full SHA for f1c1e23 - Browse repository at this point
Copy the full SHA f1c1e23View commit details -
In scalameta, we're now using Travis, because Scala Platform CI has proven to be unreliable. This commit removes Drone support, and future commits will set up Travis.
Configuration menu - View commit details
-
Copy full SHA for 1365b56 - Browse repository at this point
Copy the full SHA 1365b56View commit details -
Configuration menu - View commit details
-
Copy full SHA for 49ac8c3 - Browse repository at this point
Copy the full SHA 49ac8c3View commit details -
stop crosscompilation to 2.10 and 2.11
The maintenance burden is real. We'll need community help with this.
Configuration menu - View commit details
-
Copy full SHA for e865cd8 - Browse repository at this point
Copy the full SHA e865cd8View commit details -
A dedicated io package is appropriate in Scalameta, but I highly doubt that we need it in macros.
Configuration menu - View commit details
-
Copy full SHA for 17f9618 - Browse repository at this point
Copy the full SHA 17f9618View commit details -
Configuration menu - View commit details
-
Copy full SHA for dccbfc8 - Browse repository at this point
Copy the full SHA dccbfc8View commit details
Commits on Jul 23, 2017
-
replace inline/meta with def/macro
As the first step for the new macro system, we want to get just the macro-related functionality, and for that we don't have to implement the full power of inline and meta. Since we don't need to implement inline and meta separately right away, inline/meta becomes just a fancy way of indicating a new-style macro, and this syntax starts looking a bit excessive. Instead of introducing two new keywords and bringing our users the pain of migrating code that uses these keywords as identifiers, we propose that for the time being we use the old def/macro syntax with the block-shaped right-hand side as the syntax for new-style macros.
Configuration menu - View commit details
-
Copy full SHA for 60240e2 - Browse repository at this point
Copy the full SHA 60240e2View commit details -
Configuration menu - View commit details
-
Copy full SHA for dadee74 - Browse repository at this point
Copy the full SHA dadee74View commit details -
Configuration menu - View commit details
-
Copy full SHA for 3384c90 - Browse repository at this point
Copy the full SHA 3384c90View commit details