5 ms·
Programming language design, like programming, is about finding the right abstractions and providing them. ref: "Python did take usability into account" Which
by jodrellblank 8y ago
Programming language design, like programming, is about finding the right abstractions and providing them. ref: "Python did take usability into account"
Which APL tries to do with neat and composable functions.
Sum a list of "values": APL: +/values Python: sum(values).
Product of a list: APL: ×/values Python: import operator, functools, then reduce with a lambda function, or write a loop.
Add constant to a list: APL: 1+values Python: [1+x for x in values]
Reverse a list: APL: ⌽values Python: list(reversed(values)) but you have to care if you want an iterator or a list.
Add two lists elementwise: APL: values1+values2 Python: [x+y for x,y in zip(values1, values2)]
Take five from the front: APL: 5↑values Python: values[:5]
In APL this syntax generalises to multidimensional arrays. In Python none of these wildly different syntaxes do, nor do the magic sum/max/min functions.
In APL these are simple instructions to the user, and can be implemented fast by the runtime. In Python these are more complex patterns to learn and run slower, if you want them to work fast you have to switch again to NumPy.
I am not all-in on APL, but this is so much more powerful, concise, consistent and composable than Python - the shining example of a beginner-friendly language - for basic data munging, it's like seeing Python after using Java and wondering why Java has to be so wordy and verbose to get anything done. Why does Python have to be so wordy and verbose and limited to get basic things done? Why is this large mess of inconsistent symbols and calling conventions and library functions and magic functions and sigils considered clean and usable compared to APL's very simple repeatable patterns and careful attentive use of composable symbols?
- joshuamorton 8y agoYou examples with (and some without) numpy arrays: values.sum(), values.prod(), 1 + values, values[::-1], values1 + values2, values[:5] Yes, comparing the "array programming language" with a general purpose programming language when all your examples are array operations is going to make the general purpose language look funny. But I don't want a DSL for array operations I want a programming language. And when you aren't doing array-math, APL isn't so great. Show me how you present those arrays as a graph in APL. In "wordy, verbose" python it's import matplotlib.pyplot as plt plt.plot(array) array.show(array) Is visualizing the data you're manipulating so basic? Python chooses extensibility (numpy) over domain specificity, and you get the same power (really, the numpy examples aren't any worse than yours, in fact to someone unfamiliar, `sum` and `product` are likely clearer than `+/` and `×/`. Extensibility and composability is a better abstraction.
- jodrellblank 8y agoExtensibility and composability is a better abstraction. Say that our modern day programmer is comfortable with + × > < and can learn in a few moments that max 3⌈5 and min 3⌊5 and reverse ⌽values have their own symbols. By learning the three patterns of / as replicate, reduce and n-wise reduce, they get a large amount of composable patterns to play with, covering sum(), min(), max(), reverse(), [::-1], functools.reduce(), functools.filter(), Numpy overloads of +, Numpy .sum() and .prod(), and more. In Python, that is many standalone disconnected patterns which do not compose, In APL the "and more" is because composability means there are lots of ways of putting these operations together. values.prod() is what you have to do without composability, you can't re-use the builtin multiply without making a separate wrapper or overload. The result is visually different to sum(values) and conceptually different because it is a method call on an object, and the resulting prod() does not compose with anything else in the language. Show me how you present those arrays as a graph in APL. In "wordy, verbose" python it's [three lines, another third party install, an import and rename, a two stage operation and a bizarre array show() call passing itself as a parameter(?)]. Is visualizing the data you're manipulating so basic? Yes, in Dyalog APL it's: ]chart array And that doesn't just show a bar graph, it also loads a GUI for customizing the look of the chart, and the chart library is SharpPlot for .Net, which ships with it. (This is not in ISO standard APL, like matplotlib is not part of pure CPython. APL is not giving up extensibility, you can write your own functions which hide things behind names, or in different implementations of APL call out to OS/.Net/library features). when all your examples are array operations is going to make the general purpose language look funny. Yes, true. But is it not the everyday task of programming to process chunks of data in collections? I don't want a DSL for array operations I want a programming language. And when you aren't doing array-math, APL isn't so great. Strings are character vectors, like Python lets you treat strings as iterables and slice them, so you can do many array transforms on text. APL's array operations aren't limited to numeric math like +5 or A×B, they also work on something I don't know what to call it - geometric patterns, maybe? Like, indicate where 5 is less than integers to ten: 5 < ⍳10 0 0 0 0 0 1 1 1 1 1 Visually patterned half and half. Or this: ¯3 ⌽ 3 < ⍳9 1 1 1 0 0 0 1 1 1 Visually, spatially, patterned into thirds. You can feed this into filter() to make combinations of things more complex than "items greater than five", but "items in this pattern", the filter is not a single lambda function which takes an element and decides whether to keep or remove it, the filter-reduce is more powerful and composable than that, and building the patterns from composing the same basic primitives. And yes you could pull in Numpy and fill an array with values and rotate it, but you wouldn't think to do that to apply it to a string, because it's /so much work/ and so far away and distant from the provided black-box string methods. That is, APL is so great for things more than array-math. Albeit not everything more than array math. I sure have my own skepticism and questions about how well it scales up to larger programs and where its practical and pragmatic limits are. But, take some imaginary pixels in one array and brightnesses in another and (50<brightness)/pixels will get you the pixels brighter than 50. Try that in Python and you get something like [p for i,p in enumerate(pixels) if i in [i for i,b in enumerate(brightness) if b > 50]]. The APL is "dense and unreadable" and the Python is "clear and composable". "Oh you wouldn't do that in Python", no indeed you wouldn't, you'd have to put stuff in a tuple or object to work around the fact that Python won't let you keep simple things simple.