0% found this document useful (0 votes)
2 views

lect20-create-typesystem

The document discusses the implementation of a type system in Java, emphasizing the importance of preventing null pointer exceptions through the use of the Optional<T> type introduced in Java 8. It outlines guidelines for using Optional effectively, as well as the structure of a type system, including type hierarchy, type rules, type introduction, and dataflow. The document also mentions the Checker Framework for creating custom type checkers to enforce these rules and improve code quality.

Uploaded by

David Tsutsui
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

lect20-create-typesystem

The document discusses the implementation of a type system in Java, emphasizing the importance of preventing null pointer exceptions through the use of the Optional<T> type introduced in Java 8. It outlines guidelines for using Optional effectively, as well as the structure of a type system, including type hierarchy, type rules, type introduction, and dataflow. The document also mentions the Checker Framework for creating custom type checkers to enforce these rules and improve code quality.

Uploaded by

David Tsutsui
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

How to implement a type system

CSE 331
University of Washington
Michael Ernst
Motivation

java.lang.NullPointerException
java.lang.NullPointerException
Java's type system is too weak
Type checking prevents many errors
int i = "hello";

Type checking doesn't prevent enough errors

System.console().readLine();
Java's type system is too weak
Type checking prevents many errors
int i = "hello";

Type checking doesn't prevent enough errors


NullPointerException
System.console().readLine();
Prevent null pointer exceptions
Java 8 introduces the Optional<T> type
● Wrapper; content may be present or absent

● Constructor: of(T value)


● Methods: boolean isPresent(), T get()

Optional<String> maidenName;
Optional reminds you to check
Without Optional: With Optional:
possible possible
NullPointerException NoSuchElementException
String mName; Optional<String> omName;
mName.equals(...); omName.get().equals(...);
if (mName != null) { if (omName.isPresent()) {
mName.equals(...); omName.get().equals(...);
} } possible
Complex rules for using Optional correctly! NullPointerException
Other guidelines from:
Stephen Colebourne, Edwin
How not to use Optional Dalorzo, Vasco Ferreira C.,
Brian Goetz, Daniel
Olszewski, Nicolai Parlog,
Oleg Shelajev, ...
Stuart Marks’s rules:
1. Never, ever, use null for an Optional variable or return value.
2. Never use Optional.get() unless you can prove that the Optional is present.
3. Prefer alternative APIs over Optional.isPresent() and Optional.get().
4. It’s generally a bad idea to create an Optional for the specific purpose of
Let’s enforce the
chaining methods from it to get a value.
5. rules with a tool.
If an Optional chain has a nested Optional chain, or has an intermediate
result of Optional, it’s probably too complex.
6. Avoid using Optional in fields, method parameters, and collections.
7. Don’t use an Optional to wrap any collection type (List, Set, Map). Instead,
use an empty collection to represent the absence of values.
Which rules to enforce with a tool
Stuart Marks’s rules:
1. Never, ever, use null for an Optional variable or return value.
2. Never use Optional.get() unless you can prove that the Optional is present.
3. Prefer alternative APIs over Optional.isPresent() and Optional.get().
4. It’s generally a bad idea to create an Optional for the specific purpose of
chaining methods from it to get a value.
5. If an Optional chain has a nested Optional chain, or has an intermediate
result of Optional, it’s probably too complex.
6. Avoid using Optional in fields, method parameters, and collections.
7. Don’t use an Optional to wrap any collection type (List, Set, Map). Instead,
use an empty collection to represent the absence of values.
Which rules to enforce with a tool
Stuart Marks’s rules:
1. Never, ever, use null for an Optional variable or return value.
2. Never use Optional.get() unless you can prove that the Optional is present.
3. Prefer alternative APIs over Optional.isPresent() and Optional.get().
4. It’s generally a bad idea to create an Optional for the specific purpose of
These are
chaining methods from it to get a value.
5. type system properties.
If an Optional chain has a nested Optional chain, or has an intermediate
result of Optional, it’s probably too complex.
6. Avoid using Optional in fields, method parameters, and collections.
7. Don’t use an Optional to wrap any collection type (List, Set, Map). Instead,
use an empty collection to represent the absence of values.
Define a type system
Define a type system
1. Type hierarchy (subtyping)
2. Type rules (what operations are illegal)
3. Type introduction (what types for literals, …)
4. Dataflow (run-time tests)

We will define two type systems:


Nullness and Optional
Define a type system
1. Type hierarchy (subtyping)
2. Type rules (what operations are illegal)
3. Type introduction (what types for literals, …)
4. Dataflow (run-time tests)
1. Type hierarchy
Animal Object

Reptile Mammal List Number

Giraffe Human Integer Float


2 pieces of information:
● the types
● their relationships (lower = fewer values, more properties)
Type hierarchy for nullness

@Nullable @NonNull

@NonNull @Nullable

@NonNull @Nullable

2 pieces of information:
● the types
● their relationships
Type hierarchy for nullness

@Nullable
@Nullable @NonNull

@NonNull @Null

@NonNull @Nullable

2 pieces of information:
● the types
● their relationships
Type hierarchy for Optional
“Never use Optional.get() unless you can prove that the Optional is present.”

@Maybe
@Nullable
Present

@NonNull @Present

2 pieces of information:
● the types
● their relationships
Type = type qualifier + Java basetype
@Present Optional<String> maidenName;
Type qualifier Java basetype
Type @MaybePresent
Optional<String>

Default qualifier = @MaybePresent @Present


Optional<String>
● @MaybePresent Optional<String>
equivalent
● Optional<String>
Type = type qualifier + Java basetype
@Present Optional<String> maidenName;
Type qualifier Java basetype
Type @MaybePresent
Optional<String>

Default qualifier = @MaybePresent @Present


Optional<String>
● @MaybePresent Optional<String>
equivalent
● Optional<String>
Define a type system
1. Type hierarchy (subtyping)
2. Type rules (what operations are illegal)
3. Type introduction (what types for literals, …)
4. Dataflow (run-time tests)
2. Type rules
To prevent null pointer exceptions:
● expr.field

expr.getValue()
receiver must be non-null
● synchronized (expr) { … }
monitor must be non-null
● ...
@MaybePresent

Type rules for Optional @Present


“Never use Optional.get() unless you can prove that the Optional is present.”

Only call Optional.get() on a receiver of type


@Present Optional. example call:

myOptional.get()
class Optional<T> {
T get() { … } example call:

} a.equals(b)
@MaybePresent

Type rules for Optional @Present


“Never use Optional.get() unless you can prove that the Optional is present.”

Only call Optional.get() on a receiver of type


@Present Optional. example call:

myOptional.get()
class Optional<T> {
T get(Optional<T> this) { … }
}
@MaybePresent

Type rules for Optional @Present


“Never use Optional.get() unless you can prove that the Optional is present.”

Only call Optional.get() on a receiver of type


@Present Optional. example call:

myOptional.get()
class Optional<T> {
T get(@Present Optional<T> this) {…}
}
@MaybePresent

Type rules for Optional @Present


“Never use Optional.get() unless you can prove that the Optional is present.”

Only call Optional.get() on a receiver of type


@Present Optional. example call:

myOptional.get()
class Optional<T> {
T get(@Present Optional<T> this) {…}
T orElseThrow(@Present O… this, …) {…}
}
Define a type system
1. Type hierarchy (subtyping)
2. Type rules (what operations are illegal)
3. Type introduction (what types for literals…)
4. Dataflow (run-time tests)
Type introduction rules
For Nullness type system:
● null : @Nullable

● "Hello World" : @NonNull


@MaybePresent

Type introduction for Optional @Present


“Never use Optional.get() unless you can prove that the Optional is present.”

Optional<T> of(T value) {…}


Optional<T> ofNullable(T value){…}
@MaybePresent

Type introduction for Optional @Present


“Never use Optional.get() unless you can prove that the Optional is present.”

@Present Optional<T> of(T value) {…}


Optional<T> ofNullable(@Nullable T value){…}
Define a type system
1. Type hierarchy (subtyping)
2. Type rules (what operations are illegal)
3. Type introduction (what types for literals, …)
4. Dataflow (run-time tests)
Flow-sensitive type refinement
After an operation, give an expression a more
specific type

@Nullable Object x; @Nullable Object y;


if (x != null) { y = new SomeType();
... x is @NonNull here ... y is @NonNull here
} y = unknownValue;
... x is @Nullable again ... y is @Nullable again
@MaybePresent

Type refinement for Optional @Present


“Never use Optional.get() unless you can prove that the Optional is present.”

After receiver.isPresent() returns true,


the receiver’s type is @Present
@MaybePresent Optional<String> x;
if (x.isPresent()) {
... x is @Present here
}
... x is @MaybePresent again
Now, let’s implement it
Follow the instructions in the
Checker Framework Manual
https://checkerframework.org/manual/#creating-a-checker
You can use the Optional Checker
Distributed with the Checker Framework
Checks 6 of the 7 rules for using Optional
Pluggable type-checking improves code
Checker Framework for creating type checkers
● Featureful, effective, easy to use, scalable
Prevent bugs at compile time
Create custom type-checkers
Improve your code!

http://CheckerFramework.org/

You might also like