digitalmars.D.learn - returning different types via function
- seany (17/17) Nov 19 2013 Consider this:
- seany (2/2) Nov 19 2013 Uh I forgot to mention that it should do this without global
- Brad Anderson (3/20) Nov 19 2013 You could use std.typecons.Nullable, std.variant.Variant, or
- Dicebot (6/12) Nov 19 2013 You can wrap return type in Variant
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (6/17) Nov 19 2013 In addition to what the others said, I see two more options:
- bearophile (22/38) Nov 19 2013 I told you to use ref if you want to modify in-place the length
- Dicebot (5/12) Nov 19 2013 I don't want to argue this in details right now but I think that
- bearophile (7/11) Nov 19 2013 Nullable is a struct, it doesn't introduce a new leavel of
- Meta (19/21) Nov 19 2013 I have found that Nullable is pretty much useless for this type
- bearophile (20/32) Nov 20 2013 This code doesn't throw, so the behavour is different:
- Jesse Phillips (8/11) Nov 19 2013 I think you have a misunderstanding here. C does not allow you to
Consider this: I have a function FUNC, it takes a string array, and does something with it, and retruns the same. Implemented based on a previous thread, here is what i have string[] FUNC (ref string[] ZZ) { /* do something */ } and the calling is, ZZ = FUNC(ZZ) Now, I want, should the function be not successful in doing what it intends to do, to return a boolean value of false, to ZZ, un fortunately ZZ is already a string[] (so i want liek a C style fopen -like function, that , although called with the syntax: file *f = fopen(balh, "bla"); can set f to be false) Is this possible in D?
Nov 19 2013
Uh I forgot to mention that it should do this without global variables, and without try / catch
Nov 19 2013
On Tuesday, 19 November 2013 at 19:15:10 UTC, seany wrote:Consider this: I have a function FUNC, it takes a string array, and does something with it, and retruns the same. Implemented based on a previous thread, here is what i have string[] FUNC (ref string[] ZZ) { /* do something */ } and the calling is, ZZ = FUNC(ZZ) Now, I want, should the function be not successful in doing what it intends to do, to return a boolean value of false, to ZZ, un fortunately ZZ is already a string[] (so i want liek a C style fopen -like function, that , although called with the syntax: file *f = fopen(balh, "bla"); can set f to be false) Is this possible in D?You could use std.typecons.Nullable, std.variant.Variant, or switch to using exceptions for error reporting.
Nov 19 2013
On Tuesday, 19 November 2013 at 19:15:10 UTC, seany wrote:Now, I want, should the function be not successful in doing what it intends to do, to return a boolean value of false, to ZZ, un fortunately ZZ is already a string[] (so i want liek a C style fopen -like function, that , although called with the syntax: file *f = fopen(balh, "bla"); can set f to be false) Is this possible in D?You can wrap return type in Variant (http://dlang.org/phobos/std_variant.html) but it is inefficient, weakens typing and considered a bad approach in natively compiled language. Better approach probably is to use null as an indicator (as string[] is a reference type) or throw an exception.
Nov 19 2013
On 11/19/2013 11:15 AM, seany wrote:Consider this: I have a function FUNC, it takes a string array, and does something with it, and retruns the same. Implemented based on a previous thread, here is what i have string[] FUNC (ref string[] ZZ) { /* do something */ } and the calling is, ZZ = FUNC(ZZ)In addition to what the others said, I see two more options: a) Instead of returning the same slice return a flag. (The slice is available through the out parameter anyway.) b) Return a struct (or Tuple) with two members. Ali
Nov 19 2013
seany:I have a function FUNC, it takes a string array, and does something with it, and retruns the same. Implemented based on a previous thread, here is what i have string[] FUNC (ref string[] ZZ)I told you to use ref if you want to modify in-place the length of the array, as in the exaple you have shown. In general you don't need the ref.Now, I want, should the function be not successful in doing what it intends to do, to return a boolean value of false, to ZZ, un fortunately ZZ is already a string[] (so i want liek a C style fopen -like function, that , although called with the syntax: file *f = fopen(balh, "bla"); can set f to be false) Is this possible in D?The clean design is to use std.typecons.Nullable: Nullable!(string[]) func(string[] zz) { Also consider making zz const (with "in"), and creating a pure/nothrow function: Nullable!(string[]) func(in string[] zz) pure nothrow { A less clean but sometimes acceptable design is to use a "out" variable in func, and return a boolean: bool func(string[] zz, out string[] result) { -------------------- Dicebot:You can wrap return type in Variant (http://dlang.org/phobos/std_variant.html) but it is inefficient, weakens typing and considered a bad approach in natively compiled language. Better approach probably is to use null as an indicator (as string[] is a reference type) or throw an exception.A Nullable in usually efficient enough (there is even an alternative Nullable that doesn't increase the data size), it makes typing stronger, and it should become more common in system languages (and indeed it's commonly used in Rust, where the pattern matching makes its usage nicer). [] is a bad indicator because perhaps ZZ could be empty, so you are mixing signals. Bye, bearophile
Nov 19 2013
On Tuesday, 19 November 2013 at 19:31:41 UTC, bearophile wrote:A Nullable in usually efficient enough (there is even an alternative Nullable that doesn't increase the data size), it makes typing stronger, and it should become more common in system languages (and indeed it's commonly used in Rust, where the pattern matching makes its usage nicer). [] is a bad indicator because perhaps ZZ could be empty, so you are mixing signals.I don't want to argue this in details right now but I think that simply banning null references as valid arrays in program as a whole via contracts is better approach than adding extra level of indirection via Nullable ;)
Nov 19 2013
Dicebot:I don't want to argue this in details right now but I think that simply banning null references as valid arrays in program as a whole via contracts is better approach than adding extra level of indirection via Nullable ;)Nullable is a struct, it doesn't introduce a new leavel of indirection (sometimes it doesn't even add new data). And in the specific situation what's better could only be judged by the OP, because he/she has not shown the code. Bye, bearophile
Nov 19 2013
On Tuesday, 19 November 2013 at 19:31:41 UTC, bearophile wrote:The clean design is to use std.typecons.Nullable: Nullable!(string[]) func(string[] zz) {I have found that Nullable is pretty much useless for this type of usage, because it aliases itself to the underlying value, and then any safety it would provide is lost. See the following: import std.typecons; Nullable!(string[]) func(string[] zz) pure nothrow { return Nullable!(string[])(); } void main() { //AssertError thrown for trying to get //a value that is null. Might as well //return null at this point auto x = func(["test"]) ~ ["test"]; } Nullable either needs to be changed, or a new type that doesn't alias itself to the underlying value needs to be added to std.typecons.
Nov 19 2013
Meta:import std.typecons; Nullable!(string[]) func(string[] zz) pure nothrow { return Nullable!(string[])(); } void main() { //AssertError thrown for trying to get //a value that is null. Might as well //return null at this point auto x = func(["test"]) ~ ["test"]; }This code doesn't throw, so the behavour is different: string[] func(string[] zz) pure nothrow { return []; // This calls the runtime! } void main() { auto x = func(["test"]) ~ ["test"]; } In this case you are saying that an empty string[] is a correct output for func, while in the case with Nullable you are saying that it can't return an empty result. But I agree that the design of a language like Whiley is better, with its Flow Typing: http://whiley.org/guide/typing/flow-typing/ In such case Whiley forces you to analyse the return of func(), and after the analysis the type of such return value changes according to if the branch you are seeing. So exceptions happen, and less programmer mistakes. Bye, bearophile
Nov 20 2013
On Tuesday, 19 November 2013 at 19:15:10 UTC, seany wrote:(so i want liek a C style fopen -like function, that , although called with the syntax: file *f = fopen(balh, "bla"); can set f to be false)I think you have a misunderstanding here. C does not allow you to return "false." Instead C states that 0/NULL is false. Similarly D also considers null and 0 to be false inside a conditional (where in D's case those are two different values). So yes, you can do the same in D, but since false, null, and 0 are actually all different types and will not implicitly cast to the other.
Nov 19 2013