Nitpick String and C-Interop Specification

Nitpick provides a native string type, a robust set of compiler intrinsics, and seamless FFI compatibility with C-style strings.

1. The string Type

The string type is natively memory-managed by Nitpick’s RAII/GC system. Strings are automatically tracked and freed at the end of their lifecycle—there is no need to manually free them.

string:greeting = "Hello World";

1.1 Single Characters

Nitpick does not have a distinct char type. Single-character literals ('A') map directly to either int8 or uint8.

int8:c = 'A';
string:s = string_from_char(c);

2. String Literals

Nitpick supports standard strings and template strings (interpolation).

⚠️ COMPILER IDIOSYNCRASY (v0.8.4): While legacy documentation mentions raw strings (r"") and multi-line triple-quote strings (""" """), the npkc parser currently throws a syntax error if you attempt to use them.

3. C-Interop and FFI Pointers

One of the most confusing aspects of Nitpick for beginners is how to interface with standard C libraries (like puts or printf) that expect a char*.

3.1 Seamless string Interop

Nitpick’s string type is intentionally designed to be fully null-terminated under the hood. You do not need to cast a string to a byte pointer. Instead, declare the external C function’s parameter as string directly. Nitpick’s ABI will handle the char* decay automatically.

// Correct: Let Nitpick handle the C-string decay
extern func:puts = int32(string:str);

func:main = int32() {
    string:msg = "Hello World";
    drop puts(msg); 
    exit 0i32;
};

3.2 Fat Pointers (->) vs. Thin Pointers (*)

If you must deal with raw byte buffers instead of string objects, you must understand the difference between Nitpick pointers and C pointers:

If you try to declare an int8* inside normal Nitpick logic, the compiler throws a hard error. If you try to declare an int8-> inside an extern func:, the compiler rejects it for violating the C ABI.

4. Built-in String Intrinsics

Nitpick provides a massive suite of string intrinsics that require no module imports. Because string is an opaque type, you should always use these built-ins for manipulation rather than attempting pointer arithmetic.

Length & Identity

Modification

Type Conversion