-
Notifications
You must be signed in to change notification settings - Fork 0
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
Basic values and tests #26
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid using abstract classes and classes here? There is no need for them. An idiomatic way in TypeScript is to rather use discriminated unions: { kind: 'int32', val: bigint } | { kind: 'bool', val: boolean }
.
The reason is that we would run into multiple issues with classes such as instanceof
, equality, hashing, etc.
Also, it's quite easy to construct values with discriminated unions like |
And how do you enforce field validity in those discriminated unions? The class constructors make sure u32 values are actually u32, I don't see a way of doing that with your suggestion. |
I am actually not sure about why you want to have field validation there. You definitely do not want validation in many cases, e.g., when copying values. This is typically done somewhere in the parser/reader. If you need validation, simply introduce a validation function that does a switch over different kinds. The intermediate representation is just data. |
Can you give me an example of such copying, where you would explicitly not want the validity check, because I genuinely don't understand what use case you have in mind. |
I don't want to get into a discussion between classes and discriminated unions in TypeScript. What I can say is that there are very few cases, where I have seen value in using classes (I mean, TypeScript classes) in TypeScript. Most of the time, plain objects and discriminated unions do the job just fine. Here are just a few things that make TS classes hard to use: useless equality, useless In your PR, we need something similar to sealed classes in Scala. Discriminated unions provide you with exactly that. You don't want to inherit from values, nor you need other features of classes. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like it really much better! Left a few stylistic comments.
solarkraft/src/state/value.ts
Outdated
export type IntValue = { | ||
val: bigint | ||
type: string | ||
} & (IntValue_u32 | IntValue_i32 | IntValue_u64 | IntValue_i64 | IntValue_u128 | IntValue_i128) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would not you simply enumerate all cases right here? You still have to define types for IntValue_u32
below.
For instance, this is just immediate and does not require any scrolling:
export type IntValue =
{ val: bigint, type: "u32" }
| { val: bigint, type: "i32" }
| { val: bigint, type: "u64" }
...
Alternatively, we could do:
export type IntValue =
{ type: "uint", bits: 32 | 64 | 128, val: bigint }
{ type: "int", bits: 32 | 64 | 128, val: bigint }
solarkraft/src/state/value.ts
Outdated
export type IntValue_u32 = { | ||
type: "u32" | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is the value of these definitions?
solarkraft/src/state/value.ts
Outdated
} | ||
|
||
// Byte arrays (Bytes, BytesN) | ||
// The `len` field is present iff the length is fixed (i.e. for BytesN) | ||
// TODO: tests | ||
export class ArrValue implements Value { | ||
export type ArrValue = { | ||
val: IntValue_u32[] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if we already know that we have an unsigned u32
here, why don't we just use number
? Most likely, you would have to use the array length in loops, which would make it much easier if we are using number
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good! Let's merge it. I think you would still run into issues when looping over bigints, but we can deal with that later.
Partially addresses #23 (missing compound values, e.g. Map/Vec)