Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ad-hoc types #235

Merged
merged 9 commits into from May 29, 2016

Conversation

@bvssvni
Copy link
Member

commented May 27, 2016

Closes #236

This PR adds ad-hoc types to Dyon. It is a very simple type check that works well with dynamic modules, where ordinary type definitions are difficult to use since dynamic modules might be loaded in different orders and with different imports. Ad-hoc types makes it possible to have some extra type checks within the design space of Dyon.

How to use Ad-Hoc Types

Ad-hoc types in Dyon means you can write a name in front of the type of an argument, and the type checker will treat it as a distinct type. You can use any name that is not a built-in type in Dyon:

fn km(v: f64) -> km f64 { return clone(v) }

fn walk(distance: km f64) { ... }

If you omit the type, Dyon will use {} by default. It is common to use CamelCase for such types:

fn new_person(name: str, age: f64) -> Person {
    return { name: name, age: age }
}

The inner type and the ad-hoc type works with each other, so you can pass Person to {} and vice versa:

fn call(person: Person) {
    println("Hi " + person.name + "!")
}

call({ name: "John" })

Restricted algebra with Ad-hoc types

One usage of ad-hoc types is to add physical units safety to your program. For this reason, the ad-hoc types disallow + or - between an ad-hoc type and a built-in type:

 --- ERROR --- 
In `source/test.dyon`:

Type mismatch: Binary operator can not be used with `km f64` and `f64`
2,21:     println(km(5) + 4)
2,21:                     ^

When you use + or -, the result will be inferred to be the same ad-hoc type as both arguments.

Multiplication is not allowed because this often changes the physical unit. To do multiplication, you need a function that unwraps the type before multiplication:

fn main() {
    println(mul(km: km(5), km: km(4)))
}

fn km(v: f64) -> km f64 { return clone(v) }

fn km2(v: f64) -> km2 f64 { return clone(v) }

fn unwrap_km(v: km f64) -> f64 { return clone(v) }

fn mul_km_km(a: km f64, b: km f64) -> km2 f64 {
    return km2(unwrap(km: a) * unwrap(km: b))
}

bvssvni added some commits May 27, 2016

Added ad-hoc types
- Added “typechk/ad_hoc.dyon”
- Renamed “typecheck" module to “ty” to avoid confusion with
“lifetime::type check”
Allow addition between same ad-hoc types
- Added “typechk/add_ad_hoc.dyon”
- Added “typechk/add_ad_hoc_2.dyon”
Type check `+=` and `-=` for ad-hoc types
- Added “typechk/add_ad_hoc_3.dyon”
Fixed bug in lifetime checker that links wrong declarations
Should not link an item as declaration if it has ids.

- Added “typechk/add_ad_hoc_4.dyon”

@bvssvni bvssvni merged commit 45f8e93 into PistonDevelopers:master May 29, 2016

@bvssvni bvssvni deleted the bvssvni:ad_hoc_types branch May 29, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.