I'd add a few more (equally regarding APL and K and J and q)
* They make it easier (and thus idiomatic and common) to write code that is vectorizable, GPUable, parallelizable, etc.
For example (q syntax here), if you have a string x that has parentheses, and you want to know if they are balanced, a "balance" vector would be b:sums (x='(')-x=')' [sums is cumulative sum] this would count +1 for each open, -1 for each close. To verify the string is balanced, you have (all b>=0) and 0=last b [read: minimum of b is 0, and last of b is 0]. They can be combined to one vectorizable expression:
(all b>=0) and 0=last b:sums (x='(')-x=')'
* The bugs in these languages tend to be almost exclusively logic bugs (wrong implementation assumptions, common to every language) or one-off bugs if your cut-and-paste vectors with mismatched indices. Others are very rare
* The terseness makes a lot of code fit on the screen at the same time. Which requires more mental effort to process but pays off hugely as you get a lot more context at the same time.
* They make it easier (and thus idiomatic and common) to write code that is vectorizable, GPUable, parallelizable, etc.
For example (q syntax here), if you have a string x that has parentheses, and you want to know if they are balanced, a "balance" vector would be b:sums (x='(')-x=')' [sums is cumulative sum] this would count +1 for each open, -1 for each close. To verify the string is balanced, you have (all b>=0) and 0=last b [read: minimum of b is 0, and last of b is 0]. They can be combined to one vectorizable expression:
(all b>=0) and 0=last b:sums (x='(')-x=')'
* The bugs in these languages tend to be almost exclusively logic bugs (wrong implementation assumptions, common to every language) or one-off bugs if your cut-and-paste vectors with mismatched indices. Others are very rare
* The terseness makes a lot of code fit on the screen at the same time. Which requires more mental effort to process but pays off hugely as you get a lot more context at the same time.