Most (not all) APL code I've seen uses very short names, often one letter names, for function names. And APL programmers are famous for cataloging "idiom" which are short phrases for common subroutines. In other words, it's best practice to repeat 3- or 4- symbol phrases instead of defining a subroutine.
Of course, there's nothing about an array language that requires using symbols; but for some reason most do.
The idioms become words and you read them like words, you don't step through each letter of a word when you read it, you recognize the shape. The same thing happens in APL and its ilk, any commonly used sequence is instantly understood as its function without having to parse each individual symbol and what it does.
higher-order functions (over, scan, each, etc) are called adverbs.
sure, that's a very useful feature, like elsewhere.
> I wonder about a purely aesthetic issue: how does it look to interleave those symbols with user-defined words that by nature will be much, much longer, i.e. "create-log-entry" or "calculate-estimated-revenue".
strictly speaking, dashes and underscores in k can't even be a part of identifier - they are core language primitives. it is very uncommon to see java-like identifiers like CalculateEstimatedRevenue, why would you want that?
to your question:
here's a bit of an oddity: all user-defined functions and core language operators can be called using functional notation:
v:1 2 3 / some vector
v+v / usual infix notation, two operands: left and right
2 4 6
+[v;v] / same as infix, but called as it were a function.
2 4 6
add:{x+y} / a user-defined function: a lambda with a name and two operands.
add[v;v]
2 4 6
but there is an important distinction between the two. you can't use your `add` function infix, you must call it as a function, and there are good reasons for that: 2 add 2 / that's not gonna work
that said, mixing language primitives with function calls looks and reads just fine: +/add[v;v]
12
hope this helps!So does it end up as
v_sepallength: 11 14 12
v_sepallthickness: 1.3 1.5 1.2
mul[v_sepallength;v_sepalthickness]
Or, do you just not do that sort of stuff in these languages? I'm not very familiar with them, but I have ended up with some pretty long programs using Pandas in Python.less important things can have longer names. variables in a broader scope can have longer names.
if you have a hundred different vectors, don't just dump them in a pile; put them in dictionaries, tables, namespaces, or scopes.
the complexity is built differently in k.
* namespaces do exist, and are just as useful as they are in c++ and especially my beloved *sun.misc.unsafe*. i recommend.
* instead of passing 20 arguments to a function (which is impossible - the limit is lower), we pass a dictionary if we have to. k **pretends** that everything is passed by value, but in reality it is much smarter than that.
* notion of *scopes* is a bit of a non-sequitur here, but it is fundamentally important that there is no *lexical scoping* in k. the only two scopes which are available from the scope of a lambda are exactly *local* and *global*. and for as long as your function doesn't mess around with global scope or i/o (which is essentially the same thing), it remains pure, which is super cool. this design is not just for simplicity - it is for a good reason, and more than one.
* the above doesn't mean that it is impossible to create a *closure* in k and pass it around as a value.
* functions take up to three implicit arguments - named x,y and z (they can be renamed explicitly, but why not just document their semantics instead, in-situ?). all you need to do to declare xyz is reference them in the function definition. in competent k code, you'll rarely see a function with more than xyz.
* in k community, we don't use upper case unless the apartment is on fire. god forbid.
* shorter names and more documentation, and there will be joy.i tell you more. it is very much recommended to avoid doing this sort of stuff in all languages.
v_sepallength: 11 14 12
v_sepallthickness: 1.3 1.5 1.2
mul[v_sepallength;v_sepalthickness]
no: /sepal:lengths and stroke widths
spl:[l:11 14 12;w:1.3 1.5 1.2] /this is your "struct", if you will
spl.w
1.3 1.5 1.2 /proof
*/spl
14.3 21. 14.4 /for mul, we don't even have to bother with field names
*/spl`l`w /but if you insist, lets make it explicit
14.3 21. 14.4
to produce a "factory" for well-formed spl objects is a no-brainer as well.why we don't use v_ prefix:
1. everything what can be a vector should be a vector.
2. we can't use underscore anyway - it is an operator.