I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

You are encouraged to solve this task according to the task description, using any language you may know.

Given a prompt and a list containing a number of strings of which one is to be selected, create a function that:

• prints a textual menu formatted as an index value followed by its corresponding string for each item in the list;
• prompts the user to enter a number;
• returns the string corresponding to the selected index number.

The function should reject input that is not an integer or is out of range by redisplaying the whole menu before asking again for a number. The function should return an empty string if called with an empty list.

For test purposes use the following four phrases in a list:

```   fee fie
huff and puff
mirror mirror
tick tock
```
Note

This task is fashioned after the action of the Bash select statement.

## 11l

`V items = [‘fee fie’, ‘huff and puff’, ‘mirror mirror’, ‘tick tock’] L   L(item) items      print(‘#2. #.’.format(L.index + 1, item))    V reply = input(‘Which is from the three pigs: ’).trim(‘ ’)   I !reply.is_digit()      L.continue    I Int(reply) C 1..items.len      print(‘You chose: ’items[Int(reply) - 1])      L.break`
Output:
``` 1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: a
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 0
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 2
You chose: huff and puff
```

## Action!

`DEFINE PTR="CARD" BYTE FUNC Init(PTR ARRAY items)  items(0)="fee fie"  items(1)="huff and puff"  items(2)="mirror mirror"  items(3)="tick tock"RETURN (4) PROC ShowMenu(PTR ARRAY items BYTE count)  BYTE i   FOR i=1 TO count  DO    PrintF("(%B) %S%E",i,items(i-1))  ODRETURN BYTE FUNC GetMenuItem(PTR ARRAY items BYTE count)  BYTE res   DO    ShowMenu(items,count) PutE()    Print("Make your choise: ")    res=InputB()  UNTIL res>=1 AND res<=count  ODRETURN (res-1) PROC Main()  PTR ARRAY items(10)  BYTE count,res   count=Init(items)  res=GetMenuItem(items,count)  PrintF("You have chosen: %S%E",items(res))RETURN`
Output:
```(1) fee fie
(2) huff and puff
(3) mirror mirror
(4) tick tock

(1) fee fie
(2) huff and puff
(3) mirror mirror
(4) tick tock

You have chosen: huff and puff
```

`with ada.text_io,Ada.Strings.Unbounded; use  ada.text_io, Ada.Strings.Unbounded; procedure menu is 	type menu_strings is array (positive range <>) of Unbounded_String ;	function "+" (s : string) return Unbounded_String is (To_Unbounded_String (s)); 	function choice (m : menu_strings; prompt : string) return string is	begin		if m'length > 0 then			loop 				put_line (prompt);				for i in m'range loop					put_line (i'img &") " & To_String (m(i)));				end loop;				begin					return To_String (m(positive'value (get_line)));					exception when others => put_line ("Try again !");				end;			end loop;		end if;		return "";	end choice; begin	put_line ("You chose " & 		choice ((+"fee fie",+"huff and puff",+"mirror mirror",+"tick tock"),"Enter your choice "));end menu;`

## ALGOL 68

Translation of: C
Works with: ALGOL 68 version Revision 1 - no extensions to language used
Works with: ALGOL 68G version Any - tested with release 1.18.0-9h.tiny
`PROC menu select := (FLEX[]STRING items, UNION(STRING, VOID) prompt)STRING:(        INT choice;         IF LWB items <= UPB items THEN                WHILE                        FOR i FROM LWB items TO UPB items DO                                printf((\$g(0)") "gl\$, i, items[i]))                        OD;                        CASE prompt IN                                (STRING prompt):printf((\$g" "\$, prompt)),                                (VOID):printf(\$"Choice ? "\$)                        ESAC;                        read((choice, new line));                # WHILE # 1 > choice OR choice > UPB items                DO SKIP OD;                items[choice]        ELSE                ""        FI); test:(        FLEX[0]STRING items := ("fee fie", "huff and puff", "mirror mirror", "tick tock");        STRING prompt := "Which is from the three pigs : ";         printf((\$"You chose "g"."l\$, menu select(items, prompt))))`

Output:

```1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Which is from the three pigs :  2
You chose huff and puff.
```

## Arturo

`menu: function [items][    selection: neg 1    while [not? in? selection 1..size items][        loop.with:'i items 'item -> print ~"|i+1|. |item|"        inp: input "Enter a number: "        if numeric? inp ->            selection: to :integer inp    ]	print items\[selection-1]] menu ["fee fie" "huff and puff" "mirror mirror" "tick tock"]`
Output:
```1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: something wrong
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: 5
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: 3
mirror mirror```

## AutoHotkey

`Menu(list:=""){	if !list			; if called with an empty list		return			; return an empty string	for i, v in x := StrSplit(list, "`n", "`r")		string .= (string?"`n":"") i "- " v		, len := StrLen(v) > len ? StrLen(v) : len	while !x[Choice]		InputBox , Choice, Please Select From Menu, % string ,, % 200<len*7 ? 200 ? len*7 , % 120 + x.count()*20	return x[Choice]}`
Examples:
`list = (fee fiehuff and puffmirror mirrortick tock)MsgBox % Menu(list)		; call menu with listMsgBox % Menu()			; call menu with empty listreturn`

## AWK

` # syntax: GAWK -f MENU.AWKBEGIN {    print("you picked:",menu(""))    print("you picked:",menu("fee fie:huff and puff:mirror mirror:tick tock"))    exit(0)}function menu(str,  ans,arr,i,n) {    if (str == "") {      return    }    n = split(str,arr,":")    while (1) {      print("")      for (i=1; i<=n; i++) {        printf("%d - %s\n",i,arr[i])      }      printf("? ")      getline ans      if (ans in arr) {        return(arr[ans])      }      print("invalid choice")    }} `

## Axe

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.

In Axe, static data (such as strings) is laid out sequentially in memory. So the H in "HUFF" is the byte after the null terminator for "FIE". However, null terminators are only added to strings when they are stored with the store symbol →. strGet returns a pointer to the start of the nth null-terminated string in the data, which is why the strings must be laid out in memory correctly.

`"FEE FIE"→Str1"HUFF AND PUFF"→Str2"MIRROR MIRROR"→Str3"TICK TOCK"→Str4For(I,1,4) Disp I▶Hex+3,":",strGet(Str1,I-1),iEndDisp "NUMBER? "input→A{A}-'0'→NIf N<1 or N>4 Disp "BAD NUMBER",i ReturnEndDisp strGet(Str1,N-1),i`

## BASIC

Works with: QuickBasic version 4.5
` FUNCTION sel\$(choices\$(), prompt\$)   IF UBOUND(choices\$) - LBOUND(choices\$) = 0 THEN sel\$ = ""   ret\$ = ""   DO      FOR i = LBOUND(choices\$) TO UBOUND(choices\$)         PRINT i; ": "; choices\$(i)      NEXT i      INPUT ;prompt\$, index      IF index <= UBOUND(choices\$) AND index >= LBOUND(choices\$) THEN ret\$ = choices\$(index)   WHILE ret\$ = ""   sel\$ = ret\$END FUNCTION`

### Applesoft BASIC

While the following example could be lengthened to demonstrate larger menu-driven projects, it is useful to simply print the resulting string indexed by the user input.

` 10 M\$(4) = "TICK TOCK" 20 M\$(3) = "MIRROR MIRROR" 30 M\$(2) = "HUFF AND PUFF" 40 M\$(1) = "FEE FIE" 50  GOSUB 100"MENU 60  PRINT M\$ 70  END  100 M\$ = "" 110  FOR M = 0 TO 1 STEP 0 120      FOR N = 1 TO 1E9 130          IF  LEN (M\$(N)) THEN  PRINT N". "M\$(N): NEXT N 140      IF N = 1 THEN  RETURN  150      INPUT "ENTER A NUMBER:";N% 160     M = N% >  = 1 AND N% < N 170  NEXT M 180 M\$ = M\$(N%) 190  RETURN `

### Commodore BASIC

While the following example could be shortened to simply print the resulting string indexed by the user input, it is useful to demonstrate that larger menu-driven projects benefit from the use of the `ON n... GOSUB` statement to pass control to larger subroutines.

`1 rem menu5 rem rosetta code10 gosub 900 20 print chr\$(147);chr\$(14)30 print "   Menu   "35 print:print "Choose an incantation:":print40 for i=1 to 545 print i;chr\$(157);". ";op\$(i,1)50 next i:print55 print "choose one: ";60 get k\$:if k\$<"1" or k\$>"5" then 6065 k=val(k\$):print chr\$(147)70 on k gosub 100,200,300,400,50080 if k=5 then end 90 print:print "Press any key to continue."95 get k\$:if k\$="" then 9596 goto 20 100 rem fee fi110 print op\$(k,2)115 return 200 rem huff puff210 print op\$(k,2)215 return 300 rem mirror mirror310 print op\$(k,2)315 return 400 rem tick tock410 print op\$(k,2)415 return 500 rem quit510 print op\$(k,2):print "Goodbye!"515 return 900 rem initialize905 dim op\$(10,2)910 for a=1 to 5915 read op\$(a,1),op\$(a,2)920 next a925 return 1000 data "Fee fi fo fum","I smell the blood of an Englishman!"1005 data "Huff and puff","The house blew down!"1010 data "Mirror, mirror","You seem to be the fairest of them all!"1015 data "Tick tock","Time passes..."1020 data "<Quit>","You decide to leave."`

## Batch File

Example 1

`@echo off & setlocal enabledelayedexpansion set "menuChoices="fee fie","huff and puff","mirror mirror","tick tock"" call :menu pause>nul & exit  :menu	if defined menuChoices (		set "counter=0" & for %%a in (%menuChoices%) do (			set /a "counter+=1"			set "currentMenuChoice=%%a"			set option[!counter!]=!currentMenuChoice:"=!		)	):tryagaincls&echo.for /l %%a in (1,1,%counter%) do echo %%a^) !option[%%a]!echo.set /p "input=Choice 1-%counter%: "echo.for /l %%a in (1,1,%counter%) do (	if !input! equ %%a echo You chose [ %%a^) !option[%%a]! ] & goto :EOF)echo.echo.Invalid Input. Please try again...pausegoto :tryagain`

Example 2

` @echo off call:menu "fee fie" "huff and puff" "mirror mirror" "tick tock"pause>nulexit /b :menuclssetlocal enabledelayedexpansionset count=0set reset=endlocal ^& goto menu:menuloopfor %%i in (%*) do (	set /a count+=1	set string[!count!]=%%~i	echo string[!count!] = %%~i)echo.set /p choice=^>if "%choice%"=="" %reset%set "isNum="for /f "delims=0123456789" %%i in ("%choice%") do set isNum=%%iif defined isNum %reset%if %choice% gtr %count% %reset%echo.!string[%choice%]!goto:eof `

## BBC BASIC

`      DIM list\$(4)      list\$() = "fee fie", "huff and puff", "mirror mirror", "tick tock"      selected\$ = FNmenu(list\$(), "Please make a selection: ")      PRINT selected\$      END       DEF FNmenu(list\$(), prompt\$)      LOCAL index%, select\$      IF SUM(list\$()) = "" THEN = ""      REPEAT        CLS        FOR index% = 0 TO DIM(list\$() ,1)          IF list\$(index%)<>"" PRINT ; index% ":", list\$(index%)        NEXT        PRINT prompt\$ ;        INPUT "" select\$        index% = VAL(select\$)        IF select\$<>STR\$(index%) index% = -1        IF index%>=0 IF index%<=DIM(list\$() ,1) IF list\$(index%)="" index% = -1      UNTIL index%>=0 AND index%<=DIM(list\$(), 1)      = list\$(index%)`

Empty entries in the list are not offered as options, nor accepted as a selection.

## Brat

`menu = { prompt, choices |  true? choices.empty?  { "" }  {    choices.each_with_index { c, i |      p "#{i}. #{c}"    }     selection = ask prompt       true? selection.numeric?      { selection = selection.to_i        true? selection < 0 || { selection >= choices.length }          { p "Selection is out of range"; menu prompt, choices }          { choices[selection] }      }    { p "Selection must be a number"; menu prompt, choices }  }} p menu "Selection: " ["fee fie" "huff and puff" "mirror mirror" "tick tock"]`

## C

`#include <stdio.h>#include <stdlib.h>#include <string.h> const char *menu_select(const char *const *items, const char *prompt); intmain(void){	const char *items[] = {"fee fie", "huff and puff", "mirror mirror", "tick tock", NULL};	const char *prompt = "Which is from the three pigs?"; 	printf("You chose %s.\n", menu_select(items, prompt)); 	return EXIT_SUCCESS;} const char *menu_select(const char *const *items, const char *prompt){	char buf[BUFSIZ];	int i;	int choice;	int choice_max; 	if (items == NULL)		return NULL; 	do {		for (i = 0; items[i] != NULL; i++) {			printf("%d) %s\n", i + 1, items[i]);		}		choice_max = i;		if (prompt != NULL)			printf("%s ", prompt);		else			printf("Choice? ");		if (fgets(buf, sizeof(buf), stdin) != NULL) {			choice = atoi(buf);		}	} while (1 > choice || choice > choice_max); 	return items[choice - 1];}`

## C#

` using System;using System.Collections.Generic; public class Menu{        static void Main(string[] args)        {            List<string> menu_items = new List<string>() { "fee fie", "huff and puff", "mirror mirror", "tick tock" };            //List<string> menu_items = new List<string>();            Console.WriteLine(PrintMenu(menu_items));            Console.ReadLine();        }        private static string PrintMenu(List<string> items)        {            if (items.Count == 0)                return "";             string input = "";            int i = -1;            do            {                for (int j = 0; j < items.Count; j++)                    Console.WriteLine("{0}) {1}", j, items[j]);                 Console.WriteLine("What number?");                input = Console.ReadLine();             } while (!int.TryParse(input, out i) || i >= items.Count || i < 0);            return items[i];        }} `

## C++

`#include <iostream>#include <string>#include <vector> void print_menu(const std::vector<std::string>& terms){    for (size_t i = 0; i < terms.size(); i++) {        std::cout << i + 1 << ") " << terms[i] << '\n';    }} int parse_entry(const std::string& entry, int max_number){    int number = std::stoi(entry);    if (number < 1 || number > max_number) {        throw std::invalid_argument("");    }     return number;} std::string data_entry(const std::string& prompt, const std::vector<std::string>& terms){    if (terms.empty()) {        return "";    }     int choice;    while (true) {        print_menu(terms);        std::cout << prompt;         std::string entry;        std::cin >> entry;         try {            choice = parse_entry(entry, terms.size());            return terms[choice - 1];        } catch (std::invalid_argument&) {            // std::cout << "Not a valid menu entry!" << std::endl;        }    }} int main(){    std::vector<std::string> terms = {"fee fie", "huff and puff", "mirror mirror", "tick tock"};    std::cout << "You chose: " << data_entry("> ", terms) << std::endl;} `

## Ceylon

`"Run the module `menu`."shared void run() { 	value selection = menu("fee fie", "huff And puff", "mirror mirror", "tick tock"); 	print(selection);} String menu(String* strings) {	if(strings.empty) {		return "";	}	value entries = map(zipEntries(1..strings.size, strings));	while(true) {		for(index->string in entries) {			print("``index``) ``string``");		}		process.write("> ");		value input = process.readLine();		if(exists input, exists int = parseInteger(input), exists string = entries[int]) {			return string;		}	}}  `

## Clojure

`(defn menu [prompt choices]  (if (empty? choices)     ""    (let [menutxt (apply str (interleave                              (iterate inc 1)                              (map #(str \space % \newline) choices)))]      (println menutxt)      (print prompt)      (flush)      (let [index (read-string (read-line))]        ; verify        (if (or (not (integer? index))                (> index (count choices))                (< index 1))          ; try again          (recur prompt choices)          ; ok          (nth choices (dec index))))))) (println "You chose: "         (menu "Which is from the three pigs: "               ["fee fie" "huff and puff" "mirror mirror" "tick tock"]))`

## COBOL

`       IDENTIFICATION DIVISION.       PROGRAM-ID. Test-Prompt-Menu.        DATA DIVISION.       WORKING-STORAGE SECTION.        01  Num-Options    USAGE UNSIGNED-INT VALUE 4.       01  Example-Menu.           03  Example-Options-Data.               05  FILLER PIC X(30) VALUE "fee fie".               05  FILLER PIC X(30) VALUE "huff and puff".               05  FILLER PIC X(30) VALUE "mirror mirror".               05  FILLER PIC X(30) VALUE "tick tock".            03  Example-Options-Values REDEFINES Example-Options-Data.               05  Example-Options PIC X(30) OCCURS 4 TIMES.        01  Chosen-Option PIC X(30).        PROCEDURE DIVISION.           CALL "Prompt-Menu" USING BY CONTENT Num-Options               BY CONTENT Example-Menu               BY REFERENCE Chosen-Option            DISPLAY "You chose: " Chosen-Option            GOBACK           .        END PROGRAM Test-Prompt-Menu.        IDENTIFICATION DIVISION.       PROGRAM-ID. Prompt-Menu.        DATA DIVISION.       LOCAL-STORAGE SECTION.       01  User-Input        USAGE UNSIGNED-INT.       01  Input-Flag        PIC X.           88  Valid-Input   VALUE "Y".        01  Options-Index     USAGE UNSIGNED-INT.       01  Index-Display     PIC Z(10).        LINKAGE SECTION.        01  Num-Options       USAGE UNSIGNED-INT.       01  Menu-Options.           03  Options-Table PIC X(30) OCCURS 0 TO 10000000 TIMES               DEPENDING ON Num-Options.        01  Chosen-Option     PIC X(30).        PROCEDURE DIVISION USING Num-Options Menu-Options Chosen-Option.       Main.           IF Num-Options = 0               MOVE SPACES TO Chosen-Option               GOBACK           END-IF            PERFORM UNTIL Valid-Input               PERFORM Display-Menu-Options                DISPLAY "Choose an option: " WITH NO ADVANCING               ACCEPT User-Input                PERFORM Validate-Input           END-PERFORM            MOVE Options-Table (User-Input) TO Chosen-Option            GOBACK           .        Display-Menu-Options.           PERFORM VARYING Options-Index FROM 1 BY 1                   UNTIL Num-Options < Options-Index               MOVE Options-Index TO Index-Display               DISPLAY                   Index-Display ". " Options-Table (Options-Index)               END-DISPLAY           END-PERFORM           .        Validate-Input.           IF User-Input = 0 OR > Num-Options               DISPLAY "Invalid input."           ELSE               SET Valid-Input TO TRUE           END-IF           .        END PROGRAM Prompt-Menu.`

## Common Lisp

`(defun select (prompt choices)  (if (null choices)    ""    (do (n)        ((and n (<= 0 n (1- (length choices))))         (nth n choices))      (format t "~&~a~%" prompt)      (loop for n from 0            for c in choices            do (format t "  ~d) ~a~%" n c))      (force-output)      (setf n (parse-integer (read-line *standard-input* nil)                             :junk-allowed t)))))`

## D

`import std.stdio, std.conv, std.string, std.array, std.typecons; string menuSelect(in string[] entries) {    static Nullable!(int, -1) validChoice(in string input,                                          in int nEntries)    pure nothrow {        try {            immutable n = input.to!int;            return typeof(return)((n >= 0 && n <= nEntries) ? n : -1);        } catch (Exception e) // Very generic            return typeof(return)(-1); // Not valid.    }     if (entries.empty)        return "";     while (true) {        "Choose one:".writeln;        foreach (immutable i, const entry; entries)            writefln("  %d) %s", i, entry);        "> ".write;        immutable input = readln.chomp;        immutable choice = validChoice(input, entries.length - 1);        if (choice.isNull)            "Wrong choice.".writeln;        else            return entries[choice]; // We have a valid choice.    }} void main() {    immutable items = ["fee fie", "huff and puff",                       "mirror mirror", "tick tock"];    writeln("You chose '", items.menuSelect, "'.");}`
Output:
```Choose one:
0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
> 2
You chose 'mirror mirror'.```

## Delphi

Translation of: Go
` program Menu; {\$APPTYPE CONSOLE} uses  System.SysUtils; function ChooseMenu(Options: TArray<string>; Prompt: string): string;var  index: Integer;  value: string;begin  if Length(Options) = 0 then    exit('');  repeat    writeln;    for var i := 0 to length(Options) - 1 do      writeln(i + 1, '. ', Options[i]);    write(#10, Prompt, ' ');    Readln(value);    index := StrToIntDef(value, -1);  until (index > 0) and (index <= length(Options));  Result := Options[index];end; begin  writeln('You picked ', ChooseMenu(['fee fie', 'huff and puff', 'mirror mirror',    'tick tock'], 'Enter number: '));  readln;end.`
Output:
```1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock

Enter number:  5

1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock

Enter number:  2
You picked huff and puff```

## Elixir

`defmodule Menu do  def select(_, []), do: ""  def select(prompt, items) do    IO.puts ""    Enum.with_index(items) |> Enum.each(fn {item,i} -> IO.puts " #{i}. #{item}" end)    answer = IO.gets("#{prompt}: ") |> String.strip    case Integer.parse(answer) do      {num, ""} when num in 0..length(items)-1 -> Enum.at(items, num)      _ -> select(prompt, items)    end  endend # test empty listresponse = Menu.select("Which is empty", [])IO.puts "empty list returns: #{inspect response}" # "real" testitems = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]response = Menu.select("Which is from the three pigs", items)IO.puts "you chose: #{inspect response}"`
Output:
```empty list returns: ""

0. fee fie
1. huff and puff
2. mirror mirror
3. tick tock
Which is from the three pigs: 4

0. fee fie
1. huff and puff
2. mirror mirror
3. tick tock
Which is from the three pigs: 3
you chose: "tick tock"
```

## ERRE

` PROCEDURE Selection(choices\$[],prompt\$->sel\$)   IF UBOUND(choices\$,1)-LBOUND(choices\$,1)=0 THEN       sel\$=""      EXIT PROCEDURE    END IF   ret\$=""   REPEAT      FOR i=LBOUND(choices\$,1) TO UBOUND(choices\$,1) DO         PRINT(i;": ";choices\$[i])      END FOR      PRINT(prompt\$;)      INPUT(index)      IF index<=UBOUND(choices\$,1) AND index>=LBOUND(choices\$,1) THEN ret\$=choices\$[index] END IF   UNTIL ret\$<>""   sel\$=ret\$END PROCEDURE `

## Euphoria

`include get.e function menu_select(sequence items, object prompt)    if length(items) = 0 then        return ""    else        for i = 1 to length(items) do            printf(1,"%d) %s\n",{i,items[i]})        end for         if atom(prompt) then            prompt = "Choice?"        end if         return items[prompt_number(prompt,{1,length(items)})]    end ifend function constant items = {"fee fie", "huff and puff", "mirror mirror", "tick tock"}constant prompt = "Which is from the three pigs? " printf(1,"You chose %s.\n",{menu_select(items,prompt)})`

## F#

`open System let rec menuChoice (options : string list) prompt =    if options = [] then ""    else        for i = 0 to options.Length - 1 do            printfn "%d. %s" (i + 1) options.[i]         printf "%s" prompt        let input = Int32.TryParse(Console.ReadLine())         match input with        | true, x when 1 <= x && x <= options.Length -> options.[x - 1]        | _, _ -> menuChoice options prompt [<EntryPoint>]let main _ =    let menuOptions = ["fee fie"; "huff and puff"; "mirror mirror"; "tick tock"]    let choice = menuChoice menuOptions "Choose one: "    printfn "You chose: %s" choice     0`

## Factor

`USING: formatting io kernel math math.parser sequences ; : print-menu ( seq -- )    [ 1 + swap "%d - %s\n" printf ] each-index    "Your choice? " write flush ; : (select) ( seq -- result )    dup print-menu readln string>number dup integer? [        drop 1 - swap 2dup bounds-check?        [ nth ] [ nip (select) ] if    ] [ drop (select) ] if* ; : select ( seq -- result ) [ "" ] [ (select) ] if-empty ;`

Example usage:

```( scratchpad ) { "fee fie" "huff and puff" "mirror mirror" "tick tock" } select
1 - fee fie
2 - huff and puff
3 - mirror mirror
4 - tick tock

--- Data stack:
"fee fie"```

## Fantom

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.
`class Main{  static Void displayList (Str[] items)  {    items.each |Str item, Int index|    {      echo ("\$index: \$item")    }  }   public static Str getChoice (Str[] items)  {    selection := -1    while (selection == -1)    {      displayList (items)      Env.cur.out.print ("Select: ").flush      input := Int.fromStr(Env.cur.in.readLine, 10, false)      if (input != null)      {        if (input >= 0 && input < items.size)        {          selection = input        }      }      echo ("Try again")    }    return items[selection]  }   public static Void main ()  {    choice := getChoice (["fee fie", "huff and puff", "mirror mirror", "tick tock"])    echo ("You chose: \$choice")  }}`

## Forth

### Idiomatic Forth

Out of the box Forth does not have lists. This version uses strings and a vector table, which arguably is more how one would do this task in Forth. It returns a nil string if a nil string is given otherwise the input string becomes the title of the menu.

`\ Rosetta Code Menu Idiomatic Forth \ vector table compiler: CASE:  ( -- ) CREATE ;: |      ( -- <text>)  '  ,  ;  IMMEDIATE: ;CASE  ( -- ) DOES>  SWAP CELLS + @ EXECUTE ; : NIL      ( -- addr len) S" " ;: FEE      ( -- addr len) S" fee fie" ;: HUFF     ( -- addr len) S" huff and puff" ;: MIRROR   ( -- addr len) S" mirror mirror" ;: TICKTOCK ( -- addr len) S" tick tock" ; CASE: SELECT ( n -- addr len)     | NIL | FEE | HUFF | MIRROR | TICKTOCK;CASE CHAR 1 CONSTANT '1'CHAR 4 CONSTANT '4': BETWEEN ( n low hi -- ?)  1+ WITHIN ; : MENU ( addr len -- addr len )       DUP 0=        IF          2DROP  NIL  EXIT       ELSE          BEGIN             CR             CR 2DUP 3 SPACES   TYPE             CR   ." 1 " 1 SELECT TYPE             CR   ." 2 " 2 SELECT TYPE             CR   ." 3 " 3 SELECT TYPE             CR   ." 4 " 4 SELECT TYPE             CR ." Choice: " KEY DUP EMIT             DUP '1' '4' BETWEEN 0=          WHILE              DROP          REPEAT          -ROT 2DROP    \ drop input string          CR [CHAR] 0 -  SELECT       THEN ;`

### If there must be lists

Here we extend Forth to support simple lists and complete the task using the language extensions.

`\ Rosetta Menu task with Simple lists in Forth : STRING, ( caddr len -- ) HERE  OVER CHAR+  ALLOT  PLACE ;: "       ( -- ) [CHAR] " PARSE  STRING, ; : {       ( -- ) ALIGN 0 C, ;: }       ( -- ) { ; : {NEXT} ( str -- next_str)  COUNT + ;: {NTH}  ( n array_addr -- str)  SWAP 0 DO {NEXT} LOOP ; : {LEN}  ( array_addr -- )  \ count strings in a list          0 >R                      \ Counter on Rstack          {NEXT}                    \ skip 1st empty string          BEGIN             {NEXT} DUP [email protected]          \ Fetch length byte          WHILE                     \ While true             R> 1+ >R               \ Inc. counter          REPEAT          DROP          R> ;                      \ return counter to data stack : {TYPE}    ( \$ -- ) COUNT TYPE ;: '"'    ( -- )   [CHAR] " EMIT ;: {""}   ( \$ -- )  '"' SPACE {TYPE} '"' SPACE ;: }PRINT ( n array -- ) {NTH} {TYPE} ; \ ===== TASK BEGINS =====CREATE GOODLIST       { " fee fie"         " huff and puff"         " mirror mirror"         " tick tock" } CREATE NIL  {   } CHAR 1 CONSTANT '1'CHAR 4 CONSTANT '4'CHAR 0 CONSTANT '0' : BETWEEN ( n low hi -- ?)  1+ WITHIN ; : .MENULN ( n -- n) DUP '0' + EMIT SPACE OVER }PRINT ; : MENU    ( list -- string )       DUP {LEN} 0=       IF           DROP NIL       ELSE          BEGIN             CR             CR 1 .MENULN             CR 2 .MENULN             CR 3 .MENULN             CR 4 .MENULN             CR ." Choice: " KEY DUP EMIT             DUP '1' '4' BETWEEN         0= WHILE              DROP          REPEAT         [CHAR] 0 -         CR SWAP {NTH}       THEN ;`

Test at the gForth console

```GOODLIST MENU

1 fee fie
2 huff and puff
3 mirror mirror
4 tick tock
Choice: 0

1 fee fie
2 huff and puff
3 mirror mirror
4 tick tock
Choice: Q

1 fee fie
2 huff and puff
3 mirror mirror
4 tick tock
Choice: 2
ok
{TYPE} huff and puff ok
ok
{TYPE}  ok```

## Fortran

Please find the build instructions in the comments at the start of the FORTRAN 2008 source. Compiler: gfortran from the GNU compiler collection. Command interpreter: bash.

` !a=./f && make \$a && OMP_NUM_THREADS=2 \$a!gfortran -std=f2008 -Wall -fopenmp -ffree-form -fall-intrinsics -fimplicit-none f.f08 -o f        module menu      public :: selector      contains       function selector(title,options) result(choice)      character(len=*),intent(in) :: title      character(len=*),dimension(:),intent(in) :: options      character(len=len(options)) :: choice      integer :: i,ichoose,ios,n       choice = ""       n = size(options)      if (n > 0) then        do          print "(a)",title          print "(i8,"", "",a)",(i,options(i),i=1,n)          read (*,fmt="(i8)",iostat=ios) ichoose           if (ios == -1) exit ! EOF error          if (ios /= 0) cycle ! other error          if (ichoose < 1) cycle          if (ichoose > n) cycle ! out-of-bounds           choice = options(ichoose)          exit        end do      end if      end function selector      end module menu       program menu_demo      use menu      character(len=14),dimension(:),allocatable :: zero_items,fairytale      character(len=len(zero_items)) :: s       !! empty list demo      allocate(zero_items(0))      print "(a)","input items:",zero_items      s = selector('Choose from the empty list',zero_items)      print "(a)","returned:",s      if (s == "") print "(a)","(an empty string)"       !! Fairy tale demo      allocate(fairytale(4))      fairytale = (/'fee fie       ','huff and puff ', &        'mirror mirror ','tick tock     '/)      print "(a)","input items:",fairytale      s = selector('Choose a fairy tale',fairytale)      print "(a)","returned: ",s      if (s == "") print "(a)","(an empty string)"       end program menu_demo  `

## FreeBASIC

`dim as string menu(1 to 4)={ "fee fie", "huff and puff", "mirror mirror", "tick tock" } function menu_select( m() as string ) as string    dim as integer i, vc = 0    dim as string c    while vc<1 or vc > ubound(m)        cls        for i = 1 to ubound(m)            print i;"  ";m(i)        next i        print         input "Choice? ", c        vc = val(c)    wend    return m(vc)end function print menu_select( menu() )`

## Gambas

` Public Sub Main()     Dim asMenu As String[] = ["fee fie", "huff And puff", "mirror mirror", "tick tock"]    Dim sValuePrompt As String = "Please select one of the above numbers> "    Dim sChoice As String    Dim sFeedbackFormat As String = "You have chosen '&1'\r\n"     sChoice = Menu(asMenu, sValuePrompt)    If sChoice = "" Then        Print "menu returned an empty string"    Else        Print Subst(sFeedbackFormat, sChoice)    Endif End Private Function Menu(asChoices As String[], sPrompt As String) As String     Dim sReturnValue As String = ""    Dim sMenuLineFormat As String = "&1) &2"    Dim sAnswer As String    Dim iAnswer As Integer    Dim iIndex As Integer = 0    Dim sMenuItem As String     If Not IsNull(asChoices) Then        If asChoices.Count > 0 Then            Do                For iIndex = 0 To asChoices.Max                    sMenuItem = asChoices[iIndex]                    Print Subst(sMenuLineFormat, iIndex, sMenuItem)                Next                 Print sPrompt                Input sAnswer                 If IsNumber(sAnswer) Then                    iAnswer = sAnswer                    If (0 <= iAnswer) And (iAnswer <= asChoices.Max) Then                        sReturnValue = asChoices[iAnswer]                        Break                    Endif                Endif            Loop        Endif    Endif     Return sReturnValue End `

## Go

`package main import "fmt" func menu(choices []string, prompt string) string {    if len(choices) == 0 {        return ""    }    var c int    for {        fmt.Println("")        for i, s := range choices {            fmt.Printf("%d.  %s\n", i+1, s)        }        fmt.Print(prompt)        _, err := fmt.Scanln(&c)         if err == nil && c > 0 && c <= len(choices) {            break        }    }    return choices[c-1]} func main() {    pick := menu(nil, "No prompt")    fmt.Printf("No choices, result = %q\n", pick)     choices := []string{        "fee fie",        "huff and puff",        "mirror mirror",        "tick tock",    }    pick = menu(choices, "Enter number: ")    fmt.Printf("You picked %q\n", pick)}`

Output:

```No choices, result = ""

1.  fee fie
2.  huff and puff
3.  mirror mirror
4.  tick tock
Enter number: 2
You picked "huff and puff"
```

## GW-BASIC

` 10 DATA "Fee fie", "Huff and Puff", "Mirror mirror", "Tick tock"20 VC = 030 DIM M\$(3)40 FOR I = 0 TO 350 READ M\$(I)60 NEXT I70 CLS80 FOR I = 0 TO 390 PRINT I+1;"   ";M\$(I)100 NEXT I110 PRINT120 INPUT "Choice? ", C\$130 VC = VAL(C\$)140 IF VC<1 OR VC>4 THEN GOTO 70150 PRINT "You picked ", M\$(VC-1)160 END `

`module RosettaSelect where import Data.Maybe (listToMaybe)import Control.Monad (guard) select :: [String] -> IO Stringselect []   = return ""select menu = do  putStr \$ showMenu menu  putStr "Choose an item: "  choice <- getLine  maybe (select menu) return \$ choose menu choice showMenu :: [String] -> StringshowMenu menu = unlines [show n ++ ") " ++ item | (n, item) <- zip [1..] menu] choose :: [String] -> String -> Maybe Stringchoose menu choice = do  n <- maybeRead choice  guard \$ n > 0  listToMaybe \$ drop (n-1) menu maybeRead :: Read a => String -> Maybe amaybeRead = fmap fst . listToMaybe . filter (null . snd) . reads`

Example usage, at the GHCI prompt:

`*RosettaSelect> select ["fee fie", "huff and puff", "mirror mirror", "tick tock"]1) fee fie2) huff and puff3) mirror mirror4) tick tockChoose an item: 3"mirror mirror"*RosettaSelect>`

## HicEst

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.
`CHARACTER list = "fee fie,huff and puff,mirror mirror,tick tock,", answer*20    POP(Menu=list, SelTxt=answer) SUBROUTINE list ! callback procedure must have same name as menu argument ! Subroutine with no arguments: all objects are global ! The global variable \$\$ returns the selected list index   WRITE(Messagebox, Name) answer, \$\$END`

## Icon and Unicon

New version : Note the procedures below the "subroutines below" line are the actual Rosetta task set.

procedure main() shows how to call the choose_from_menu "function", which demonstrates use of differing menu lists and a empty list.

` ## menu.icn : rewrite of the faulty version on Rosetta Code site 24/4/2021 procedure main() L := ["fee fie", "huff and puff", "mirror mirror", "tick tock"]K := ["hidie hi", "hidie ho", "mirror mirror on the Wall", "tick tock tick tok"]Z := []  choice := choose_from_menu(L)      # call using menu L write("Returned value =", choice) choice := choose_from_menu(K)      # call using menu K write("Returned value =", choice) choice := choose_from_menu(Z)      # call using empty list write("Returned value =", choice)  end ## of main# --------- subroutines below --------------------------------- procedure choose_from_menu(X)  displaymenu(X)repeat {   writes("Choose a number from the menu above: ")   a := read()   if a == "" then return(a)   ## no selection   write("You selected ",a)  if numeric(a) then {   if integer(a) <= 0 | integer(a) > *X  then displaymenu(X) else      {                    ## check entered option in range        write(a, " ==> ",X[a])      return ( string(a))	 }	}  else displaymenu(X)				          } end ## choose_from_menu(X) procedure displaymenu(X)	every i := 1 to *X do		write(i,") ",X[i])    ## dispay menu options end ## displaymenu(X)  `

## J

Solution:

` CHOICES =: ];._2 'fee fie;huff and puff;mirror mirror;tick tock;'PROMPT =: 'Which is from the three pigs? ' showMenu =: [email protected]:(,"1~ (' ' ,.~ 3 ": [email protected]:(1 ,~ #)))read_stdin =: 1!:1@:1: menu =: '? '&\$: :(4 : 0) NB. use:  [prompt] menu choice_array CHOICES =. y if. 0 = # CHOICES do. return. end. PROMPT =. x whilst. RESULT [email protected]:e. i. # CHOICES do.  showMenu CHOICES  smoutput PROMPT  RESULT =. _1 ". read_stdin'' end. RESULT {:: CHOICES) `

See Talk page for explanation.

## Java

`public static String select(List<String> list, String prompt){    if(list.size() == 0) return "";    Scanner sc = new Scanner(System.in);    String ret = null;    do{        for(int i=0;i<list.size();i++){            System.out.println(i + ": "+list.get(i));        }        System.out.print(prompt);        int index = sc.nextInt();        if(index >= 0 && index < list.size()){            ret = list.get(index);        }    }while(ret == null);    return ret;}`

## JavaScript

Works with: Node.js
`const readline = require('readline'); async function menuSelect(question, choices) {  if (choices.length === 0) return '';   const prompt = choices.reduce((promptPart, choice, i) => {    return promptPart += `\${i + 1}. \${choice}\n`;  }, '');   let inputChoice = -1;  while (inputChoice < 1 || inputChoice > choices.length) {    inputChoice = await getSelection(`\n\${prompt}\${question}: `);  }   return choices[inputChoice - 1];} function getSelection(prompt) {  return new Promise((resolve) => {    const lr = readline.createInterface({      input: process.stdin,      output: process.stdout    });     lr.question(prompt, (response) => {      lr.close();      resolve(parseInt(response) || -1);    });  });} const choices = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock'];const question = 'Which is from the three pigs?';menuSelect(question, choices).then((answer) => {  console.log(`\nYou chose \${answer}`);});`

## jq

Works with: jq version 1.5

This version uses jq 1.5's 'input' builtin to read programmatically from STDIN.

`def choice:  def read(prompt; max):    def __read__:      prompt,      ( input as \$input        | if (\$input|type) == "number" and 0 < \$input and \$input <= max then \$input          else __read__          end);    __read__;   if length == 0 then ""  else  . as \$in  | ("Enter your choice:\n" +      (reduce range(0; length) as \$i (""; . + "\(\$i + 1): \(\$in[\$i])\n")) ) as \$prompt  | read(\$prompt; length) as \$read  | if (\$read|type) == "string" then \$read    else "Thank you for selecting \(\$in[\$read-1])" end  end ;`

Example:

`["fee fie", "huff and puff", "mirror mirror", "tick tock"] | choice`
` \$ jq -n -r -f Menu.jqEnter your choice:1: fee fie2: huff and puff3: mirror mirror4: tick tock 5Enter your choice:1: fee fie2: huff and puff3: mirror mirror4: tick tock 1Thank you for selecting fee fie`

## Julia

Translation of: Python
`using Printf function _menu(items)    for (ind, item) in enumerate(items)        @printf "  %2i) %s\n" ind item    endend _ok(::Any,::Any) = falsefunction _ok(reply::AbstractString, itemcount)    n = tryparse(Int, reply)    return isnull(n) || 0 ≤ get(n) ≤ itemcountend "Prompt to select an item from the items"function _selector(items, prompt::AbstractString)    isempty(items) && return ""    reply = -1    itemcount = length(items)    while !_ok(reply, itemcount)        _menu(items)        print(prompt)        reply = strip(readline(STDIN))    end    return items[parse(Int, reply)]end items = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]item = _selector(items, "Which is from the three pigs: ")println("You chose: ", item)`

## Kotlin

`// version 1.1.2 fun menu(list: List<String>): String {    if (list.isEmpty()) return ""    val n = list.size    while (true) {        println("\n   M E N U\n")        for (i in 0 until n) println("\${i + 1}: \${list[i]}")        print("\nEnter your choice 1 - \$n : ")        val index = readLine()!!.toIntOrNull()        if (index == null || index !in 1..n) continue        return list[index - 1]    }} fun main(args: Array<String>) {    val list = listOf(        "fee fie",        "huff and puff",        "mirror mirror",        "tick tock"    )    val choice = menu(list)    println("\nYou chose : \$choice")}`

Sample session:

Output:
```   M E N U

1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock

Enter your choice 1 - 4 : 0

M E N U

1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock

Enter your choice 1 - 4 : asdf

M E N U

1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock

Enter your choice 1 - 4 : 2

You chose : huff and puff
```

## langur

Works with: langur version 0.7.1
`val .select = f(.entries) {    if not isArray(.entries): throw "invalid args"    if len(.entries) == 0: return ZLS     # print the menu    writeln join "\n", map(f \$"\.i:2;: \.e;", .entries, 1..len .entries)     val .idx = toNumber read(        "Select entry #: ",        f(.x) {            if not matching(RE/^[0-9]+\$/, .x): return false            val .y = toNumber .x            .y > 0 and .y <= len(.entries)        },        "invalid selection\n", -1,    )     .entries[.idx]} writeln .select(["fee fie", "eat pi", "huff and puff", "tick tock"])`
Output:
``` 1: fee fie
2: eat pi
3: huff and puff
4: tick tock
Select entry #: 7
invalid selection
Select entry #: 2
eat pi```

## Logo

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.
Works with: UCB Logo
`to select :prompt [:options]  foreach :options [(print # ?)]  forever [    type :prompt type "| |    make "n readword    if (and [number? :n] [:n >= 1] [:n <= count :options]) [output item :n :options]    print sentence [Must enter a number between 1 and] count :options  ]end print equal? [huff and puff] (select  [Which is from the three pigs?]  [fee fie] [huff and puff] [mirror mirror] [tick tock]) `

## Lua

`function select (list)   if not list or #list == 0 then      return ""   end   local last, sel = #list   repeat      for i,option in ipairs(list) do         io.write(i, ". ", option, "\n")      end      io.write("Choose an item (1-", tostring(last), "): ")      sel = tonumber(string.match(io.read("*l"), "^%d+\$"))   until type(sel) == "number" and sel >= 1 and sel <= last   return list[math.floor(sel)]end print("Nothing:", select {})print()print("You chose:", select {"fee fie", "huff and puff", "mirror mirror", "tick tock"})`
Output:
```Nothing:

1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): 0
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): a
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): 1.7
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): 10
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Choose an item (1-4): 3
You chose:  mirror mirror
```

## Mathematica / Wolfram Language

Interpreter: Wolfram Desktop and Wolfram Desktop Kernel

Works with: Wolfram Language version 12

Redisplays the list of choices on every invalid input as per the task description. In the notebook interface (of Wolfram Desktop, at least), Print[] would most pragmatically be located outside of the loop because Input[] uses a dialog box.

`textMenu[data_List] := Module[{choice},  If[[email protected] == 0, [email protected]""];  While[!([email protected] && [email protected] >= choice > 0),   MapIndexed[Print[#2[[1]], ") ", #1]&, data];   choice = Input["Enter selection..."]   ];  data[[choice]]  ]`
Kernel (REPL) output (function definition omitted):
```Wolfram Desktop Kernel (using Wolfram Language 12.0.0) for Microsoft Windows (64-bit)

In[1]:= (*! ELIDED !*)

Out[2]=

In[3]:= textMenu[{"fee fie", "huff and puff", "mirror mirror", "tick tock"}]
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...0
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...5
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...-1
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...fee fie
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Enter selection...3

Out[3]= mirror mirror```

## MATLAB

`function sucess = menu(list)     if numel(list) == 0        sucess = '';        return    end     while(true)         disp('Please select one of these options:');         for i = (1:numel(list))             disp([num2str(i) ') ' list{i}]);         end         disp([num2str(numel(list)+1) ') exit']);         try            key = input(':: ');            if key == numel(list)+1                break            elseif (key > numel(list)) || (key < 0)                continue            else                disp(['-> ' list{key}]);            end        catch            continue        end      end     sucess = true; end `

## min

Works with: min version 0.19.3

min has an operator `choose` that nearly conforms to this task. The input list is altered so that the choice can be returned, and the empty list case is handled.

`(  :prompt =list  (list bool)  (list (' dup append) map prompt choose)  ("") if) :menu ("fee fie" "huff and puff" "mirror mirror" "tick tock")"Enter an option" menu"You chose: " print! puts!`
Output:
```Enter an option
1 - fee fie
2 - huff and puff
3 - mirror mirror
4 - tick tock
Enter your choice (1 - 4): 5
Invalid choice.
1 - fee fie
2 - huff and puff
3 - mirror mirror
4 - tick tock
Enter your choice (1 - 4): 1
You chose: fee fie
```

## Modula-2

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.
`MODULE  Menu; FROM    InOut IMPORT WriteString, WriteCard, WriteLn, ReadCard; CONST   StringLength     = 100;        MenuSize         = 4; TYPE    String           = ARRAY[0..StringLength-1] OF CHAR; VAR     menu             : ARRAY[0..MenuSize] OF String;        selection, index : CARDINAL; BEGIN    menu[1] := "fee fie";    menu[2] := "huff and puff";    menu[3] := "mirror mirror";    menu[4] := "tick tock";     FOR index := 1 TO HIGH(menu) DO        WriteString("[");        WriteCard(    index,1);        WriteString(        "] ");        WriteString(            menu[index]);        WriteLn;    END;(*of FOR*)     WriteString("Choose what you want : ");    ReadCard(selection);     IF (selection <= HIGH(menu)) AND (selection > 0) THEN        WriteString("You have chosen: ");        WriteString(                  menu[selection]);        WriteLn;    ELSE        WriteString("Selection is out of range!");        WriteLn;    END (*of IF*)END Menu.`

## MUMPS

`MENU(STRINGS,SEP) ;http://rosettacode.org/wiki/Menu NEW I,A,MAX ;I is a loop variable ;A is the string read in from the user ;MAX is the number of substrings in the STRINGS list ;SET STRINGS="fee fie^huff and puff^mirror mirror^tick tock" SET MAX=\$LENGTH(STRINGS,SEP) QUIT:MAX=0 ""WRITEMENU  FOR I=1:1:MAX WRITE I,": ",\$PIECE(STRINGS,SEP,I),! READ:30 !,"Choose a string by its index: ",A,! IF (A<1)!(A>MAX)!(A\1'=A) GOTO WRITEMENU KILL I,MAX QUIT \$PIECE(STRINGS,SEP,A)`
Usage:
```USER>W !,\$\$MENU^ROSETTA("fee fie^huff and puff^mirror mirror^tick tock","^")

1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock

Choose a string by its index: 3
mirror mirror
USER>W !,\$\$MENU^ROSETTA("fee fie^huff and puff^mirror mirror^tick tock","^")

1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock

Choose a string by its index: 5
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock

Choose a string by its index: A
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock

Choose a string by its index: 0
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock

Choose a string by its index: 1
fee fie
```

## Nanoquery

Translation of: Ursa
`def _menu(\$items)	for (\$i = 0) (\$i < len(\$items)) (\$i = \$i + 1)		println "  " + \$i + ") " + \$items[\$i]	endend def _ok(\$reply, \$itemcount)	try		\$n = int(\$reply)		return ((\$n >= 0) && (\$n < \$itemcount))	catch		return \$false	endend def selector(\$items, \$pmt)	// Prompt to select an item from the items	if (len(\$items) = 0)		return ""	end	\$reply = -1	\$itemcount = len(\$items)	while !_ok(\$reply, \$itemcount)		_menu(\$items)		println \$pmt		\$reply = int(input())	end	return \$items[\$reply]end \$items = list()append \$items "fee fie" "huff and puff" "mirror mirror" "tick tock"\$item = selector(\$items, "Which is from the three pigs: ")println "You chose: " + \$item`

## Nim

Translation of: Python
`import strutils, rdstdin proc menu(xs: openArray[string]) =  for i, x in xs: echo "  ", i, ") ", x proc ok(reply: string; count: Positive): bool =  try:    let n = parseInt(reply)    return 0 <= n and n < count  except: return false proc selector(xs: openArray[string]; prompt: string): string =  if xs.len == 0: return ""  var reply = "-1"  while not ok(reply, xs.len):    menu(xs)    reply = readLineFromStdin(prompt).strip()  return xs[parseInt(reply)] const xs = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]let item = selector(xs, "Which is from the three pigs: ")echo "You chose: ", item`
Output:
```  0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs: foo
0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs: 4
0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs: 2
You chose: mirror mirror```

## OCaml

` let select ?(prompt="Choice? ") = function  | [] -> ""  | choices ->      let rec menu () =        List.iteri (Printf.printf "%d: %s\n") choices;        print_string prompt;        try List.nth choices (read_int ())        with _ -> menu ()      in menu () `

Example use in the REPL:

` # select ["fee fie"; "huff and puff"; "mirror mirror"; "tick tock"];;0: fee fie1: huff and puff2: mirror mirror3: tick tockChoice? 2- : string = "mirror mirror" `

## OpenEdge/Progress

`FUNCTION bashMenu RETURNS CHAR(   i_c AS CHAR):    DEF VAR ii        AS INT.   DEF VAR hfr       AS HANDLE.   DEF VAR hmenu     AS HANDLE EXTENT.   DEF VAR ikey      AS INT.   DEF VAR ireturn   AS INT INITIAL ?.    EXTENT( hmenu ) = NUM-ENTRIES( i_c ).    CREATE FRAME hfr ASSIGN      WIDTH    =  80      HEIGHT   =  NUM-ENTRIES( i_c )      PARENT   =  CURRENT-WINDOW      VISIBLE  =  TRUE      .    DO ii = 1 TO NUM-ENTRIES( i_c ):       CREATE TEXT hmenu ASSIGN         FRAME          =  hfr         FORMAT         =  "x(79)"         SCREEN-VALUE   =  SUBSTITUTE( "&1. &2", ii, ENTRY( ii, i_c ) )         ROW            =  ii         VISIBLE        =  TRUE         .    END.    IF i_c = "" THEN      ireturn = 1.    DO WHILE ireturn = ?:       READKEY.      ikey = INTEGER( CHR( LASTKEY ) ) NO-ERROR.      IF ikey >= 1 AND ikey <= NUM-ENTRIES( i_c ) THEN         ireturn = ikey.    END.     RETURN ENTRY( ireturn, i_c ). END FUNCTION. MESSAGE    bashMenu( "fee fie,huff and puff,mirror mirror,tick tock" )VIEW-AS ALERT-BOX.`

## Oz

`declare  fun {Select Prompt Items}     case Items of nil then ""     else	for	   Item in Items	   Index in 1..{Length Items}	do	   {System.showInfo Index#") "#Item}	end	{System.printInfo Prompt}	try	   {Nth Items {ReadInt}}	catch _ then	   {Select Prompt Items}	end     end  end   fun {ReadInt}     class TextFile from Open.file Open.text end     StdIo = {New TextFile init(name:stdin)}  in     {String.toInt {StdIo getS(\$)}}  end   Item = {Select "Which is from the three pigs: "	  ["fee fie" "huff and puff" "mirror mirror" "tick tock"]} in  {System.showInfo "You chose: "#Item}`

## PARI/GP

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.
`choose(v)=my(n);for(i=1,#v,print(i". "v[i]));while(type(n=input())!="t_INT"|n>#v|n<1,);v[n]choose(["fee fie","huff and puff","mirror mirror","tick tock"])`

## Pascal

Works with: Free_Pascal

Tested with Free Pascal 2.6.4 (arm).

`program Menu;{\$ASSERTIONS ON}uses  objects;var  MenuItems :PUnSortedStrCollection;  selected  :string; Function SelectMenuItem(MenuItems :PUnSortedStrCollection):string;var  i, idx :integer;  code   :word;  choice :string;begin  // Return empty string if the collection is empty.  if MenuItems^.Count = 0 then  begin    SelectMenuItem := '';    Exit;  end;   repeat    for i:=0 to MenuItems^.Count-1 do    begin      writeln(i+1:2, ') ', PString(MenuItems^.At(i))^);    end;    write('Make your choice: ');    readln(choice);    // Try to convert choice to an integer.    // Code contains 0 if this was successful.    val(choice, idx, code)  until (code=0) and (idx>0) and (idx<=MenuItems^.Count);  // Return the selected element.  SelectMenuItem := PString(MenuItems^.At(idx-1))^;end; begin  // Create an unsorted string collection for the menu items.  MenuItems := new(PUnSortedStrCollection, Init(10, 10));   // Add some menu items to the collection.  MenuItems^.Insert(NewStr('fee fie'));  MenuItems^.Insert(NewStr('huff and puff'));  MenuItems^.Insert(NewStr('mirror mirror'));  MenuItems^.Insert(NewStr('tick tock'));   // Display the menu and get user input.  selected := SelectMenuItem(MenuItems);  writeln('You chose: ', selected);   dispose(MenuItems, Done);   // Test function with an empty collection.  MenuItems := new(PUnSortedStrCollection, Init(10, 10));   selected := SelectMenuItem(MenuItems);  // Assert that the function returns an empty string.  assert(selected = '', 'Assertion failed: the function did not return an empty string.');   dispose(MenuItems, Done);end.`
Output:
```\$ bin/menu
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
You chose: mirror mirror
```

## Perl

`sub menu{        my (\$prompt,@array) = @_;        return '' unless @array;         print "  \$_: \$array[\$_]\n" for(0..\$#array);        print \$prompt;        \$n = <>;        return \$array[\$n] if \$n =~ /^\d+\$/ and defined \$array[\$n];        return &menu(\$prompt,@array);} @a = ('fee fie', 'huff and puff', 'mirror mirror', 'tick tock');\$prompt = 'Which is from the three pigs: '; \$a = &menu(\$prompt,@a); print "You chose: \$a\n";`

## Phix

`function menu_select(sequence items, object prompt)sequence res = ""    items = remove_all("",items)    if length(items)!=0 then        while 1 do            for i=1 to length(items) do                printf(1,"%d) %s\n",{i,items[i]})            end for            puts(1,iff(atom(prompt)?"Choice?":prompt))            res = scanf(trim(gets(0)),"%d")            puts(1,"\n")            if length(res)=1 then                integer nres = res[1][1]                if nres>0 and nres<=length(items) then                    res = items[nres]                    exit                end if            end if        end while    end if    return resend function constant items = {"fee fie", "huff and puff", "mirror mirror", "tick tock"}constant prompt = "Which is from the three pigs? "string res = menu_select(items,prompt)printf(1,"You chose %s.\n",{res})`

## PHP

`<?php\$stdin = fopen("php://stdin", "r");\$allowed = array(1 => 'fee fie', 'huff and puff', 'mirror mirror', 'tick tock'); for(;;) {    foreach (\$allowed as \$id => \$name) {        echo "  \$id: \$name\n";    }    echo "Which is from the four pigs: ";    \$stdin_string = fgets(\$stdin, 4096);    if (isset(\$allowed[(int) \$stdin_string])) {        echo "You chose: {\$allowed[(int) \$stdin_string]}\n";        break;    }}`

## PicoLisp

`(de choose (Prompt Items)   (use N      (loop         (for (I . Item) Items            (prinl I ": " Item) )         (prin Prompt " ")         (flush)         (NIL (setq N (in NIL (read))))         (T (>= (length Items) N 1) (prinl (get Items N))) ) ) )(choose "Which is from the three pigs?"   '("fee fie" "huff and puff" "mirror mirror" "tick tock") )`
Output:
```1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Which is from the three pigs? q
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Which is from the three pigs? 5
1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
Which is from the three pigs? 2
huff and puff
```

## PL/I

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.
`  test: proc options (main); declare menu(4) character(100) varying static initial (   'fee fie', 'huff and puff', 'mirror mirror', 'tick tock');declare (i, k) fixed binary; do i = lbound(menu,1) to hbound(menu,1);   put skip edit (trim(i), ': ', menu(i) ) (a);end;put skip list ('please choose an item number');get list (k);if k >= lbound(menu,1) & k <= hbound(menu,1) then   put skip edit ('you chose ', menu(k)) (a);else   put skip list ('Could not find your phrase'); end test; `

## PowerShell

` function Select-TextItem{  <#    .SYNOPSIS        Prints a textual menu formatted as an index value followed by its corresponding string for each object in the list.    .DESCRIPTION        Prints a textual menu formatted as an index value followed by its corresponding string for each object in the list;        Prompts the user to enter a number;        Returns an object corresponding to the selected index number.    .PARAMETER InputObject        An array of objects.    .PARAMETER Prompt        The menu prompt string.    .EXAMPLE        “fee fie”, “huff and puff”, “mirror mirror”, “tick tock” | Select-TextItem    .EXAMPLE        “huff and puff”, “fee fie”, “tick tock”, “mirror mirror” | Sort-Object | Select-TextItem -Prompt "Select a string"    .EXAMPLE        Select-TextItem -InputObject (Get-Process)    .EXAMPLE        (Get-Process | Where-Object {\$_.Name -match "notepad"}) | Select-TextItem -Prompt "Select a Process" | Stop-Process -ErrorAction SilentlyContinue  #>    [CmdletBinding()]    Param    (        [Parameter(Mandatory=\$true,                   ValueFromPipeline=\$true)]        \$InputObject,         [Parameter(Mandatory=\$false)]        [string]        \$Prompt = "Enter Selection"    )     Begin    {        \$menuOptions = @()    }    Process    {        \$menuOptions += \$InputObject    }    End    {        if(!\$inputObject){            return ""        }        do        {            [int]\$optionNumber = 1              foreach (\$option in \$menuOptions)             {                 Write-Host ("{0,3}: {1}" -f \$optionNumber,\$option)                 \$optionNumber++             }              Write-Host ("{0,3}: {1}" -f 0,"To cancel")               \$choice = Read-Host \$Prompt              \$selectedValue = ""              if (\$choice -gt 0 -and \$choice -le \$menuOptions.Count)             {                 \$selectedValue = \$menuOptions[\$choice - 1]             }          }        until (\$choice -match "^[0-9]+\$" -and (\$choice -eq 0 -or \$choice -le \$menuOptions.Count))         return \$selectedValue    }} “fee fie”, “huff and puff”, “mirror mirror”, “tick tock” | Select-TextItem -Prompt "Select a string" `
Output:
```  1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock
0: To cancel
Select a string: 3
mirror mirror
```

## ProDOS

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.
` :aprintline ==========MENU==========printline 1. Fee Fieprintline 2. Huff Puffprintline 3. Mirror, Mirrorprintline 4. Tick, Tockeditvar /newvar /value=a /userinput=1 /title=What page do you want to go to? if -a- /hasvalue 1 printline You chose a line from the book Jack and the Beanstalk. & exitcurrentprogram 1if -a- /hasvalue 2 printline You chose a line from the book The Three Little Pigs. & exitcurrentprogram 1if -a- /hasvalue 3 printline You chose a line from the book Snow White. & exitcurrentprogram 1if -a- /hasvalue 4 printline You chose a line from the book Beauty and the Beast. & exitcurrentprogram 1printline You either chose an invalid choice or didn't chose. editvar /newvar /value=goback /userinput=1 /title=Do you want to chose something else?if -goback- /hasvalue y goto :a else exitcurrentprogram 1 `

## Prolog

Works with: SWI-Prolog version 6
` rosetta_menu([], "") :- !.              %% Incase of an empty list.    rosetta_menu(Items, SelectedItem) :-    repeat,                             %% Repeat until everything that follows is true.        display_menu(Items),            %% IO        get_choice(Choice),             %% IO    number(Choice),                     %% True if Choice is a number.    nth1(Choice, Items, SelectedItem),  %% True if SelectedItem is the 1-based nth member of Items, (fails if Choice is out of range)    !.                                   display_menu(Items) :-    nl,     foreach( nth1(Index, Items, Item),             format('~w) ~s~n', [Index, Item]) ). get_choice(Choice) :-    prompt1('Select a menu item by number:'),    read(Choice). `

Example run:

` ?- rosetta_menu(["fee fie", "huff and puff", "mirror mirror", "tick tock"], String). 1) fee fie2) huff and puff3) mirror mirror4) tick tockSelect a menu item by number:a. 1) fee fie2) huff and puff3) mirror mirror4) tick tockSelect a menu item by number:10. 1) fee fie2) huff and puff3) mirror mirror4) tick tockSelect a menu item by number:3.String = "mirror mirror". `

## PureBasic

`If OpenConsole()  Define i, txt\$, choice  Dim txts.s(4)  EnableGraphicalConsole(1)  ;- Enable graphical mode in the console  Repeat    ClearConsole()    Restore TheStrings       ; Set reads address    For i=1 To 4      Read.s  txt\$      txts(i)=txt\$      ConsoleLocate(3,i): Print(Str(i)+": "+txt\$)    Next    ConsoleLocate(3,6): Print("Your choice? ")    choice=Val(Input())  Until choice>=1 And choice<=4  ClearConsole()  ConsoleLocate(3,2): Print("You chose: "+txts(choice))  ;  ;-Now, wait for the user before ending to allow a nice presentation  ConsoleLocate(3,5): Print("Press ENTER to quit"): Input()EndIfEnd DataSection  TheStrings:  Data.s  "fee fie", "huff And puff", "mirror mirror", "tick tock"EndDataSection`

## Python

`def _menu(items):    for indexitem in enumerate(items):        print ("  %2i) %s" % indexitem) def _ok(reply, itemcount):    try:        n = int(reply)        return 0 <= n < itemcount    except:        return False def selector(items, prompt):    'Prompt to select an item from the items'    if not items: return ''    reply = -1    itemcount = len(items)    while not _ok(reply, itemcount):        _menu(items)        # Use input instead of raw_input for Python 3.x        reply = raw_input(prompt).strip()    return items[int(reply)] if __name__ == '__main__':    items = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock']    item = selector(items, 'Which is from the three pigs: ')    print ("You chose: " + item)`

Sample runs:

```   0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs:  -1
0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs:      0
You chose: fee fie
>>> ================================ RESTART ================================
>>>
0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs: 4
0) fee fie
1) huff and puff
2) mirror mirror
3) tick tock
Which is from the three pigs: 3
You chose: tick tock```

## R

`showmenu <- function(choices = NULL){   if (is.null(choices)) return("")   ans <- menu(choices)   if(ans==0) "" else choices[ans] }str <- showmenu(c("fee fie", "huff and puff", "mirror mirror", "tick tock"))str <- showmenu() `

## Racket

` #lang racket (define (menu choices)  (cond [(null? choices) ""]        [else (for ([c choices] [i (in-naturals 1)]) (printf "~a. ~a\n" i c))              (printf "Enter a number: ")              (define n (string->number (read-line)))              (or (and (exact-integer? n)                       (<= 1 n (length choices))                       (list-ref choices (sub1 n)))                  (menu choices))])) (menu '("fee fie" "huff and puff" "mirror mirror" "tick tock")) `

Sample Run:

```1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: three
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: help
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: 3!!
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Enter a number: 3
"mirror mirror"
```

## Raku

(formerly Perl 6)

`sub menu ( \$prompt, @items ) {    return '' unless @items.elems;    repeat until my \$selection ~~ /^ \d+ \$/ && @items[--\$selection] {        my \$i = 1;        say "  {\$i++}) \$_" for @items;        \$selection = prompt \$prompt;    }    return @items[\$selection];} my @choices = 'fee fie', 'huff and puff', 'mirror mirror', 'tick tock';my \$prompt = 'Enter the number corresponding to your selection: '; my \$answer = menu( \$prompt, [] );say "You chose: \$answer" if \$answer.chars; \$answer = menu( \$prompt, @choices );say "You chose: \$answer" if \$answer.chars;`

## REBOL

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.
`rebol [	Title: "Text Menu"	URL: http://rosettacode.org/wiki/Select] choices: ["fee fie" "huff and puff" "mirror mirror" "tick tock"]choice: "" valid?: func [	choices [block! list! series!]	choice][	if error? try [choice: to-integer choice] [return false]	all [0 < choice  choice <= length? choices]] while [not valid? choices choice][	repeat i length? choices [print ["  " i ":" choices/:i]]	choice: ask "Which is from the three pigs? "]print ["You chose:" pick choices to-integer choice]`

Output:

```   1 : fee fie
2 : huff and puff
3 : mirror mirror
4 : tick tock
Which is from the three pigs? klf
1 : fee fie
2 : huff and puff
3 : mirror mirror
4 : tick tock
Which is from the three pigs? 5
1 : fee fie
2 : huff and puff
3 : mirror mirror
4 : tick tock
Which is from the three pigs? 2
You chose: huff and puff```

## Red

`Red ["text menu"] menu: function [items][	print either empty? items [""] [until [		repeat n length? items [print [n ":" items/:n]]		attempt [pick items to-integer ask "Your choice: "]	]]]`
Output:
```>> menu ["fee fie" "huff and puff" "mirror mirror" "tick tock"]
1 : fee fie
2 : huff and puff
3 : mirror mirror
4 : tick tock
1 : fee fie
2 : huff and puff
3 : mirror mirror
4 : tick tock
1 : fee fie
2 : huff and puff
3 : mirror mirror
4 : tick tock
mirror mirror

>> ```

## REXX

`/*REXX program displays a list,  then prompts the user for a selection number (integer).*/        do forever                               /*keep prompting until response is OK. */        call list_create                         /*create the list from scratch.        */        call list_show                           /*display (show)  the list to the user.*/        if #==0   then return ''                 /*if list is empty,  then return  null.*/        say right(' choose an item by entering a number from 1 ───►' #, 70, '═')        parse pull x                             /*get the user's choice  (if any).     */               select              when x=''              then call sayErr  "a choice wasn't entered"              when words(x)\==1      then call sayErr  'too many choices entered:'              when \datatype(x,'N')  then call sayErr  "the choice isn't numeric:"              when \datatype(x,'W')  then call sayErr  "the choice isn't an integer:"              when x<1 | x>#         then call sayErr  "the choice isn't within range:"              otherwise              leave       /*this leaves the    DO FOREVER   loop.*/              end   /*select*/        end         /*forever*/                                                 /*user might've entered   2.  or  003  */x=x/1                                            /*normalize the number (maybe).        */say;  say 'you chose item' x": " #.xreturn #.x                                       /*stick a fork in it,  we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/list_create:   #.1= 'fee fie'                    /*this is one method for list-building.*/               #.2= 'huff and puff'               #.3= 'mirror mirror'               #.4= 'tick tock'               #=4                               /*store the number of choices in   #   */               return                            /*(above)  is just one convention.     *//*──────────────────────────────────────────────────────────────────────────────────────*/list_show:     say                               /*display a blank line.                */                      do j=1  for #              /*display the list of choices.         */                      say '[item'   j"]   " #.j  /*display item number with its choice. */                      end   /*j*/               say                               /*display another blank line.          */               return/*──────────────────────────────────────────────────────────────────────────────────────*/sayErr:        say;         say  '***error***'  arg(1)  x;          say;            return`
output   (which includes what the user entered):
```[item 1]  fee fie
[item 2]  huff and puff
[item 3]  mirror mirror
[item 4]  tick tock

════════════════════ choose an item by entering a number from 1 ───► 4
2           ◄■■■■■■■■■■■■■■■■■■■■■■ what the user entered at the terminal.

you chose item 2:  huff and puff
```

## Ring

` aList = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]selected = menu(aList, "please make a selection: ")see "" + selected + nl func menu aList, prompt     ndex = 1     while index>0 and index<=len(aList)           for index = 1 to len(aList)               if aList[index]!="" see "" + index + " : " + aList[index] + " " ok           next           see nl           see prompt           give select           index = number(select)           see "" + aList[index] + nl           if select!=string(index) index = -1 ok           if index>=0 if index<=len(aList) if aList[index]="" index = -1 ok ok ok     end     return aList[index] `

Output:

```1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock
huff and puff
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock
fee fie
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock
tick tock
1 : fee fie 2 : huff and puff 3 : mirror mirror 4 : tick tock
mirror mirror
```

## Ruby

` def select(prompt, items = [])  if items.empty?    ''  else    answer = -1    until (0...items.length).cover?(answer)      items.each_with_index {|i,j| puts "#{j}. #{i}"}      print "#{prompt}: "      begin        answer = Integer(gets)      rescue ArgumentError        redo      end    end    items[answer]  endend # test empty listresponse = select('Which is empty')puts "empty list returns: >#{response}<\n" # "real" testitems = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock']response = select('Which is from the three pigs', items)puts "you chose: >#{response}<" `

## Run BASIC

`dim choose\$(5)choose\$(1) = "1 Fee Fie"choose\$(2) = "2 Huff Puff"choose\$(3) = "3 Mirror, Mirror"choose\$(4) = "4 Tick, Tock"choose\$(5) = "Exit" [start]print "Menu Selection"listbox #lb,choose\$(),5button #sel, "Accept",[select]wait [select]selected\$=#lb selection\$()print " "if selected\$<>"" then  print "You selected ";selected\$ else  print "No selection made"end if button #con, "Continue",[go2]wait[go2]if selected\$<>"Exit" then  cls  goto [start] else  cls  endend if`

## Rust

` fn menu_select<'a>(items: &'a [&'a str]) -> &'a str {    if items.len() == 0 {        return "";    }     let stdin = std::io::stdin();    let mut buffer = String::new();     loop {        for (i, item) in items.iter().enumerate() {            println!("{}) {}", i + 1, item);        }        print!("Pick a number from 1 to {}: ", items.len());         // Read the user input:        stdin.read_line(&mut buffer).unwrap();        println!();         if let Ok(selected_index) = buffer.trim().parse::<usize>() {            if 0 < selected_index {                if let Some(selected_item) = items.get(selected_index - 1) {                    return selected_item;                }            }        }         // The buffer will contain the old input, so we need to clear it before we can reuse it.        buffer.clear();    }} fn main() {    // Empty list:    let selection = menu_select(&[]);    println!("No choice: {:?}", selection);     // List with items:    let items = [        "fee fie",        "huff and puff",        "mirror mirror",        "tick tock",    ];     let selection = menu_select(&items);    println!("You chose: {}", selection);} `

## Scala

### Scala idiom (Functional)

`import scala.util.Try object Menu extends App {  val choice = menu(list)   def menu(menuList: Seq[String]): String = {    if (menuList.isEmpty) "" else {      val n = menuList.size       def getChoice: Try[Int] = {        println("\n   M E N U\n")        menuList.zipWithIndex.map { case (text, index) => s"\${index + 1}: \$text" }.foreach(println(_))        print(s"\nEnter your choice 1 - \$n : ")        Try {          io.StdIn.readInt()        }      }       menuList(Iterator.continually(getChoice)        .dropWhile(p => p.isFailure || !(1 to n).contains(p.get))        .next.get - 1)    }  }   def list = Seq("fee fie", "huff and puff", "mirror mirror", "tick tock")   println(s"\nYou chose : \$choice")}`

## Seed7

`\$ include "seed7_05.s7i"; const func string: menuSelect (in array string: items, in string: prompt) is func  result    var string: selection is "";  local    var string: item is "";    var integer: index is 0;    var integer: num is 0;  begin    if length(items) <> 0 then      repeat        for item key index range items do          writeln(index <& ". " <& item);        end for;        write(prompt);        readln(num);      until num >= 1 and num <= length(items);      selection := items[num];    end if  end func; const array string: items is [] ("fee fie", "huff and puff", "mirror mirror", "tick tock");const string: prompt is "Which is from the three pigs? "; const proc: main is func  begin    writeln("You chose " <& menuSelect(items, prompt));  end func;`

## Sidef

`func menu (prompt, arr) {    arr.len > 0 || return ''    loop {        for i in ^arr {            say "  #{i}: #{arr[i]}"        }        var n = Sys.scanln(prompt) \\ return()        n ~~ /^[0-9]+\z/ ? Num(n) : next        arr.exists(n) && return arr[n]    }} var list = ['fee fie', 'huff and puff', 'mirror mirror', 'tick tock']var prompt = 'Please choose an item number: ' var answer = menu(prompt, list)say "You choose: #{answer}"`

## Swift

`func getMenuInput(selections: [String]) -> String {  guard !selections.isEmpty else {    return ""  }   func printMenu() {    for (i, str) in selections.enumerated() {      print("\(i + 1)) \(str)")    }     print("Selection: ", terminator: "")  }   while true {    printMenu()     guard let input = readLine(strippingNewline: true), !input.isEmpty else {      return ""    }     guard let n = Int(input), n > 0, n <= selections.count else {      continue    }     return selections[n - 1]  }} let selected = getMenuInput(selections: [  "fee fie",  "huff and puff",  "mirror mirror",  "tick tock"]) print("You chose: \(selected)")`

## Tcl

`proc select {prompt choices} {    set nc [llength \$choices]    if {!\$nc} {	return ""    }    set numWidth [string length \$nc]    while true {	set i 0	foreach s \$choices {	    puts [format "  %-*d: %s" \$numWidth [incr i] \$s]	}	puts -nonewline "\$prompt: "	flush stdout	gets stdin num	if {[string is int -strict \$num] && \$num >= 1 && \$num <= \$nc} {	    incr num -1	    return [lindex \$choices \$num]	}    }}`

Testing it out interactively...

`% puts >[select test {}]<><% puts >[select "Which is from the three pigs" {    "fee fie" "huff and puff" "mirror mirror" "tick tock"}]<  1: fee fie  2: huff and puff  3: mirror mirror  4: tick tockWhich is from the three pigs: 0  1: fee fie  2: huff and puff  3: mirror mirror  4: tick tockWhich is from the three pigs: skdfjhgz  1: fee fie  2: huff and puff  3: mirror mirror  4: tick tockWhich is from the three pigs:   1: fee fie  2: huff and puff  3: mirror mirror  4: tick tockWhich is from the three pigs: 5  1: fee fie  2: huff and puff  3: mirror mirror  4: tick tockWhich is from the three pigs: 2>huff and puff<`

## TI-83 BASIC

TI-83 BASIC does not support lists of strings, so this works by accepting a string containing an arbitrary number of items separated by colons. If you want to use a different delimiter, change the colons on lines 2, 3, 6 and 7 to your symbol of choice.

The calculator's screen isn't big enough to display more than 7 (9 on the new C Silver Edition and CE calcs) options at a time, so the display scrolls to accommodate options if necessary. You won't be able to see options that have scrolled off the top of the screen, but they're still accessible from the input.

Although TI-BASIC can handle empty strings, there's no way to give it one through the Input function, so it doesn't have to worry about being "called with an empty list."

```Input "",Str1 //input as ITEM 1:ITEM 2:ITEM 3...
":"+Str1+":→Str1
Σ(sub(Str1,X,1)=":",X,1,length(Str1→X
0→dim(L₁
For(Z,2,length(Str1
inString(Str1,":",Z-1
1+Ans+.01inString(Str1,":",Ans+1→L₁(1+dim(L₁
ᴇ2fPart(Ans→Z
End
seq(iPart(L₁(X))+.01(ᴇ2fPart(L₁(X))-iPart(L₁(X))),X,1,dim(L₁→L₁
Repeat A>0 and A<X
ClrHome
For(Z,1,dim(L₁
Disp "  :"+sub(Str1,iPart(L₁(Z)),ᴇ2fPart(L₁(Z
Output(min(7,Z),1+(Z≤7),Z
End
Input A
End
Disp sub(Str1,iPart(L₁(A)),ᴇ2fPart(L₁(A
```

Output with FEE FIE:HUFF AND PUFF:MIRROR MIRROR:TICK TOCK

` 1:FEE FIE 2:HUFF AND PUFF 3:MIRROR MIRROR 4:TICK TOCK? [flashing cursor]`

The language also has a Menu( command, but it doesn't really follow the requirements for the challenge (only up to 7 options allowed, no user input, option is selected using the arrow keys instead of by entering a number, etc)

```"FEE FIE→Str0
"HUFF AND PUFF→Str1
"MIRROR MIRROR→Str2
"TICK TOCK→Str3
Lbl A
Disp Str0
Return
Lbl B
Disp Str1
Return
Lbl C
Disp Str2
Return
Lbl D
Disp Str3
```

## True BASIC

`DIM menu\$(4)MAT READ menu\$DATA "fee fie", "huff and puff", "mirror mirror", "tick tock" FUNCTION sel\$(choices\$())    IF UBOUND(choices\$) - LBOUND(choices\$) = 0 THEN LET sel\$ = ""    LET ret\$ = ""    DO       FOR i = LBOUND(choices\$) TO UBOUND(choices\$)           PRINT i; ": "; choices\$(i)       NEXT i       PRINT prompt\$;       INPUT index       IF index <= UBOUND(choices\$) AND index >= LBOUND(choices\$) THEN LET ret\$ = choices\$(index)    LOOP WHILE ret\$ = ""    LET sel\$ = ret\$END FUNCTION PRINT sel\$(menu\$())END`

## UNIX Shell

This example uses the Bash select statement, but Bash did not invent this feature. The select loop comes originally from the Korn Shell, and appears in some other shells. This loop always continues to read menu choices until the script breaks the loop, or the standard input reaches end of file (EOF).

• If the user enters a blank line, the select loop repeats the list of choices. This is the only way to print the list again. An invalid choice only repeats the prompt, not the list.

Our choose function wraps a select loop. This wrapper implements the task requirement to provide an empty string from an empty list of choices. It also breaks the select loop after the first good choice.

Works with: bash
Works with: ksh93
Works with: pdksh
Works with: zsh
`# choose 'choice 1' 'choice 2' ...#   Prints menu to standard error. Prompts with PS3.#   Reads REPLY from standard input. Sets CHOICE.choose() {    CHOICE=                     # Default CHOICE is empty string.    [[ \$# -gt 0 ]] || return    # Return if "[email protected]" is empty.    select CHOICE; do           # Select from "[email protected]".        if [[ -n \$CHOICE ]]; then            break        else            echo Invalid choice.        fi    done} PS3='Which is from the three pigs: 'choose 'fee fie' 'huff and puff' 'mirror mirror' 'tick tock'[[ -n \$CHOICE ]] && echo You chose: \$CHOICE[[ -z \$CHOICE ]] && echo No input.`
```\$ bash menu.sh
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Which is from the three pigs: 5
Invalid choice.
Which is from the three pigs: 2
You chose: huff and puff
\$```
```\$ zsh menu.sh
1) fee fie         2) huff and puff   3) mirror mirror   4) tick tock
Which is from the three pigs: 2
You chose: huff and puff```

### es

 This example is incorrect. Please fix the code and remove this message.Details: The function should return an empty string if called with an empty list. Please also check if this could really used as a function aka subroutine.

There is no select loop, but this es script provides just enough code to mimic one.

• Deviation from task: When the list of choices is empty, this function returns an empty list, not an empty string.
`# choose 'choice 1' 'choice 2' ...#   Prints menu to standard error. Prompts with \$prompt.#   Returns choice. If no input, returns empty list.fn choose args {	# If args are empty, return empty list.	~ \$#args 0 && return 	# Echo to standard error.	let (reply =; choice =; fn-menu =; fn-ch =) >[1=2] {		fn-menu = {			# Show menu.			let (i = 1) for (c = \$args) {				echo \$i') '\$c				i = `{expr \$i + 1}			}		}		fn-ch = {			# Set choice = \$args(\$reply), but ignore error			# if \$reply is not a valid index.			choice = <={catch @ e {result} {				result \$args(\$reply)			}}		} 		menu		forever {			# Show prompt, read reply.			echo -n \$prompt			reply = <={%read} 			# If no input, return empty list.			~ \$#reply 0 && return 			# Parse reply and return choice.			reply = <={%split \ \t\n \$reply}			if {~ \$#reply 0} {				# Empty reply: show menu again.				menu			} {~ \$#reply 1 && ch; ~ \$#choice 1} {				return \$choice			} {				echo Invalid choice.			}		}	}} let (choice = <={	local (prompt = 'Which is from the three pigs: ')		choose 'fee fie' 'huff and puff' 'mirror mirror' 'tick tock'}) {	~ \$#choice 1 && echo You chose: \$choice	~ \$#choice 0 && echo No input.}`
```\$ es menu.es
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock
Which is from the three pigs: 2
You chose: huff and puff```

## Ursa

Translation of: Python
`def _menu (string<> items)	for (decl int i) (< i (size items)) (inc i)		out "  " i ") " items<i> endl console	end forend _menu def _ok (string reply, int itemcount)	try		decl int n		set n (int reply)		return (and (or (> n 0) (= n 0)) (< n itemcount))	catch		return false	end tryend _ok def selector (string<> items, string prompt)	# Prompt to select an item from the items	if (= (size items) 0)		return ""	end if	decl int itemcount reply	set reply -1	set itemcount (size items)	while (not (_ok reply itemcount))		_menu items		out prompt console		set reply (in int console)	end while	return items<(int reply)>end selector decl string<> itemsappend "fee fie" "huff and puff" "mirror mirror" "tick tock" itemsdecl string itemset item (selector items "Which is from the three pigs: ")out "You chose: " item endl console`

## VBScript

`'The FunctionFunction Menu(ArrList, Prompt)    Select Case False   'Non-standard usage hahaha        Case IsArray(ArrList)           Menu = ""   'Empty output string for non-arrays           Exit Function        Case UBound(ArrList) >= LBound(ArrList)           Menu = ""   'Empty output string for empty arrays           Exit Function    End Select    'Display menu and prompt    Do While True        For i = LBound(ArrList) To UBound(ArrList)            WScript.StdOut.WriteLine((i + 1) & ". " & ArrList(i))        Next        WScript.StdOut.Write(Prompt)        Choice = WScript.StdIn.ReadLine        'Check if input is valid        If IsNumeric(Choice) Then   'Check for numeric-ness            If CStr(CLng(Choice)) = Choice Then   'Check for integer-ness (no decimal part)                Index = Choice - 1   'Arrays are 0-based                'Check if Index is in array                If LBound(ArrList) <= Index And Index <= UBound(ArrList) Then                    Exit Do                End If            End If        End If        WScript.StdOut.WriteLine("Invalid choice.")    Loop    Menu = ArrList(Index)End Function 'The Main ThingSample = Array("fee fie", "huff and puff", "mirror mirror", "tick tock")InputText = "Which is from the three pigs: "WScript.StdOut.WriteLine("Output: " & Menu(Sample, InputText))`
Output:
```C:\>cscript /nologo menu.vbs
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: cdsfklfm
Invalid choice.
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: -2
Invalid choice.
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 3.14159
Invalid choice.
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 45
Invalid choice.
1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock
Which is from the three pigs: 2
Output: huff and puff```

## Wren

Library: Wren-ioutil
`import "/ioutil" for Input var menu = Fn.new { |list|    var n = list.count    if (n == 0) return ""    var prompt = "\n   M E N U\n\n"    for (i in 0...n) prompt = prompt + "%(i+1). %(list[i])\n"    prompt = prompt + "\nEnter your choice (1 - %(n)): "    var index = Input.integer(prompt, 1, n)    return list[index-1]} var list = ["fee fie", "huff and puff", "mirror mirror", "tick tock"]var choice = menu.call(list)System.print("\nYou chose : %(choice)")`
Output:

Sample run:

```   M E N U

1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock

Enter your choice (1 - 4): 6
Must be an integer between 1 and 4, try again.

M E N U

1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock

Enter your choice (1 - 4): m
Must be an integer between 1 and 4, try again.

M E N U

1. fee fie
2. huff and puff
3. mirror mirror
4. tick tock

Enter your choice (1 - 4): 4

You chose : tick tock
```

## XPL0

`string 0; func Menu(List);int  List;int  Size, I, C;[Size:= List(0);if Size < 1 then return List(0); \if empty list, return pointer to 0for I:= 1 to Size-1 do        [IntOut(0, I);  Text(0, ": ");        Text(0, List(I));  CrLf(0);        ];CrLf(0);Text(0, List(Size));            \display promptloop    [C:= ChIn(0);           \buffered keyboard requires Enter key        if C>=^1 & C<=Size-1+^0 then return List(C-^0);        Text(0, "Please enter 1 thru ");  IntOut(0, Size-1);        Text(0, ": ");        ];]; Text(0, Menu([5, "fee fie", "huff and puff", "mirror mirror", "tick tock",                "Which phrase is from the Three Little Pigs? "]))`

Example output:

```1: fee fie
2: huff and puff
3: mirror mirror
4: tick tock

Which phrase is from the Three Little Pigs? 5
Please enter 1 thru 4: 2
huff and puff
```

## Yabasic

`// Rosetta Code problem: https://www.rosettacode.org/wiki/Menu// by Jjuanhdez, 06/2022 dim choose\$(5)restore menudatafor a = 0 to 5 : read choose\$(a) : next a print menu\$(choose\$())end sub menu\$(m\$())    clear screen    repeat        print color("green","black") at(0,0) "Menu selection"        vc = 0         b = arraysize(m\$(),1)        while vc < 1 or vc > b            for i = 1 to b-1                print i, "  ", choose\$(i)            next i            print choose\$(b)            print             input "Your choice: " c            print at(0,7) "Your choice:      "            if c > 0 and c < 6 then                vc = c                print color("yellow","black") at(0,8) choose\$(vc)            else                print color("red","black") at(0,8) choose\$(0)                break            fi        wend    until vc = 5end sub label menudatadata "Ack, not good", "fee fie      ", "huff and puff"data "mirror mirror", "tick tock    ", "exit         "`

## zkl

`fcn teleprompter(options){   os:=T("exit").extend(vm.arglist); N:=os.len();   if(N==1) return("");   while(1){      Utils.zipWith(fcn(n,o){"%d) %s".fmt(n,o).println()},[0..],os);      a:=ask("Your choice: ");      try{ n:=a.toInt(); if(0<=n<N) return(os[n]); } catch{}      println("Ack, not good");   }} teleprompter("fee fie" , "huff and puff" , "mirror mirror" , "tick tock").println();`
Output:
```0) exit
1) fee fie
2) huff and puff
3) mirror mirror
4) tick tock