On Thursday, October 6, 2016 at 11:31:13 AM UTC+5:30, Chris Angelico wrote: > On Thu, Oct 6, 2016 at 3:57 PM, Gregory Ewing wrote: > > Chris Angelico wrote: > >> > >> Hence my > >> query about how variadic functions and automatic currying work - how > >> does it know whether to curry or run? > > > > > > Calling it "automatic" was probably a bad choice of words. > > I don't mean to imply that Haskell goes around currying > > things behind your back when you don't want it to. > > No no, I never meant it like that. Automatic currying can be a huge > boon, but also a stringent limitation. > > > The Haskell definition > > > > f x y z = x + y + z > > > > is equivalent to the Python definition > > > > f = lambda x: lambda y: lambda z: x + y + z > > > > To call it, you write > > > > f 1 2 3 > > Right, and that's fine as long as the function takes a fixed number of > arguments. > > > For a variable number of arguments, you could use a list > > instead of a tuple, but again you would need to explicitly > > construct the list when calling. > > In other words, it still has to take a fixed number of arguments. > Effectively, variadic functions are _impossible_, so instead you use > argument packaging. > > That's not necessarily a bad thing. Not all language features need to > be everywhere. Python has named arguments, and that's great; other > high level languages generally do the same sort of thing with an > options mapping. For example, here's how Pike lets you create a > subprocess: > > // Process.Process(command_line, options); > Process.Process("ffmpeg -i file.blk file.mkv", ([ > "cwd": "/path/whatever", > "uid": 1000, "gid": 1000, > "timeout": 15, > ])); > > command_line is either a string (which will be split according to > shell rules) or an array of strings (already split); options is a > mapping. Here's Python's version of that: > > # subprocess.run(args, *, **kwargs) > subprocess.run("ffmpeg -i file.blk file.mkv", > cwd="/path/whatever", > # uid and gid not supported, but you get the idea > timeout=15, > ) > > args is either a string or a list of strings, and options are provided > via keyword arguments. (Interestingly, though Python and Pike offer a > lot of options as you create a subprocess, there are actually very few > that are common. Weird.) This is not a problem. And if variadic > functions are a problem to Haskell, so be it. They don't exist. That > does at least answer my question about "how does Haskell handle > variadic functions and currying" - and, importantly, it answers the > question that comes up periodically of "why can't Python do automatic > currying". > > > I hope you can see from this that there's no confusion over > > "whether to curry or run". It all depends on how you define > > the function. > > Yeah. No confusion because it does fit into the simple structure that > I described as also working for Python. > > There's one other consideration. With Python functions, you often want > to run a function for its side effects and ignore its return value. > With automatic currying, you'd get no error doing that with > insufficient arguments, you'd just be dropping the curried egg - erm, > I mean, function - on the ground. It'd be a subtlety like this: > > print("Heading") > print("=======") > print > print("First line of data") > print("Second line of data") > > In Py2, this prints a blank line underneath the heading. In Py3, it > merely evaluates the print function, then drops it. This can currently > happen only with the zero argument case, but if you accept > insufficient arguments to mean curry, it could happen any time. That's > somewhat unideal. > > ChrisA
It is fair to say that Haskell's variadic function support is poorer than C's [Collecting into a list fails for different types Collecting into a tuple fails because (t1,t2) and (t1,t2,t3) are incompatible types. There's some heavy artillery called type families round this whose messiness puts haskell squarely into C++ camp] Python's variadicity is better than any other language (I know) (Common Lisp??) [Except for mutable-default gotcha] -- https://mail.python.org/mailman/listinfo/python-list