Re: lang effort: type conversions




"Aaron Gray" <ang.usenet@xxxxxxxxx> wrote in message
news:4gkv8rF1neodjU1@xxxxxxxxxxxxxxxxx
if anyone cares (or wants to make comment), after working some more of
the inferencer for the lang I am implementing, I have started to consider
some rules.



the basic syntax is more or less c style, and similar goes for
declarations:
int x;
int fib(int x)if(x>2)fib(x-1)+fib(x-2) else 1;

there will also the variant type ('var'), which may take any other type,
and will not have many of the same restrictions as the other types.

Yes I have came to the same idea of using a variant type with either
explicit declaration or invisible syntatic sugar like you are in
functions.

yes. the variation does lead to the occurance that function declarations are
handled slightly differently and in several different locations.



numerical types:

for numbers, the following types are viewed as primitive:
int, represented as a fixnum, with 29 bit precision, 28 unsigned;

Why, what are the extra bits for ?

it is a tagged reference representation (eg: fixnum), so the extra bits are
needed for the tag.

If you wish to interface to FFI code which I believe you do then what are
you going to do there ?

type conversion.

for now, the limitation will be 28 or 29 bits, but this may be changed later
on if reasonable.

luckily, most values will fit easily in 28 bits...

part of the reason, is a limit like this will allow fixnum-specific
bytecodes, which will not need any typechecking or similar.


long, either a fixnum or an on-heap object, with undefined precision (for
now, 64 bit, but maybe bignums may also exist);
float, as with fixnums, it is in-place with reduced precision;
double, on heap with full precision;
rat, rational, fixnum (if integral), or on heap (if needed).

other numeric types (eg: complex) will typically be heap-based, and will
have more generic rules (and are more resigned to being slower).

basic ops division integer division
int+int->int, int/int->float, int\int->int
long+long->long, long/long->double, long\long->long
long+int->long, long/int->double, long\int->long
rat+rat->rat rat/rat->rat undefined...
rat+int->rat, rat/int->rat
rat+long->rat, rat/long->rat
float+float->float
double+double->double
double+float->double
float+rat->double
...


variants will work slightly different wrt integer values:
all operations will use the smallest, sufficiently large numerical type,
and will promote types as needed (wheras int will generally allow them to
overflow). likewise, int/int->int if int%int=0.

I would suggest not doing that and have a "function" that "normalizes"
values down to the minimum representation size required. Much better to
have this explicit and under control of the programmer for maths reasons
and also for execution speed of maths.


ints and floats will be fairly well interchangable for many things, but
yeah. it is no big deal in this case since flonums are encoded in-place...

I am also considering seperating the variable and function namespaces.

function calls will work by first checking the function namespace, then
the variable one (if no functions are declared by that name in the
current scope).

declared functions will be immutable. mutable functions are possible, but
will need to be declared like variables.

example:
fact(x)if(x>1)x*fact(x-1) else 1;
will declare an immutable function, however:
var fact=fun r(x)if(x>1)x*r(x-1) else 1;
will declare a mutable one.


also for declared functions, this may be restricted further:
declared functions may not be used in the creation of new objects at all;
it will only be possible to use these functions in a new object via
either delegation or cloning.

why ? Are your functions pure ?

this will allow optimizing code using the arg/return types of said
functions, which is not really possible if functions are mutable (and
operations like inlining risk giving incorrect behavior).

if rules are imposed, they allow more easily determining the possibility of
said optimizations.


note that in the case of delegation, it will be allowed to overload the
functions with new ones (if they have matching function definitions).

overload or replace ?

technically the latter, but I was using the former term (as has been my
experience...).

eg:
one has overloading, as in multiple functions with the same name;
one has overloading, as in replacing it in a subclass;
....

these restrictions will not apply to first-class functions.

note, however, for other reasons closures may not be allowed as methods
(first-class functions and closures are distinguished based on whether or
not they capture variables from the parent scope).

why ?

this one is semantics.

I originally decided to distinguish them for reasons related to concurrency
and persistency (this is done automatically by the compiler, which checks
for variable capture...). for a first class function, it is not necessary to
remember anything about it's origin, and 2 functions with the same args/body
are equivalent, thus allowing them to be stored or coppied without respect
to original definition.

closures are much more fussy, and one has to worry about environment
preservation, ...


the general semantics imply disallowing closures to be used as methods, and
only allowing functions that do not capture variables (note that there is no
lexical toplevel in my language, rather, lexical bindings are generally only
present within functions).

implementation also implies disallowing declared functions from being
referenced and used as methods.

casts, conversions, and coercions, implicit and explicit.

I am working on producing a sound system of them as side task at the
moment. I had a model years ago but cannot remember it or find the
documentation, may be I'll go and look harder.

yes, ok.

Aaron




.



Relevant Pages

  • Re: Problem in the calling the dll functions
    ... Some other reasons are possible, ... into the application and the DLL as possible (at least, trace all function calls). ... Check that all DLL functions are properly declared, and the declarations ...
    (microsoft.public.dotnet.languages.vc)
  • Re: Optimizing n-gram generation
    ... I know nothing about declarations ... ... help if you wrap the GETHASH call in a (THE FIXNUM ...) form. ... Declaring types for data and maxn speeded it up by ... hash key might be better ...
    (comp.lang.lisp)
  • Re: combinations not working
    ... Fixnum allows negative integers which are not ... I tried various declarations when evaluating this code and dropped them ... Anyhow you have to declare i and p fixnum as well ...
    (comp.lang.lisp)
  • Re: Optimizing n-gram generation
    ... I know nothing about declarations ... ... help if you wrap the GETHASH call in a (THE FIXNUM ...) form. ... It has already been pointed out that if MAXN is small, ... hash key might be better ...
    (comp.lang.lisp)
  • Re: Optimizing Numerical Code
    ... Try this one with type declarations for all variables: ... (loop for iterations fixnum below *max-iterations* ... for period fixnum from 1 ...
    (comp.lang.lisp)