First class citizen functions, short lambdas, comprehension lists, generators, map(), filter(), itertools, operator and functools are quite a rich toolbox already. But you won't have more. It's a choice.
The idea is to have enough to be productive, and not enough to be dogmatic. The experience of Guido, and it's one that I share, is that too much functional tooling drives a style that favors expressive writing at the expense of ease of reading.
It's not by chance that LISP and Haskell are considered hard languages to get into, while Python is considered easy to start with.
It has a cost, since no language is perfect, but that's the path this language follows and requesting a snake to fly will only bring you disappointments.
Python tries to strike the balance between the importance of a rich expressiveness and the non negotiable necessity of keeping the code readable: you read a line much more often that you write it, after all. It's a key philosophy of the language. It shaped and will shape numerous decisions around it.
This PEP is a perfect example : it tooks years for the concept to be integrated in Python, and the last debate about this concrete implementation took months. The result is a carefully crafted feature with a lot of details to discourage abuse and remove the needs for pondering when to use it or not.
and i think you are leaving out functional languages which share python's readability, if not surpass it, while remaining much more expressive. that's f# and ocaml.
f#, in my opinion, is superior in everyway to python and subsumes python's abilities of readability, easiness, oop, and scripting, while greatly raising the ceiling of possibility. it's criminally underused, especially in areas where python has been chosen.
and i disagree lisp is harder to get into. racket is just as easy to learn as python, if not easier, due to its regularity. the how to code / systematic program design course on edX and the book how to design programs showcases this.
The first thing I checked is your very vocal assurance that F# is a better scripting language than Python. That seemed very weird to me, after all it's Python strong point. Since I script a lot, I looked for the most popular F# lib to parse script arguments.
Argu seems the winner, according to http://fsharpworks.com/survey.html. Their tutorial is pretty good (https://fsprojects.github.io/Argu/tutorial.html), and here is their hello world. 24 lines of, packing a dense symbology and using a lot of the specific language features:
open Argu
type CLIArguments =
| Working_Directory of path:string
| Listener of host:string * port:int
| Data of base64:byte[]
| Port of tcp_port:int
| Log_Level of level:int
| Detach
with
interface IArgParserTemplate with
member s.Usage =
match s with
| Working_Directory _ -> "specify a working directory."
| Listener _ -> "specify a listener (hostname : port)."
| Data _ -> "binary data in base64 encoding."
| Port _ -> "specify a primary port."
| Log_Level _ -> "set the log level."
| Detach _ -> "detach daemon from console."
let parser = ArgumentParser.Create<CLIArguments>(programName = "gadget.exe")
let results = parser.Parse [| "--detach" ; "--listener" ; "localhost" ; "8080" |]
printfn "%A" results.GetAllResults();;
The same thing with click, the Python most popular solution, is 11 lines, and it's shaped around almost only regular calls and parameters: import click as cli, base64, urllib.parse as url
@cli.command("gadget.exe")
@cli.option('--working-directory', help='specify a working directory.', type=cli.File('rb'))
@cli.option('--listener', help="specify a listener (hostname : port)", type=url.urlparse)
@cli.option('--data', help='binary data in base64 encoding.', type=base64.b64decode)
@cli.option('--port', help='"specify a working directory.', type=cli.File('rb'))
@cli.option('--log-level', help='set the log level.', type=int)
@cli.option('--detach', is_flag=True, help='detach daemon from console')
def hello(**kwargs):
print(kwargs)
hello(["--detach", "--listener", "localhost:8080"])
I have a hard time finding the motivation to look for the truth behind your other arguments after that.what are your objections? what is the dense symbology?
discriminated unions (what the CLIArguments is) are very simple to define and understand. the usage member nearly uses the simplest possible pattern matching available. pattern matching is a staple of functional languages. it's a case statement in its simplest use but is so much more in general.
these two things are the bread and butter of f#. they may take a modicum more initial effort than simple function calls, but it pays off in readability and expandability. it seems python takes the easy route. it makes things apparently simple at first but difficult in the long run.
i know both languages, to a degree, and find the python hard to read. it's also faking types, which is kind of funny. the f# code is fully typed.
lines of code is meaningless to me here because the f# has better delineation of concepts here.
and lastly, there's actually no reason why you couldn't write an f# library to behave like the python one here. that is not true the other way around. that's the power of f#'s multi-paradigm nature.
Also, click is weird because it wants to take over traditional function syntax and "under the covers" rewrite them. Compared to a much simpler Args -> Map kind of construction, this is a great example of how Python introduces unneeded complexity and prefers to create huge spelunking expeditions into its poorly-explained function invocation syntax & semantics. The PEP we're all commenting around is another great example of that approach. It's too bad Python's community is often more interested in novel uses of Python's semantics than actually readable, reusable concepts.
The irony is other "deep in their own waters" approaches produce stuff that's much more readable than click's without also being some kind of solve-the-universe's-problems black-box. Python dooms itself to that because of its refusal to embrace more composable primitives. They'll always end up with completing big-bang projects that don't play well together. Examples available upon request.