Skip to content
Sh4rK edited this page Jun 24, 2012 · 21 revisions

Language Features

  • Is Clay object-oriented?

    Unlike mainstream object-oriented languages such as Java, C++ and Python, Clay does not provide class definitions or inheritance. However Clay provides excellent support for polymorphism using an overloaded function dispatch system and variants (which are basically tagged unions). Rather than calling a method of an object as you would in a traditional OO language, in Clay you call a function and pass in arguments that determine which specific overload of the function will be called. The overload may be determined either at compile time or at run-time.

  • Does Clay provide operator overloading?

    Yes. You can overload +, -, *, / and many other operators by providing overloads for special functions in the operators module. For e.g.:

    import operators;
    overload operators.add(a: MyType, b:MyType) {
    ...
    }
    
  • Does Clay do type-inference?

    Yes. Clay does pervasive type-propagation by doing whole program analysis. It can determine the types of local variables, return types of functions and even the types of function arguments.

  • Can I write inline assembly in Clay?

    Not yet. But you can write inline LLVM code.

  • Are function arguments passed by-value or by-reference?

    Function arguments are passed by-reference. This might change to by-const-reference as a default with an explicit by-mutable-reference option.

Built-Ins

  • How are strings implemented? Does Clay support UTF8?

    Currently Clay strings are just mutable byte vectors stored on the heap. In the future, strings will be immutable with better support for UTF8.

  • How do I get the largest value for an integer type?

    Use Greatest(Int), Greatest(Int64), etc.

  • How do I get the size of a value of type T in bytes?

    Use TypeSize(T). For e.g. TypeSize(Int32) will give you 4.

Variants

  • How much space (in bytes) does a variant occupy?

    Variants are implemented as tag + value. Since all values of the variant have the same size, the size of the variant is machine word size (for the tag) + size of largest variant member.

  • How do I dynamically dispatch the appropriate method for a variant?

    Use the asterisk to dispatch on a variant value: f(*v). For e.g., if you have a variant with two members, and a function overloaded for both member types:

    variant Shape (Circle, Square);
    define draw;
    overload draw(c:Circle) {...}
    overload draw(s:Square) {...}
    

    Then, to dynamically dispatch on a value shape of type Shape:

    draw(*shape);  // where shape = Shape(...)
    
  • Are variant types closed or open?

    Variants are open so you can add new member types to a variant after it has been defined. For e.g. if you have a variant defined as variant Shape (Circle, Square);, you can expand it to include a new member with instance Shape Triangle;

Performance

  • Benchmarks are slower than equivalent C or C++ code

    Clay's library includes bounds check and integer overflow assertions by default, which adds about 10% overhead in typical code. Make sure you test with -Dclay.DisableAssertions to disable all assertions, or -Dclay.DisableAssertions.boundsChecks -Dclay.DisableAssertions.overflowChecks to disable only bounds and overflow check assertions, to get a fair comparison.

Building Clay

  • How do I build a debug or release version of Clay?

    When running cmake, set the CMAKE_BUILD_TYPE attribute to Debug or Release as needed. For e.g.: cmake -DCMAKE_BUILD_TYPE=Debug ..

  • Clay complains about parser errors on /* tokens

    Older versions of GCC have a compiler bug that breaks Clay's parser. Try updating your GCC, or using Clang.

  • __Clay won't compile because it says it requires LLVM 3.1, even though I have LLVM 3.1xx

    LLVM minor revisions and developer versions are not source compatible. Only LLVM 3.1 (not 3.1svn) release is currently supported.

  • How do I build clay-bindgen?

    clay-bindgen should compile without any issues with LLVM 3.1