# rash: asynchronous shell https://github.com/nqpz/rash Niels G. W. Serup
2 February 2025
ngws@metanohi.name
# Example program in rash ```{sh} #!/usr/bin/env rash >echo Please enter the first number. read number1 >echo Please enter the second number. read number2 result=>expr ${number1} + ${number2} >echo ${number1} + ${number2} = ${result} ```
# Motivation 
# Motivation ```text can(manage(lunch_club)) :- can(use(chatbot)). ```
# Motivation ```text can(manage(lunch_club)) :- can(use(chatbot)). ``` ```text can(use(chatbot)) :- has(irc). ```
# Motivation ```text can(manage(lunch_club)) :- can(use(chatbot)). ``` ```text can(use_for(chatbot, bookkeeping)) :- used_at(chatbot, lunch_time). ```
# Motivation ```text can(use_for(chatbot, bookkeeping)) :- used_at(chatbot, lunch_time). ``` ```text can(use_for(chatbot, ???)). ```
# Motivation ```text can(use_for(chatbot, bookkeeping)) :- used_at(chatbot, lunch_time). ``` ```text can(use_for(chatbot, Game)) :- viable_game_for_medium(irc, Game). ```
# Motivation ```text can(use_for(chatbot, Game)) :- viable_game_for_medium(irc, Game). ``` ```text viable_game_for_medium(irc, ???). ```
# Motivation ```text can(use_for(chatbot, Game)) :- viable_game_for_medium(irc, Game). ``` ```text viable_game_for_medium(irc, Game) :- game_for_genre(text_based, Game). ```
# Motivation ```text viable_game_for_medium(irc, Game) :- game_for_genre(text_based, Game). ``` ```text game_for_genre(text_based, funny_remarks). ```
# Motivation ```text viable_game_for_medium(irc, Game) :- game_for_genre(text_based, Game). ``` ```text game_for_genre(text_based, Game) :- state_based_game(Game). ```
# Motivation ```text game_for_genre(text_based, Game) :- state_based_game(Game). ``` ```text state_based_game(jeopardy). state_based_game(connect_four). state_based_game(wheel_of_fortune). state_based_game(...). ```
# Motivation ```text state_based_game(jeopardy). state_based_game(connect_four). state_based_game(wheel_of_fortune). state_based_game(...). ``` ```text can(play(Game)) :- state_based_game(Game), can(keep_state). ```
# Motivation ```text can(play(Game)) :- state_based_game(Game), can(keep_state). ``` ```text can(keep_state) :- has(background_process). ``` ```text can(keep_state) :- has(manual_state_file_handling). ```
# Motivation ```text can(play(Game)) :- state_based_game(Game), can(keep_state). ``` ```text can(keep_state) :- has(background_process). ``` ```text can(keep_state) :- has(manual_state_file_handling). ``` ```text can(keep_state) :- has(rash). ```
# Motivation ```text can(play(Game)) :- state_based_game(Game), can(keep_state). ``` ```text can(keep_state) :- has(rash). ```
`has(rash)` ⇓\ `can(keep_state)`\ ⇓\ `can(play(Game)) :- state_based_game(Game)`\ ⇓\ `game_for_genre(text_based, Game)`\ ⇓\ `viable_game_for_medium(irc, Game)`\ ⇓ `can(use_for(chatbot, Game))`
`has(rash)`
# The rash approach - No background process - Automatic state management through files - The program state is frozen on `read` instructions
and thawed on program restarts
# Language design 
# Language design 
# Assembly + shell script = rash
# Demonstration ```{sh} numbers=>seq 1 100 numbers_shuffled=<${numbers}>sort -R random_number=<${numbers_shuffled}>head -n1 >echo Guess the number! :guess read guess >test ${guess} -lt ${random_number} jz too_low >test ${guess} -gt ${random_number} jz too_high >test ${guess} -eq ${random_number} jz correct :too_low >echo Your guess was too low, try again. j guess :too_high >echo Your guess was too high, try again. j guess :correct >echo Congratulations, you guessed the number! ```
# Future work ## Following the trends of industry - Turbo Pascal - Turbo Prolog - Turbo C - Turbo Assembler - Turbo BASIC - **Turbo Rash?**
# Future work ## Better syntax - **Needs:** - No jump (goto) commands - Ability to read environment variables - *Ensure backwards compatibility* - **Approach:** - Add another representation - Transform it into the current representation - We get state keeping for free
# Future work ## Better piping - **Current problem:** - Can only emulate piping through intermediate values. - **Future problem if better piping gets implemented:** - Can only freeze state once all subprocesses are done.
# Conclusion - Great language for stateful needs - Try it out https://github.com/nqpz/rash