Some intrinsics are fine, for example the math intrinsics (sin, cos, etc.) are nice because they allow the compiler to optimize on certain architectures that have those builtin. Others are necessary like SizeOf, High, Low, etc.
I'm still not the biggest fan of them because: If it looks like a function it should behave like a function. Those listed above behave nearly like functions, but not fully, so for example you can't take the pointer to those functions:
var
fp: function(x: Double): Double;
begin
fp := @sin; // Error
end;
Even worse it becomes with functions like Read(ln) Write(ln) or str. Those functions are not just special implementations, they also have special syntax. First the obvious, the arbitrary number and type of parameters:
WriteLn('String', True, 3.14, 42);
I mean this is a cool feature, but it's odd that there is only like a few functions like that and they aren't extensible. Why not allow the user to write their own compiletime varardic functions? You can do in C++:
void WriteLn() {
std::cout << std::endl;
}
template <typename T, typename ...Args>
void WriteLn(T const &val, Args &&...args) {
std::cout << val;
WriteLn(args...);
}
int main() {
WriteLn("String", 'c', 3.14, 42, true);
return 0;
}
Which now works pretty much exactly the same as WriteLn in pascal, but because it's an in language construct it's extensible. The following doesn't work in Pascal:
type
TMyRec = record
a, b: Integer;
end;
var
r: TMyRec;
begin
WriteLn(r);
end.
But because in C++ it's not compiler magic but in language definitions, I can extend the functionality as much as I like:
struct MyStruct {
int a, b;
};
template <typename ...Args>
void WriteLn(MyStruct const &val, Args &&...args) {
std::cout << "a=" << val.a << ",b=" << val.b;
WriteLn(args...);
}
int main() {
MyStruct s = {.a=42, .b=32};
WriteLn(s);
return 0;
}
The behavior of WriteLn is pretty cool, but also very limited, it would be much better if it could be amended. Other languages do so by having a default string serialization method, toString in Java or C# or str(x) in Python. It's not as flexible as C++ but still alows you to re-use those magic functions like print for more than just base types.
But even worse, WriteLn has a special syntax for formatting:
WriteLn(MyVar:4); // Write with padding of 4
Like the : syntax is used no where else, it's a special construct only for Write(ln) and Str functions, something that is also completely unnecessary, because you could just have a function that takes two arguments instead of one (or tuple types) and use this instead.
Like I'm all for flexibility in writing code, but it should be in one consistent way that allows it to be used very flexible and applied in many different situations, not a special magic solution that is only usable for one very specific thing