├── FeatureTracking.md
├── README.md
├── Resources
├── Derpy-Outlined.svg
├── Derpy.svg
├── Emojis
│ ├── angry.svg
│ ├── approved.svg
│ ├── blush.svg
│ ├── confused.svg
│ ├── cry.svg
│ ├── emojis.svg
│ ├── facepalm.svg
│ ├── glasses.svg
│ ├── gun.svg
│ ├── hearteyes.svg
│ ├── lol.svg
│ ├── party.svg
│ ├── ree.svg
│ ├── sad.svg
│ ├── sick.svg
│ ├── sip.svg
│ ├── sleep.svg
│ ├── smile.svg
│ ├── think.svg
│ └── triggered.svg
├── LICENSE
├── Logo-Long-Inverted-Outline.svg
├── Logo-Long-Inverted.svg
├── Logo-Long.svg
├── Logo-Short-Inverted-Outline.svg
├── Logo-Short-Inverted.svg
└── Logo-Short.svg
├── Samples
├── 99BottlesOfBeer.draco
├── FizzBuzz.draco
├── FizzBuzzWithPatternMatching.draco
├── HashDeriveMacro.draco
├── LICENSE
├── ListProceduralMacro.draco
├── MemoizeMacro.draco
├── Quine.draco
├── RecursiveFibonacci.draco
└── TruthMachine.draco
└── Specification
├── Comments.md
├── ControlFlow.md
├── EntryPoint.md
├── ExpressionsAndBuiltins.md
├── Generics.md
├── Introduction.md
├── LICENSE
├── ModuleSystem.md
└── Overloading.md
/FeatureTracking.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | This document attempts to collect all aspects of a language (by some opinionated partitioning). The number of issues is becoming significant, and we need to know what we need to work on to actually get somewhere. Feel free to add aspects that are currently left out.
4 |
5 | Legend:
6 | - 🟢 - well-designed
7 | - 🟡 - a lot of work is still required, but first steps are made
8 | - 🔴 - hasn't been considered yet
9 |
10 | ## General features
11 |
12 | * 🟢 Variables
13 | * basic structure proposed in [proposal 0.1](https://github.com/Draco-lang/Language-suggestions/issues/33)
14 | * [The val and var issue](https://github.com/Draco-lang/Language-suggestions/issues/12)
15 | * Specification in [RFC0001](https://github.com/Draco-lang/Language-suggestions/pull/55) for both global and local variables
16 | * 🟡 Functions/methods
17 | * 🟢 Free functions
18 | * Proposed in [proposal 0.1](https://github.com/Draco-lang/Language-suggestions/issues/33)
19 | * Specification in [RFC0001](https://github.com/Draco-lang/Language-suggestions/pull/55)
20 | * 🟡 Member functions
21 | * Proposed in the issue about [record types](https://github.com/Draco-lang/Language-suggestions/issues/41)
22 | * 🟢 Main Function
23 | * Proposed in [Main function signatures issue](https://github.com/Draco-lang/Language-suggestions/issues/63)
24 | * Specification in [RFC0004](https://github.com/Draco-lang/Language-suggestions/pull/78) and [RFC0013](https://github.com/Draco-lang/Language-suggestions/pull/117)
25 | * 🟡 Control structures
26 | * 🟢 If-else
27 | * Proposed in [proposal 0.1](https://github.com/Draco-lang/Language-suggestions/issues/33)
28 | * Specification in [RFC0001](https://github.com/Draco-lang/Language-suggestions/pull/55)
29 | * 🟢 While-loop
30 | * Proposed in [proposal 0.1](https://github.com/Draco-lang/Language-suggestions/issues/33)
31 | * Specification in [RFC0001](https://github.com/Draco-lang/Language-suggestions/pull/55)
32 | * 🟡 For-loop
33 | * Proposed in [proposal 0.2](https://github.com/Draco-lang/Language-suggestions/issues/40)
34 | * 🟡 Match
35 | * Proposed in the [pattern matching issue](https://github.com/Draco-lang/Language-suggestions/issues/44)
36 | * 🟢 Goto
37 | * Proposed in the [goto and implicit loop labels issue](https://github.com/Draco-lang/Language-suggestions/issues/45)
38 | * Specification in [RFC0001](https://github.com/Draco-lang/Language-suggestions/pull/55)
39 | * 🟢 Break/continue in loops
40 | * Proposed in the [goto and implicit loop labels issue](https://github.com/Draco-lang/Language-suggestions/issues/45) as specialized labels
41 | * Specification in [RFC0001](https://github.com/Draco-lang/Language-suggestions/pull/55)
42 | * 🟡 Let ... in construct
43 | * [Proposal](https://github.com/Draco-lang/Language-suggestions/issues/51)
44 | * 🟢Literal values
45 | * Proposal in the [literal values issue](https://github.com/Draco-lang/Language-suggestions/issues/50)
46 | * [String interpolation issue](https://github.com/Draco-lang/Language-suggestions/issues/53)
47 | * Specification for string literals in [RFC0005](https://github.com/Draco-lang/Language-suggestions/pull/79)
48 | * Specification for primitive literals in [RFC0002](https://github.com/Draco-lang/Language-suggestions/pull/56)
49 | * 🟡 Operators
50 | * Basic, built-in operators proposed in [proposal 0.1](https://github.com/Draco-lang/Language-suggestions/issues/33)
51 | * [Exponential operator](https://github.com/Draco-lang/Language-suggestions/issues/34)
52 | * [Implies operator](https://github.com/Draco-lang/Language-suggestions/issues/36)
53 | * [Inequality syntax](https://github.com/Draco-lang/Language-suggestions/issues/35)
54 | * [Colon as tuple construction](https://github.com/Draco-lang/Language-suggestions/issues/22)
55 | * [User-defined operators](https://github.com/Draco-lang/Language-suggestions/issues/72)
56 | * Specification for basic operators in [RFC0002](https://github.com/Draco-lang/Language-suggestions/pull/56)
57 | * 🟡 Exceptions, throwing, catching
58 | * [Exceptions, try-catch-finally proposal](https://github.com/Draco-lang/Language-suggestions/issues/54)
59 | * 🟢 Modules
60 | * [Issue about declarations and definitions](https://github.com/Draco-lang/Language-suggestions/issues/30)
61 | * The [module system issue](https://github.com/Draco-lang/Language-suggestions/issues/58)
62 | * Specification for module system in [RFC0011](https://github.com/Draco-lang/Language-suggestions/pull/112)
63 |
64 | ## Type-system
65 |
66 | * 🟡 Built-in primitives
67 | * Many are proposed in [proposal 0.1](https://github.com/Draco-lang/Language-suggestions/issues/33)
68 | * There are quite a few left out, never mentioned (like interop primitives)
69 | * Specification in [RFC0002](https://github.com/Draco-lang/Language-suggestions/pull/56)
70 | * 🟡 Record types
71 | * Proposal about the [basics of record types](https://github.com/Draco-lang/Language-suggestions/issues/41)
72 | * 🟡 Discriminated unions
73 | * [The DUs vs inheritance issue](https://github.com/Draco-lang/Language-suggestions/issues/5)
74 | * 🟡 Traits
75 | * [Proposal](https://github.com/Draco-lang/Language-suggestions/issues/52)
76 | * [Internals](https://github.com/Draco-lang/Language-suggestions/issues/39)
77 | * Very much related and strong hints are in the [record types issue](https://github.com/Draco-lang/Language-suggestions/issues/41)
78 | * 🟡 Properties
79 | * Issue about possibilities, possible syntaxes [for properties](https://github.com/Draco-lang/Language-suggestions/issues/47)
80 | * 🟡 Type-inference
81 | * Overview is in the [proposal 0.2](https://github.com/Draco-lang/Language-suggestions/issues/40)
82 | * There is the [type inference issue](https://github.com/Draco-lang/Language-suggestions/issues/42)
83 | * The initial [inference issue](https://github.com/Draco-lang/Language-suggestions/issues/10)
84 | * 🟢 Overloading
85 | * Overview is in the [proposal 0.2](https://github.com/Draco-lang/Language-suggestions/issues/40)
86 | * Specification for overloading in [RFC0010](https://github.com/Draco-lang/Language-suggestions/pull/111) and [RFC0012](https://github.com/Draco-lang/Language-suggestions/pull/115)
87 | * 🟡 Generics
88 | * For methods, mentioned in [proposal 0.2](https://github.com/Draco-lang/Language-suggestions/issues/40)
89 | * For methods specification in [RFC0012](https://github.com/Draco-lang/Language-suggestions/pull/115)
90 | * For types, nothing is mentioned yet
91 | * 🟡 Nullability
92 | * The issue [about erasable nullables](https://github.com/Draco-lang/Language-suggestions/issues/24)
93 | * 🔴 Casting
94 | * Not mentioned anywhere yet
95 |
96 | ## Special features
97 |
98 | * 🔴 Asynchronous programming
99 | * Not mentioned anywhere yet
100 | * 🔴 Generators
101 | * Not mentioned anywhere yet
102 | * 🟡 Pattern matching
103 | * Proposed in the [pattern matching issue](https://github.com/Draco-lang/Language-suggestions/issues/44)
104 | * [Case-exclusion issue](https://github.com/Draco-lang/Language-suggestions/issues/9)
105 | * 🟡 Lambda functions
106 | * Discussed in the [lambdas issue](https://github.com/Draco-lang/Language-suggestions/issues/49)
107 |
108 |
109 | ## Metaprogramming
110 |
111 | * 🟡 Attributes
112 | * Briefly mentioned in the [metaprogramming issue](https://github.com/Draco-lang/Language-suggestions/issues/16)
113 | * Nothing exact proposed yet
114 | * 🟡 Derive-metchanism
115 | * Briefly mentioned in the [metaprogramming issue](https://github.com/Draco-lang/Language-suggestions/issues/16)
116 | * Nothing exact proposed yet
117 | * 🟡 Macro-system
118 | * Possibilities outlined in the [metaprogramming issue](https://github.com/Draco-lang/Language-suggestions/issues/16)
119 | * A slightly more detailed "wish-list" for capabilities in the [F# CEs expressed as higher-order macros issue](https://github.com/Draco-lang/Language-suggestions/issues/29)
120 |
121 | ## Other
122 |
123 | * 🟢 Documentation
124 | * [Documentation comments issue](https://github.com/Draco-lang/Language-suggestions/issues/37)
125 | * Specifications in [RFC0009](https://github.com/Draco-lang/Language-suggestions/pull/102)
126 | * 🟡 Enforcing TCO
127 | * [tailrec proposal](https://github.com/Draco-lang/Language-suggestions/issues/11)
128 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
A new .NET programming language in the making
7 |
8 |
9 |
10 |
11 |
12 | ### Important about this repository
13 |
14 | This was the initial repository we created to formulate very random ideas about designing a language. There are many-many issues discussing design choices ranging from "the usual" to very radical or plain weird ones. **The language isn't the collection of these issues.** We use these issues to initiate discussions, shift perspectives, collect ideas from other languages and so on. Currently, the actual [specification](Specification) is extremely small and bare-bones.
15 |
16 | ### I just want to see how the language looks!
17 |
18 | [See the Samples folder.](./Samples/)
19 |
20 | ### The aims of the language
21 |
22 | > I want to do to C# what Kotlin did to Java
23 |
24 | Draco should be a high-level language which could replace C#. Here are a few major key points that we aren't changing:
25 |
26 | * It is strongly statically typed
27 | * It is not academic & should be easily used by a regular .NET developer
28 | * It should be more or less readable by people not knowing it (as opposed to ML, for instance)
29 | * It should be debuggable
30 | * It prefers generalized approaches over sugared special cases
31 | * It adds a bigger and more worked out feature earlier, than an underspecified one that will result in extra features to work out the missed use cases
32 |
33 | ### Current state of the project
34 |
35 | There is a very basic and not finished [Compiler](https://github.com/Draco-lang/Compiler).
36 |
37 | Right now we are still working out the core of the language. We do this by collecting ideas, inspiration, frustrating things and useful bits from existing languages. We have started working on a specification (see the [Specification](Specification) folder) and you can see an [examples folder](./Samples/) that we try to keep updated to more or less reflect our current idea of the language. You can also take a look at the [feature tracking](FeatureTracking.md) document, where we keep track of all features we want to investigate.
38 |
39 | ### Our workflow
40 |
41 | 1. We start from an idea or a discussion, usually either on our [Discord server](https://discord.gg/gHfhpPFzYu) or in an issue.
42 | 2. The ideas we like are then worked on as an issue, we append comments, elaborate on the features and internals.
43 | 3. When we want to add something to the specification, we either create a new, or edit an existing file in the [Specification](Specification) folder, write the specification document and open a Pull Request with the name `RFCnnnn - Short description`.
44 | 4. We critique the RFC, modify if needed, even leave out features we can't agree on for a while.
45 | 5. When no more comments arrive on the RFC and we can agree on the feature, we merge it into the specification.
46 |
47 | ### Propose your ideas!
48 |
49 | Now that you grasped the main idea, feel free to open an issue which
50 |
51 | * Proposes a language idea. No strict requirements, so for now, any idea is welcomed
52 | * Tells about your experience using any programming language. Tell us what you find interesting about a language or what you disliked about it
53 |
--------------------------------------------------------------------------------
/Resources/Derpy-Outlined.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
138 |
--------------------------------------------------------------------------------
/Resources/Derpy.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
117 |
--------------------------------------------------------------------------------
/Resources/Emojis/angry.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
121 |
--------------------------------------------------------------------------------
/Resources/Emojis/approved.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
119 |
--------------------------------------------------------------------------------
/Resources/Emojis/blush.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
139 |
--------------------------------------------------------------------------------
/Resources/Emojis/confused.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
152 |
--------------------------------------------------------------------------------
/Resources/Emojis/cry.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
95 |
--------------------------------------------------------------------------------
/Resources/Emojis/facepalm.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
120 |
--------------------------------------------------------------------------------
/Resources/Emojis/glasses.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
159 |
--------------------------------------------------------------------------------
/Resources/Emojis/gun.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
140 |
--------------------------------------------------------------------------------
/Resources/Emojis/hearteyes.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
111 |
--------------------------------------------------------------------------------
/Resources/Emojis/lol.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
92 |
--------------------------------------------------------------------------------
/Resources/Emojis/party.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
199 |
--------------------------------------------------------------------------------
/Resources/Emojis/ree.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
96 |
--------------------------------------------------------------------------------
/Resources/Emojis/sad.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
93 |
--------------------------------------------------------------------------------
/Resources/Emojis/sick.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
156 |
--------------------------------------------------------------------------------
/Resources/Emojis/sip.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
186 |
--------------------------------------------------------------------------------
/Resources/Emojis/sleep.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
120 |
--------------------------------------------------------------------------------
/Resources/Emojis/smile.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
120 |
--------------------------------------------------------------------------------
/Resources/Emojis/think.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
110 |
--------------------------------------------------------------------------------
/Resources/Logo-Short-Inverted.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
184 |
--------------------------------------------------------------------------------
/Resources/Logo-Short.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
162 |
--------------------------------------------------------------------------------
/Samples/99BottlesOfBeer.draco:
--------------------------------------------------------------------------------
1 | import System.Linq.Enumerable;
2 | import System.Console;
3 |
4 | func main() {
5 | func capitalize(s: string): string =
6 | "\{char.ToUpper(s[0])}\{s.Substring(1)}";
7 |
8 | func bottles(n: int32): string = match (n)
9 | {
10 | 0 -> "no more bottles";
11 | 1 -> "1 bottle";
12 | _ -> "\{n} bottles";
13 | };
14 |
15 | for (var i in Reverse(Range(1, 99))) {
16 | WriteLine("""
17 | \{capitalize(bottles(i))} of beer on the wall, \{bottles(i)} of beer.
18 | Take one down, pass it around, \{bottles(i - 1)} of beer on the wall.
19 | """);
20 | }
21 | WriteLine("""
22 | No more bottles of beer on the wall, no more bottles of beer.
23 | Go to the store and buy some more, 99 bottles of beer on the wall.
24 | """);
25 | }
26 |
--------------------------------------------------------------------------------
/Samples/FizzBuzz.draco:
--------------------------------------------------------------------------------
1 | import System.Console;
2 | import System.Linq.Enumerable;
3 |
4 | func main() {
5 | for (i in Range(100)) {
6 | if (i mod 3 != 0 and i mod 5 != 0) {
7 | WriteLine(i);
8 | goto continue;
9 | }
10 | if (i mod 3 == 0) Write("Fizz");
11 | if (i mod 5 == 0) Write("Buzz");
12 | WriteLine();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/Samples/FizzBuzzWithPatternMatching.draco:
--------------------------------------------------------------------------------
1 | import System.Console;
2 | import System.Linq.Enumerable;
3 |
4 | func main() {
5 | for (i in Range(100)) {
6 | match (i mod 3, i mod 5) {
7 | (0, 0) -> WriteLine("FizzBuzz");
8 | (0, _) -> WriteLine("Fizz");
9 | (_, 0) -> WriteLine("Buzz");
10 | _ -> WriteLine(i);
11 | }
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Samples/HashDeriveMacro.draco:
--------------------------------------------------------------------------------
1 | import System.Collections.Generic;
2 |
3 | // Derive macros are a special case of attribute macros. They only append code
4 | // to the existing target instead of modifying it. This typically allows us to
5 | // implement extra traits for an annotated type.
6 | @derive_macro(Hash)
7 | func hash_derive(target: Ast, args: []Ast): Result {
8 | // We expect a type as a target
9 | val target = target.asTypeDeclaration();
10 |
11 | // We don't expect any arguments
12 | if (args.Length > 0) return MacroExpansionError("Hash derive expects no arguments!");
13 |
14 | // Generate the Add calls to the System.HashCode instance
15 | val adds = List();
16 | for (m in target.Members) adds.Add(quote!{ hashCode.Add(this.#(m.name)); });
17 |
18 | // Implement the function for the type
19 | return quote!{
20 | impl #(target.Name) {
21 | func GetHashCode(this): int32 {
22 | val hashCode = System.HashCode();
23 | #(adds)...
24 | return hashCode.ToHashCode();
25 | }
26 | }
27 | };
28 | }
29 |
30 | // Example time!
31 |
32 | @derive(Hash)
33 | type Person(name: string, age: int32);
34 |
35 | // The extra generated code:
36 | impl Person {
37 | func GetHashCode(this): int32 {
38 | val hashCode = System.HashCode();
39 | hashCode.Add(this.name);
40 | hashCode.Add(this.age);
41 | return hashCode.ToHashCode();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/Samples/LICENSE:
--------------------------------------------------------------------------------
1 | CC0 1.0 Universal
2 |
3 | Statement of Purpose
4 |
5 | The laws of most jurisdictions throughout the world automatically confer
6 | exclusive Copyright and Related Rights (defined below) upon the creator and
7 | subsequent owner(s) (each and all, an "owner") of an original work of
8 | authorship and/or a database (each, a "Work").
9 |
10 | Certain owners wish to permanently relinquish those rights to a Work for the
11 | purpose of contributing to a commons of creative, cultural and scientific
12 | works ("Commons") that the public can reliably and without fear of later
13 | claims of infringement build upon, modify, incorporate in other works, reuse
14 | and redistribute as freely as possible in any form whatsoever and for any
15 | purposes, including without limitation commercial purposes. These owners may
16 | contribute to the Commons to promote the ideal of a free culture and the
17 | further production of creative, cultural and scientific works, or to gain
18 | reputation or greater distribution for their Work in part through the use and
19 | efforts of others.
20 |
21 | For these and/or other purposes and motivations, and without any expectation
22 | of additional consideration or compensation, the person associating CC0 with a
23 | Work (the "Affirmer"), to the extent that he or she is an owner of Copyright
24 | and Related Rights in the Work, voluntarily elects to apply CC0 to the Work
25 | and publicly distribute the Work under its terms, with knowledge of his or her
26 | Copyright and Related Rights in the Work and the meaning and intended legal
27 | effect of CC0 on those rights.
28 |
29 | 1. Copyright and Related Rights. A Work made available under CC0 may be
30 | protected by copyright and related or neighboring rights ("Copyright and
31 | Related Rights"). Copyright and Related Rights include, but are not limited
32 | to, the following:
33 |
34 | i. the right to reproduce, adapt, distribute, perform, display, communicate,
35 | and translate a Work;
36 |
37 | ii. moral rights retained by the original author(s) and/or performer(s);
38 |
39 | iii. publicity and privacy rights pertaining to a person's image or likeness
40 | depicted in a Work;
41 |
42 | iv. rights protecting against unfair competition in regards to a Work,
43 | subject to the limitations in paragraph 4(a), below;
44 |
45 | v. rights protecting the extraction, dissemination, use and reuse of data in
46 | a Work;
47 |
48 | vi. database rights (such as those arising under Directive 96/9/EC of the
49 | European Parliament and of the Council of 11 March 1996 on the legal
50 | protection of databases, and under any national implementation thereof,
51 | including any amended or successor version of such directive); and
52 |
53 | vii. other similar, equivalent or corresponding rights throughout the world
54 | based on applicable law or treaty, and any national implementations thereof.
55 |
56 | 2. Waiver. To the greatest extent permitted by, but not in contravention of,
57 | applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and
58 | unconditionally waives, abandons, and surrenders all of Affirmer's Copyright
59 | and Related Rights and associated claims and causes of action, whether now
60 | known or unknown (including existing as well as future claims and causes of
61 | action), in the Work (i) in all territories worldwide, (ii) for the maximum
62 | duration provided by applicable law or treaty (including future time
63 | extensions), (iii) in any current or future medium and for any number of
64 | copies, and (iv) for any purpose whatsoever, including without limitation
65 | commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes
66 | the Waiver for the benefit of each member of the public at large and to the
67 | detriment of Affirmer's heirs and successors, fully intending that such Waiver
68 | shall not be subject to revocation, rescission, cancellation, termination, or
69 | any other legal or equitable action to disrupt the quiet enjoyment of the Work
70 | by the public as contemplated by Affirmer's express Statement of Purpose.
71 |
72 | 3. Public License Fallback. Should any part of the Waiver for any reason be
73 | judged legally invalid or ineffective under applicable law, then the Waiver
74 | shall be preserved to the maximum extent permitted taking into account
75 | Affirmer's express Statement of Purpose. In addition, to the extent the Waiver
76 | is so judged Affirmer hereby grants to each affected person a royalty-free,
77 | non transferable, non sublicensable, non exclusive, irrevocable and
78 | unconditional license to exercise Affirmer's Copyright and Related Rights in
79 | the Work (i) in all territories worldwide, (ii) for the maximum duration
80 | provided by applicable law or treaty (including future time extensions), (iii)
81 | in any current or future medium and for any number of copies, and (iv) for any
82 | purpose whatsoever, including without limitation commercial, advertising or
83 | promotional purposes (the "License"). The License shall be deemed effective as
84 | of the date CC0 was applied by Affirmer to the Work. Should any part of the
85 | License for any reason be judged legally invalid or ineffective under
86 | applicable law, such partial invalidity or ineffectiveness shall not
87 | invalidate the remainder of the License, and in such case Affirmer hereby
88 | affirms that he or she will not (i) exercise any of his or her remaining
89 | Copyright and Related Rights in the Work or (ii) assert any associated claims
90 | and causes of action with respect to the Work, in either case contrary to
91 | Affirmer's express Statement of Purpose.
92 |
93 | 4. Limitations and Disclaimers.
94 |
95 | a. No trademark or patent rights held by Affirmer are waived, abandoned,
96 | surrendered, licensed or otherwise affected by this document.
97 |
98 | b. Affirmer offers the Work as-is and makes no representations or warranties
99 | of any kind concerning the Work, express, implied, statutory or otherwise,
100 | including without limitation warranties of title, merchantability, fitness
101 | for a particular purpose, non infringement, or the absence of latent or
102 | other defects, accuracy, or the present or absence of errors, whether or not
103 | discoverable, all to the greatest extent permissible under applicable law.
104 |
105 | c. Affirmer disclaims responsibility for clearing rights of other persons
106 | that may apply to the Work or any use thereof, including without limitation
107 | any person's Copyright and Related Rights in the Work. Further, Affirmer
108 | disclaims responsibility for obtaining any necessary consents, permissions
109 | or other rights required for any use of the Work.
110 |
111 | d. Affirmer understands and acknowledges that Creative Commons is not a
112 | party to this document and has no duty or obligation with respect to this
113 | CC0 or use of the Work.
114 |
115 | For more information, please see
116 |
--------------------------------------------------------------------------------
/Samples/ListProceduralMacro.draco:
--------------------------------------------------------------------------------
1 | // Procedural macros are invoked by
2 | // foo!(arg1, arg2, ...)
3 | // or foo![arg1, arg2, ...]
4 | // or foo!{arg1, arg2, ...}
5 | //
6 | // The punctuation doesn't matter, it just needs to be pairwise.
7 | @procedural_macro(list)
8 | func make_list(args: []Ast): Result {
9 | val adds = List();
10 | for (a in args) adds.Add(quote!{ result.Add(#a); });
11 |
12 | return quote!{
13 | // In a new block to be a valid expression
14 | {
15 | val result = System.Collections.Generic.List();
16 | #(adds)...
17 | result
18 | }
19 | };
20 | }
21 |
22 | // Example time!
23 |
24 | func main() {
25 | val l = list![1, 2, 3];
26 | }
27 |
28 | // Expanded to:
29 | func main() {
30 | val l = {
31 | val result = System.Collections.Generic.List();
32 | result.Add(1);
33 | result.Add(2);
34 | result.Add(3);
35 | result
36 | };
37 | }
--------------------------------------------------------------------------------
/Samples/MemoizeMacro.draco:
--------------------------------------------------------------------------------
1 | // Attribute macros are functions annotated with 'attribute_macro', passing in
2 | // the name of the created attribute as an identifier. The name of the function
3 | // doesn't matter, it's not related to how you actually invoke the macro. This
4 | // is useful when there is potential that you need to reuse your macro logic in
5 | // multiple metaprograms. Other than the attribute, this is a regular function.
6 | // All syntax-based metaprograms are functions that take in the AST + the
7 | // optional arguments, then return the modified result or an expansion error.
8 | // Attribute macros mean that their target is the language element they are
9 | // annotating and they replace that element with their result. This macro can be
10 | // used to annotate functions to make them memoize their results by storing
11 | // already computed results in a dictionary. The biggest difference between this
12 | // and a Roslyn SourceGenerator, is that here the original function is extended
13 | // with the new functionality, we don't need to externally augment the function
14 | // and then reference an externally implemented function in the original
15 | // implementation.
16 |
17 | // The exact APIs is debatable, the point is more towards illustrating how this
18 | // doesn't have to be a super hard thing to do. Writing syntactic abstractions
19 | // like this should be simple.
20 |
21 | // Here 'unwrap' is used to mean unwrap the Ok value of a Result, or
22 | // return the error on error, similarly to Rust's '?''. The exact syntax is
23 | // debatable and isn't really an important part of the snippet.
24 |
25 | // A builtin macro could be provided that would act as a template engine around
26 | // the language, this is the role of 'quote!' (just like the Rust crate).
27 | @attribute_macro(Memoize)
28 | func memoize_logic(target: Ast, args: []Ast): Result {
29 | // First, we assert that the target is a function. The type-checking
30 | // functions can conveniently return a Result
31 | val target = unwrap target.asFunc(); // Variable shadowing can be lovely!
32 |
33 | // We don't expect any arguments
34 | if (args.Length > 0) return MacroExpansionError("Memoization expects no arguments!");
35 |
36 | // We will need this later
37 | val argNames = target.Signature.Parameters.Select(p => p.Name);
38 |
39 | // Here #(...) means substitution of an AST
40 | return quote!{
41 | // Declare a dictionary outside
42 | val cache = System.Collections.Generic.Dictionary();
43 | // Generate the new function
44 | #(target.Signature) // func name(...args): ReturnType
45 | {
46 | // Build a tuple of parameter names, check if cache has it
47 | if (!cache.TryGetValue((#(argNames),...), out val result) {
48 | // Not in the cache, invoke the original computation
49 | // We a bit cheat here by wrapping it up in a lambda and invoke it
50 | result = (func() {
51 | return #(target.Body);
52 | })();
53 | // Store
54 | cache.Add((#(argNames),...), result);
55 | }
56 | return result;
57 | }
58 | };
59 | }
60 |
61 | // Example:
62 |
63 | @Memoize
64 | func fib(n: int32): int32 =
65 | if (n < 2) 1
66 | else fib(n - 1) + fib(n - 2);
67 |
68 | // Expanded to:
69 | // val cache = System.Collections.Generic.Dictionary();
70 | // func fib(n: int32): int32 {
71 | // if (!cache.TryGetValue((n), out val result)) {
72 | // result = (func() {
73 | // return if (n < 2) 1
74 | // else fib(n - 1) + fib(n - 2);
75 | // })();
76 | // cache.Add((n), result);
77 | // }
78 | // return result;
79 | // }
80 |
--------------------------------------------------------------------------------
/Samples/Quine.draco:
--------------------------------------------------------------------------------
1 | import System.Console;
2 |
3 | func main() {
4 | var s = #"""
5 | import System.Console;
6 |
7 | func main() {
8 | var s = {0}"""
9 | {1}
10 | """{0};
11 | Write(s, '#', s);
12 | }
13 | """#;
14 | Write(s, '#', s);
15 | }
16 |
--------------------------------------------------------------------------------
/Samples/RecursiveFibonacci.draco:
--------------------------------------------------------------------------------
1 | func fib(n: int32): int32 =
2 | if (n < 2) 1
3 | else fib(n - 1) + fib(n - 2);
4 |
--------------------------------------------------------------------------------
/Samples/TruthMachine.draco:
--------------------------------------------------------------------------------
1 | import System.Console;
2 |
3 | func main() {
4 | val input = ReadLine();
5 | if (input == "0") {
6 | Write("0");
7 | }
8 | else {
9 | // We just assume 1 for anything non-0
10 | while (true) Write("1");
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Specification/Comments.md:
--------------------------------------------------------------------------------
1 | # Comments in code
2 | This document specifies regular comments and documentation comments.
3 | ## What are comments
4 | Comments are non-functional text written in the code that does not alter the behavior of the language element.
5 | ## Single line comments
6 | Single line comments start with a `//`, if the `//` is not part of a string, and end with a newline.
7 | ## Documentation comments
8 | Documentation comments are a special type of comments, they add a description to a language element. In draco, documentation comments are written using markdown.
9 | Documentation comments are continuous lines that start with a `///`, and everything that comes after the `///` is interpreted as markdown.
10 | The documentation comment is attached to the first language element declared under it. If there is no such element, the documentation comment is ignored like a normal comment.
11 | Linking to other language elements can be done using the regular markdown syntax, either `[Text that should be displayed](Path to the language element)` or ``, the latter being a shorthand for `[language element](language element)` to avoid repetition. Alternatively, the empty link `[Path to the language element]()` will be interpreted as `[Path to the language element](Path to the language element)` as well to be able to avoid syntactical ambiguities with the angle brackets variant. Linking to symbols using HTML links is not specified yet.
12 | The documentation comment is in the same scope as the language element the comment is attached to. If the language element exposes any language elements the comment could refer to, these elements are implicitly accessible for the comment without any further qualifications. This is the case for function definitions and their parameters. For example, if we use function `Abs` with one parameter `num`, this parameter can be accessed like `[num](num)`.
13 | Every markdown heading corresponds to a section in the documentation comment. Documentation comments are expected to be either a simple paragraph without any sections, or a more complex structure containing sections. A general description of the language element (in C# this would be under the `summary` tag) is expected either under the `summary` section, or at the start of the documentation without being contained in any sections. There is a small set of standard sections, but the user can use any section they want.
14 | The standard sections are:
15 | - `summary` - general description of the language element, if this section is not present any text at the start of the documentation that is not contained in any section is considered to be summary
16 | - `returns` - value the language element returns (only makes sense for functions).
17 | - `parameters` - description of the parameters the language element accepts, either enumeration or subsections are expected here (only makes sense for functions).
18 | - `type parameters` - description of the type parameters the language element accepts, either enumeration or subsections are expected here (only makes sense for functions).
19 | - `exception` - exceptions the language element throws (only makes sense for functions).
20 | - `example` - code example how to use the language element.
21 | Example of documentation comment with sections:
22 | ```js
23 | /// Function, that adds 2 numbers.
24 | /// # parameters
25 | /// - num1: The first number to add.
26 | /// - num2: The second number to add.
27 | /// # returns
28 | /// The sum of and .
29 | func Add(num1: int32, num2: int32): int32 = num1 + num2;
30 | ```
31 | The documentation generated from this comment could look something like:
32 |
33 | Function, that adds 2 numbers.
34 | parameters
35 | num1: The first number to add.
36 | num2: The second number to add.
37 | returns
38 | The sum of num1 and num2.
39 |
40 |
41 | Example of documentation comment without sections:
42 | ```js
43 | /// Adds [num1]() and [num2]().
44 | func Add(num1: int32, num2: int32): int32 = num1 + num2;
45 | ```
46 | The documentation generated from this comment could look something like:
47 |
50 |
--------------------------------------------------------------------------------
/Specification/ControlFlow.md:
--------------------------------------------------------------------------------
1 | # Basic control-flow/declarations
2 |
3 | This RFC lays down the fundamental control-flow and declaration structures for the language. It describes both the the syntax and intended semantics in a semi-formal way. The goal is to have even just some bare-bones elements that we can agree on and build the other RFCs and proposals on.
4 |
5 | ## Function definition
6 |
7 | This RFC introduces free-functions (functions that are not tied to types), member functions are not part of it.
8 |
9 | ### Syntax
10 |
11 | There will be two syntax variants, the "block syntax":
12 |
13 | ```swift
14 | func function_name(arg1: Type1, arg2: Type2): ReturnType {
15 | // Function body
16 | }
17 | ```
18 |
19 | And the "inline-expression" syntax (roughly equivalent to arrow-bodied methods in C#):
20 |
21 | ```swift
22 | func function_name(arg1: Type1, arg2: Type2): ReturnType = expression;
23 | ```
24 |
25 | The `: ReturnType` part is optional for both syntaxes.
26 |
27 | The parameter list can optionally contain a variadic argument list as the last parameter, which must have the `...parameterName: CollectionType` declaration syntax.
28 | ```swift
29 | func function_name(arg1: Type1, arg2: Type2, ...args: Array)
30 | ```
31 |
32 | If a collection is passed as a variadic argument, the collection won't be passed as individual elements - like in C# -, but as a single element instead. If the given collection should be passed as the individual elements it contains, the spread operator must be used.
33 | ```swift
34 | func foo(...args: Array