Is there a use for... [modified]
-
Valid in current paradigm:
var a = 5.5;
Invalid in current paradigm, but valid if paradigm theoretically adopted by C#:
a = new func(delegate() { return 5.5; });
Using a theoretical library of additional functions, both are valid:
DTBase a = (DTVar)5.5;
a = new DTFunc(delegate() { return 5.5; });The key point is that, instead of being a specific type of variable, "a" is now defined by what you get when you call it.
-
In my meanderings through weird code ideas, I wrote down some simple classes in C# based on the idea of "What if variables were typed based on what they returned when called, using that as what they are." So, for example, an equation that returns a double "is" a double (or derived from DTBase(double)); a DTFunc(string) that concatenates a string based on relevant factors "is" a string (or derived from DTBase(string)) and, of course, a DTVar(int) contains and "is" an integer. (Parenthesis substituted for angle brackets) Being as this website is about code and being that I wrote this in C#, I decided to see what other programming netizens might think of this idea, as well as the rather present idea that someone may have thought of this first. Thanks.
modified on Friday, August 26, 2011 9:16 PM
And here is a heavily-commented "Guess My Number" game using this paradigm (granted, it's not runnable without the classes, but it is heavily-commented. Should I release that code? I've no idea if anyone is the least bit intruiged):
// A simple "Guess my number" program.
// The length of the number to guess. DTVar length = 7; // A starting phrase. Console.WriteLine("Guess my Number, a {0}-digit number.", length); // True if or when the player guesses entirely correctly. DTVar allCorrect = false; // A function that matches the output of two DTArgs arguments, // and returns a string with X's in all locations where they don't match. DTFunc matchingF = new DTFunc( (a, b) => { // Our return string. string r = ""; // If our first DTArgs has values remaining, while (a.Count > 0) { // We can call a DTArgs to return the next argument, // or we can convert it. // As DTBase works on the principle that // the thing is what it returns when called, // the conversion can be implicit. // A DTArgs is an argument queue, essentially. char a1 = a; char b1 = b.Call; // If the two characters match, add that character to the string. // if they don't match, add 'X' to the string. r += (a1 == b1 ? a1 : 'X'); } return r; } ); // A function to generate a new "phone number". DTBase numberF = new DTFunc( delegate() { // Stores "length" number of random integers from 0 to 9 in a string. string r = ""; // "length" may be a DTVar, but because the use is unambiguous, // it can use implicit conversion. for (int t = 0; t < length; ++t) r += Rand.Next(10); // Returns the string "phone number". return r; } );
-
And here is a heavily-commented "Guess My Number" game using this paradigm (granted, it's not runnable without the classes, but it is heavily-commented. Should I release that code? I've no idea if anyone is the least bit intruiged):
// A simple "Guess my number" program.
// The length of the number to guess. DTVar length = 7; // A starting phrase. Console.WriteLine("Guess my Number, a {0}-digit number.", length); // True if or when the player guesses entirely correctly. DTVar allCorrect = false; // A function that matches the output of two DTArgs arguments, // and returns a string with X's in all locations where they don't match. DTFunc matchingF = new DTFunc( (a, b) => { // Our return string. string r = ""; // If our first DTArgs has values remaining, while (a.Count > 0) { // We can call a DTArgs to return the next argument, // or we can convert it. // As DTBase works on the principle that // the thing is what it returns when called, // the conversion can be implicit. // A DTArgs is an argument queue, essentially. char a1 = a; char b1 = b.Call; // If the two characters match, add that character to the string. // if they don't match, add 'X' to the string. r += (a1 == b1 ? a1 : 'X'); } return r; } ); // A function to generate a new "phone number". DTBase numberF = new DTFunc( delegate() { // Stores "length" number of random integers from 0 to 9 in a string. string r = ""; // "length" may be a DTVar, but because the use is unambiguous, // it can use implicit conversion. for (int t = 0; t < length; ++t) r += Rand.Next(10); // Returns the string "phone number". return r; } );
Hi Narf, I think this kind of experimentation is a very cool thing to do: at a minimum you will come to a greater understanding of what the language limits are, and your creativity is definitely showing here ! I don't have the 'bandwidth' or inclination to study your code and figure out what you are doing, but it seems to me that you are moving C# one step past 'var' and 'dynamic' towards behaving like more loosely-typed languages (Haskell ? Ruby ?). For me there's so much built-in to .NET in its current highly-evolved state, that I am going to stick with it, as is ... and it's evolving rapidly. If I want a List of integers converted to a string, (as early as .NET 2.0, I believe), I can use Linq like this: (and there may well be a simpler way: I'm no expert on Linq): List s = new List {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}.ConvertAll(i => Convert.ToString(i)); So, please do, keep going, follow your vision ! Don't let those who 'don't get it' phase you in the least :) best, Bill
"In the River of Delights, Panic has not failed me." Jorge Luis Borges
modified on Monday, August 29, 2011 11:34 PM
-
In my meanderings through weird code ideas, I wrote down some simple classes in C# based on the idea of "What if variables were typed based on what they returned when called, using that as what they are." So, for example, an equation that returns a double "is" a double (or derived from DTBase(double)); a DTFunc(string) that concatenates a string based on relevant factors "is" a string (or derived from DTBase(string)) and, of course, a DTVar(int) contains and "is" an integer. (Parenthesis substituted for angle brackets) Being as this website is about code and being that I wrote this in C#, I decided to see what other programming netizens might think of this idea, as well as the rather present idea that someone may have thought of this first. Thanks.
modified on Friday, August 26, 2011 9:16 PM
-
I think there is an interesting discussion to be had here but I don't quite see what you are gaining over a Func<double> (with DTFunc<T>), or just a normal variable with DTVar.
I apologize if you did read this particular post, but it sounds like you didn't, so I'm reposting it. Valid in current paradigm:
var a = 5.5;
Invalid in current paradigm, but valid if paradigm theoretically adopted by C#:
a = new func(delegate() { return 5.5; });
Using a theoretical library of additional functions, both are valid:
DTBase a = (DTVar)5.5;
a = new DTFunc(delegate() { return 5.5; });The key point is that, instead of being a specific type of variable, "a" is now defined by what you get when you call it. If you're wondering what use being able to type variables by what they return when "called" is, a few suggested thoughts are:
Dictionary> formulasForGame; // Functions, equations, single variables and file reads.
List> urlRetrieval; // Retrieves urls from various places and sources. Optionally, a list of DTArgs.
List> chatRelays; // A set of functions that relay text strings for chat according to the specific sending needs of each specific receiver and sender.
And any other situation where you want a generic, quick way to access data by type, not implementation. That is to say, counting double and Func(double) as separate implementations, but the same type. Thank you for your patience and interest. :)
-
I apologize if you did read this particular post, but it sounds like you didn't, so I'm reposting it. Valid in current paradigm:
var a = 5.5;
Invalid in current paradigm, but valid if paradigm theoretically adopted by C#:
a = new func(delegate() { return 5.5; });
Using a theoretical library of additional functions, both are valid:
DTBase a = (DTVar)5.5;
a = new DTFunc(delegate() { return 5.5; });The key point is that, instead of being a specific type of variable, "a" is now defined by what you get when you call it. If you're wondering what use being able to type variables by what they return when "called" is, a few suggested thoughts are:
Dictionary> formulasForGame; // Functions, equations, single variables and file reads.
List> urlRetrieval; // Retrieves urls from various places and sources. Optionally, a list of DTArgs.
List> chatRelays; // A set of functions that relay text strings for chat according to the specific sending needs of each specific receiver and sender.
And any other situation where you want a generic, quick way to access data by type, not implementation. That is to say, counting double and Func(double) as separate implementations, but the same type. Thank you for your patience and interest. :)
This:
a = new func<double>(delegate() { return 5.5; });
... may be invalid if you declare a as double, but if you want this kind of flexibility, surely you can use Func<double> in most cases (and when you want a constant, write a lambda or anonymous delegate to return it, as here). I guess that is possibly useful in some cases though. What is the performance hit like on this? You are adding a lookup (or method call) each time the 'variable' is referenced? Have you considered:
public implicit operator T(DTBase<T> val) { return val.Value; }
public implicit operator DTBase<T>(T val) { return new DTVar<T>(val); }That would make your implementation almost transparent.
-
In my meanderings through weird code ideas, I wrote down some simple classes in C# based on the idea of "What if variables were typed based on what they returned when called, using that as what they are." So, for example, an equation that returns a double "is" a double (or derived from DTBase(double)); a DTFunc(string) that concatenates a string based on relevant factors "is" a string (or derived from DTBase(string)) and, of course, a DTVar(int) contains and "is" an integer. (Parenthesis substituted for angle brackets) Being as this website is about code and being that I wrote this in C#, I decided to see what other programming netizens might think of this idea, as well as the rather present idea that someone may have thought of this first. Thanks.
modified on Friday, August 26, 2011 9:16 PM
-
are you suggesting implicit casting of Func instances to T? or perhaps 'implicit resolving' would be a better term.
Implicitly storing anything that returns T when "called", in T.
-
Implicitly storing anything that returns T when "called", in T.
-
I believe that is simply alternative semantics to what i said ;P but its getting late now and the caffeine is wearing off so i can't be sure ..... my brain hurts
Func is only one thing that could be placed in T. A Queue would be equally qualified, as it has a candidate for calling that results in T.