Skip to content

Commit

Permalink
ChangeLog: narrow down 0.1 scope
Browse files Browse the repository at this point in the history
Punt further lib tinkering to 0.2 and compiler hacking to 0.3. Move blue-sky stuff to Plan.txt
  • Loading branch information
jckarter committed Nov 8, 2011
1 parent 293c650 commit 6826c08
Show file tree
Hide file tree
Showing 2 changed files with 220 additions and 144 deletions.
205 changes: 61 additions & 144 deletions ChangeLog.txt
Expand Up @@ -249,168 +249,85 @@ Compiler frontend changes:
basename of the input file instead of "a.out". For instance, "clay hello.clay" will
output an executable named "hello" (or "hello.exe" if compiling for a Windows target).

===============
Planned changes
===============

These changes are planned for future releases. They're written in past tense so they
can be easily cut and pasted above.
==================
TO BE DONE FOR 0.1
==================
* Frontload backward-incompatible syntax changes as much as possible.

* The representation of StringConstants has been changed to be compatible with
C strings.
* Keywords that do similar things have been combined:
The 'static' keyword in expressions and argument lists is now the '#' operator.
Identifiers now lower to StringConstants, and must always be quoted:

* Tuple syntax has been changed to use square brackets. Parens are now used only for
grouping.
// 0.0
()
(1,)
(1, 2, 3)

// 0.1
[]
[1]
[1, 2, 3]

Arrays (formerly occupying []) can be constructed with the array() function.
// 0.0
[1, 2, 3] // array

// 0.1
array(1, 2, 3)

* The frontend now supports a -D flag, which populates the __defines__ module:

clay -DNDEBUG -DFLAVOR=Raspberry foo.clay

// foo.clay
import __defines__.(NDEBUG?, FLAVOR);

[| NDEBUG?]
assert(s) { }

main() { println("Compiled for ", FLAVOR); }

* The 'static' keyword in expressions and argument lists is now the '#' operator.
Identifiers must now always be quoted:
static 9 => #9
static foo => #foo
static #foo => #"foo"
#foo => #"foo"
* A new keyword 'super' is provided to call the next matching overload.
[T|Integer?(T)] show(x:T) { println(x); }

overload show(x:UInt8) { print("my little "); super(x); }
* 'record' has been renamed to 'struct', and library functions with 'record' or
'Record' in the name have been renamed to 'struct'/'Struct'.
* The mapping of types to LLVM representation is exposed. A type is a symbol for which
llvmRepresentation(#T) is overloaded. llvmRepresentation(#T) should return an
identifier containing the LLVM IR description of the type. For example:
define Int;
overload llvmRepresentation(#Int) = #"i32";

define Vec[T,n];
[T,n | Type?(T)] overload llvmRepresentation(#Vec[T,n])
= cat(
#"<",
LLVMRepresentation(T), #" * ", StaticName(n),
#">"
);
"struct", "variant", and "enum" syntax is still provided, but they now desugar
into symbol forms.

* 'union' syntax is provided for defining named union types. Example:
union FloatBits32(bits:Int32, float:Float32);
The anonymous union type Union[..T] is still present.
* 'newtype' syntax is provided for strong typedefs. A newtype shares the exact
low-level representation and ABI of the original type, but its type is distinct.
The type can be defined to delegate its overloads to the original type by default,
or to provide access to the original type representation by field reference.
Examples:
newtype PositionToken = Int; // delegate to Int
newtype PositionToken (value:Int); // use "token.value" to access Int
* All structs now have "RegularRecord" value semantics, and the "RegularRecord?"
predicate is gone. Structs should not provide custom value semantics. A new
syntax '<bikeshed>' is provided for types with custom value semantics.

<bikeshed> Vector[T](buffer:Pointer[T], size:SizeT, capacity:SizeT);

In addition to custom value semantics, <bikeshed> types also have unspecified
memory layouts and are not necessarily ABI-compatible with equivalent C structs.

* The prelude has been shrunk to only include a minimum set of libraries by default.
Those prelude modules have been moved to core/*, and the default prelude
public imports core.*.
The following modules must now be imported if used:
<tbd>
The module clayfixed.v0_0.fatprelude imports the above modules for backward
compatibility.
* Dispatch is now overloadable. The dispatch overload desugars as follows:
<tbd>
The prelude provides a default implementation for variants that works as in Clay 0.0,
as well as a default implementation for multiple dispatch that decomposes into
cascading single dispatch.
* Variant representation is now overloadable. In addition to the default tagged-union
representation, the prelude also provides a nullable pointer representation, which
is used for Maybe[Pointer[T]], Maybe[SharedPointer[T]], and Maybe[UniquePointer[T]].
Pointer types should now be considered non-nullable and Maybe[] used for
nullable pointers.
* Standard containers now implement bounds checking in index(). A new operator
indexUnsafe(a, ..b) (with operator syntax a<[..b]>) is provided for unchecked
indexing.
* External functions now have Clay linkage by default. External C functions must be
declared with the C ABI (or stdcall or fastcall):
// 0.0
external foo(x:Int) Int;
// 0.1
external (C) foo(x:Int):Int;
Clay-linkage externals may return multiple values and throw exceptions.
cdecl/stdcall/fastcall externals will now throw an error if they are declared to
use non-POD types as arguments or return values, or if they are declared as returning
multiple return values.
* External declarations may now be parameterized. For example, the libc family of
"sqrt" functions may be bound as follows:
define LibcMathLetter;
overload LibcMathLetter(#Float) = #"f";
overload LibcMathLetter(#Double) = #"";
overload LibcMathLetter(#LongDouble) = #"l";

[T|T == Float or T == Double or T == LongDouble]
external (C, cat(#"sqrt", LibcMathLetter(T))) sqrt(n:T):T;

External definitions may also be parameterized, but must be given a set of types
for which to be instantiated. <...>

* A new external ABI "llvmIntrinsic" is provided to simplify interfacing with LLVM
intrinsics. Function arguments map one-to-one to LLVM intrinsic arguments except for
static integer or boolean arguments, which are expanded into literal arguments in LLVM
IR, allowing Clay to interface with intrinsics that expect literal arguments.
The given external symbol name is unmangled. Example:
[align,volatile? | Int?(align) and Bool?(volatile?)]
external (llvmIntrinsic, "llvm.memcpy.p0i8.p0i8.i32") llvm_memcpy32(

* Integer division now uses the new 'div' operator. '/' now only does floating-point division:
var x = 3 div 2; // 1
var x = 3/2; // type error
The div operator desugars to the quotient(a,b) function. An update statement form
'div=' is also provided.
The 'clayfixed.v0_0.integerdivide' module provides divide(a,b) overloads for truncating
integer division for backward compatibility.

* A new external ABI "llvm" is provided for access to the native LLVM calling convention.
It also special-cases static integer and boolean arguments, interpolating them as literal
values into the function call. This allows for interfacing with LLVM intrinsics.
[align,volatile?]
external (llvm, "llvm.memcpy.p0i8.p0i8.i32") llvm_memcpy32(
dst:Pointer[UInt8],
src:Pointer[UInt8],
len:Int32,
#align,
#volatile?
);

* Throw is now an expression:
var p = malloc(123) or throw OutOfMemory();
var quotient = if (x == 0) throw DivisionByZero() else y/x;

* Integer division now uses the div operator. '/' now only does floating-point division:
var x = 3 div 2; // 1
var x = 3/2; // type error
The div operator desugars to the quotient(a,b) function. An update statement form
'div=' is also provided.
* The fieldRef, index, and staticIndex operators have been unified. Field and tuple reference
syntax now desugars to indexing with identifiers or static integers:
foo.bar ==> foo[#"bar"] ==> index(foo, #"bar")
foo.1 ==> foo[#1] ==> index(foo, #1)

* Sequences can no longer be concatenated with '+' or '+='. The 'cat' or 'push'
functions should be used instead.
The 'clayfixed.v0_0.sequenceaddition' module includes these overloads for backward
compatibility.

* The Number(String) and String(Number) constructors have been removed. 'str' should
be used to convert numbers to strings, and 'parse' to convert strings to numbers:
// 0.0
var x = String(1);
var y = Int("1");

// 0.1
var x = str(1);
var y = parse("1", Int);
The 'clayfixed.v0_0.stringconversionconstructors' module includes the old constructor
overloads for backward compatibility.

* String literals now support interpolation, which desugars into calls to the
str() function. Single identifiers or function calls can be interpolated with
$identifier or $identifier(..args), and arbitrary expressions with ${ ..expr }:
"$x $y $z"
==> str(x, #" ", y, #" ", z)
"Yes, we have $n bananas"
==> str(#"Yes, we have ", n, #" bananas")
"Yes, we have $bananaCount() bananas"
==> str(#"Yes, we have ", bananaCount(), #" bananas")
"Yes, we have ${n + m} bananas"
==> str(#"Yes, we have ", n + m, #" bananas")
"Yes, we have ${n + m} bananas"
==> str(#"Yes, we have ", n + m, #" bananas")
Identifier strings with interpolants desugar to identifier():
#"$x $y"
==> static identifier(x, #" ", y)

A custom desugar can be specified by placing a function name before a string
literal:
utf8 "foo" ==> utf8(#"foo")
println "x + y = ${x + y}"; ==> println(#"x + y = ", x + y);
* make x86-64 C abi work
* more frontend normalization with clang/llc
* use llvm 3.0 exceptions
* llvm 3.0 atomic primitives
* keyword and default arguments

* A shorthand for single-argument pattern variable predicates is provided:
// Longhand
Expand Down
159 changes: 159 additions & 0 deletions Plan.txt
@@ -0,0 +1,159 @@
===
0.2
===

0.2 will focus on cleaning up and improving the standard library.

* shrink prelude
* core/std/contrib separation
* ranges
* type-safe concurrency
* cleanups

* The prelude has been shrunk to only include a minimum set of libraries by default.
Those prelude modules have been moved to core/*, and the default prelude
public imports core.*.
The following modules must now be imported if used:
<tbd>
The module clayfixed.v0_0.fatprelude imports the above modules for backward
compatibility.

* The Number(String) and String(Number) constructors have been removed. 'str' should
be used to convert numbers to strings, and 'parse' to convert strings to numbers:
// 0.0
var x = String(1);
var y = Int("1");

// 0.1
var x = str(1);
var y = parse("1", Int);
The 'clayfixed.v0_0.stringconversionconstructors' module includes the old constructor
overloads for backward compatibility.

* Sequences can no longer be concatenated with '+' or '+='. The 'cat' or 'push'
functions should be used instead.
The 'clayfixed.v0_0.sequenceaddition' module includes these overloads for backward
compatibility.

* Standard containers now implement bounds checking in index(). A new operator
indexUnsafe(a, ..b) (with operator syntax a<[..b]>) is provided for unchecked
indexing.

===
0.3
===

0.3 will improve the language semantics and implementation.

* unify type and procedure symbols
* typeclasses
* region typing
* pattern matching and destructuring
* better type system

* The mapping of types to LLVM representation is exposed. A type is a symbol for which
llvmRepresentation(#T) is overloaded. llvmRepresentation(#T) should return an
identifier containing the LLVM IR description of the type. For example:
define Int;
overload llvmRepresentation(#Int) = #"i32";

define Vec[T,n];
[T,n | Type?(T)] overload llvmRepresentation(#Vec[T,n])
= cat(
#"<",
LLVMRepresentation(T), #" * ", StaticName(n),
#">"
);
"struct", "variant", and "enum" syntax is still provided, but they now desugar
into symbol forms.

* 'union' syntax is provided for defining named union types. Example:
union FloatBits32(bits:Int32, float:Float32);
The anonymous union type Union[..T] is still present.

* 'newtype' syntax is provided for strong typedefs. A newtype shares the exact
low-level representation and ABI of the original type, but its type is distinct.
The type can be defined to delegate its overloads to the original type by default,
or to provide access to the original type representation by field reference.
Examples:
newtype PositionToken = Int; // delegate to Int
newtype PositionToken (value:Int); // use "token.value" to access Int

* All structs now have "RegularRecord" value semantics, and the "RegularRecord?"
predicate is gone. Structs should not provide custom value semantics. A new
syntax '<bikeshed>' is provided for types with custom value semantics.

<bikeshed> Vector[T](buffer:Pointer[T], size:SizeT, capacity:SizeT);

In addition to custom value semantics, <bikeshed> types also have unspecified
memory layouts and are not necessarily ABI-compatible with equivalent C structs.

* A new keyword 'super' is provided to call the next matching overload.
[T|Integer?(T)] show(x:T) { println(x); }

overload show(x:UInt8) { print("my little "); super(x); }

* Throw is now an expression:
var p = malloc(123) or throw OutOfMemory();
var quotient = if (x == 0) throw DivisionByZero() else y/x;

* Dispatch is now overloadable. The dispatch overload desugars as follows:
<tbd>
The prelude provides a default implementation for variants that works as in Clay 0.0,
as well as a default implementation for multiple dispatch that decomposes into
cascading single dispatch.

* Variant representation is now overloadable. In addition to the default tagged-union
representation, the prelude also provides a nullable pointer representation, which
is used for Maybe[Pointer[T]], Maybe[SharedPointer[T]], and Maybe[UniquePointer[T]].
Pointer types should now be considered non-nullable and Maybe[] used for
nullable pointers.

* The compiler now does deep unreachability propagation. Functions can also be defined
'noreturn' in lieu of return types.

* External declarations may now be parameterized. For example, the libc family of
"sqrt" functions may be bound as follows:
define LibcMathLetter;
overload LibcMathLetter(#Float) = #"f";
overload LibcMathLetter(#Double) = #"";
overload LibcMathLetter(#LongDouble) = #"l";

[T|T == Float or T == Double or T == LongDouble]
external (C, cat(#"sqrt", LibcMathLetter(T))) sqrt(n:T):T;

External definitions may also be parameterized, but must be given a set of types
for which to be instantiated. <...>

* External functions now have Clay linkage by default. External C functions must be
declared with the C ABI (or stdcall or fastcall):
// 0.0
external foo(x:Int) Int;
// 0.1
external (C) foo(x:Int):Int;
Clay-linkage externals may return multiple values and throw exceptions.
cdecl/stdcall/fastcall externals will now throw an error if they are declared to
use non-POD types as arguments or return values, or if they are declared as returning
multiple return values.

* String literals now support interpolation, which desugars into calls to the
str() function. Single identifiers or function calls can be interpolated with
$identifier or $identifier(..args), and arbitrary expressions with ${ ..expr }:
"$x $y $z"
==> str(x, #" ", y, #" ", z)
"Yes, we have $n bananas"
==> str(#"Yes, we have ", n, #" bananas")
"Yes, we have $bananaCount() bananas"
==> str(#"Yes, we have ", bananaCount(), #" bananas")
"Yes, we have ${n + m} bananas"
==> str(#"Yes, we have ", n + m, #" bananas")
"Yes, we have ${n + m} bananas"
==> str(#"Yes, we have ", n + m, #" bananas")
Identifier strings with interpolants desugar to identifier():
#"$x $y"
==> static identifier(x, #" ", y)

A custom desugar can be specified by placing a function name before a string
literal:
utf8 "foo" ==> utf8(#"foo")
println "x + y = ${x + y}"; ==> println(#"x + y = ", x + y);

0 comments on commit 6826c08

Please sign in to comment.