Thank you for writing and for your valuable feedback Brian.  Based on your 
feedback, I was going to hold off on releasing my proposed v3 and go with 
your suggestion of writing an IsFinite() method so that my module could 
panic if it detects that code would run forever.

But I started thinking about what you said about interfaces in Go, and that 
one should prefer returning a concrete type over an interface. Then I 
realised that all I need to do is make my FiniteNumber type in v3 be a 
concrete type and not an interface, but keep Sequence, FiniteSequence, and 
Number as interfaces.  When I do that, I get both compile time checking for 
code that would run forever AND I get all my examples for the FiniteNumber 
type, which implements Number, in my go documentation. Thanks to your 
feedback, my proposed v3 would definitely be superior to the existing v2.

On Saturday, November 18, 2023 at 9:19:43 AM UTC-6 Brian Candler wrote:

> Maybe you're overthinking this. One option would be for Number to have a 
> boolean attribute saying whether it's definitely finite, exposed as an 
> IsFinite() method on Sequence. Calling FindLast() on a sequence where 
> IsFinite() is false would panic. It's not compile-time safe, but it's 
> better than an infinite loop.
>
> Potentially, sqroot.Sqrt(9) could set IsFinite true (if that's cheap to 
> determine).
>
> > But in v3, Number has to be an interface because FiniteNumber has to 
> extend Number
>
> I don't think it has to "extend" (do you mean "embed"?): there are other 
> ways to share common code, e.g. factor it out into helper functions.
>
> There is no need for types which implement the same interface to have any 
> structural commonality at all.  Nor do overlapping interfaces for that 
> matter.
>
> In Go, the rule of thumb is: accept interfaces, return concrete types.  
> (The main exception is errors, where it's conventional to return an error 
> interface value, and a nil interface means "no error")
>
> Hence you could have interfaces Sequence and FiniteSequence defined with 
> the same set of methods, except that FiniteSequence has an extra dummy 
> method like ReallyIsFinite().  It's never called, but is implemented by 
> FiniteNumber and not Number, for type checking purposes only.
>
> On Saturday, 18 November 2023 at 13:41:37 UTC Travis Keep wrote:
>
>> I have published this module: 
>> https://pkg.go.dev/github.com/keep94/sqroot/v2 for analysing square 
>> roots and cube roots.  The module works, but it is easy to write code that 
>> will run forever. For example in v2:
>>
>> // Print the position of the last 7 in the square root of 2. Oops, the 
>> square root of 2 goes
>> // goes forever.
>> fmt.Println(sqroot.FindLast(sqroot.Sqrt(2), []int{7}))
>>
>> // This code snippet runs in a finite amount of time as it prints the 
>> position of the
>> // last 7 within the first 100 digits of the square root of 2.
>> fmt.Println(sqroot.FindLast(sqroot.Sqrt(2).WithSignificant(100), 
>> []int{7}))
>>
>> v3, which hasn't been published makes it so that most code that would run 
>> forever won't compile.  It does this by introducing new types: 
>> FiniteSequence which extends Sequence and FiniteNumber which extends 
>> Number.  In v3, sqroot.Sqrt() returns a Number since square roots can have 
>> either a finite or infinite number of digits, but 
>> sqroot.Sqrot(2).WithSignificant(100) returns a FiniteNumber because it can 
>> have no more than 100 digits.  In v3, sqroot.FindLast() takes a 
>> FiniteSequence as a parameter, which is how 
>> fmt.Println(sqroot.FindLast(sqroot.Sqrt(2), []int{7})) won't compile in v3.
>>
>> The safety that v3 adds is great, but it comes at a cost. In v2, Number 
>> is a concrete type. Its methods have examples in the documentation. But in 
>> v3, Number has to be an interface because FiniteNumber has to extend Number 
>> and Go does not support inheritance of concrete types.  With Number as an 
>> interface, all the examples for the Number methods disappear from the 
>> documentation.  
>>
>> Also v3 adds some extra complexity with its diamond inheritance tree. 
>> FiniteSequence and Number extend Sequence, and FiniteNumber extends Number 
>> and FiniteSequence.
>>
>> So I am wondering whether or not to publish v3.  v3 is definitely harder 
>> to misuse than v2, but v3 can't have all the code examples that v2 has 
>> because Number is an interface in v3 not a concrete type.
>>
>> So I am wondering what the community thinks is best in this situation.
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/1860d329-bf43-4518-a3d4-f9923fd5389en%40googlegroups.com.

Reply via email to