> I cannot imagine a single language without the if operator, but only a few PLs accommodate full-fledged trait bounds, not to mention pattern matching. This is inconsistency . . .
How?
> Sometimes, software engineers find their languages too primitive to express their ideas even in dynamic code. But they do not give up . . .
Is this a failure of the language, or a failure of the engineer?
> If we make our languages fully dynamic, we will win biformity and inconsistency,[^] but will imminently lose the pleasure of compile-time validation and will end up debugging our programs at mid-nights . . . One possible solution I have seen is dependent types. With dependent types, we can parameterise types not only with other types but with values, too.
Types are a productive abstraction/model in programming languages. One of many. Each has its strengths and weaknesses; each is appropriate in some circumstances and not in others. Types are not the solution to all problems, any more than currying or OOP or whatever else is.
Shader languages are also hellbent on avoiding branches too so if is frowned upon and often not used. I could easily imagine not having it in a shader language.
The old assembly-like languages (ARB_fragment_program, NV_fragment_program*, et al.) did indeed not have branches, only selection and conditional termination, because that was the extent of the capabilities of the underlying hardware. (I understand the execution on modern fragment processors can’t actually diverge within a single batch, either, so they execute both branches and select afterwards, but they are at least capable enough not to do that if the branch went the same way everywhere. But it’s been a long time since I’ve had a state-of-the-art GPU to play with.)
Still true. Cuda warps work by team of 32 threads and if there is a branch they have to take both and then select the result. It's fine for loop termination ``while (i < 1000)`` but if there is actual work it's often significantly better to switch to branchless code.
This is very much changing. IMHO, doing shader language design today, you should give let the programmer express things in the most natural way possible, and let the compiler figure out whether to generate a branch or branchless code. Yes, often you want the latter, but compilers are pretty good at figuring that out.
How?
> Sometimes, software engineers find their languages too primitive to express their ideas even in dynamic code. But they do not give up . . .
Is this a failure of the language, or a failure of the engineer?
> If we make our languages fully dynamic, we will win biformity and inconsistency,[^] but will imminently lose the pleasure of compile-time validation and will end up debugging our programs at mid-nights . . . One possible solution I have seen is dependent types. With dependent types, we can parameterise types not only with other types but with values, too.
Types are a productive abstraction/model in programming languages. One of many. Each has its strengths and weaknesses; each is appropriate in some circumstances and not in others. Types are not the solution to all problems, any more than currying or OOP or whatever else is.