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

feat: Turn int and float into core types #225

Merged
merged 9 commits into from
Jun 24, 2024
Merged

feat: Turn int and float into core types #225

merged 9 commits into from
Jun 24, 2024

Conversation

mark-koch
Copy link
Collaborator

@mark-koch mark-koch commented May 28, 2024

This PR adds a new NumericType to the type hierarchy that now represents int and float.

Closes #250

@mark-koch mark-koch force-pushed the feat/numeric-tys branch 2 times, most recently from 8c04951 to d22d4bb Compare May 28, 2024 09:39
@mark-koch mark-koch requested a review from croyzor May 29, 2024 09:04
@@ -79,6 +86,23 @@ def check_instantiate(
return NoneType()


@dataclass(frozen=True)
class _NumericTypeDef(TypeDef):
"""Type definition associated with the builtin `None` type.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

associated with the Numeric type!


builtins = GuppyModule("builtins", import_builtins=False)

T = guppy.type_var(builtins, "T")
L = guppy.type_var(builtins, "L", linear=True)


# Define the nat type so scripts can import it
nat = nat_type_def
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect this to implement some numeric dunder methods, like __add__, __eq__, __gt__?

@@ -145,16 +122,12 @@ def synthesize(self, args: list[ast.expr]) -> tuple[ast.expr, Type]:

for i in range(len(args)):
args[i], ty = ExprSynthesizer(self.ctx).synthesize(args[i])
if isinstance(ty, OpaqueType) and ty.defn == self.ctx.globals["int"]:
if isinstance(ty, NumericType) and ty.kind == NumericType.Kind.Int:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't nat be valid too? Maybe bool?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arguably anything that implements __float__...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we need a better way to figure out which types are automatically coreced (also applies to function tuples etc.). These CustomCallCheckers are quite hacky...

I'm tempted to just leave it as is until we have a proper solution?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

arguably anything that implements float...

This only works as long as float is at the top of the numeric hierarchy. For example, if we add complex in the future, it might also have a __float__ method but shouldn't be coreced automtically.

Also we'd need coercsion from nat to int etc...

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the better interim solution is that we coerce NumericType instead of just int, then come up with something better down the line

Copy link
Collaborator

@croyzor croyzor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm surprised not to see any special handling for nat in the type checker, and that it doesn't have any methods implemented by default. Are we ever checking that nats >= 0?

@mark-koch
Copy link
Collaborator Author

My plan was to leave all of this to another PR so this one doesn't become too big. But I could also add it here if you'd prefer to look at everything?

@croyzor
Copy link
Collaborator

croyzor commented May 30, 2024

I think the better way to split it up would be NumericType in this PR, then the one that adds the functionality also adds nat

@mark-koch mark-koch changed the title feat: Add nat type and turn int and float into core types feat: Make bool a numeric type and turn int and float into core types May 30, 2024
@mark-koch mark-koch requested a review from croyzor May 30, 2024 12:49
@codecov-commenter
Copy link

codecov-commenter commented May 30, 2024

Codecov Report

Attention: Patch coverage is 95.52239% with 3 lines in your changes missing coverage. Please review.

Please upload report for BASE (main@b2901d8). Learn more about missing BASE report.

Files Patch % Lines
guppylang/checker/core.py 87.50% 1 Missing ⚠️
guppylang/tys/builtin.py 91.66% 1 Missing ⚠️
guppylang/tys/ty.py 96.87% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #225   +/-   ##
=======================================
  Coverage        ?   90.69%           
=======================================
  Files           ?       44           
  Lines           ?     4730           
  Branches        ?        0           
=======================================
  Hits            ?     4290           
  Misses          ?      440           
  Partials        ?        0           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

return func

def synthesize(self, args: list[ast.expr]) -> tuple[ast.expr, Type]:
args, _, inst = synthesize_call(self.func.ty, args, self.node, self.ctx)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really understand what this call is doing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It checks args against the function inputs and potentially infers some type args. The call to self._get_func().synthesize_call() below delegates to the corresponding integer function.

@qartik
Copy link
Member

qartik commented May 30, 2024

bools are now treated as a numeric values as in Python.

What's the motivation for this change?

@mark-koch
Copy link
Collaborator Author

What's the motivation for this change?

Mainly consistency with Python. Adding __add__ etc to bool is easy to do and Imo we should follow Python as closely as possible unless we have a good reason not to.

I don't feel super strongly though, so we could reconsider if numeric bools are controversial?

@qartik
Copy link
Member

qartik commented May 30, 2024

If we are considering guppy as a strongly typed language, I think bool should not be implicitly treated as a numeric type. We could certainly provide casting/conversion functions for explicit coercion, if they don't exist already.

@mark-koch mark-koch changed the title feat: Make bool a numeric type and turn int and float into core types feat: Turn int and float into core types Jun 24, 2024
@mark-koch
Copy link
Collaborator Author

@qartik I moved the bool change to another PR #263 and created issue #264 for discussion.

@croyzor Could you have another at this PR? Sorry for moving things around so much

@mark-koch mark-koch requested a review from croyzor June 24, 2024 13:52
@@ -145,6 +175,10 @@ def bool_type() -> OpaqueType:
return OpaqueType([], bool_type_def)


def int_type() -> NumericType:
return NumericType(NumericType.Kind.Int)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not contain some reference to int_type_def?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this used? I see a couple of places it'd work in this PR but it's just being inlined

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this not contain some reference to int_type_def?

No, only the int_type_def has a reference to a NumericType. The inverse mapping from type to type def is implemeted here:

def get_instance_func(self, ty: Type | TypeDef, name: str) -> CallableDef | None:
"""Looks up an instance function with a given name for a type.
Returns `None` if the name doesn't exist or isn't a function.
"""
type_defn: TypeDef
match ty:
case TypeDef() as type_defn:
pass
case BoundTypeVar() | ExistentialTypeVar() | SumType():
return None
case NumericType(kind):
match kind:
case NumericType.Kind.Int:
type_defn = int_type_def
case NumericType.Kind.Float:
type_defn = float_type_def
case kind:
return assert_never(kind)
case FunctionType():
type_defn = callable_type_def
case OpaqueType() as ty:
type_defn = ty.defn
case StructType() as ty:
type_defn = ty.defn
case TupleType():
type_defn = tuple_type_def
case NoneType():
type_defn = none_type_def
case _:
return assert_never(ty)

Is this used? I see a couple of places it'd work in this PR but it's just being inlined

Good point, it's indeed unused. I'll remove it 👍

args=num_params * [tys.TypeArg(tys.BoundedNatArg(n=INT_WIDTH))],
parent=UNDEFINED,
)
ops.CustomOp(extension=ext, op_name=op_name, args=args, parent=UNDEFINED)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice 👍

@mark-koch mark-koch merged commit 99217dc into main Jun 24, 2024
3 checks passed
@mark-koch mark-koch deleted the feat/numeric-tys branch June 24, 2024 16:03
github-merge-queue bot pushed a commit that referenced this pull request Jul 2, 2024
🤖 I have created a release *beep* *boop*
---


## [0.6.0](v0.5.2...v0.6.0)
(2024-07-02)


### Features

* Add array type ([#258](#258))
([041c621](041c621))
* Add nat type ([#254](#254))
([a461a9d](a461a9d))
* Add result function
([#271](#271))
([792fb87](792fb87)),
closes [#270](#270)
* Allow constant nats as type args
([#255](#255))
([d706735](d706735))
* Generate constructor methods for structs
([#262](#262))
([f68d0af](f68d0af)),
closes [#261](#261)
* Return already-compiled hugrs from `GuppyModule.compile`
([#247](#247))
([9d01eae](9d01eae))
* Turn int and float into core types
([#225](#225))
([99217dc](99217dc))


### Bug Fixes

* Add missing test file
([#266](#266))
([75231fe](75231fe))
* Loading custom polymorphic function defs as values
([#260](#260))
([d15b2f5](d15b2f5)),
closes [#259](#259)

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Unify numeric type representations
4 participants