abs-lang / abs

Home of the ABS programming language: the joy of shell scripting.
https://www.abs-lang.org
MIT License
518 stars 35 forks source link

Simplify arg numbering #253

Open kmptkp opened 5 years ago

kmptkp commented 5 years ago

The first argument of a script is arg(2), not the expected arg(1) (or arg(0)). This is unlike the shell, where the first argument is $1 not $2, creating slight confusion when starting with abs. At the same time, arg(0) answers the path of the abs binary, which I'm guessing is basically never useful to users of abs and is again unlike the shell which doesn't answer the path of its binary, rather arg(1) corresponds to the shell's $0.

From the point of view of abs users, it would thus be much more coherent and simple to change abs to be like the shell: arg(0) answers the path of the script like $0, arg(1) answers the first argument, etc.

odino commented 5 years ago

Here's what happens:

$ cat bash.ignore
echo $0
echo $1
echo $2

$ cat abs.ignore 
echo(arg(0))
echo(arg(1))
echo(arg(2))

$ bash bash.ignore 1 2 3
bash.ignore
1
2

$ abs abs.ignore 1 2 3
abs
abs.ignore
1

So ABS arguments are actually shifted by one position -- as we add the executed program at the very beginning. This is consistent with Go's os.Args behavior.

Just to give an overview:

There doesn't seem to be a consensus out there. Though I will say it's weird to get a list of arguments and have the first one being the executable itself. At the same time, it's maybe more pragmatic than having a special variable like python's sys.executable (I couldn't find a way to get the executable name on bash itself but I assume there's going to be a magic way to do so there as well).

Opinions? :slightly_smiling_face: I'm also down to simply update the documentation to make the current functionality clear.

kmptkp commented 5 years ago

It depends on who you think your target audience is. If you think abs is meant to be adopted by people writing go, or by web developers, then the current situation is fine. If on the other hand abs is optimised to appeal to shell scripters, then having all the arguments "off by one" wrt the shell is going to be a wart. (And I would guess that it is not an accident that the more "scripting" languages on your list - python, ruby, bash - all have the equivalent of $1=argument1, etc. rather than $2=argument1. So I would still vote for not passing in the path of the abs binary, and thus being arg(n) being consistent with the bash.

odino commented 5 years ago

That is fine by me -- eventually, I want it to be seamless for people used to shell scripting.

This poses a new "problem", how do we get the path to the executable? What do you think of:

?

Now that I think of it, maybe starting with the env variable and then converting to modules might make more sense...open to suggestions :smile:

odino commented 5 years ago

@kmptkp any feedback?

odino commented 5 years ago

I'd like to move this to 1.9, when we have modules and can do require("system").executable

ryuheechul commented 4 years ago

It was confusing to have executable as the first one and all others shifted by one position because of it. It is different from bash so I got confused at first. However I think this is only a problem when people don't know about this. After I learned this, it's not a problem for me. Especially since I can even just do something like this to get rid of the first one easily.

my_args = args()[1:]

However, I'm curious what could be the best way to do something like this in abs

echo $@ # echo all args 
shift
echo $@ # echo all args except the first one
odino commented 4 years ago

@ryuheechul in bash the shift is "permanent" -- so it removes the argument and "goodbye forever" to the first one. Is that what you'd like to achieve?

No way to do it as such in ABS, unless you use your shortcut (args()[1:]) -- but it doesn't really make the shift permanent. I'd actually argue that's a good thing we aren't allowed to modify global variables like this :slightly_smiling_face:

ryuheechul commented 4 years ago

@odino Thanks for response πŸ™‚. You got my intention right and I agree with your reasoning for avoid changing global variables especially when the script is big. However when it’s short enough, shift + $@ can be short and quick way to run another command depends on the first arg. However since args()[3:].join(β€˜ β€˜) is not bad either actually. I was just curious if there was a guideline for this usage and I think you answered it πŸ‘

odino commented 4 years ago

No guideline, I'd actually advice to do what you suggested :)

On Wed, May 6, 2020, 9:07 PM Heechul Ryu notifications@github.com wrote:

@odino https://github.com/odino Thanks for response πŸ™‚. You got my intention right and I agree with your reasoning for avoid changing global variables especially when the script is big. However when it’s short enough, shift + $@ can be short and quick way to run another command depends on the first arg. However since args()[3:].join(β€˜ β€˜) is not bad either actually. I was just curious if there was a guideline for this usage and I think you answered it πŸ‘

β€” You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/abs-lang/abs/issues/253#issuecomment-624773106, or unsubscribe https://github.com/notifications/unsubscribe-auth/AACQFZC55R2UEUU3EAWX5GDRQGKONANCNFSM4IHIZNIA .