Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Concept: functions #715

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft

Conversation

glennj
Copy link
Contributor

@glennj glennj commented Dec 20, 2024

Functions concept

@glennj glennj marked this pull request as draft December 20, 2024 23:23
@glennj glennj requested a review from a team December 20, 2024 23:23
Copy link
Member

@kotp kotp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still in WIP/Draft state...


## Defining a Function

You declare a function is one of two ways.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You declare a function is one of two ways.
You declare a function in one of two ways.

The first is a "portable" style

```bash
funcname () { COMMANDS; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use function_name here?

It also shows what is, I think, the style used for multiple names, while also using full words instead of abbreviations, so is helpful as documentation in its clarity as well.

Showing what I mean in a later suggestion...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point. Perhaps my_function since it doesn't start with "function".

Alternately, you can use the `function` keyword

```bash
function funcname { COMMANDS; }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
function funcname { COMMANDS; }
function function_name { COMMANDS; }

Comment on lines +33 to +36
~~~~exercism/advanced
The special parameter `$0` is not changed inside a function; it is still the name of the executing script.
The currently executing function can access its name with the `$FUNCNAME` variable.
~~~~
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could give a link to the special parameters section manual page:

https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html

Technically, "global" is not the right word to use.
Assignments to non-local variables will assign to the variable with that name that has been declared in some previous scope, up to the global scope.

This example is taken from the bash manual
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which section of the man page? I am not finding this in the man pages section 1. Or a better question which bash manual?

Can we give the command or link to get to it?


Functions can call themselves recursively.
By default, there is no limit to the depth of recursion.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

# Functions

Many Bash scripts are written in a strictly imperative style: execute one command, then execute another command, and so on.
But often you'll need to have a group of commands that conceptually perform a single purpose.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
But often you'll need to have a group of commands that conceptually perform a single purpose.
Sometimes you need to group together commands that conceptually perform a single purpose.


## Defining a Function

You declare a function is one of two ways.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
You declare a function is one of two ways.
You can declare a function in two ways.

funcname () { COMMANDS; }
```

This is the style that was created with the original Bourne shell.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This is the style that was created with the original Bourne shell.
This is the style from the original Bourne shell.

function funcname { COMMANDS; }
```

There is no difference between the two styles.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we recommend the portable syntax?

## Function Parameters

Functions, once defined, act like any other command (builtin or not).
Like any command, you can provide _arguments_ for your functions.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Like any command, you can provide _arguments_ for your functions.
Like any command, you can provide _arguments_ to your functions.

A function, like any command, has an _exit status_.
By default, the status of a function is the exit status of the _last command executed_.

You can use the `return` command to return from a function with a specific exit status.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you want to mention the behavior of return without an arg?

The return status of a function is just a number.
How can a function produce output?

Your function simply emits output on standard output.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Your function simply emits output on standard output.
Your function can print to standard output.
Then, you can use command substitution to capture it.

Use the familiar _command substitution_ to capture it:

```bash
d6 () { echo $(( 1 + RANDOM % 6 )); }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always quote every expansion ;)


### Using Both the Output and the Status

The exit status of a function is still available to use when you are capturing the output.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The exit status of a function is still available to use when you are capturing the output.
The exit status of a function is available to use even when you are capturing the output.

fi
```

## Recursion
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No examples? Fibonacci would be a classic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants