Skip to content

Commit 2a96c3c

Browse files
committed
docs
1 parent fee3e8e commit 2a96c3c

File tree

1 file changed

+104
-29
lines changed
  • manifold-deps-parent/manifold-params

1 file changed

+104
-29
lines changed

manifold-deps-parent/manifold-params/README.md

Lines changed: 104 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,46 @@
66
[![chat](https://img.shields.io/badge/discord-manifold-seagreen.svg?logo=discord)](https://discord.gg/9x2pCPAASn)
77
[![GitHub Repo stars](https://img.shields.io/github/stars/manifold-systems/manifold?logo=github&style=flat&color=tan)](https://github.com/manifold-systems/manifold)
88

9-
The `manifold-params` project is a compiler plugin that implements optional parameters and named arguments for methods,
10-
constructors, and records. Use it with any Java project to add clarity and flexibility to call sites and to reduce boilerplate
11-
in class definitions.
9+
The `manifold-params` project is a compiler plugin that implements binary compatible _optional parameters and named arguments_
10+
for methods, constructors, and records. Use it with any Java project to add clarity and flexibility to call sites and as
11+
a refreshing alternative to method overloads and builders.
1212

1313
```java
1414
public String valueOf(char[] data,
1515
int offset = 0,
1616
int count = data.length - offset) {...}
1717

18-
valueOf(array) // use default values for offet and count
19-
valueOf(array, 2) // use default value for count
20-
valueOf(array, count:20) // use default value for offset
18+
valueOf(array) // use default args for offet and count
19+
valueOf(array, 2) // use default args for count
20+
valueOf(array, count:20) // use default arg just for offset by naming count argument
2121
```
2222

23-
Optional parameters and named arguments are fully integrated in both **IntelliJ IDEA** and **Android Studio**. Use the IDE's
24-
features to be more productive with optional parameters and named arguments.
23+
Optional parameters and named arguments are fully integrated in both **IntelliJ IDEA** and **Android Studio**.
24+
25+
<!-- TOC -->
26+
* [Optional parameters & named arguments](#optional-parameters--named-arguments)
27+
* [Optional parameters](#optional-parameters)
28+
* [Named arguments](#named-arguments)
29+
* [Overloading and overriding](#overloading-and-overriding)
30+
* [Binary compatible](#binary-compatible)
31+
* [Notes & tidbits](#notes--tidbits)
32+
* [IDE Support](#ide-support)
33+
* [Install](#install)
34+
* [Setup](#setup)
35+
* [Building this project](#building-this-project)
36+
* [Using this project](#using-this-project)
37+
* [Binaries](#binaries)
38+
* [Gradle](#gradle)
39+
* [Maven](#maven)
40+
* [Javadoc](#javadoc)
41+
* [License](#license)
42+
* [Versioning](#versioning)
43+
* [Author](#author)
44+
<!-- TOC -->
2545

2646
## Optional parameters
2747

28-
An optional parameter has a default value assigned to it, much like a field or local variable with an initial value.
48+
An optional parameter has a default value, much like a field or local variable can have an initial value.
2949
```java
3050
void println(String text = "") {...}
3151
```
@@ -36,29 +56,11 @@ println("flubber");
3656
println(text: "flubber"); // named argument syntax
3757
```
3858

39-
A default value may be an arbitrary expression of any complexity and can reference preceding parameters.
59+
A default value expression may be arbitrarily complex and can reference preceding parameters.
4060
```java
4161
public record Destination(Country country, String city = country.capital()) {}
4262
```
4363

44-
A method override automatically inherits all the super method's default parameter values. The default values are fixed in
45-
the super class and may not be changed in the overriding method.
46-
```java
47-
public interface Contacts {
48-
Contact add(String name, String address = null, String phone = null);
49-
}
50-
51-
public class MyContacts implements Contacts {
52-
@Override // no default parameter values allowed here
53-
public Contact add(String name, String address, String phone) {...}
54-
}
55-
56-
Contacts contacts = new MyContacts();
57-
contacts.add("Fred");
58-
// calling directly inherits defaults
59-
((MyContacts)contacts).add("Bob");
60-
```
61-
6264
If an optional parameter precedes a required parameter, positional arguments may still be used with all the parameters.
6365
```java
6466
public Item(int id = -1, String name) {...}
@@ -101,7 +103,61 @@ configure("MyConfig",
101103
showName: false,
102104
autoSave: false);
103105
```
104-
106+
107+
## Overloading and overriding
108+
109+
A method override automatically inherits all the super method's default parameter values. The default values are fixed in
110+
the super class and may not be changed in the overriding method.
111+
```java
112+
public interface Contacts {
113+
Contact add(String name, String address = null, String phone = null);
114+
}
115+
116+
public class MyContacts implements Contacts {
117+
@Override // no default parameter values allowed here, they are strictly inherited
118+
public Contact add(String name, String address, String phone) {...}
119+
}
120+
```
121+
122+
A method having optional parameters logically consists of the set of methods comprising the methods one would otherwise
123+
write if using Java's idiomatic method overloads.
124+
```java
125+
void message(String content, int id = 0, LocalTime timestamp = null )
126+
```
127+
Logically occupies the following method signatures.
128+
```java
129+
void message(String)
130+
void message(String, int)
131+
void message(String, int, LocalTime)
132+
```
133+
These are called the _sub-signatures_ of the optional parameter method.
134+
135+
An optional parameter method automatically overrides any super type methods whose signatures are _sub-signatures_ of the
136+
optional parameter method. Generally, a sub-signature is one that partially matches the optional parameter method using
137+
Java's idiomatic "telescoping" method overload analogy as described above.
138+
```java
139+
class Base {
140+
void func() {...}
141+
}
142+
143+
class Sub extends Base {
144+
@Override
145+
void func(int id = 0) {...}
146+
}
147+
```
148+
`Sub#func(int)` indirectly overrides `Base#func()`. As with full signature overriding, the compiler issues a warning for
149+
this if `@Override` is not applied to `func(int)`. Note, a future release may include a more suitable annotation to name
150+
specific overloaded method signatures.
151+
152+
Overloading is permitted with optional parameter methods, however a compiler error results if sub-signatures overlap.
153+
```java
154+
class Sample {
155+
void func()
156+
void func(int alpha = 0) //error: clashes with func()
157+
void func(int beta, int gamma = 0) //error: clashes with func(int)
158+
}
159+
```
160+
105161
## Binary compatible
106162

107163
Adding new optional parameters to existing methods is binary compatible with code compiled before adding the new parameters.
@@ -123,6 +179,25 @@ size(myWidth);
123179
size(myWidth, myHeight);
124180
```
125181

182+
## Notes & tidbits
183+
184+
#### Why limit named arguments to only methods with optional parameters?
185+
Since the feature is neither part of the language nor the JVM, supporting named args for arbitrary methods would incur a
186+
bit of perf/space overhead for each method/constructor/record, which isn't really justifiable considering modern IDEs like
187+
IntelliJ IDEA already render positional argument names, aka "name hints", in call sites. Basically, if you want this feature,
188+
you already have it without any direct language support. Right?
189+
190+
Where named arguments become invaluable is when used as a means to select optional parameters. The synergy between these
191+
two features provides a concise, flexible, and maintainable alternative to builders and "telescoping" method/constructor
192+
overloads.
193+
194+
#### Why does the named argument syntax use `:` instead of `=`?
195+
Indeed, many languages having named arguments, such as Kotlin and Scala, use the syntax: `foo(x = 8)`. One problem with
196+
that, however, is Java's assignment expression clashes where `x = 8` may be parsed as an assignment as opposed to a mapping
197+
of an argument. While this could be worked out, overloading the assignment operator in a prominent place like argument parsing
198+
probably isn't the best idea.
199+
200+
Perhaps the main reason is aesthetics. `x: 8` just reads more like a naming or labeling of something. Shrug.
126201
127202
# IDE Support
128203

0 commit comments

Comments
 (0)