Is there a programming language...
-
...that works "easily" with semantic types? For example, I may have:
int age = 51;
which completely loses the concept that 51 is an age (in years). What I want is something like:AgeInYears myAge = 51;
and yet still be able to specify that I can perform, say, arithmetic operations on "myAge". For example, in C#, I could write:class AgeInYears
{
public int Value {get;set;}
}... implement operators on AgeInYears
But that gets messy real fast - every "semantic type" needs these operators, etc. Furthermore, the unit of measurement is still not handled very elegantly. So, as the question states, are there programming languages out there that are more expressive of semantic types? Marc
I hate myself for typing this:
namespace TestApp1
{
using AgeInYears = System.Int32;class Program { static void Main(string\[\] args) { AgeInYears myAge = 10; AgeInYears oldAge = 50; AgeInYears timeUntilOldAge = oldAge - myAge; } }
}
Yes, that's perfectly legal C# code. Its technically an int, works the same way that #define does in c++ to replace types. It only works in single code files though.
-
...that works "easily" with semantic types? For example, I may have:
int age = 51;
which completely loses the concept that 51 is an age (in years). What I want is something like:AgeInYears myAge = 51;
and yet still be able to specify that I can perform, say, arithmetic operations on "myAge". For example, in C#, I could write:class AgeInYears
{
public int Value {get;set;}
}... implement operators on AgeInYears
But that gets messy real fast - every "semantic type" needs these operators, etc. Furthermore, the unit of measurement is still not handled very elegantly. So, as the question states, are there programming languages out there that are more expressive of semantic types? Marc
In C++11, there is the notion of user defined literals. Have a look at this : http://akrzemi1.wordpress.com/2012/08/12/user-defined-literals-part-i/[^]
I'd rather be phishing!
-
Well, you can do things analagous to this in Smalltalk.
Pete O'Hanlon wrote:
Well, you can do things analagous to this in Smalltalk.
Funny you mention that, I was looking at smalltalk a couple minutes ago! Marc
-
I hate myself for typing this:
namespace TestApp1
{
using AgeInYears = System.Int32;class Program { static void Main(string\[\] args) { AgeInYears myAge = 10; AgeInYears oldAge = 50; AgeInYears timeUntilOldAge = oldAge - myAge; } }
}
Yes, that's perfectly legal C# code. Its technically an int, works the same way that #define does in c++ to replace types. It only works in single code files though.
Ron Beyer wrote:
Yes, that's perfectly legal C# code.
Fascinating. I'm glad there are some things of which I'm still ignorant. :) Marc
-
I hate myself for typing this:
namespace TestApp1
{
using AgeInYears = System.Int32;class Program { static void Main(string\[\] args) { AgeInYears myAge = 10; AgeInYears oldAge = 50; AgeInYears timeUntilOldAge = oldAge - myAge; } }
}
Yes, that's perfectly legal C# code. Its technically an int, works the same way that #define does in c++ to replace types. It only works in single code files though.
Ron Beyer wrote:
AgeInYears oldAge = 50;
You know that you're offending quite a lot of the CP users here, don't you? ;P
Anything that is unrelated to elephants is irrelephant
Anonymous
-----
The problem with quotes on the internet is that you can never tell if they're genuine
Winston Churchill, 1944
-----
I'd just like a chance to prove that money can't make me happy.
Me, all the time -
Ron Beyer wrote:
AgeInYears oldAge = 50;
You know that you're offending quite a lot of the CP users here, don't you? ;P
Anything that is unrelated to elephants is irrelephant
Anonymous
-----
The problem with quotes on the internet is that you can never tell if they're genuine
Winston Churchill, 1944
-----
I'd just like a chance to prove that money can't make me happy.
Me, all the time -
...that works "easily" with semantic types? For example, I may have:
int age = 51;
which completely loses the concept that 51 is an age (in years). What I want is something like:AgeInYears myAge = 51;
and yet still be able to specify that I can perform, say, arithmetic operations on "myAge". For example, in C#, I could write:class AgeInYears
{
public int Value {get;set;}
}... implement operators on AgeInYears
But that gets messy real fast - every "semantic type" needs these operators, etc. Furthermore, the unit of measurement is still not handled very elegantly. So, as the question states, are there programming languages out there that are more expressive of semantic types? Marc
Obviously, you don't mean just time: otherwise, timespan and datetime in c# would do the trick. For phisical entities (mass, distance, acceleration, ....) there is a C++ library in BOOST: http://www.boost.org/doc/libs/1_41_0/doc/html/boost_units/Dimensional_Analysis.html[^] I remember reading an article (which I can't find) that used this to implement classes that allow you to do the following:
Acceleration g = new Acceleration(9.88); // m/(s*s)
Mass m = new mass(25); // kg
Force f = m * g;Is that what you're looking for? Update: Found it. http://www.boostpro.com/mplbook/metafunctions.html[^].
Pablo. "Accident: An inevitable occurrence due to the action of immutable natural laws." (Ambrose Bierce, circa 1899). "You are to act in the light of experience as guided by intelligence" (Rex Stout, "In the Best Families", 1950).
-
...that works "easily" with semantic types? For example, I may have:
int age = 51;
which completely loses the concept that 51 is an age (in years). What I want is something like:AgeInYears myAge = 51;
and yet still be able to specify that I can perform, say, arithmetic operations on "myAge". For example, in C#, I could write:class AgeInYears
{
public int Value {get;set;}
}... implement operators on AgeInYears
But that gets messy real fast - every "semantic type" needs these operators, etc. Furthermore, the unit of measurement is still not handled very elegantly. So, as the question states, are there programming languages out there that are more expressive of semantic types? Marc
Yes. F# supports units of measurement[^]. For example, you can do this:
[] type years
let myAge = 32
The downside this is strictly language support, and not runtime support. Units are lost at runtime, but it's still pretty handy.
-
Well, if only you don't add this:
if (myAge >= oldAge)
thisGuyIsDead = true;or
if (myAge >= oldAge)
BookSpaceInRetirementHome(this);Anything that is unrelated to elephants is irrelephant
Anonymous
-----
The problem with quotes on the internet is that you can never tell if they're genuine
Winston Churchill, 1944
-----
I'd just like a chance to prove that money can't make me happy.
Me, all the time -
I hate myself for typing this:
namespace TestApp1
{
using AgeInYears = System.Int32;class Program { static void Main(string\[\] args) { AgeInYears myAge = 10; AgeInYears oldAge = 50; AgeInYears timeUntilOldAge = oldAge - myAge; } }
}
Yes, that's perfectly legal C# code. Its technically an int, works the same way that #define does in c++ to replace types. It only works in single code files though.
-
Ron Beyer wrote:
Yes, that's perfectly legal C# code.
Fascinating. I'm glad there are some things of which I'm still ignorant. :) Marc
I wouldn't get too excited about it though, its really one of the more horrible C# "features". Try the little program out once, then type out a function that has int's as parameters, Intellisense replaces any occurrence of the type with AgeInYears. And while you can define more than one alias for the same type, Intellisense will pick the last defined one to replace in the preview window. Its also a really good way of making code impossible to follow.
-
Ron Beyer wrote:
works the same way that #define does in c++ to replace types.
In C++ one would use
typedef
for this purpose. Using#define
is just wrongWithin you lies the power for good - Use it!
-
Pete O'Hanlon wrote:
Well, you can do things analagous to this in Smalltalk.
Funny you mention that, I was looking at smalltalk a couple minutes ago! Marc
Great minds and all of that.
-
In C++11, there is the notion of user defined literals. Have a look at this : http://akrzemi1.wordpress.com/2012/08/12/user-defined-literals-part-i/[^]
I'd rather be phishing!
Maximilien wrote:
In C++11, there is the notion of user defined literals.
Wow, that was a fascinating read - thanks for the link. It's been many years since I looked at C++! Marc
-
Obviously, you don't mean just time: otherwise, timespan and datetime in c# would do the trick. For phisical entities (mass, distance, acceleration, ....) there is a C++ library in BOOST: http://www.boost.org/doc/libs/1_41_0/doc/html/boost_units/Dimensional_Analysis.html[^] I remember reading an article (which I can't find) that used this to implement classes that allow you to do the following:
Acceleration g = new Acceleration(9.88); // m/(s*s)
Mass m = new mass(25); // kg
Force f = m * g;Is that what you're looking for? Update: Found it. http://www.boostpro.com/mplbook/metafunctions.html[^].
Pablo. "Accident: An inevitable occurrence due to the action of immutable natural laws." (Ambrose Bierce, circa 1899). "You are to act in the light of experience as guided by intelligence" (Rex Stout, "In the Best Families", 1950).
Pablo Aliskevicius wrote:
I remember reading an article (which I can't find) that used this to implement classes that allow you to do the following:
Yes, I was just reading about that. There's a CP article that also does some pre-processing for C# that allows units of measure to be specified, very similar to F#. And yes, that's one piece of the puzzle I'm working on. :) Marc
-
Yes. F# supports units of measurement[^]. For example, you can do this:
[] type years
let myAge = 32
The downside this is strictly language support, and not runtime support. Units are lost at runtime, but it's still pretty handy.
Phil Martin wrote:
Units are lost at runtime
Which is unfortunate because I'd possibly like to be able to reflect on the unit of measure. But it's an interesting avenue to explore. Thanks! Marc
-
I wouldn't get too excited about it though, its really one of the more horrible C# "features". Try the little program out once, then type out a function that has int's as parameters, Intellisense replaces any occurrence of the type with AgeInYears. And while you can define more than one alias for the same type, Intellisense will pick the last defined one to replace in the preview window. Its also a really good way of making code impossible to follow.
Ron Beyer wrote:
Its also a really good way of making code impossible to follow.
No worse than using "var" implicit types, I suspect. ;) Marc
-
...that works "easily" with semantic types? For example, I may have:
int age = 51;
which completely loses the concept that 51 is an age (in years). What I want is something like:AgeInYears myAge = 51;
and yet still be able to specify that I can perform, say, arithmetic operations on "myAge". For example, in C#, I could write:class AgeInYears
{
public int Value {get;set;}
}... implement operators on AgeInYears
But that gets messy real fast - every "semantic type" needs these operators, etc. Furthermore, the unit of measurement is still not handled very elegantly. So, as the question states, are there programming languages out there that are more expressive of semantic types? Marc
Annoyingly,
int
is asealed
type in C#, or all you would have to do is provide the implicit cast operators:class AgeInYears : int
{
public static implicit operator AgeInYears(int i)
{
return (AgeInYears)i;
}
public static implicit operator int(AgeInYears a)
{
return (int)a;
}
}But...what is an age plus an age? It's not really anything useful if you think about it. What you should be thinking of here is an Age plus a Timespan equals a DateTime, but then an Age can't really be assigned an integer value unless it already has a Datetime component - perhaps it is relative to the time at which the Age object is instantiated? And don't forget that an Age is not a constant value: it will vary as the application runs... :laugh:
-
Annoyingly,
int
is asealed
type in C#, or all you would have to do is provide the implicit cast operators:class AgeInYears : int
{
public static implicit operator AgeInYears(int i)
{
return (AgeInYears)i;
}
public static implicit operator int(AgeInYears a)
{
return (int)a;
}
}But...what is an age plus an age? It's not really anything useful if you think about it. What you should be thinking of here is an Age plus a Timespan equals a DateTime, but then an Age can't really be assigned an integer value unless it already has a Datetime component - perhaps it is relative to the time at which the Age object is instantiated? And don't forget that an Age is not a constant value: it will vary as the application runs... :laugh:
OriginalGriff wrote:
Annoyingly,
int
is asealed
type in C#, or all you would have to do is provide the implicit cast operators:Exactly!
OriginalGriff wrote:
And don't forget that an Age is not a constant value: it will vary as the application runs...
I know. :) It was a contrived example.
OriginalGriff wrote:
But...what is an age plus an age?
Yeah, this stuff gets one to really think about the meaning of things. :) Marc
-
I wouldn't get too excited about it though, its really one of the more horrible C# "features". Try the little program out once, then type out a function that has int's as parameters, Intellisense replaces any occurrence of the type with AgeInYears. And while you can define more than one alias for the same type, Intellisense will pick the last defined one to replace in the preview window. Its also a really good way of making code impossible to follow.
That's a problem with Intellisense then, not the language. Defining aliases is the one best use for the
using
directive, but I limit it to complex types like Dictionary-of-Dictionary-of-List kinds of things. Or, you can make a more general alias for a particular type, likeusing Connection=System.Data.SqlClient.SqlConnection
.