What does Bash script and Eiffel have in common ?

37 views
Skip to first unread message

Finnian Reilly

unread,
Feb 14, 2025, 6:02:51 AMFeb 14
to Eiffel Users
I just noticed that Bash script and Eiffel have two syntactic similarities. 
  • Use of local reserved word
  • optional () on function call

bash.png
Is that a coincidence I wonder ?

Miguel Oliveira e Silva

unread,
Feb 14, 2025, 10:25:26 AMFeb 14
to eiffel...@googlegroups.com

Local variables [1] exist (at least) since ALGOL 60 (1960) [2] (that's part of "magic" that makes recursive functions feasible).  Programming languages Pascal (1970) and C (~1972) also has local variables (any non-static variable declared inside a block). Most likely, Eiffel (~1985) and bash (1989) simply explicitly give the proper name to that kind of variables.

--

Eiffel (IMHO) [still] is quite unique in the application of the uniform access principle to argumentless-functions/attributes.

-miguel

[1] Execution stack stored variables.

[2] https://en.wikipedia.org/wiki/ALGOL_60 , https://www.algol60.org

--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/eiffel-users/76eabd7e-ae35-419c-a60e-49ac420037b1n%40googlegroups.com.
-- 
Miguel Oliveira e Silva
IEETA-DETI, University of Aveiro, Portugal

Bertrand Meyer (ETH)

unread,
Feb 14, 2025, 11:20:13 AMFeb 14
to eiffel...@googlegroups.com

To be precise in Eiffel “optional () on function call” is not quite right. If there are no arguments there is no “()” part. The full formal argument list in parentheses simply does not appear.

 

The relevant syntax production is Entity_declaration_list == {Entity_declaration_group ";" }+

 

(A Formal_arguments part is defined as "(" Entity_declarations ")" .)

 

This convention ensures uniform access (parentheses would be meaningless for an attribute).

 

-- BM

Ian Joyner

unread,
Feb 14, 2025, 7:28:39 PMFeb 14
to eiffel...@googlegroups.com
Even if ‘()’ is optional, it should NEVER be used. It is just syntactic junk from C. But syntactic junk is usually an indication of deeper problems and indeed that is the case with ().

() breaks uniform access. It reveals that an name invocation is to a called block (wrongly equated to function). () breaks encapsulation and reveals this implementation. () is a kind of Hungarian notation, revealing things that should be hidden.

Programmers seem to now be so captured by this awful syntax that it is occurring in natural language (perhaps to indicate verbs). But programmers are also increasingly using the awful CamelCase in natural language as well.

Ian

On 14 Feb 2025, at 22:02, Finnian Reilly <frei...@gmail.com> wrote:

I just noticed that Bash script and Eiffel have two syntactic similarities. 
  • Use of local reserved word
  • optional () on function call

<bash.png>
Is that a coincidence I wonder ?

--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/eiffel-users/76eabd7e-ae35-419c-a60e-49ac420037b1n%40googlegroups.com.
<bash.png>

Finnian Reilly

unread,
Feb 15, 2025, 5:07:39 AMFeb 15
to Eiffel Users
After further research I discovered the following about Bash functions. They should be thought of as faux-applications for the following reasons:
  • When  you call them you cannot put parenthesis around the arguments. They have to be listed like command line args.
  • It is only possible to return success (0) or failure (1). You cannot for example return a string type. But this allows you to use them in conditional statements.
But still they are useful to make your bash scripts more readable. I had occasion to use them in this script (under development) which is a useful model for how to get an Eiffel process to message a script run with root permissions by using file locks for synchronisation.
Bash does not have boolean variables but I found a handy way to emulate them with the -v test which functions like the Eiffel attached test

dir_path=/var/local/$domain_name
rules_path=$dir_path/user.rules
lock_path=$dir_path/rules.lock
last_digest=""

if [[ ! -d "$dir_path" ]]; then
mkdir dir_path
fi

if [[ ! -e "$rules_path" ]]; then
cp /lib/ufw/user.rules $dir_path
chown $USER:$USER $rules_path
chmod 644 $rules_path
fi

# Dry run on dev machine
if [[ "$(hostname)" != "$domain_name" ]]; then
dry_run=true
else
unset dry_run
fi

echo $USER
echo "Listening for changes to: $rules_path"

while inotifywait -q -e close_write $rules_path 1>/dev/null; do
set_digest
while "$digest" != "$last_digest"; do
echo Updating firewall rules
# if not a dry run on dev machine
if [[ -v dry_run ]]; then
install_rules; ufw reload
else
echo ufw reload
fi
last_digest="$digest"
set_digest
done
done

Ulrich Windl

unread,
Feb 15, 2025, 5:44:23 AMFeb 15
to eiffel...@googlegroups.com
Hi!

That's not correct about return: You can return an integer (status code), but in most cases it's interpreted as Boolean failure code (as the C library functions do).

--

Kind regards,
Ulrich Windl

Finnian Reilly

unread,
Feb 15, 2025, 5:59:19 AMFeb 15
to Eiffel Users

That's not correct about return: You can return an integer (status code),
I wrote "It is only possible to return success (0) or failure (1)."  0  and 1 in brackets are both integers. How is that not correct? Apart from the fact I didn't mention that failure can be any error code.

Finnian Reilly

unread,
Feb 15, 2025, 6:12:28 AMFeb 15
to Eiffel Users
 but in most cases it's interpreted as Boolean failure code (as the C library functions do).
if you are referring to conditional statement like if then then it is not true to say the return value is  interpreted as a boolean otherwise success would be 1 and failure would be 0.

Finnian Reilly

unread,
Feb 15, 2025, 6:15:00 AMFeb 15
to Eiffel Users
For example: 
check_root() {
    [[ "$EUID" -eq 0 ]] && exit 0 || exit 1
}
# cannot be interpreted as boolean
if check_root; then
    echo "Running as root"
else
    echo "Not running as root"
fi


Ulrich Windl

unread,
Feb 15, 2025, 8:56:09 AMFeb 15
to eiffel...@googlegroups.com
Please learn about $?.

Ulrich Windl

unread,
Feb 15, 2025, 9:00:09 AMFeb 15
to eiffel...@googlegroups.com
The code is wrong:
check_root() {
    [[ "$EUID" -eq 0 ]] && exit 0 || exit 1
}

Correct is:
check_root() {
    [[ "$EUID" -eq 0 ]]
}

If you "exit" in a routine the process terminates; so there is no sense in querying the result.

Finnian Reilly

unread,
Feb 15, 2025, 9:27:09 AMFeb 15
to Eiffel Users
On Saturday, 15 February 2025 at 14:00:09 UTC Ulrich W. wrote:
The code is wrong:
check_root() {
    [[ "$EUID" -eq 0 ]] && exit 0 || exit 1
}

Correct is:
check_root() {
    [[ "$EUID" -eq 0 ]]
}
Thanks for pointing out the mistake of Chat GPT, and it did look a little strange to me. This shows why you cannot rely on Chat GPT for coding. Our programming careers are safe for the time being. :-)

Finnian Reilly

unread,
Feb 15, 2025, 9:37:30 AMFeb 15
to Eiffel Users
Please learn about $?.
Yes I know about $?, but since I just wanted some code to illustrative a particular point I was happy to accept the GTP code at face value. 
Reply all
Reply to author
Forward
0 new messages