-
Notifications
You must be signed in to change notification settings - Fork 30
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 C# Fluent API, along with LINQ #244
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.
Would it make sense to move the Retagging @mausch. |
Perhaps, yes, as that will reduce the 'noise'. |
I would love it if those functions where defined in a separate file. I don't like looking at them when I am trying to think about and work with the core Hedgehog concepts. |
@dharmaturtle, @moodmosaic, @TysonMN I went ahead and finished porting the rest of the functions marked with Either way, the rest of the modules could be ported as well, but they didn't seem to have pre-established C# support so I left them out. |
Looking forward trying this! Thank you for all the hard work 🍻 |
I think this should be evaluated again now that |
Agreed. |
I've rebased on Edit: Not sure what happened in that last build, says certain packages don't exist in nuget? |
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.
Overall, looks great.
What is visible in C# now? For example, Are Gen.Digit
and Gen.digit
both visible?
Maybe in this PR or a future one, the output of Property.Check
can give the C# code to recheck a failed property.
Oh, maybe you already answered this when you said
How is it that the F# modules are not exposed? |
I mean that they are exposed in the C# API. Both would be visible to C# users, with the advisory that they use the |
I think it might be better to not expose the F# modules, but I don't think this PR needs to wait for that change.
Assuming we don't expose the F# modules, would it be possible to expose the C# code in the same namespace, namely |
I think the only way to do that would be to provide a separate nuget package for C# users, and use some directives to change the functions or modules to be private? I don't think it's possible to just hide F# code from other .NET languages in the same package meant for F# consumption. |
That would be a great addition. 👍
I'm wondering how other projects deal with this 🤔 |
@adam-becker, there is a conflict in |
@TysonMN I saw that, I'm still at work and haven't had a chance to get to it yet. |
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.
Massive piece of work 🎢 💯 🚀 🦄 👍
This makes the F# part a lot cleaner as there are no attributes related to C# and no preprocessor directives related to Fable.
(I wonder if we could use T4 to generate all the stuff in CSharp/Xyz.fs.)
@adam-becker, if you can rebase this with master
(there's a conflict around Gen.dateTime) I believe we can consider merging this. 🍻
@moodmosaic Concerning the |
We could add back in only those I mentioned in the comments above. |
Is it only those? I see a few more functions in Also, I think this idea might be viable: #if CSHARP
module internal Gen =
#else
module Gen =
#endif We'd have to do 2 separate builds one with that symbol defined, one without. But this would hide all of the F# API for the C# package. We could also do the opposite for hiding the C# API from F#. |
You can use the
However, it only hides from F# editing environments. It still displays in C#... at least in Rider and Visual Studio. Dunno how to check what Ionide does. E.g. this module.... module Asdf =
[<CompiledName("HerpDerp"); CompilerMessage("This method is not intended for use from F#.", 10001, IsHidden=true, IsError=false)>]
let Qwerty = () looks like this in C# VS: but looks like this in F# VS: To be clear, you can still call it; it just won't show up in Intellisense: C# Rider: F# Rider: |
Yep, it's tricky to actually hide those... We've tried also this in the past: #156 (comment) |
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.
@TysonMN's suggestion to tackle #156 separately makes sense, given the size and context of this pull request.
However, since now it's going to be explicit whether you're using Hedgehog vs Hedgehog.CSharp, perhaps there's no need to think about #156.
The idea could be that
- if you're using Hedgehog.CSharp from C# code, nothing you pick up via IntelliSense should throw a NotSupportException
- if you're using stuff from Hedgehog (not Hedgehog.CSharp) from C# code, then anything that uses a statically resolved type parameter could throw...
Ready to merge at this point, once those 2 small suggestions I just left are resolved.
@moodmosaic Ready to merge! |
Great! Sometimes we can merge via a merge commit, and sometimes via squash and merge. What would you prefer? |
Either is fine with me |
|
||
static member FromBool (value : bool) : Property<unit> = | ||
Property.ofBool(value) | ||
|
||
static member FromGen (gen : Gen<Journal * Result<'T>>) : Property<'T> = | ||
Property.ofGen gen | ||
|
||
static member FromResult (result : Result<'T>) : Property<'T> = | ||
Property.ofResult result | ||
|
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.
Yeah, if we could generate all src/Hedgehog/CSharp/*.fs files via T4 it'd be awesome (T4 is a pain to work with OTOH). 👍
What a milestone 🚀 🌕 Thank you @adam-becker, and also @TysonMN and @dharmaturtle for the feedback. 👍 |
Fixes #172
I also followed the conversation on #183. I believe the best way to support C# is to just make a compatibility layer. I decided to target
Gen
initially to get some feedback before continuing. With that in mind, this PR is marked as a draft.Pros
bind2
just to be able to apply theCompiledNameAttribute
to support overloads. This is better accomplished with aclass
in F# since members allow overloading.Func<_>
incompatibilities. The current approach of adding "C# friendly" methods as needed would make this awkward to use from C#. Which module would a user import or access to get the method they're looking for?Hedgehog.CSharp
in this PR). Note that this isn't duplicating implementation of functions, just exposing a forwarding function for C# users.CompiledNameAttribute
from the core library helps Fable support because you can also remove the#if !FABLE_COMPILER ... #end
directives. The directive can be thrown on all of theHedgehog.CSharp
types instead and not compile any of the compatibility layer when using Fable.T
,TResult
) and F# ('a
,'b
)Cons
Example usage: