Secondly, w00t! I got my christmas present
And work is finally calming down after release and the clean-up of a monumental clusterfuck caused by a single mis-labeled constant used once in code (not mine). Which allowed me a little time tonight (and more time going forward) to fix Tangent bugs and bemuse myself.
A note about syntax and a minor bugfix:
public void foo( arg){ //...}
now works. foo takes one argument which must be at least a string, and stores the type into generic T. If string is omitted from the above declaration, foo will take any type.
Tonight though I started into quickie work on units of measurement for Tangent. I talked about this a little a few posts back, and Daerax's link helped remind me of schooling in the dusty parts of my mind. I'm not looking to use them so much for calculation, but more to disambiguate int into '# of _'.
I'm thinking that a little bit of this operation should be pretty easy (famous last words, I know...). Tangent already knows the concept of Type Expressions. Adding some for the measures to represent measure multiplication, division, and exponentiation should be easy. Tangent also knows fairly arbitrary overloads for types. Adding something to int/float/etc. that takes a measure and returns (int & measure) should also be pretty simple.
By the weekend, I'd like to get simple measures done. x meters is different than x feet. Then complex measures. Then measures in syntax. Then conversions. Then probably some cleanup/finishing (perhaps inferring/constraining on exponents).
So, the feature in a nutshell:
- A measure is a distinct type element; similar to an enum that it's not a record of data but instead a differentiator for a single element of data. They'll be declared similarly to a class, but use a different keyword.
- Their instances will be value types with the number as the only data.
- Extra methods and static data may be declared on the measure.
- Likely need a special conversion syntax to ensure reflexiveness of conversions.
- Likely need aliases to make meter, meters, m, metre... work.
- All measures will act as goose types.
- Measures will probably be constructable only via a # + measure type -> measure instance style. (10 seconds; 9.88 m/s^2; 1000000 usd;)
- Will probably need some caching/intelligence to make sure that a constructed type uses a declared type if it exists (eg. if you define methods for a newton and then via operations construct a (kg m/s^2) [a newton], those methods should be available)
- Likely will allow a generic parameter to define the numeric that represents the value, stealing the conversions from the numeric types (int/int -> float; int meters/int seconds -> float m/s). Too bad I'm not doing this from scratch and can't just use arbitrary precision numbers as default.
More to come as it's implemented.
In addition to the free book The Implementation of Functional Programming Languages and Elements of Functional Programming