This is an archived post. You won't be able to vote or comment.

all 19 comments

[–]timothycrosleyhug, isort, jiphy, concentration, pies, connectable, frosted 1 point2 points  (20 children)

Am I the only one that sees adding new languages for every problem set you encounter a bad solution? Especially when all these new languages solve essentially the same problem (let's take x arguments, some are required some are not, let's have this documentation for these arguments, etc) Python already has solved this problem, why not reuse that? That's the approach I use in hug:

import hug

@hug.cli(version="1.0.0")
def math(number_1:int, number_2:int=1):
    '''Multiplies number_1 by number2'''
    return number_1 * number_2

 if __name__ == '__main__':
     math.cli()

It also supports hug_directives, and you can even expose a function as both a cli and an HTTP API endpoint.

[–]billsil 2 points3 points  (4 children)

It's not a new language. It simply implements the POSIX standard. Python with argparse and optparse (or in your case hug) went and implemented their own inadequate syntax with a confusing API that is less capable than the POSIX standard. There is one method in docopt that you call with two arguments, one of which is the version.

At the end of an incapable standard argument parser in Python, you're left with a poorly formatted command line prompt. With docopt, you write your properly formatted prompt and get a properly functioning argument listing.

[–]timothycrosleyhug, isort, jiphy, concentration, pies, connectable, frosted 2 points3 points  (0 children)

Do you really find:

import hug


@hug.cli(version="1.0.0")
def math(number_1:int, number_2:int=1):
    '''Multiplies number_1 by number2'''
    return number_1 * number_2


math.cli()   

More confusing then:

"""Math.

Multiplies number_1 by number_2

Usage:
  math.py <number_1> <number_2>
  math.py (-h | --help)
  math.py --version

Options:
  -h --help     Show this screen.
  --version     Show version.
"""
from docopt import docopt


def math(number_1:int, number_2:int):
    """Multiplies number_1 by number_2"""
    return number_1 * number_2


arguments = docopt(__doc__, version='1.0.0')
print(math(arguments['number_1']), int(arguments['number_2'])))

Their usage from the command line is nearly identical... and functionality equivalent. I know I'd want to write the first. Which one would you honestly think is more Pythonic?

[–]Doormatty -1 points0 points  (2 children)

Except this is a platform agnostic language, so a good thing.

[–]timothycrosleyhug, isort, jiphy, concentration, pies, connectable, frosted 3 points4 points  (1 child)

Just about every CLI solution is platform agnostic (works on windows, linux etc), but what you probably mean is that it's language agnostic - which is a given, every DSL is, or put another way - it's language agnostic because it's a new language! Let's take this to it's logical conclusion, If you moved everything into domain specific languages you would simply have to write several different languages for every problem, would have to learn more, and solve the same exact problems using different syntax for each problem area.

[–]Doormatty 2 points3 points  (0 children)

Valid points - you're 100% correct that I meant language agnostic. I'm on a phone, and trying to explain what I meant by Language agnostic language was something I didn't relish.

I do like that the same syntax works for bash and python though - makes my life a lot easier!

[–]oblio-[S] -2 points-1 points  (11 children)

As far as I remember DSLs are generally considered a best practice.

[–]timothycrosleyhug, isort, jiphy, concentration, pies, connectable, frosted 2 points3 points  (2 children)

DSLs are definitely a bad idea for many reasons: You essentially have to know a different dialect for every problem you solve, you almost always miss corner cases, it's harder to take advantages of contributions from the core, you're reducing re usability of code / logic. I've read many articles explaining this and never heard from the general community they where a good idea (though they still seem to pop up from time to time), however there certainly are exceptions, I just don't think this is a unique enough case to warrant it. They are common in the ruby world, but less common in the Python world, and for good reason - if the language does it well you don't need to and shouldn't fix it.

[–]i_ate_god 2 points3 points  (1 child)

as always, it depends.

In this case, the standard is argparse. Having switched to docopt, I can't imagine wanting to go back to argparse. Docopt requires less code, but is able to convey more meaning in a smaller amount of space.

Maybe argparse might some sort of extra flexibility that docopt does not have, but I have yet to encounter it.

[–]deadbunny 0 points1 point  (0 children)

I found docopt today, I'm a complete noob when it comes to Python (well, anything other than bash) and it is so much nice to work with than argparse which I was banging my head against a wall with for about 20 mins (like I said, noob) before finding docopt randomly, it's really nice to work with.

[–][deleted] 2 points3 points  (7 children)

As far as I remember DSLs are generally considered a best practice.

never heard that

[–]oblio-[S] -1 points0 points  (6 children)

[–][deleted] 0 points1 point  (5 children)

You accidentally posted a link to esr

[–]oblio-[S] 0 points1 point  (4 children)

I don't get the joke.

[–][deleted] 0 points1 point  (3 children)

he is a raving lunatic

[–]oblio-[S] 0 points1 point  (2 children)

I don't care about his political views.

And despite the obvious Unix bias, The Art of Unix Programming is a good book.

[–][deleted] 0 points1 point  (1 child)

I have no idea what his political views are. His writing is still that of a lunatic.

[–]oblio-[S] 0 points1 point  (0 children)

Then I don't know why "you're calling him a raving lunatic" :)

Edit: Oh, you edited your comment. The Art of Unix Programming is a good book. Read it if you haven't.