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

Implement type-level string append function #726

Merged
merged 6 commits into from
Jan 24, 2025

Conversation

krame505
Copy link
Contributor

@krame505 krame505 commented Aug 1, 2024

This adds a TApp type pseudo-constructor like TAdd and friends, for appending type-level strings.

@quark17
Copy link
Collaborator

quark17 commented Oct 17, 2024

Looks good! I'm a tad concerned that TApp can be misread as type application (like BSC's TAp), but I'm not sure that I have a better suggestion.

@mieszko
Copy link
Collaborator

mieszko commented Oct 17, 2024

Looks good! I'm a tad concerned that TApp can be misread as type application (like BSC's TAp), but I'm not sure that I have a better suggestion.

Yeah TApp looks to me like application of some kind. Why not just TAppend? Unambiguous, and not too long.

@krame505
Copy link
Contributor Author

I went with TApp mostly for consistency, the other type-level functions are all abbreviated to 3 letters: TAdd, TSub, TMul, TDiv, TLog, TExp, TMax, TMin.

TAppend is a little more verbose. No strong objection, though.

@quark17
Copy link
Collaborator

quark17 commented Nov 7, 2024

If we can decide on the name, then this can be merged. As far as consistency, note that the other type constructors are for numeric types. Another option for this one could be, say, TStrApp (which doesn't save any characters over TAppend). I have no strong objection to TAppend, but would feel better getting more opinions -- maybe we can discuss offline next week?

Can you confirm my understanding: This feature came up because it can be used with the other PR for splitting structs, but that PR doesn't include these commits? I get that this feature is generally useful, but I just wanted to understand any relationship/dependency between the PRs.

@krame505
Copy link
Contributor Author

krame505 commented Nov 7, 2024

I was originally planning to do the computation of names for split fields completely at the type level. I forget the exact blocking problem that I ran into with this approach, but I ultimately ended up doing the field name computation in the evaluator with ordinary type class methods instead. So this feature is not currently used by anything, but it seems like a good thing to have, for completeness.

Note that to make type-level string construction useful, we would probably also want to add a type-level primitive NumToStr :: # -> $.

@krame505
Copy link
Contributor Author

krame505 commented Nov 15, 2024

Meeting consensus: we'll call the primitives TStrCat and TNumToStr. We should also add a StrAlias type class, corresponding to Alias and NumAlias. We could have equivalent type classes StrCat and NumToStr, I'm not sure how useful these are however, with StrAlias.

I'll add these when I get around to it, hopefully before our next sync meeting.

@krame505
Copy link
Contributor Author

I finally got around to finishing this - I renamed TApp to TStrCat and added a TNumToStr primitive.

Copy link
Collaborator

@quark17 quark17 left a comment

Choose a reason for hiding this comment

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

Thanks! Just a few more nits. Should be minor, but let me know if you'd prefer me to do them.

Unrelated to your PR, I notice that there are issues in the existing documentation for numeric type functions and pseudo-functions (for example, it mixes up SizeOf and sizeOf which are not the same), and so I might want to go in an fix up that part of the documentation anyway.

@@ -4154,7 +4167,7 @@ \subsubsection{Rules}


%================================================================
\subsection{Operations on Numeric Types}
\subsection{Operations on Numeric and String Types}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you have thoughts on whether this should be one subsection versus two separate subsections ("Operations on Numeric Types" and "Operations on String Types")?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have no strong opinions here. I don't think there will be very many more string type operations added in the future, though.

@@ -21,11 +21,11 @@ opNumT i [x, y] | i == idTMin = Just (min x y)
opNumT _ _ = Nothing

numOpNames :: [Id]
numOpNames = [idTAdd, idTSub, idTMul, idTDiv, idTExp, idTLog, idTMax, idTMin]
numOpNames = [idTAdd, idTSub, idTMul, idTDiv, idTExp, idTLog, idTMax, idTMin, idTNumToStr]
Copy link
Collaborator

Choose a reason for hiding this comment

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

I notice that this is used in Pred.expandSyn to decide whether to apply type functions. That code uses isTFun to decide what functions can be applied and apTFun to apply them. While apTFun has been extended to know how to apply opStrT (and not just opNumT), the isTFun is still only returning True for numOpNames -- it should be extended to also include strOpNames.

Although, if we could avoid having lists that need to be kept in sync with functions, that'd be nice. For example, I wonder if the function can be changed to return a Maybe (using Nothing for unrecognized TFun IDs) and then you wouldn't need the separate list. But anyway, that's not required for your PR; it's sufficient to just strOpNames to Pred.isTFun.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure that the isTFun guard is even needed now - opNumT and opStrT already return Maybes. The default for an unrecognized type function in apTFun is foldl TAp t as, which is the same as for exp. Unless this guard exists as a performance optimization?

@quark17 quark17 merged commit 2917e47 into B-Lang-org:main Jan 24, 2025
79 checks passed
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.

3 participants