Rosetta Code/Find unimplemented tasks

From Rosetta Code
Task
Rosetta Code/Find unimplemented tasks
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Given the name of a language on Rosetta Code, find all tasks which are not implemented in that language.


Note: Implementations should allow for fetching more data than can be returned in one request to Rosetta Code.

You'll need to use the Media Wiki API, which you can find out about locally, here, or in Media Wiki's API documentation at, API:Query

Ada

Library: AWS

Parsing XML with XMLAda from Adacore

with Aws.Client, Aws.Messages, Aws.Response, Aws.Resources, Aws.Url;
with Dom.Readers, Dom.Core, Dom.Core.Documents, Dom.Core.Nodes, Dom.Core.Attrs;
with Input_Sources.Strings, Unicode, Unicode.Ces.Utf8;
with Ada.Strings.Unbounded, Ada.Text_IO, Ada.Command_Line;
with Ada.Containers.Vectors;

use  Aws.Client, Aws.Messages, Aws.Response, Aws.Resources, Aws.Url;
use Dom.Readers, Dom.Core, Dom.Core.Documents, Dom.Core.Nodes, Dom.Core.Attrs;
use Aws, Ada.Strings.Unbounded, Input_Sources.Strings;
use Ada.Text_IO, Ada.Command_Line;

procedure Not_Coded is

   package Members_Vectors is new Ada.Containers.Vectors (
      Index_Type => Positive,
      Element_Type => Unbounded_String);
   use Members_Vectors;

   All_Tasks, Language_Members : Vector;

   procedure Get_Vector (Category : in String; Mbr_Vector : in out Vector) is
      Reader : Tree_Reader;
      Doc    : Document;
      List   : Node_List;
      N      : Node;
      A      : Attr;
      Page   : Aws.Response.Data;
      S      : Messages.Status_Code;

      -- Query has cmlimit value of 100, so we need 5 calls to
      -- retrieve the complete list of Programming_category
      Uri_Xml    : constant String  :=
         "http://rosettacode.org/mw/api.php?action=query&list=categorymembers"
         &
         "&format=xml&cmlimit=100&cmtitle=Category:";
      Cmcontinue : Unbounded_String := Null_Unbounded_String;
   begin
      loop
         Page :=
            Aws.Client.Get (Uri_Xml & Category & (To_String (Cmcontinue)));
         S    := Response.Status_Code (Page);
         if S not  in Messages.Success then
            Put_Line
              ("Unable to retrieve data => Status Code :" &
               Image (S) &
               " Reason :" &
               Reason_Phrase (S));
            raise Connection_Error;
         end if;
         declare
            Xml    : constant String := Message_Body (Page);
            Source : String_Input;
         begin
            Open
              (Xml'Unrestricted_Access,
               Unicode.Ces.Utf8.Utf8_Encoding,
               Source);
            Parse (Reader, Source);
            Close (Source);
         end;
         Doc  := Get_Tree (Reader);
         List := Get_Elements_By_Tag_Name (Doc, "cm");
         for Index in 1 .. Length (List) loop
            N := Item (List, Index - 1);
            A := Get_Named_Item (Attributes (N), "title");
            Members_Vectors.Append
              (Mbr_Vector,
               To_Unbounded_String (Value (A)));
         end loop;
         Free (List);
         List := Get_Elements_By_Tag_Name (Doc, "query-continue");
         if Length (List) = 0 then
            -- we are done
            Free (List);
            Free (Reader);
            exit;
         end if;
         N          := First_Child (Item (List, 0));
         A          := Get_Named_Item (Attributes (N), "cmcontinue");
         Cmcontinue :=
            To_Unbounded_String
              ("&cmcontinue=" & Aws.Url.Encode (Value (A)));
         Free (List);
         Free (Reader);
      end loop;
   end Get_Vector;

   procedure Quick_Diff (From : in out Vector; Substract : in Vector) is
      Beginning, Position : Extended_Index;
   begin
      -- take adavantage that both lists are already sorted
      Beginning := First_Index (From);
      for I in First_Index (Substract) .. Last_Index (Substract) loop
         Position :=
            Find_Index
              (Container => From,
               Item      => Members_Vectors.Element (Substract, I),
               Index     => Beginning);
         if not (Position = No_Index) then
            Delete (From, Position);
            Beginning := Position;
         end if;
      end loop;
   end Quick_Diff;

begin
   if Argument_Count = 0 then
      Put_Line ("Can't process : No language given!");
      return;
   else
      Get_Vector (Argument (1), Language_Members);
   end if;

   Get_Vector ("Programming_Tasks", All_Tasks);
   Quick_Diff (All_Tasks, Language_Members);

   for I in First_Index (All_Tasks) .. Last_Index (All_Tasks) loop
      Put_Line (To_String (Members_Vectors.Element (All_Tasks, I)));
   end loop;
   Put_Line
     ("Numbers of tasks not implemented :=" &
      Integer'Image (Last_Index ((All_Tasks))));
end Not_Coded;

ARM Assembly

Works with: as version Raspberry Pi
or android 32 bits with application Termux
/* ARM assembly Raspberry PI  */
/*  program tasksearchRasp.s   */
/* access RosettaCode.org and data extract       */
/* use openssl  for access to port 443 */
/* test openssl : package libssl-dev  */

/* REMARK 1 : this program use routines in a include file 
   see task Include a file language arm assembly 
   for the routine affichageMess conversion10 
   see at end of this program the instruction include */

/*******************************************/
/* Constantes                              */
/*******************************************/
.include "../constantes.inc"

//.equ EXIT,          1
.equ TAILLEBUFFER,  500

.equ SSL_OP_NO_SSLv3,        0x02000000
.equ SSL_OP_NO_COMPRESSION,  0x00020000
.equ SSL_MODE_AUTO_RETRY,    0x00000004
.equ SSL_CTRL_MODE,          33

.equ BIO_C_SET_CONNECT,      100
.equ BIO_C_DO_STATE_MACHINE, 101
.equ BIO_C_SET_SSL,          109
.equ BIO_C_GET_SSL,          110

.equ LGBUFFERREQ,       512001
.equ LGBUFFER2,         128001

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessDebutPgm:       .asciz "Program 32 bits start \n"
szRetourLigne:        .asciz "\n"
szMessFinOK:          .asciz "Program end OK. \n"
szMessErreur:         .asciz "Erreur  !!!"
//szMessExtractArea:    .asciz "Extraction = "
szMessConnectOK:      .asciz "Connexion site OK.\n"
szMessInitOK:         .asciz "Initialisation SSL OK.\n"
szMessReqOK:          .asciz "Send requete OK.\n"
szNomSite1:           .asciz "www.rosettacode.org:443"   @ host name and port
szLibStart:           .asciz "<query><categorymembers>"          @ search string 
szLibsearch1:         .asciz "<cm pageid="
szLibsearch2:         .asciz "title="
szNomrepCertif:       .asciz "/pi/certificats"
szRequete1:           .asciz "GET /w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=1000&format=xml HTTP/1.1 \r\nHost: rosettacode.org\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\n\r\n"
szRequete2:           .asciz "GET /w/api.php?action=query&list=categorymembers&cmtitle=Category:ARM%20Assembly&cmlimit=500&format=xml HTTP/1.1 \r\nHost: rosettacode.org\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\n\r\n"

/*********************************/
/* UnInitialized data            */
/*********************************/
.bss  
.align 4
sBufferreq:           .skip LGBUFFERREQ
sBufferreq1:          .skip LGBUFFERREQ
szExtractArea:        .skip TAILLEBUFFER
szExtractArea1:       .skip TAILLEBUFFER
szTaskName:           .skip 128
szTaskNamePgm:        .skip 128
.align 4
stNewSSL:             .skip 200
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main 
main:
    ldr r0,iAdrszMessDebutPgm
    bl affichageMess                             @ start message 

    /* connexion host port 443 and send query */ 
    ldr r0,iAdrszNomSite1
    ldr r1,iAdrszRequete1
    ldr r2,iAdrsBufferreq
    bl envoiRequete
    cmp r0,#-1
    beq 99f                                       @ error ?

    ldr r0,iAdrszNomSite1
    ldr r1,iAdrszRequete2
    ldr r2,iAdrsBufferreq1
    bl envoiRequete
    cmp r0,#-1
    beq 99f                                       @ error ?

    bl analyseReponse

    ldr r0,iAdrszMessFinOK                        @ end message
    bl affichageMess
    mov r0, #0                                    @ return code ok
    b 100f
99:
    ldr r0,iAdrszMessErreur                       @ error
    bl affichageMess
    mov r0, #1                                    @ return code error
    b 100f
100: 
    mov r7,#EXIT                                  @ program end
    svc #0                                        @ system call
iAdrszMessDebutPgm:          .int szMessDebutPgm
iAdrszMessFinOK:             .int szMessFinOK
iAdrszMessErreur:            .int szMessErreur
iAdrszNomSite1:              .int szNomSite1
iAdrszRequete2:              .int szRequete2 
iAdrszRequete1:              .int szRequete1
iAdrsBufferreq:             .int sBufferreq
iAdrsBufferreq1:             .int sBufferreq1
/*********************************************************/
/*   connexion host port 443 and send query            */
/*********************************************************/
envoiRequete:
    push {r2-r9,lr}                 @ save registers
    mov r8,r0                       @ save address site name
    mov r9,r1                       @ save address requete
    mov r7,r2                       @ save address buffer 
    @*************************************
    @ openSsl functions use              *
    @*************************************
                                    @init ssl
    mov r0,#0
    bl OPENSSL_init_crypto
    bl ERR_load_BIO_strings
    mov r2, #0
    mov r1, #0
    mov r0, #2
    bl OPENSSL_init_crypto
    mov r2, #0
    mov r1, #0
    mov r0, #0
    bl OPENSSL_init_ssl
    cmp r0,#0
    blt erreur
    bl TLS_client_method
    bl SSL_CTX_new
    cmp r0,#0
    ble erreur
    mov r6,r0                       @ save ctx
    ldr r1,iFlag
    bl SSL_CTX_set_options
    mov r0,r6
    mov r1,#0
    ldr r2,iAdrszNomrepCertif
    bl SSL_CTX_load_verify_locations
    cmp r0,#0
    ble erreur
    mov r0,r6
    bl BIO_new_ssl_connect
    cmp r0,#0
    beq erreur
    cmp r0,#-1
    beq erreur
    mov r5,r0                       @ save bio
    ldr r0,iAdrszMessInitOK
    bl affichageMess
    mov r0,r5
    mov r1,#BIO_C_GET_SSL
    mov r2,#0
    ldr r3,iAdrstNewSSL
    bl BIO_ctrl
    ldr r0,iAdrstNewSSL
    ldr r0,[r0]
    mov r1,#SSL_CTRL_MODE
    mov r2,#SSL_MODE_AUTO_RETRY
    mov r3,#0
    bl SSL_ctrl
    mov r0,r5                       @ bio
    mov r1,#BIO_C_SET_CONNECT
    mov r2,#0
    mov r3,r8                       @ site address
    bl BIO_ctrl
    mov r0,r5                       @ bio
    mov r1,#BIO_C_DO_STATE_MACHINE
    mov r2,#0
    mov r3,#0
    bl  BIO_ctrl
    cmp r0,#0
    blt erreur
    
    ldr r0,iAdrszMessConnectOK
    bl affichageMess
                                    @ compute query length
    mov r2,#0                       @ init length
    mov r1,r9                       @ query address
1:                                  @ loop compute length query
    ldrb r0,[r1,r2]
    cmp r0,#0
    addne r2,#1
    bne 1b
                                    @ send query
    mov r0,r5                       @ bio
                                    @ r1 = address query
                                    @ r2 = length query
    mov r3,#0
    bl BIO_write                    @ send query
    cmp r0,#0
    blt erreur
    ldr r0,iAdrszMessReqOK
    bl affichageMess
2:                                  @ begin loop to read datas
    mov r0,r5                       @ bio
    mov r1,r7                       @ buffer address
    mov r2,#LGBUFFERREQ - 1
    mov r3,#0
    bl BIO_read
    cmp r0,#0
    ble 4f                          @ error ou pb server
    mov r1,r7
    add r7,r0
    sub r2,r7,#6
    ldr r2,[r2]                     
    ldr r3,iCharEnd
    cmp r2,r3                       @ text end ?
    beq 4f
    mov r1,#0xFF                    @ delay loop 
3:
    subs r1,#1
    bgt 3b
    b 2b                            @ loop read other chunk
4:                                  @ read end
    //ldr r0,iAdrsBufferreq           @ to display buffer response of the query
    //bl affichageMess
    mov r0, r5                      @ close bio
    bl BIO_free_all
    mov r0,#0
    b 100f
erreur:                             @ error display
    ldr r1,iAdrszMessErreur
    bl   afficheerreur
    mov r0,#-1                      @ error code
    b 100f
100:
    pop {r2-r9,pc}                  @ restaur registers 
iFlag:                      .int SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION
iAdrstNewSSL:               .int stNewSSL
iAdrszNomrepCertif:         .int szNomrepCertif
iCharEnd:                   .int 0x0A0D300A
iAdrszMessConnectOK:        .int szMessConnectOK
iAdrszMessInitOK:           .int szMessInitOK
iAdrszMessReqOK:            .int szMessReqOK
/*********************************************************/
/*   response analyze                                    */
/*********************************************************/
analyseReponse:
     push {r1-r6,lr}                         @ save registers
                                             @ search start in task buffer
    ldr r0,iAdrsBufferreq                    @ buffer address
    mov r7,r0
    ldr r1,iAdrszLibStart                    @ key text address 
    bl rechercheSousChaine
    cmp r0,#-1
    beq 99f
    add r7,r7,r0                             @ new search buffer address
    mov r0,r7
                                             @ search start in task buffer
    ldr r0,iAdrsBufferreq11                  @ buffer address
    mov r5,r0
    ldr r1,iAdrszLibStart                    @ key text address 
    bl rechercheSousChaine
    cmp r0,#-1
    beq 99f                                  @ error ?
    add r5,r5,r0
    mov r0,r5
1:                                           @ loop begin to find task in program buffer
    mov r0,r5
    ldr r1,iAdrszLibsearch1                  @ text code task address 
    mov r2,#1                                @ occurence key text
    mov r3,#2                                @ offset
    ldr r4,iAdrszExtractArea1                @ address result area
    bl extChaine
    cmp r0,#-1
    beq 99f                                  @ error ?
    mov r5,r0                                @ new address to search
    ldr r0,iAdrszExtractArea1 
    bl conversionAtoD                        @ conversion code task to numeric
    mov r10,r0                               @ save numeric code
    mov r0,r5                                @ search  task name in pgm buffer                             @
    ldr r1,iAdrszLibsearch2                  @ key text address 
    mov r2,#1                                @ occurence key text
    mov r3,#2                                @ offset
    ldr r4,iAdrszTaskNamePgm                 @ address result area
    bl extChaine
    cmp r0,#-1
    beq 99f
    mov r5,r0                                @ new address to search 
2:                                           @ loop search buffer tasks
    mov r0,r7
    ldr r1,iAdrszLibsearch1                  @ key text address 
    mov r2,#1                                @ occurence key text
    mov r3,#2                                @ offset
    ldr r4,iAdrszExtractArea                 @ address result area
    bl extChaine
    cmp r0,#-1
    beq 99f
    mov r7,r0
    mov r0,r7
    ldr r1,iAdrszLibsearch2                  @ key text address 
    mov r2,#1                                @ occurence key text
    mov r3,#2                                @ offset
    ldr r4,iAdrszTaskName                    @ address result area
    bl extChaine
    cmp r0,#-1
    beq 99f
    mov r7,r0                                @ new search address in task buffer
    ldr r0,iAdrszExtractArea 
    bl conversionAtoD                        @ conversion code task in numeric
    cmp r10,r0                               @ compere two task code  
    beq 10f                                  @ search next codes if equals
    
    ldr r0,iAdrszTaskName                    @ else display task name
    bl affichageMess
    ldr r0,iAdrszRetourLigne
    bl affichageMess
    
    add r0,r7,#4                             @ search if end of task list 
    ldrb r2,[r0]
    cmp r2,#'/'
    bne 2b                                   @ no -> loop
    add r0,#1
    ldrb r2,[r0]
    cmp r2,#'c'
    bne 2b                                   @ no -> loop
    
    b 100f                                   @ yes -> list end 
10:
    add r0,r5,#4                             @ search if end of pgm task list
    ldrb r2,[r0]
    cmp r2,#'/'
    bne 1b
    add r0,#1
    ldrb r2,[r0]
    cmp r2,#'c'
    bne 1b

    b 100f                                   @ list pgm end
    
99:
    ldr r0,iAdrszMessErreur1                   @ error
    bl affichageMess
    mov r0, #-1                               @ error return code
    b 100f
100:
    pop {r1-r6,pc}                            @ restaur registers 
iAdrsBufferreq11:               .int sBufferreq1
iAdrszLibStart:                 .int szLibStart
iAdrszLibsearch1:               .int szLibsearch1
iAdrszLibsearch2:               .int szLibsearch2
iAdrszTaskName:                 .int szTaskName
iAdrszTaskNamePgm:              .int szTaskNamePgm
iAdrszExtractArea:              .int szExtractArea
iAdrszExtractArea1:             .int szExtractArea1
iAdrszRetourLigne:              .int szRetourLigne
iAdrszMessErreur1:              .int szMessErreur
/*********************************************************/
/*   Text Extraction behind text key                     */
/*********************************************************/
/* r0  buffer address   */
/* r1  key text to search */
/* r2  number occurences to key text */
/* r3  offset */
/* r4  result address */
extChaine:
    push {r2-r8,lr}      @ save registers
    mov r5,r0            @ save buffer address
    mov r6,r1            @ save key text
                         @ compute text length
    mov r7,#0
1:                       @ loop 
    ldrb r0,[r5,r7]      @ load a byte
    cmp r0,#0            @ end ?
    addne r7,#1          @ no -> loop 
    bne 1b
    add r7,r5            @ compute text end

    mov r8,#0
2:                       @ compute length text key
    ldrb r0,[r6,r8]
    cmp r0,#0
    addne r8,#1
    bne 2b

3:                       @ loop to search nième(r2)  key text 
    mov r0,r5
    mov r1,r6
    bl rechercheSousChaine
    cmp r0,#0
    blt 100f
    subs r2,#1
    addgt r5,r0       
    addgt r5,r8
    bgt 3b
    add r0,r5           @ add address text to index
    add r3,r0           @ add offset 
    sub r3,#1
                        @ and add length key text
    add r3,r8
    cmp r3,r7           @ > at text end 
    movge r0,#-1        @ yes -> error
    bge 100f
    mov r0,#0
4:                      @ character loop copy
    ldrb r2,[r3,r0]
    strb r2,[r4,r0]
    cmp r2,#0           @ text end ?
    moveq r0,#0         @ return zero
    beq 100f
    cmp r2,#'"'         @ text end ?
    beq 5f
    cmp r0,#48          @ extraction length
    beq 5f
    add r0,#1
    b 4b                @ and loop
5:
    mov r2,#0           @ store final zéro
    strb r2,[r4,r0]
    add r0,#1
    add r0,r3           @ r0 return the last position of extraction
                        @ it is possible o search another text
100:
   	pop {r2-r8,pc}      @ restaur registers 

/******************************************************************/
/*   search substring in string                                   */ 
/******************************************************************/
/* r0 contains address string */
/* r1 contains address substring */
/* r0 return start index substring or -1 if not find */
rechercheSousChaine:
    push {r1-r6,lr}                       @ save registers 
    mov r2,#0                             @ index position string
    mov r3,#0                             @ index position substring
    mov r6,#-1                            @ search index
    ldrb r4,[r1,r3]                       @ load first byte substring
    cmp r4,#0                             @ zero final ?
    moveq r0,#-1                          @ error 
    beq 100f
1:
    ldrb r5,[r0,r2]                       @ load string byte
    cmp r5,#0                             @ zero final ?
    moveq r0,#-1                          @ yes -> not find
    beq 100f
    cmp r5,r4                             @ compare character two strings 
    beq 2f
    mov r6,#-1                            @ not equal - > raz index 
    mov r3,#0                             @ and raz byte counter
    ldrb r4,[r1,r3]                       @ and load byte
    add r2,#1                             @ and increment byte counter
    b 1b                                  @ and loop
2:                                        @ characters equal
    cmp r6,#-1                            @ first character equal ?
    moveq r6,r2                           @ yes -> start index in r6
    add r3,#1                             @ increment substring counter
    ldrb r4,[r1,r3]                       @ and load next byte
    cmp r4,#0                             @ zero final ?
    beq 3f                                @ yes -> search end
    add r2,#1                             @ else increment string index
    b 1b                                  @ and loop
3:
    mov r0,r6                             @ return start index substring in the string
100:
    pop {r1-r6,pc}                        @ restaur registres

/***************************************************/
/*      ROUTINES INCLUDE                 */
/***************************************************/
.include "../affichage.inc"
Output:
Program 32 bits start
Initialisation SSL OK.
Connexion site OK.
Send requete OK.
Initialisation SSL OK.
Connexion site OK.
Send requete OK.
Abstract type
Accumulator factory
Active Directory/Connect
Active Directory/Search for a user
Active object
Add a variable to a class instance at runtime
Algebraic data types

AutoHotkey

The GUI overkill version with comments.

#NoEnv ; do not resolve environment variables (speed)
#SingleInstance force ; allow only one instance
SetBatchLines, -1 ; set to highest script speed
SetControlDelay, 0 ; set delay between control commands to lowest
 
; additional label, for clarity only
AutoExec:
  Gui, Add, DDL, x10 y10 w270 r20 vlngStr ; add drop-down list
  Gui, Add, Button, x290 y10 gShowLng, Show Unimplemented ; add button
  Gui, Add, ListView, x10 y36 w400 h300 vcatLst gOnLV, Unimplemented ; add listview
  Gui, Add, StatusBar, vsbStr, ; add statusbar
  Gui, Show, , RosettaCode unimplemented list ; show the gui
  allLng := getList("lng") ; get a list of all available languages
  selectStr = Select language... ; set selection string for ddl
  GuiControl, , LngStr, |%selectStr%||%allLng% ; set the ddl to new contents
  SB_SetIcon("user32.dll", 5) ; change statusbar icon
  SB_SetText("Done loading languages. Select from menu.") ; change statusbar text
Return ; end of the autoexec section. Script waits for input.

; subroutine for language list in ddl update
ShowLng:
  Gui, Submit, NoHide ; refresh all gui variables
  If (lngStr != selectStr) ; if the current selected language is not the selection string
  {
    SB_SetIcon("user32.dll", 2) ; set statusbar icon to exclamation
    SB_SetText("Loading unimplemented tasks... Please wait.") ; set statusbar text
    allTsk := getList("tsk") ; get a list of all tasks
    allThis := getList(lngStr) ; get a list of all done tasks for this language
    Loop, Parse, allTsk, | ; parse the list of all tasks
    {
      If !InStr(allThis,A_LoopField) ; if the current task is not found in the list of all tasks
        notImpl .= A_LoopField . "|" ; add the current field to the notImpl variable
      allTskCnt := A_Index ; save the index for final count
    }
    StringTrimRight, notImpl, notImpl, 1 ; remove last delimiter
    LV_Delete() ; emty the listview
    GuiControl, -Redraw, catLst ; set the listview to not redraw while adding (speed)
    Loop, Parse, notImpl, | ; parse the list of not implemented tasks
    {
      LV_Add("", A_LoopField) ; add them to the listview, field by field
      notImplCnt := A_Index ; save the index for final count
    }
    GuiControl, +Redraw, catLst ; set the listview back to normal
    SB_SetIcon("user32.dll", 5) ; change statusbar icon to information
    SB_SetText("There are " . notImplCnt . " of " . allTskCnt
      . " tasks unimplemented. Double-click task to open in browser.") ; set the statusbar text
    notImpl = ; empty the notImpl variable
    notImplCnt = 0 ; set the count back to 0
  }
Return

; subroutine for action on listview
OnLV:
  If (A_GuiEvent = "DoubleClick") ; if the listview was double-clicked
  {
    LV_GetText(rowTxt, A_EventInfo) ; get the text of the clicked row
    rowTxt := Enc_Uri(rowTxt) ; uri-encode the text
    StringReplace, rowTxt, rowTxt, `%20, _, All ; replace all space-encodings with underscores
    Run % "http://rosettacode.org/wiki/" . rowTxt ; run the resulting link in the default browser
  }
Return
 
; generic function to gather list
getList(category)
{
  fileName = temp.xml ; set temp-file name
  If (category = "lng") ; if the category received is lng
  {
    category = Programming_Languages ; set the category
    fileName = lng.xml ; set temp-file name
    IfExist, %fileName% ; if the file already exists
    {
      FileGetTime, modTime, %fileName% ; get the last modified time
      EnvSub, modTime, %A_Now%, days ; get the difference between now and last modified time in days
      If (modTime < 3) ; if the result is less than 3
        Goto, GetFileNoDL ; go to function-internal subroutine to parse
    }
    SB_SetIcon("user32.dll", 2) ; set statusbar icon
    SB_SetText("Loading languages... Please wait.") ; set statusbar text
  }
  If (category = "tsk") ; if the category received is tsk
    category = Programming_Tasks ; set the category
 
  getFile: ; function-internal subroutine for getting a file and parsing it
    ; construct the url
    url := "http://www.rosettacode.org/w/api.php?action=query&list="
          . "categorymembers&cmtitle=Category:" . category
          . "&cmlimit=500&format=xml" . doContinue
    UrlDownloadToFile, %url%, %fileName% ; download the url
 
  getFileNoDL: ; function-internal subroutine for parsing a file
    FileRead, data, %fileName% ; read file into variable
    pos = 1 ; set while-loop counter
    rxp = title="(.*?)" ; set regular expression
    While (pos := RegExMatch(data, rxp, title, pos)) ; get the contents of the title fields one-by-one
    {
      If InStr(title1, "Category:") ; if the contents contain Category:
        StringTrimLeft, title1, title1, 9 ; remove that from the contents
      StringReplace, title1, title1, |, `|, All ; escape all containing delimiters
      title1 := Dec_XML(UTF82Ansi(title1)) ; convert to ansi first and then decode html entities
      allTitles .= title1 . "|" ; add this title to list
      pos++ ; increment counter
    }
    rxp = cmcontinue="(.*?)" ; set regular expression
    If RegExMatch(data, rxp, next) ; when found
    {
      doContinue = &cmcontinue=%next1% ; set continuation string to add to url
      Goto getFile ; go to function-internal subroutine to redownload and parse
    }
    StringTrimRight, allTitles, allTitles, 1 ; remove last delimiter from result
  Return allTitles ; return result
}
 
; function to convert html entities to ansi equivalents
Dec_XML(str) 
{
   Loop 
      If RegexMatch(str, "S)(&#(\d+);)", dec)
         StringReplace, str, str, %dec1%, % Chr(dec2), All 
      Else If   RegexMatch(str, "Si)(&#x([\da-f]+);)", hex)
         StringReplace, str, str, %hex1%, % Chr("0x" . hex2), All 
      Else 
         Break 
   StringReplace, str, str, &nbsp;, %A_Space%, All 
   StringReplace, str, str, &quot;, ", All
   StringReplace, str, str, &apos;, ', All 
   StringReplace, str, str, &lt;,   <, All 
   StringReplace, str, str, &gt;,   >, All 
   StringReplace, str, str, &amp;,  &, All
   return, str 
} 

; function to uri-encode input string
Enc_Uri(str) 
{ 
   f = %A_FormatInteger% 
   SetFormat, Integer, Hex 
   If RegExMatch(str, "^\w+:/{0,2}", pr) 
      StringTrimLeft, str, str, StrLen(pr) 
   StringReplace, str, str, `%, `%25, All 
   Loop 
      If RegExMatch(str, "i)[^\w\.~%/:]", char) 
         StringReplace, str, str, %char%, % "%" . SubStr(Asc(char),3), All 
      Else Break 
   SetFormat, Integer, %f% 
   Return, pr . str 
}

; function to convert unicode to ansi text
UTF82Ansi(zString) 
{ 
  Ansi2Unicode(zString, wString, 65001) 
  Unicode2Ansi(wString, sString, 0) 
  Return sString 
} 

; helper function for unicode to ansi function
Ansi2Unicode(ByRef sString, ByRef wString, CP = 0) 
{ 
  nSize := DllCall("MultiByteToWideChar", "Uint", CP 
    , "Uint", 0, "Uint", &sString, "int", -1 
    , "Uint", 0, "int", 0)
  VarSetCapacity(wString, nSize * 2)
  DllCall("MultiByteToWideChar" 
    , "Uint", CP, "Uint", 0, "Uint", &sString, "int", -1 
    , "Uint", &wString, "int", nSize) 
} 

; helper function for unicode to ansi function
Unicode2Ansi(ByRef wString, ByRef sString, CP = 0) 
{ 
  nSize := DllCall("WideCharToMultiByte" 
    , "Uint", CP, "Uint", 0, "Uint", &wString, "int", -1 
    , "Uint", 0, "int", 0, "Uint", 0, "Uint", 0) 
  VarSetCapacity(sString, nSize) 
  DllCall("WideCharToMultiByte" 
    , "Uint", CP, "Uint", 0, "Uint", &wString, "int", -1 
    , "str", sString, "int", nSize, "Uint", 0, "Uint", 0) 
}

; subroutine called when user closes the gui
GuiClose:
  ExitApp ; exit the script
Return

Output

Loads a list of all languages. Pick the language you would like to see the unimplemented tasks of, press the button, double click the selected task to launch in default browser. It will download the languages to file and redownload if older than 3 days (to save unnecessary bandwith).

BBC BASIC

      SYS "LoadLibrary", "URLMON.DLL" TO U%
      IF U% == 0 ERROR 100, "DLL not available in your OS"
      SYS "GetProcAddress", U%, "URLDownloadToFileA" TO U%

      Q$=CHR$34             : REM The quote
      BlkSize%=256 * 1024   : REM 256k must be enough
      DIM Blk% BlkSize% - 1 : REM Reserve memory block to load data into

      PROCFetchData("Programming_Tasks")

      REM Count number of tasks and declare and populate Task$() array.
      P%=Blk%
      REPEAT
        I%=INSTR($$P%, "title")
        IF I% Tasks%+=1 : P%+=I%
      UNTIL I% == 0
      DIM Task$(Tasks%-1)
      P%=Blk%
      FOR I%=0 TO Tasks% - 1
        Task$(I%)=FNValue(P%, "title")
      NEXT

      PROCShowUnimplemented("BBC_BASIC")
      PROCShowUnimplemented("C++")
      END

      REM -------------------------------------------------------------------------
      REM Compare each task title against loaded language data in memory.
      DEF PROCShowUnimplemented(language$)
      LOCAL i%, j%, mem%, n%

      PROCFetchData(language$)
      mem%=Blk%
      PRINT "Unimplemented tasks for the '" language$ "' programming language:"
      FOR i%=0 TO Tasks% - 1
        j%=INSTR($$mem%, Task$(i%))
        IF j% THEN
          mem%+=j%
        ELSE
          n%+=1
          PRINT " -" Task$(i%)
        ENDIF
      NEXT
      PRINT "Total is: ";n% '
      ENDPROC

      REM -------------------------------------------------------------------------
      REM Stitch the pages for this category together in the memory block.
      DEF PROCFetchData(category$)
      LOCAL mem%, continue$, e%, f%, tempfile$, url$

      tempfile$=@tmp$ + "result.json"
      mem%=Blk%
      REPEAT
        url$="http://www.rosettacode.org/w/api.php?" +\
        \    "action=query&list=categorymembers&cmtitle=Category:" + category$ +\
        \    "&cmlimit=500&format=json&cmcontinue=" + continue$
  
        SYS U%, 0, url$, tempfile$, 0, 0 TO e%      : REM Get one page to a file
        IF e% ERROR 100, "Can't get data from Rosetta API"
  
        f%=OPENINtempfile$ : e%=EXT#f% : CLOSE#f%   : REM Get file size
        IF mem% - Blk% + e% > BlkSize% ERROR 100, "Insufficient memory to load data"
        OSCLI "LOAD " + tempfile$ + " " + STR$~mem% : REM Append to previous
        e%=mem% + e%
        ?e%=0                                       : REM Terminating 0x00
        continue$=FNValue(mem%, "cmcontinue")       : REM Loaded page contains this name?
        mem%=e%                                     : REM Advance memory pointer
      UNTIL continue$ == ""
      ENDPROC

      REM -------------------------------------------------------------------------
      REM Retrieve value for a JSON name from address p% and advance p% afterwards.
      DEF FNValue(RETURN p%, name$)
      LOCAL s%

      name$=Q$ + name$ + Q$ + ":"
      s%=INSTR($$p%, name$)
      IF s% == 0 THEN =""
      p%+=s% + LENname$
      =LEFT$($$p%, INSTR($$p%, Q$) - 1)
Output:
Unimplemented tasks for the 'BBC_BASIC' programming language:
 -100 prisoners
 -15 puzzle solver
 -21 game
  ......
 -Zhang-Suen thinning algorithm
 -Zsigmondy numbers
 -Zumkeller numbers
Total is: 697

Unimplemented tasks for the 'C++' programming language:
 -Abelian sandpile model/Identity
 -Achilles numbers
 -Add a variable to a class instance at runtime
  ......
 -Yahoo! search interface
 -Zsigmondy numbers
 -Zumkeller numbers
Total is: 172

C#

Using JSON (not parsed, just Regex.)

To help demonstrate paging, the cmlimit parameter has been omitted from the search query so that 10 rows are returned by default

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Net;

class Program {
    static List<string> GetTitlesFromCategory(string category) {
        string searchQueryFormat = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:{0}&format=json{1}";
        List<string> results = new List<string>();
        string cmcontinue = string.Empty;

        do {
            string cmContinueKeyValue;

            //append continue variable as needed
            if (cmcontinue.Length > 0)
                cmContinueKeyValue = String.Format("&cmcontinue={0}", cmcontinue);
            else
                cmContinueKeyValue = String.Empty;

            //execute query
            string query = String.Format(searchQueryFormat, category, cmContinueKeyValue);
            string content = new WebClient().DownloadString(query);

            results.AddRange(new Regex("\"title\":\"(.+?)\"").Matches(content).Cast<Match>().Select(x => x.Groups[1].Value));

            //detect if more results are available
            cmcontinue = Regex.Match(content, @"{""cmcontinue"":""([^""]+)""}", RegexOptions.IgnoreCase).Groups["1"].Value;                
        } while (cmcontinue.Length > 0);

        return results;
    }

    static string[] GetUnimplementedTasksFromLanguage(string language) {
        List<string> alltasks = GetTitlesFromCategory("Programming_Tasks");
        List<string> lang = GetTitlesFromCategory(language);

        return alltasks.Where(x => !lang.Contains(x)).ToArray();
    }

    static void Main(string[] args) {
        string[] unimpl = GetUnimplementedTasksFromLanguage(args[0]);

        foreach (string i in unimpl) Console.WriteLine(i);
    }
}

Clojure

This uses a couple of core libraries, and a Java method for URL encoding.

(require
  '[clojure.xml :as xml]
  '[clojure.set :as set]
  '[clojure.string :as string])
(import '[java.net URLEncoder])

The titles-cont function fetches and parses an XML response, and walks over it extracting titles. It also extracts the cmcontinue value, if present. Returns a pair [titles,cmcontinue].

(defn titles-cont [url]
  (let [docseq (-> url xml/parse xml-seq)]
    ((juxt #(filter string? %), #(-> (filter map? %) first :cmcontinue))
      (for [{:keys [tag attrs content]} docseq :when (#{:cm :query-continue} tag)]
        (if (= tag :cm)
          (attrs :title)
          (-> content first :attrs))))))

The get-titles function has 1- and 2-argument versions. The former takes the name of a category, composes the appropriate URL query, and calls the 2-argument version. The 2-argument version gets a title list (with possible cmcontinue value), chaining further calls as necessary into the lazy sequence result.

(defn urlencode [s] (URLEncoder/encode s "UTF-8"))
(defn param [p v] (str p (urlencode v)))

(defn get-titles
  ([category]
    (let [urlbase "http://www.rosettacode.org/w/api.php"
          params ["action=query"
                  "list=categorymembers"
                  "format=xml"
                  "cmlimit=200"
                  (param "cmtitle=Category:" category)]
          url (str urlbase "?" (string/join "&" params)]
      (get-titles url nil)))
  ([url continue-at]
    (let [continue-param (if continue-at (param "&cmcontinue=" continue-at))
          [titles continue] (titles-cont (str url continue-param))]
      (if continue
        (lazy-cat titles (get-titles url continue))
        titles))))

The unimplemented function gets a set of all titles and of language-implemented titles and returns the difference. It uses future in order to do the necessary URL requests in parallel.

(defn unimplemented [lang-name]
  (let [title-set #(future (apply sorted-set (get-titles %)))
        all-titles (title-set "Programming_Tasks")
        lang-titles (title-set lang-name)]
    (seq (set/difference @all-titles @lang-titles))))

(let [titles (unimplemented "Clojure")]
  (doseq [title titles] (println title))
  (println "count: " (count titles)))
(shutdown-agents)

E

Using JSON.

#!/usr/bin/env rune

# NOTE: This program will not work in released E, because TermL is an 
# imperfect superset of JSON in that version: it does not accept "\/".
# If you build E from the latest source in SVN then it will work.
#
# Usage: rosettacode-cat-subtract.e [<syntaxhighlight lang="e">]
#
# Prints a list of tasks which have not been completed in the language.
# If unspecified, the default language is E.

pragma.syntax("0.9")
pragma.enable("accumulator")

def termParser := <import:org.quasiliteral.term.makeTermParser>
def jURLEncoder := <unsafe:java.net.makeURLEncoder>

def urlEncode(text) {
  return jURLEncoder.encode(text, "UTF-8")
}

/** Convert JSON-as-term-tree to the corresponding natural E data structures. */
def jsonTermToData(term) {
    switch (term) {

        # JSON object to E map
        match term`{@assocs*}` {
            return accum [].asMap() for term`@{key :String}: @valueJson` in assocs {
                _.with(key, jsonTermToData(valueJson))
            }
        }

        # JSON array to E list
        match term`[@elements*]` {
            return accum [] for elem in elements { _.with(jsonTermToData(elem)) }
        }
        
        # Literals just need to be coerced
        match lit :any[String, int, float64] {
            return lit
        }
        
        # Doesn't support true/false/null, but we don't need that for this application.
    }
}

def fetchCategoryAccum(name, membersSoFar :Set, extraArgs) {
    stderr.println(`Fetching Category:$name $extraArgs...`)
    
    def categoryAPIResource := <http>[`//rosettacode.org/w/api.php?` +
        `action=query&list=categorymembers&cmtitle=Category:${urlEncode(name)}&` +
        `format=json&cmlimit=500&cmprop=title$extraArgs`]
    
    def members :=
      when (def responseJSON := categoryAPIResource <- getTwine()) -> {
        # stderr.println(`Fetched Category:$name $extraArgs, parsing...`)
        def response := jsonTermToData(termParser(responseJSON))

        # stderr.println(`Parsed Category:$name $extraArgs response, extracting data...`)
        def [
          "query" => ["categorymembers" => records],
          "query-continue" => continueData := null
        ] := response
        def members := accum membersSoFar for record in records { _.with(record["title"]) }
        
        switch (continueData) {
          match ==null { 
            stderr.println(`Got all ${members.size()} for Category:$name.`)
            members
          }
          match ["categorymembers" => ["cmcontinue" => continueParam]] {
            stderr.println(`Fetched ${members.size()} members for Category:$name...`)
            fetchCategoryAccum(name, members, `&cmcontinue=` + urlEncode(continueParam))
          }
        }
    } catch p { throw(p) }
    
    return members
}

def fetchCategory(name) {
  return fetchCategoryAccum(name, [].asSet(), "")
}

# Interpret program arguments
def lang := switch (interp.getArgs()) {
  match [lang] { lang }
  match [] { "E" }
}

# Fetch categories
when (def allTasks := fetchCategory("Programming_Tasks"),
      def doneTasks := fetchCategory(lang),
      def omitTasks := fetchCategory(lang + "/Omit")
     ) -> {
    
    # Compute difference and report
    def notDoneTasks := allTasks &! (doneTasks | omitTasks)
    println()
    println("\n".rjoin(notDoneTasks.getElements().sort()))

} catch p {
    # Whoops, something went wrong
    stderr.println(`$p${p.eStack()}`)
}

Erlang

init_http/0 is used by many tasks. rosetta_code_list_of/1 is used by Rosetta_Code/Rank_languages_by_popularity

-module( find_unimplemented_tasks ).
-include_lib( "xmerl/include/xmerl.hrl" ).
 
-export( [init_http/0, per_language/1, rosetta_code_list_of/1] ).

init_http() ->
	application:start( inets ).

per_language( Language ) ->
	ok = init_http(),
	Tasks = rosetta_code_list_of( "Programming_Tasks" ),
	Uninplemented = Tasks -- rosetta_code_list_of( Language ),
	io:fwrite( "Unimplemented total: ~p~n", [erlang:length(Uninplemented)] ),
	[io:fwrite("~p~n", [X]) || X <- Uninplemented].

rosetta_code_list_of( Category ) ->
	URL = "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmlimit=500&format=xml&cmtitle=Category:"
	++ Category,
	title_contents( URL, "", [] ).



title_contents( URL, Continue, Acc ) ->
	{ok, {{_HTTP,200,"OK"}, _Headers, Body}} = httpc:request( URL ++ Continue ),
	{XML, _} = xmerl_scan:string( Body ),
	News = xml_selection( "title", XML ),
	New_continue = title_contents_url_continue( xml_selection("cmcontinue", XML) ),
	title_contents_continue( URL, New_continue, Acc ++ News ).

title_contents_continue( _URL, "", Acc ) -> Acc;
title_contents_continue( URL, Continue, Acc ) -> title_contents( URL, Continue, Acc ).

title_contents_url_continue( [] ) -> "";
title_contents_url_continue( [Continue | _] ) -> "&cmcontinue=" ++ Continue.

xml_selection( Selection, XML ) ->
	[lists:map( fun xml_8211/1, X) || #xmlAttribute{value=X} <- xmerl_xpath:string("//@" ++ Selection, XML)].

xml_8211( 8211 ) -> $-;
xml_8211( 924 ) -> $\s;
xml_8211( 1050 ) -> $\s;
xml_8211( 1052 ) -> $\s;
xml_8211( Character ) -> Character.
Output:
25> find_unimplemented_tasks:per_language("Erlang").
Unimplemented total: 307
"24 game/Solve"
"Abstract type"
"Active Directory/Search for a user"
"Add a variable to a class instance at runtime"
"Address of a variable"
.
.
.
"Yahoo! search interface"
"Yin and yang"
"Zeckendorf arithmetic"
"Zeckendorf number representation"
"Zhang-Suen thinning algorithm"

Go

XML, stepping through the elements.

package main

import (
    "encoding/xml"
    "fmt"
    "io"
    "net/http"
    "net/url"
)

const language = "Go"

var baseQuery = "http://rosettacode.org/mw/api.php?action=query" +
    "&format=xml&list=categorymembers&cmlimit=100"

func req(u string, foundCm func(string)) string {
    resp, err := http.Get(u)
    if err != nil {
        fmt.Println(err) // connection or request fail
        return ""
    }
    defer resp.Body.Close()
    for p := xml.NewDecoder(resp.Body); ; {
        t, err := p.RawToken()
        switch s, ok := t.(xml.StartElement); {
        case err == io.EOF:
            return ""
        case err != nil:
            fmt.Println(err)
            return ""
        case !ok:
            continue
        case s.Name.Local == "cm":
            for _, a := range s.Attr {
                if a.Name.Local == "title" {
                    foundCm(a.Value)
                }
            }
        case s.Name.Local == "categorymembers" && len(s.Attr) > 0 &&
            s.Attr[0].Name.Local == "cmcontinue":
            return url.QueryEscape(s.Attr[0].Value)
        }
    }
    return ""
}

func main() {
    // get language members, store in a map
    langMap := make(map[string]bool)
    storeLang := func(cm string) { langMap[cm] = true }
    languageQuery := baseQuery + "&cmtitle=Category:" + language
    continueAt := req(languageQuery, storeLang)
    for continueAt > "" {
        continueAt = req(languageQuery+"&cmcontinue="+continueAt, storeLang)
    }

    // a quick check to avoid long output
    if len(langMap) == 0 {
        fmt.Println("no tasks implemented for", language)
        return
    }

    // get tasks, print as we go along
    printUnImp := func(cm string) {
        if !langMap[cm] {
            fmt.Println(cm)
        }
    }
    taskQuery := baseQuery + "&cmtitle=Category:Programming_Tasks"
    continueAt = req(taskQuery, printUnImp)
    for continueAt > "" {
        continueAt = req(taskQuery+"&cmcontinue="+continueAt, printUnImp)
    }
}

Haskell

Library: HTTP XML
from HackageDB
import Network.Browser
import Network.HTTP
import Network.URI
import Data.List
import Data.Maybe
import Text.XML.Light
import Control.Arrow
import Data.Char
  
getRespons url = do
  rsp <- Network.Browser.browse $ do
    setAllowRedirects True
    setOutHandler $ const (return ())   -- quiet
    request $ getRequest url
  return $ rspBody $ snd rsp

replaceWithSpace c = (\x -> if c==x then ' ' else x)  

encl = chr 34

unimpTasks lang = do
  allTasks <- getRespons "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml"
  impl <-  getRespons ( "http://rosettacode.org/json/isb/" ++ lang ++ ".json")
  let langxx = map (map(replaceWithSpace '_')) $ filter (/=",") $ words $ map (replaceWithSpace encl ) $ init $ drop 1 impl
      xml = onlyElems $ parseXML allTasks
      allxx = concatMap (map (fromJust.findAttr (unqual "title")). filterElementsName (== unqual "cm")) xml
  mapM_ putStrLn $ sort $ allxx \\ langxx

With only standard libraries

import Network.HTTP
import Data.Text (splitOn, pack, unpack)
import Data.List

getTasks :: String -> IO [String]
getTasks url = do
  resp <- simpleHTTP (getRequest url)
  body <- getResponseBody resp
  return $ tail $ map (unpack . head . splitOn  (pack "\"}")) $ splitOn (pack "\"title\":\"") (pack body)

main :: String -> IO ()
main lang = do
  implTasks <- getTasks $ "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:" ++ lang ++ "&format=json&cmlimit=500"
  allTasks <- getTasks "http://rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&format=json&cmlimit=500"
  mapM_ putStrLn $ allTasks \\ implTasks

Icon and Unicon

The following code only works in Unicon.

$define RCINDEX "http://rosettacode.org/mw/api.php?format=xml&action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500"
$define RCTASK  "http://rosettacode.org/mw/index.php?action=raw&title="
$define RCUA    "User-Agent: Unicon Rosetta 0.1"
$define RCXUA   "X-Unicon: http://unicon.org/"
$define TASKTOT "* Total Tasks *"
$define TOTTOT  "* Total Headers*"
 
link strings     
link hexcvt     
 
procedure main(A)   # simple single threaded read all at once implementation
    lang := \A[1] | "Unicon"
    write("Unimplemented tasks for ",lang," as of ",&date)
    every task := taskNames() do {
       if lang == languages(task) then next
       write(task)
       }
end

# Generate task names
procedure taskNames()
    continue := ""
    while \(txt := ReadURL(RCINDEX||continue)) do {
        txt ? {
            while tab(find("<cm ") & find(s :="title=\"")+*s) do
                suspend tab(find("\""))\1
            if tab(find("cmcontinue=")) then {
                continue := "&"||tab(upto(' \t'))
                }
            else break
            }
        }
end

# Generate language headers in a task
procedure languages(task)
    static WS
    initial WS := ' \t'
    page := ReadURL(RCTASK||CleanURI(task))
    page ? while (tab(find("\n==")),tab(many(WS))|"",tab(find("{{"))) do {
               header := tab(find("=="))
               header ? {
                   while tab(find("{{header|")) do {
                       suspend 2(="{{header|",tab(find("}}")))\1
                       }
                   }
               }
end
 
procedure CleanURI(u)                  #: clean up a URI
    static tr,dxml                     # xml & http translation
    initial {
       tr := table()
       every c := !string(~(&digits++&letters++'-_.!~*()/\'`')) do 
          tr[c] := "%"||hexstring(ord(c),2)
       every /tr[c := !string(&cset)] := c
       tr[" "] := "_"                                      # wiki convention
       every push(dxml := [],"&#"||right(ord(c := !"&<>'\""),3,"0")||";",c)
       }
 
    dxml[1] := u                       # insert URI as 1st arg
    u := replacem!dxml                 # de-xml it
    every (c := "") ||:= tr[!u]        # reencode everything
    c := replace(c,"%3E","'")          # Hack to put single quotes back in
    c := replace(c,"%26quot%3B","\"")  # Hack to put double quotes back in
    return c   
end
 
procedure ReadURL(url)                 #: read URL into string
    page := open(url,"m",RCUA,RCXUA) | stop("Unable to open ",url)
    text := ""
    if page["Status-Code"] < 300 then while text ||:= reads(page,-1)
    else write(&errout,image(url),": ",
                       page["Status-Code"]," ",page["Reason-Phrase"])
    close(page)
    return text
end

Sample output (abridged):

Unimplemented tasks for Unicon as of 2013/07/06:
==================================================
9_billion_names_of_God_the_integer
Active_Directory/Connect
Active_Directory/Search_for_a_user
Active_object
Address_of_a_variable
Arena_storage_pool
Atomic_updates
Balanced_ternary
...
XML/Input
XML/Output
XML/XPath
Y combinator
Zebra puzzle
Zeckendorf arithmetic
Zeckendorf number representation

J

Solution:

require 'strings web/gethttp'

findUnimpTasks=: ('Programming_Tasks' -.&getCategoryMembers ,&'/Omit') ([ #~ -.@e.) getCategoryMembers

getTagContents=: dyad define
  'starttag endtag'=. x
  ('\' -.~ endtag&taketo)&.>@(starttag&E. <@((#starttag)&}.);.1 ]) y
)

NB. RosettaCode Utilities
parseTitles=: ('"title":"';'"')&getTagContents
parseCMcontinue=:('"cmcontinue":"';'"')&getTagContents
getCMcontquery=: ('&cmcontinue=' , urlencode)^:(0 < #)@>@parseCMcontinue

getCategoryMembers=: monad define
  buildqry=. 'action=query&list=categorymembers&cmtitle=Category:' , ,&'&cmlimit=500&format=json'
  url=.'http://www.rosettacode.org/w/api.php'
  uri=. url ,'?', buildqry urlencode y
  catmbrs=. qrycont=. ''
  whilst. #qrycont=. ,getCMcontquery jsondat do.
    jsondat=. '-sL' gethttp uri , qrycont
    catmbrs=. catmbrs, parseTitles jsondat
  end.
  catmbrs
)

Note that gethttp currently requires the '-sL' to follow redirects.

Example Usage:

   4{. findUnimpTasks 'J'     NB. get first 4 unimplemented tasks for J
┌────────────────┬────────────────────────┬──────────────────────────────────┬──────────────┐
15 puzzle solverActive Directory/ConnectActive Directory/Search for a userAtomic updates
└────────────────┴────────────────────────┴──────────────────────────────────┴──────────────┘

JavaScript

The isolation of in-browser JavaScript from system resources, and the association of JavaScript code files with particular (and already loaded) documents may mean that JavaScript is not the right tool for the broader case envisaged by this task.

For the narrower context of a browser in which the 'not implemented' page has been fetched for a particular language, we can however, evaluate an XPath expression in JavaScript to generate an array of titles for the unimplemented tasks.

(function (strXPath) {
  var xr = document.evaluate(
      strXPath,
      document,
      null, 0, 0
    ),

    oNode = xr.iterateNext(),
    lstTasks = [];

  while (oNode) {
    lstTasks.push(oNode.title);
    oNode = xr.iterateNext();
  }

  return [
    lstTasks.length + " items found in " + document.title,
    ''
  ].concat(lstTasks).join('\n')

})(
  '//*[@id="mw-content-text"]/div[2]/table/tbody/tr/td/ul/li/a'
);

Output begins with:

107 items found in Reports:Tasks not implemented in Haskell - Rosetta Code

Active Directory/Connect
Active Directory/Search for a user
Bitmap/Bézier curves/Cubic
Bitmap/PPM conversion through a pipe
Bitmap/Read an image through a pipe
Call a function in a shared library
Call an object method
Canny edge detector
Casting out nines
Catmull–Clark subdivision surface
Color of a screen pixel
Colour bars/Display
Colour pinstripe/Display
Colour pinstripe/Printer
Compare sorting algorithms' performance
Conjugate transpose
Create a file on magnetic tape
Death Star
Deconvolution/2D+
Delegates
Executable library
Extreme floating point values
FTP
Fibonacci word/fractal
Find limit of recursion
...

jq

This script illustrates how jq interoperates with other command-line tools. It was tested in October, 2022 using both the C and Go implementations of jq.

The only pre-requisites other than bash are curl and jq, which is called at least five times.

#!/bin/bash
# October 8, 2022
# https://rosettacode.org/w/index.php?title=Rosetta_Code/Find_unimplemented_tasks

# Syntax: $0 [--markdown] CATEGORY

# Fetch the Category:Programming_Tasks and Category:$category pages,
# then compute the differences in the lists of titles.
# If --markdown is specified, then some markdown suitable for RosettaCode.org is added.

BN=$(basename "$0")
JQ=jq

function die     { echo "$BN: $@" >&2 ; exit 1 ; }

baseuri="https://rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:"

if [ "$1" = "--markdown" ] ; then 
  markdown="--argjson markdown true"
  shift
 else 
  markdown="--arg markdown false"
fi

category="$1"
test  -z "$category" && die "Syntax: $0 [--markdown] CATEGORY"

for id in $category Programming_Tasks; do
    id=/tmp/rosettacode.$id.titles.json
    test -s "$id" && rm "$id"
done

function getall {
    local cat="$1"
    local cmcontinue="$2"
    local tmpfile="/tmp/rosettacode.$cat.json.tmp"
 
    # cmlimit=500 is the max allowed so use paging
    curl -Ss "${baseuri}${cat}&format=json&cmlimit=500${cmcontinue}" > "$tmpfile"
    if [ ! -s "$tmpfile" ] ; then return ; fi

    $JQ '.query.categorymembers[].title' "$tmpfile" >> /tmp/rosettacode.$cat.titles.json
    cmcontinue=$($JQ -r '.continue | if . then .cmcontinue else null end' "$tmpfile" )

    if [ -z "$cmcontinue" -o "$cmcontinue" = "null" ] ; then return ; fi
    echo $BN: fetching continuation page for $cat ...
    getall "$cat" "&cmcontinue=$cmcontinue"
}

getall $category
getall Programming_Tasks
for id in $category Programming_Tasks; do
    id=/tmp/rosettacode.$id.titles.json
    test -s "$id" || die "unable to find $id"
done

$JQ -r -n $markdown --slurpfile tasks /tmp/rosettacode.Programming_Tasks.titles.json \
                    --slurpfile cat /tmp/rosettacode.$category.titles.json '
  def mark: if $markdown then "* [[\(gsub(" ";"_"))|\(.)]]" else . end;
  ($tasks - $cat)[] | mark '

Julia

using HTTP, JSON

const baseuri = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:"
const enduri = "&cmlimit=500&format=json"
queries(x) = baseuri * HTTP.Strings.escapehtml(x) * enduri

function getimplemented(query)
    tasksdone = Vector{String}()
    request = query
    while (resp = HTTP.request("GET", request)).status == 200
        fromjson = JSON.parse(String(resp.body))
        for d in fromjson["query"]["categorymembers"]
            if haskey(d, "title")
                push!(tasksdone, d["title"])
            end
        end
        if haskey(fromjson, "continue")
            cmcont, cont = fromjson["continue"]["cmcontinue"], fromjson["continue"]["continue"]
            request = query * "&cmcontinue=$cmcont&continue=$cont"
        else
            break
        end
    end
    tasksdone
end

alltasks = getimplemented(queries("Programming_Tasks"))

showunimp(x) = (println("\nUnimplemented in $x:"); for t in setdiff(alltasks,
    getimplemented(queries(x))) println(t) end)

showunimp("Julia")
showunimp("C++")
Output:
Unimplemented in Julia:
Active Directory/Connect
Active Directory/Search for a user
AVL tree
Catmull–Clark subdivision surface
Colour pinstripe/Printer
Create a file on magnetic tape
Deconvolution/2D+
Joystick position
Machine code
OLE Automation
OpenGL
Pattern matching
Pinstripe/Printer
Play recorded sounds
Rosetta Code/Find unimplemented tasks
Simulate input/Keyboard
SOAP
Speech synthesis
Suffixation of decimal numbers
Superpermutation minimisation
Sutherland-Hodgman polygon clipping
Use another language to call a function
Yahoo! search interface

Unimplemented in C++:
15 puzzle solver
Abbreviations, automatic
Abbreviations, easy
Abbreviations, simple
Add a variable to a class instance at runtime
Balanced ternary
Brace expansion
Break OO privacy
Calendar - for "REAL" programmers
Call a foreign-language function
Call an object method
Casting out nines
Check Machin-like formulas
Church Numerals
Colour pinstripe/Printer
Commatizing numbers
Constrained genericity
Cuban primes
Define a primitive data type
Dynamic variable names
Eban numbers
Eertree
Egyptian fractions
Factorial base numbers indexing permutations of a collection
First-class functions/Use numbers analogously
Fixed length records
Four is magic
Four is the number of letters in the ...
Hash join
History variables
HTTPS/Client-authenticated
Hunt The Wumpus
Idiomatically determine all the characters that can be used for symbols
Idiomatically determine all the lowercase and uppercase letters
Imaginary base numbers
Index finite lists of positive integers
Inheritance/Multiple
Interactive programming
Joystick position
Knuth's power tree
Law of cosines - triples
Lucky and even lucky numbers
Lychrel numbers
Mayan numerals
Mind boggling card trick
Nested templated data
Nonoblock
Nonogram solver
Object serialization
OLE Automation
OpenWebNet Password
Order disjoint list items
Partition an integer X into N primes
Pattern matching
Pig the dice game
Pig the dice game/Player
Pinstripe/Printer
Play recorded sounds
Ramer-Douglas-Peucker line simplification
Range consolidation
Reflection/Get source
Reflection/List methods
Reflection/List properties
Respond to an unknown method call
RIPEMD-160
Rosetta Code/Count examples
Rosetta Code/Find bare lang tags
Rosetta Code/Find unimplemented tasks
Rosetta Code/Fix code tags
Runtime evaluation
Runtime evaluation/In an environment
Safe primes and unsafe primes
Send an unknown method call
Solve a Holy Knight's tour
Solve a Hopido puzzle
Solve a Numbrix puzzle
Solve the no connection puzzle
Sort a list of object identifiers
Spelling of ordinal numbers
Strong and weak primes
Suffixation of decimal numbers
Sum and Product Puzzle
Textonyms
Topic variable
Twelve statements
URL parser
Video display modes
Word search
World Cup group stage
Yahoo! search interface
Zeckendorf arithmetic

Lua

Works with: Lua version 5.1 - 5.3
Library: lua-requests
local requests = require('requests')
local lang = arg[1]

local function merge_tables(existing, from_req)
  local result = existing

  for _, v in ipairs(from_req) do
      result[v.title] = true
  end

  return result
end

local function get_task_list(category)
  local url = 'http://www.rosettacode.org/mw/api.php'
  local query = {
    action = 'query',
    list = 'categorymembers',
    cmtitle = string.format('Category:%s', category),
    cmlimit = 500,
    cmtype = 'page',
    format = 'json'
  }
  local categories = {}

  while true do
    local resp = assert(requests.get({ url, params = query }).json())

    categories = merge_tables(categories, resp.query.categorymembers)
    
    if resp.continue then
      query.cmcontinue = resp.continue.cmcontinue
    else
      break
    end
  end

  return categories
end
    
local function get_open_tasks(lang)
  if not lang then error('Language missing!') end
  local all_tasks = get_task_list('Programming_Tasks')
  local lang_tasks = get_task_list(lang)
  local task_list = {}
  
  for t, _ in pairs(all_tasks) do
    if not lang_tasks[t] then
      table.insert(task_list, t)
    end
  end
  
  table.sort(task_list)
  return task_list
end

local open_tasks = get_open_tasks(lang)

io.write(string.format('%s has %d unimplemented programming tasks: \n', lang, #open_tasks))
for _, t in ipairs(open_tasks) do
  io.write(string.format('  %s\n', t))
end
Output:
Python has 24 unimplemented programming tasks:
  15 puzzle solver
  Bitmap/PPM conversion through a pipe
  Bitmap/Read an image through a pipe
                 ...

Maple

#Example with the Maple Language
lan := "Maple":
x := URL:-Get(cat("http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_", StringTools:-SubstituteAll(lan, " ", "_")), output = content):
x := StringTools:-StringSplit(x, "<h2><span class=\"mw-headline\" id=\"Not_implemented\">Not implemented</span>")[2]:
x := StringTools:-StringSplit(x, "<span class=\"mw-headline\" id=\"Draft_tasks_without_implementation\">Draft tasks without implementation</span>")[1]:
x := StringTools:-StringSplit(x,"<li><a href=\"/wiki/")[2..]:
for problem in x do
	printf("%s\n", StringTools:-SubstituteAll(StringTools:-Decode(StringTools:-StringSplit(problem, "\" title=")[1], 'percent'), "_", " "));
end do:
Output:
#10:09 AM 10/05/2018
15 Puzzle Game
15 puzzle solver
24 game/Solve
4-rings or 4-squares puzzle
9 billion names of God the integer
AVL tree
...
Xiaolin Wu's line algorithm
Yahoo! search interface
Yin and yang
Zebra puzzle
Zeckendorf arithmetic
Zeckendorf number representation
Zhang-Suen thinning algorithm
Zig-zag matrix

Mathematica/Wolfram Language

Two implementations are considered, the first will use the API to get all the programming tasks, then the ones implemented for a certain language, and take the difference. The other will use the Tasks not implemented page and strip the html.

ClearAll[ImportAll]
ImportAll[lang_String] := 
 Module[{data, continue, cmcontinue, extra, xml, next},
  data = {};
  continue = True;
  cmcontinue = "";
  While[continue,
   extra = If[cmcontinue =!= "", "&cmcontinue=" <> cmcontinue, ""];
   xml = Import["http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:" <> lang <> "&cmlimit=500&format=xml" <> extra, "XML"];
   AppendTo[data, Cases[xml, XMLElement["cm", _, {}], \[Infinity]]];
   next = Flatten[Cases[xml, {"cmcontinue" -> _}, \[Infinity]]];
   If[Length[next] > 0,
    next = First[next];
    cmcontinue = "cmcontinue" /. next;
    ,
    continue = False;
    ];
   ];
  Cases[Flatten[data], HoldPattern["title" -> x_] :> x, \[Infinity]]
  ]
Complement[ImportAll["Programming_Tasks"], ImportAll["Mathematica"]]

which outputs a list of items not implemented:

Output:
{Abstract type,Active Directory/Connect,Active Directory/Search for a user,Address of a variable,<<139>>,Write to Windows event log,Xiaolin Wu's line algorithm,Zeckendorf arithmetic}

Another method is by getting the Tasks not implemented page:

url = "http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_Mathematica";
html = Import[url, "XMLObject"];
pos = Position[html, XMLElement["div", {"class" -> "mw-content-ltr", "dir" -> "ltr", "lang" -> "en"}, ___]];
pos = First[pos];
data = Extract[html, pos];
pos = Position[data, XMLElement["li", {}, {XMLElement["a", {"shape" -> "rect", "href" -> _, "title" -> x_}, {x_}]}]];
data = Extract[data, pos];
data = data[[All, -1, -1, 2]];
data = {"title", "href"} /. # & /@ %;
data[[All, 2]] = "http://rosettacode.org" <> # & /@ data[[All, 2]];
newb = data[[All, 1]];
data = Hyperlink @@@ data;
data // Column
Output:
Append a record to the end of a text file
Arithmetic-geometric mean/Calculate Pi
Atomic updates
Bitcoin/address validation
Bitmap/PPM conversion through a pipe
Bitmap/Read an image through a pipe
...

Nim

import httpclient, strutils, xmltree, xmlparser, cgi, os


proc findrc(category: string): seq[string] =

  var
    name = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:$#&cmlimit=500&format=xml" % encodeUrl(category)
    cmcontinue = ""
    client = newHttpClient()

  while true:
    var x = client.getContent(name & cmcontinue).parseXml()
    for node in x.findAll("cm"):
      result.add node.attr("title")

    cmcontinue.setLen(0)
    for node in x.findAll("continue"):
      let u = node.attr("cmcontinue")
      if u.len != 0: cmcontinue = u.encodeUrl()

    if cmcontinue.len > 0: cmcontinue = "&cmcontinue=" & cmcontinue
    else: break


proc chooselang(): string =
  if paramCount() < 1: "Nim" else: paramStr(1)


let alltasks = findrc("Programming_Tasks")
let lang = chooselang()
let langTasks = lang.findrc()
echo "Unimplemented tasks for language ", lang, ':'
for task in alltasks:
  if task notin langTasks:
    echo "  ", task
Output:
./unimplemented_tasks Nim
Unimplemented tasks for language Nim:
  Active Directory/Connect
  Active Directory/Search for a user
  Function frequency
  HTTPS/Client-authenticated
  Hunt the Wumpus
  Inheritance/Multiple
  Joystick position

Oz

Library: OzHttpClient

By parsing XML and using an XPath-like mechanism:

declare
  [HTTPClient] = {Link ['x-ozlib://mesaros/net/HTTPClient.ozf']}
  [XMLParser] = {Link ['x-oz://system/xml/Parser.ozf']}

  fun {FindUnimplementedTasks Language}
     AllTasks = {FindCategory "Programming Tasks"}
     LangTasks = {FindCategory Language}
  in
     {ListDiff AllTasks LangTasks}
  end
  
  fun {FindCategory Cat}
     CatUrl = "http://www.rosettacode.org/mw/api.php?action=query"
     #"&list=categorymembers"
     #"&cmtitle=Category:"#{PercentEncode Cat}
     #"&cmlimit=500&format=xml"

     fun {Loop CMContinue}
        [_ Doc] = {Parse {GetPage CatUrl#CMContinue}}
        Titles = {XPath Doc
                  [api query categorymembers cm {Attribute title}]}
     in
        case {XPath Doc
              [api 'query-continue' categorymembers {Attribute cmcontinue}]}
        of nil then Titles
        [] [NewCMContinueAtom] then
           NewCMContinue = {PercentEncode {Atom.toString NewCMContinueAtom}}
        in
           {Append Titles
            {Loop "&cmcontinue="#NewCMContinue}}
        end
     end
  in
     {Loop nil}
  end

  
  %% XPath emulation
  fun {XPath Doc Path}
     P|Pr = Path
  in
     Doc.name = P %% assert
     {FoldL Pr XPathStep [Doc]}
  end

  Nothing = {NewName}
  fun {NotNothing X} X \= Nothing end
  
  fun {XPathStep Elements P}
     if {Atom.is P} then
        {FilteredChildren Elements P}
     elseif {Procedure.is P} then
        {Filter {Map Elements P} NotNothing}
     end
  end
 
  %% A flat list of all Type-children of all Elements.
  fun {FilteredChildren Elements Type}
     {Flatten
      {Map Elements
       fun {$ E}
          {Filter E.children
           fun {$ X}
              case X of element(name:!Type ...) then true
              else false
              end
           end}
       end}}
  end
 
  fun {Attribute Attr}
     fun {$ Element}
        case {Filter Element.attributes fun {$ A} A.name == Attr end}
        of [A] then A.value
        else Nothing
        end
     end
  end

  
  %% GetPage
  Client = {New HTTPClient.urlGET init(inPrms(toFile:false toStrm:true) _)}
  fun {GetPage RawUrl}
     Url = {VirtualString.toString RawUrl}
     OutParams
  in
     {Client getService(Url ?OutParams ?_)}
     OutParams.sOut
  end
 
  fun {PercentEncode Xs}
     case Xs of nil then nil
     [] X|Xr then
        if {Char.isDigit X} orelse {Member X [&- &_ &.  &~]}
           orelse X >= &a andthen X =< &z
           orelse X >= &z andthen X =< &Z then
           X|{PercentEncode Xr}
        else
           {Append &%|{ToHex2 X} {PercentEncode Xr}}
        end
     end
  end
  
  fun {ToHex2 X}
     [{ToHex1 X div 16} {ToHex1 X mod 16}]
  end
  
  fun {ToHex1 X}
     if X >= 0 andthen X =< 9 then &0 + X
     elseif X >= 10 andthen X =< 15 then &A + X - 10
     end
  end

  
  %% Parse
  local
     Parser = {New XMLParser.parser init} 
  in
     fun {Parse Xs} {Parser parseVS(Xs $)} end
  end

  fun {ListDiff Xs Ys}
     {FoldL Ys List.subtract Xs}
  end
in
  %% show tasks not implemented in Oz
  {ForAll {FindUnimplementedTasks "Oz"} System.showInfo}

Perl

use LWP::UserAgent;

my $ua = LWP::UserAgent->new;
$ua->agent('');

sub enc { join '', map {sprintf '%%%02x', ord} split //, shift }
sub get { $ua->request( HTTP::Request->new( GET => shift))->content }

sub tasks {
    my($category) = shift;
    my $fmt = 'http://www.rosettacode.org/w/api.php?' .
              'action=query&generator=categorymembers&gcmtitle=Category:%s&gcmlimit=500&format=json&rawcontinue=';
    my @tasks;
    my $json = get(sprintf $fmt, $category);
    while (1) {
        push @tasks, $json =~ /"title":"(.+?)"\}/g;
        $json =~ /"gcmcontinue":"(.+?)"\}/ or last;
        $json = get(sprintf $fmt . '&gcmcontinue=%s', $category, enc $1);
    }
    @tasks;
}

my %language = map {$_, 1} tasks shift || 'perl';
$language{$_} or print "$_\n" foreach tasks('Programming_Tasks'), tasks('Draft_Programming_Tasks');

See also: User:ImplSearchBot/Code

Phix

Note that Rosetta_Code/Tasks_without_examples#Phix with summary=true and output_html=false does much that same via web scraping, whereas this uses the web api.

Library: Phix/libcurl
Translation of: Go
-- demo\rosetta\Find_unimplemented_tasks.exw
without js -- (libcurl, file i/o, peek, progress..)
constant language = "Phix",
--       language = "Go",
--       language = "Julia",
--       language = "Python",
--       language = "Wren",
         base_query = "http://rosettacode.org/mw/api.php?action=query"&
                      "&format=xml&list=categorymembers&cmlimit=100"

include builtins\libcurl.e
atom curl = NULL
atom pErrorBuffer
include builtins\xml.e

function req(string url, integer rid)
    if curl=NULL then
        curl_global_init()
        curl = curl_easy_init()
        pErrorBuffer = allocate(CURL_ERROR_SIZE)
        curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, pErrorBuffer)
    end if
    curl_easy_setopt(curl, CURLOPT_URL, url)
    object res = curl_easy_perform_ex(curl)
    if integer(res) then
        string error = sprintf("%d [%s]",{res,peek_string(pErrorBuffer)})
        crash("Download error: %s\n",{error})
    end if
    if not string(res) then ?9/0 end if
    object xml = xml_parse(res)[XML_CONTENTS]
    res = xml_get_nodes(xml,"continue")
    res = iff(res=={}?"":xml_get_attribute(res[1],"cmcontinue"))
    xml = xml_get_nodes(xml,"query")[1]
    xml = xml_get_nodes(xml,"categorymembers")[1]
    xml = xml_get_nodes(xml,"cm")
    for i=1 to length(xml) do
        call_proc(rid,{xml_get_attribute(xml[i],"title")})
    end for
    return res
end function

function html_clean(string ri)
    ri = substitute(ri,`"`,`"`)
    ri = substitute(ri,`'`,`'`)
    ri = substitute(ri,"\xE2\x80\x99","'")
    ri = substitute(ri,"\xC3\xB6","o")
    ri = substitute(ri,"%3A",":")
    ri = substitute(ri,"%E2%80%93","-")
    ri = substitute(ri,"%E2%80%99","'")
    ri = substitute(ri,"%27","'")
    ri = substitute(ri,"%2B","+")
    ri = substitute(ri,"%C3%A8","e")
    ri = substitute(ri,"%C3%A9","e")
    ri = substitute(ri,"%C3%B6","o")
    ri = substitute(ri,"%C5%91","o")
    ri = substitute(ri,"%22",`"`)
    ri = substitute(ri,"%2A","*")
    return ri
end function

sequence titles = {}
procedure store_title(string title)
    titles = append(titles,title)
end procedure

integer unimplemented_count = 0,
        task_count = 0
procedure print_unimplemented(string title)
    if not find(title,titles) then
        title = html_clean(title)
        printf(1,"%s\n",{title})
        unimplemented_count += 1
    end if
    task_count += 1
end procedure

procedure main()
    printf(1,"Loading implemented tasks list...\n")
    -- get and store task itles
    string lang_query := base_query & "&cmtitle=Category:" & language,
           continue_at := req(lang_query, store_title)
    while continue_at!="" do
        continue_at = req(lang_query&"&cmcontinue="&continue_at, store_title)
    end while
 
    -- a quick check to avoid long output
    if length(titles)==0 then
        printf(1,"no tasks implemented for %s\n", {language})
        return
    end if
 
    -- get tasks, print as we go along
    printf(1,"Tasks:\n")
    string task_query := base_query & "&cmtitle=Category:Programming_Tasks"
    continue_at = req(task_query, print_unimplemented)
    while continue_at!="" do
        continue_at = req(task_query&"&cmcontinue="&continue_at, print_unimplemented)
    end while
    printf(1,"%d unimplemented tasks found for %s.\n",{unimplemented_count,language})

    integer full_tasks = unimplemented_count
    printf(1,"Draft tasks:\n")
    task_query := base_query & "&cmtitle=Category:Draft_Programming_Tasks"
    continue_at = req(task_query, print_unimplemented)
    while continue_at!="" do
        continue_at = req(task_query&"&cmcontinue="&continue_at, print_unimplemented)
    end while
    integer draft_tasks = unimplemented_count-full_tasks
    printf(1,"%d unimplemented draft tasks found for %s.\n",{draft_tasks,language})

    printf(1,"%d unimplemented tasks in total found for %s (out of %d).\n",{unimplemented_count,language,task_count})

end procedure
main()
Output:
Abstract type
Active Directory/Connect
Active Directory/Search for a user
...
Yahoo! search interface
78 unimplemented tasks found for Phix.

PicoLisp

(load "@lib/http.l" "@lib/xm.l")

(de rosettaCategory (Cat)
   (let (Cont NIL  Xml)
      (make
         (loop
            (client "rosettacode.org" 80
               (pack
                  "mw/api.php?action=query&list=categorymembers&cmtitle=Category:"
                  Cat
                  "&cmlimit=200&format=xml"
                  Cont )
               (while (line))
               (setq Xml (and (xml?) (xml))) )
            (NIL Xml)
            (for M (body Xml 'query 'categorymembers)
               (link (attr M 'title)) )
            (NIL (attr Xml 'query-continue' categorymembers 'cmcontinue))
            (setq Cont (pack "&cmcontinue=" @)) ) ) ) )

(de unimplemented (Task)
   (diff
      (rosettaCategory "Programming_Tasks")
      (rosettaCategory Task) ) )

PowerShell

I don't think this script follows the spirit of the task, but it works.

function Find-UnimplementedTask
{
    [CmdletBinding()]
    [OutputType([string[]])]
    Param
    (
        [Parameter(Mandatory=$true,
                   Position=0)]
        [string]
        $Language
    )

    $url = "http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_$Language"
    $web = Invoke-WebRequest $url
    $unimplemented = 1

    [string[]](($web.AllElements |
        Where-Object {$_.class -eq "mw-content-ltr"})[$unimplemented].outerText -split "`r`n" |
        Select-String -Pattern "[^0-9A-Z]$" -CaseSensitive)
}
$tasks = Find-UnimplementedTask -Language PowerShell

$tasks[0..5],".`n.`n.",$tasks[-6..-1]
Write-Host "`nTotal unimplemented Tasks: $($tasks.Count)"
Output:
15 Puzzle Game
2048 
24 game/Solve
4-rings or 4-squares puzzle
9 billion names of God the integer
AKS test for primes 
.
.
.
Xiaolin Wu's line algorithm
Yahoo! search interface 
Yin and yang
Zebra puzzle 
Zeckendorf arithmetic 
Zhang-Suen thinning algorithm

Total unimplemented Tasks: 388

Python

Library: mwclient

"""
Given the name of a language on Rosetta Code,
finds all tasks which are not implemented in that language.
"""
from operator import attrgetter
from typing import Iterator

import mwclient

URL = 'www.rosettacode.org'
API_PATH = '/mw/'


def unimplemented_tasks(language: str,
                        *,
                        url: str,
                        api_path: str) -> Iterator[str]:
    """Yields all unimplemented tasks for a specified language"""
    site = mwclient.Site(url, path=api_path)
    all_tasks = site.categories['Programming Tasks']
    language_tasks = site.categories[language]
    name = attrgetter('name')
    all_tasks_names = map(name, all_tasks)
    language_tasks_names = set(map(name, language_tasks))
    for task in all_tasks_names:
        if task not in language_tasks_names:
            yield task


if __name__ == '__main__':
    tasks = unimplemented_tasks('Python', url=URL, api_path=API_PATH)
    print(*tasks, sep='\n')

Library: Requests

"""
Given the name of a language on Rosetta Code,
finds all tasks which are not implemented in that language.
"""
from functools import partial
from operator import itemgetter
from typing import (Dict,
                    Iterator,
                    Union)

import requests

URL = 'http://www.rosettacode.org/mw/api.php'
REQUEST_PARAMETERS = dict(action='query',
                          list='categorymembers',
                          cmlimit=500,
                          rawcontinue=True,
                          format='json')


def unimplemented_tasks(language: str,
                        *,
                        url: str,
                        request_params: Dict[str, Union[str, int, bool]]
                        ) -> Iterator[str]:
    """Yields all unimplemented tasks for a specified language"""
    with requests.Session() as session:
        tasks = partial(tasks_titles,
                        session=session,
                        url=url,
                        **request_params)
        all_tasks = tasks(cmtitle='Category:Programming_Tasks')
        language_tasks = set(tasks(cmtitle=f'Category:{language}'))
        for task in all_tasks:
            if task not in language_tasks:
                yield task


def tasks_titles(*,
                 session: requests.Session,
                 url: str,
                 **params: Union[str, int, bool]) -> Iterator[str]:
    """Yields tasks names for a specified category"""
    while True:
        request = session.get(url, params=params)
        data = request.json()
        yield from map(itemgetter('title'), data['query']['categorymembers'])
        query_continue = data.get('query-continue')
        if query_continue is None:
            return
        params.update(query_continue['categorymembers'])


if __name__ == '__main__':
    tasks = unimplemented_tasks('Python',
                                url=URL,
                                request_params=REQUEST_PARAMETERS)
    print(*tasks, sep='\n')

Library: urllib

Python 2.x

import xml.dom.minidom
import urllib, sys
 
def findrc(category):
    name = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:%s&cmlimit=500&format=xml" % urllib.quote(category)
    cmcontinue, titles = '', []
    while True:
        u = urllib.urlopen(name + cmcontinue)
        xmldata = u.read()
        u.close()
        x = xml.dom.minidom.parseString(xmldata)
        titles += [i.getAttribute("title") for i in x.getElementsByTagName("cm")]
        cmcontinue = filter( None,
                             (urllib.quote(i.getAttribute("cmcontinue"))
                              for i in x.getElementsByTagName("categorymembers")) )
        if cmcontinue:
            cmcontinue = '&cmcontinue=' + cmcontinue[0]
        else:
            break
    return titles
 
alltasks = findrc("Programming_Tasks")
lang = findrc(sys.argv[1])
 
for i in [i for i in alltasks if i not in lang]:
    print i

Python 3.x

#Aamrun, 3rd February 2023

import xml.dom.minidom
import sys, urllib.parse, urllib.request
 
def findrc(category):
    name = "http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:%s&cmlimit=500&format=xml" % urllib.parse.quote(category)
    cmcontinue, titles = '', []
    while True:
        u = urllib.request.urlopen(name + cmcontinue)
        xmldata = u.read()
        u.close()
        x = xml.dom.minidom.parseString(xmldata)
        titles += [i.getAttribute("title") for i in x.getElementsByTagName("cm")]
        cmcontinue = list(filter( None,
                             (urllib.parse.quote(i.getAttribute("cmcontinue"))
                              for i in x.getElementsByTagName("categorymembers")) ))
        if cmcontinue:
            cmcontinue = '&cmcontinue=' + cmcontinue[0]
        else:
            break
    return titles
 
alltasks = findrc("Programming_Tasks")
lang = findrc(sys.argv[1])
 
for i in [i for i in alltasks if i not in lang]:
    print(i)

R

Library: XML (R)
library(XML)
find.unimplemented.tasks <- function(lang="R"){
	PT <- xmlInternalTreeParse( paste("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:Programming_Tasks&cmlimit=500&format=xml",sep="") )
	PT.nodes <- getNodeSet(PT,"//cm")
	PT.titles = as.character( sapply(PT.nodes, xmlGetAttr, "title") )
	language <- xmlInternalTreeParse( paste("http://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:", 
	lang, "&cmlimit=500&format=xml",sep="") )
	lang.nodes <- getNodeSet(language,"//cm")
	lang.titles = as.character( sapply(lang.nodes, xmlGetAttr, "title") )
	unimplemented <- setdiff(PT.titles, lang.titles)
	unimplemented
}
# Usage
find.unimplemented.tasks(lang="Python")
langs <- c("R","python","perl")
sapply(langs, find.unimplemented.tasks) # fetching data for multiple languages

Racket

#lang racket

(require net/url net/uri-codec json (only-in racket/dict [dict-ref ref]))

(define (RC-get verb params)
  ((compose1 get-pure-port string->url format)
   "http://rosettacode.org/mw/~a.php?~a" verb (alist->form-urlencoded params)))

(define (get-category catname)
  (let loop ([c #f])
    (define t
      ((compose1 read-json RC-get) 'api
       `([action . "query"] [format . "json"]
         [list . "categorymembers"] [cmtitle . ,(format "Category:~a" catname)]
         [cmcontinue . ,(and c (ref c 'cmcontinue))] [cmlimit . "500"])))
    (define (c-m key) (ref (ref t key '()) 'categorymembers #f))
    (append (for/list ([page (c-m 'query)]) (ref page 'title))
            (cond [(c-m 'query-continue) => loop] [else '()]))))

;; The above is the required "library" code, same as the "Rosetta
;; Code/Count" entry

(define (show-unimplemented lang)
  (for-each displayln (remove* (get-category lang)
                               (get-category 'Programming_Tasks))))

(show-unimplemented 'Racket) ; see all of the Racket entries

Raku

(formerly Perl 6)

Works with: Rakudo version 2018.04.1
use HTTP::UserAgent;
use URI::Escape;
use JSON::Fast;
use Sort::Naturally;

unit sub MAIN( Str :$lang = 'Raku' );

my $client = HTTP::UserAgent.new;
my $url = 'https://rosettacode.org/w';

my @total;
my @impl;

@total.append: .&get-cat for 'Programming_Tasks', 'Draft_Programming_Tasks';
@impl = get-cat $lang;

say "Unimplemented tasks in $lang:";
my @unimplemented = (@total (-) @impl).keys.sort: *.&naturally;
.say for @unimplemented;
say "{+@unimplemented} unimplemented tasks";

sub get-cat ($category) {
    flat mediawiki-query(
        $url, 'pages',
        :generator<categorymembers>,
        :gcmtitle("Category:$category"),
        :gcmlimit<350>,
        :rawcontinue(),
        :prop<title>
    ).map({ .<title> });
}

sub mediawiki-query ($site, $type, *%query) {
    my $url = "$site/api.php?" ~ uri-query-string(
        :action<query>, :format<json>, :formatversion<2>, |%query);
    my $continue = '';

    gather loop {
        my $response = $client.get("$url&$continue");
        my $data = from-json($response.content);
        take $_ for $data.<query>.{$type}.values;
        $continue = uri-query-string |($data.<query-continue>{*}».hash.hash or last);
    }
}

sub uri-query-string (*%fields) { %fields.map({ "{.key}={uri-escape .value}" }).join("&") }
Output:
As of Sept. 2, 2022
Unimplemented tasks in Raku:
3d turtle graphics
15 puzzle game in 3D
Addition-chain exponentiation
Audio alarm
Audio frequency generator
Audio overlap loop
Binary coded decimal
Black box
Blackjack strategy
Boids
Catmull–Clark subdivision surface
Chess player
CLI-based maze-game
Compare sorting algorithms' performance
Compiler/AST interpreter
Compiler/Preprocessor
Compiler/syntax analyzer
Create an executable for a program in an interpreted language
Cross compilation
Cycles of a permutation
Diophantine linear system solving
Dominoes
Elevator simulation
Execute Computer/Zero
Free polyominoes enumeration
Generalised floating point multiplication
Hexapawn
Honeycombs
IRC gateway
Morpion solitaire
Number triplets game
OLE automation
OpenGL pixel shader
P-Adic square roots
Play recorded sounds
Red black tree sort
Remote agent/Agent interface
Remote agent/Agent logic
Remote agent/Simulation
Simple turtle graphics
Solve a Rubik's cube
Solving coin problems
Sorting algorithms/Tree sort on a linked list
Tamagotchi emulator
Tetris
Ukkonen’s suffix tree construction
Unicode polynomial equation
Uno (card game)
Use a REST API
Waveform analysis/Top and tail
Weather routing
WebGL rotating F
52 unimplemented tasks

Ring

# Project: Rosetta Code/Find unimplemented tasks
 
load "stdlib.ring"
ros= download("http://rosettacode.org/wiki/Category:Programming_Tasks") 
lang = "Ring"
pos = 1
num = 0
totalros = 0
rosname = ""
rostitle = ""
see "Tasks not implemented in " + lang + " language:" + nl
for n = 1 to len(ros)
        nr = searchstring(ros,'<li><a href="/wiki/',pos)
        if nr = 0
           exit
        else
           pos = nr + 1    
        ok
        nr = searchname(nr)  
        nr = searchtitle(nr) 
next
see nl
see "Total: " + totalros + " examples." + nl
 
func searchstring(str,substr,n)
       newstr=right(str,len(str)-n+1)
       nr = substr(newstr, substr)
       if nr = 0
          return 0
       else
          return n + nr -1
       ok
 
func searchname(sn)
       nr2 = searchstring(ros,'">',sn)
       nr3 = searchstring(ros,"</a></li>",sn)
       rosname = substr(ros,nr2+2,nr3-nr2-2)
       return sn
 
func searchtitle(sn)
        st = searchstring(ros,"title=",sn)
        rostitle = substr(ros,sn+19,st-sn-21)
        rostitle = "rosettacode.org/wiki/" + rostitle
        rostitle = download(rostitle)
        s = substr(rostitle,lang)
        if s = 0
           num = num + 1
           totalros = totalros + 1
           see "" + num + ". " + rosname + nl
        ok
        return sn
 
func count(cstring,dstring)
       sum = 0
       while substr(cstring,dstring) > 0
               sum = sum + 1
              cstring = substr(cstring,substr(cstring,dstring)+len(string(sum)))
       end
       return sum

Output:

Tasks not implemented in Ring language:
1. 15 puzzle solver
2. 2048
3. 24 game/Solve
4. 9 billion names of God the integer
5. Abstract type
6. Active Directory/Search for a user
7. Address of a variable
8. AKS test for primes
9. Align columns
10. Amb
......
343. Xiaolin Wu's line algorithm
344. XML/DOM serialization
345. XML/Input
346. XML/Output
347. XML/XPath
348. Y combinator
349. Yahoo! search interface
350. Yin and yang
351. Zeckendorf arithmetic
352. Zhang-Suen thinning algorithm

Total: 352 examples.  

Ruby

Finds tasks that are either not implemented or omitted. Sorts by task creation time.

Uses the RosettaCode module from Count programming examples#Ruby

require 'rosettacode'
require 'time'

module RosettaCode
  def self.get_unimplemented(lang)
    programming_tasks = []
    category_members("Programming_Tasks") {|task| programming_tasks << task}

    lang_tasks = []
    category_members(lang) {|task| lang_tasks << task}

    lang_tasks_omit = []
    category_members("#{lang}/Omit") {|task| lang_tasks_omit << task}

    [programming_tasks - lang_tasks, lang_tasks_omit]
  end

  def self.created_time(title)
    url = get_api_url({
      "action" => "query",
      "titles" => title,
      "format" => "xml",
      "rvlimit" => 500,
      "prop" => "revisions",
      "rvprop" => "timestamp"
    })
    doc = REXML::Document.new open(url)
    REXML::XPath.each(doc, "//rev").collect do |node| 
      Time.parse( node.attribute("timestamp").value )
    end.min 
  end

end

puts Time.now
lang = ARGV[0] || "Ruby"
unimplemented, omitted = RosettaCode.get_unimplemented(lang)
unimplemented.collect {|title| [title, RosettaCode.created_time(title)]} .
              sort_by {|e| e[1]} .
              each do |title, date|
                puts "%s %6s %s" % [
                  date.strftime("%Y-%m-%d"), 
                  omitted.include?(title) ? "[omit]" : "" ,
                  title
                ]
              end

Output for Ruby

2010-04-05 11:08:07 -0500
2007-01-14        Table creation
2007-01-25 [omit] Pointers and references
2007-02-04        SQL-based authentication
2007-02-09        Metered concurrency
2007-02-27 [omit] Address of a variable
2007-02-27 [omit] Variable size/Set
2007-02-27        Variable size/Get
2007-06-08        OpenGL
2007-06-08        HTTPS/Authenticated
2007-11-06        Pattern matching
2007-11-08 [omit] Parametric polymorphism
2007-11-13        Special characters
2007-12-11        Arithmetic evaluation
2007-12-21 [omit] Proof
2007-12-24        Plot coordinate pairs
2007-12-24        Polynomial regression
2007-12-24        Compare sorting algorithms' performance
2008-03-27        Dragon curve
2008-03-28        Formal power series
2008-09-11        RCRPG
2008-11-02        Active object
2008-11-13        Window creation/X11
2008-12-05 [omit] Constrained genericity
2009-02-17        Rendezvous
2009-03-22        Arena storage pool
2009-05-23        Ray-casting algorithm
2009-05-26 [omit] Memory allocation
2009-05-26        Simulate input/Mouse
2009-05-27        Mouse position
2009-05-27        Keyboard macros
2009-05-27        Window management
2009-05-27        Color of a screen pixel
2009-06-01        HTTPS/Client-authenticated
2009-06-02        Simulate input/Keyboard
2009-06-08 [omit] Create an object at a given address
2009-06-10        Events
2009-06-10        Scope modifiers
2009-08-09        Verify distribution uniformity/Chi-squared test
2009-08-11        Call a function from a foreign language
2009-08-12        Safe addition
2009-12-05        Rate counter
2010-01-02        Loading Animated 3D Data
2010-01-06        Catmull–Clark subdivision surface
2010-01-21        Hough transform
2010-01-25        Compile-time calculation
2010-02-14        Knapsack problem/Bounded
2010-02-21        Deconvolution/1D
2010-02-23        Deconvolution/2D+
2010-02-24        Knapsack problem/Continuous
2010-03-23        Sutherland-Hodgman polygon clipping
2010-03-23        Find Common Directory Path

Run BASIC

Find tasks not implemented. Select Language from DropDown and click [GO] or [Exit].

WordWrap$ = "style='white-space: pre-wrap;white-space: -moz-pre-wrap;white-space: -pre-wrap;white-space: -o-pre-wrap;word-wrap: break-word'"
a$	= httpGet$("http://rosettacode.org/wiki/Category:Programming_Languages")
a$	= word$(a$,2,"mw-subcategories")
a$	= word$(a$,1,"</table>")
i	= instr(a$,"/wiki/Category:")
html "<B>   Select language from list<BR>"
html "<SELECT name='lang'>"
while i <> 0
  j	= instr(a$,""" title=""Category:",i)
  lang$	= mid$(a$,i+15,j-i-15)
  k	= instr(a$,""">",j + 18)
  langName$ = mid$(a$,j + 18,k-(j+18))
  count	= count + 1
  html  "<option value='";lang$;"'>";langName$;"</option>"
  i	= instr(a$,"/wiki/Category:",k)
wend
html "</select>"
html "<p>Number of Languages:";count;"<BR>        "
button #go,"GO", [go]
html "        "
button #ex, "Exit", [exit]
wait

[go]
cls
lang$	= #request get$("lang")
h$	= "http://rosettacode.org/wiki/Reports:Tasks_not_implemented_in_";lang$
a$	= httpGet$(h$)
a$	= word$(a$,3,"mw-content-ltr")
html "<table border=1><tr>"
i	= instr(a$,"<a href=""/wiki/")
while i > 0 
  i	= instr(a$,"title=""",i)
  j	= instr(a$,""">",i+7)
  if c mod 4	= 0 then html "</tr><tr ";WordWrap$;">"
  c	= c + 1
  html "<td>";mid$(a$,i+7,j-(i+7));"</td>"
  i	= instr(a$,"<a href=""/wiki/",i+7)
wend
html "</tr></table>"
print "Total unImplemented Tasks:";c
[exit]
end
24 game/SolveAbstract typeAccumulator factoryActive Directory/ConnectActive Directory/Search for a user
Arena storage poolArithmetic/RationalArithmetic evaluationAverage loop lengthAverages/Mean angle
Averages/Mean time of dayBitcoin/address validationBitmap/PPM conversion through a pipeBitmap/Read an image through a pipeBreak OO privacy
CRC-32CSV to HTML translationCalendarCalendar - for "real" programmersCall a function
Call an object methodCanny edge detectorCarmichael 3 strong pseudoprimes, or Miller Rabin's nemesisCatmull–Clark subdivision surfaceChat server
Check Machin-like formulasCholesky decompositionColour pinstripe/PrinterCompare sorting algorithms' performanceConstrained genericity
Continued fractionContinued fraction arithmetic/Continued fraction r2cf(Rational N)Continued fraction arithmetic/G(matrix NG, Contined Fraction N)Continued fraction arithmetic/G(matrix NG, Contined Fraction N1, Contined Fraction N2)Count the coins
Zebra puzzleZeckendorf number representation

Total unImplemented Tasks:177

Rust

use std::collections::{BTreeMap, HashSet};

use reqwest::Url;
use serde::Deserialize;
use serde_json::Value;

/// A Rosetta Code task.
#[derive(Clone, PartialEq, Eq, Hash, Debug, Deserialize)]
pub struct Task {
    /// The ID of the page containing the task in the MediaWiki API.
    #[serde(rename = "pageid")]
    pub id: u64,

    /// The human-readable title of the task.
    pub title: String,
}

/// Encapsulates errors that might occur during JSON parsing.
#[derive(Debug)]
enum TaskParseError {
    /// Something went wrong with the HTTP request to the API.
    Http(reqwest::Error),

    /// There was a problem parsing the API response into JSON.
    Json(serde_json::Error),

    /// The response JSON contained unexpected keys or values.
    UnexpectedFormat,
}

impl From<serde_json::Error> for TaskParseError {
    fn from(err: serde_json::Error) -> Self {
        TaskParseError::Json(err)
    }
}

impl From<reqwest::Error> for TaskParseError {
    fn from(err: reqwest::Error) -> Self {
        TaskParseError::Http(err)
    }
}

/// Represents a category of pages on Rosetta Code, such as "Rust".
struct Category {
    name: String,
    continue_params: Option<BTreeMap<String, String>>,
}

impl Category {
    fn new(name: &str) -> Category {
        let mut continue_params = BTreeMap::new();
        continue_params.insert("continue".to_owned(), "".to_owned());

        Category {
            name: name.to_owned(),
            continue_params: Some(continue_params),
        }
    }
}

/// Sends a request to Rosetta Code through the MediaWiki API. If successful, returns the response
/// as a JSON object.
fn query_api(
    category_name: &str,
    continue_params: &BTreeMap<String, String>,
) -> Result<Value, TaskParseError> {
    let mut url = Url::parse("http://rosettacode.org/mw/api.php").expect("invalid URL");
    url.query_pairs_mut()
        .append_pair("action", "query")
        .append_pair("list", "categorymembers")
        .append_pair("cmtitle", &format!("Category:{}", category_name))
        .append_pair("cmlimit", "500")
        .append_pair("format", "json")
        .extend_pairs(continue_params);

    Ok(reqwest::blocking::get(url)?.json()?)
}

/// Given a JSON object, parses the task information from the MediaWiki API response.
fn parse_tasks(json: &Value) -> Result<Vec<Task>, TaskParseError> {
    let tasks_json = json
        .pointer("/query/categorymembers")
        .and_then(Value::as_array)
        .ok_or(TaskParseError::UnexpectedFormat)?;

    tasks_json
        .iter()
        .map(|json| Task::deserialize(json).map_err(From::from))
        .collect()
}

impl Iterator for Category {
    type Item = Vec<Task>;

    fn next(&mut self) -> Option<Self::Item> {
        self.continue_params.as_ref()?;

        query_api(&self.name, self.continue_params.as_ref()?)
            .and_then(|result| {
                // If there are more pages of results to request, save them for the next iteration.
                self.continue_params =
                    result
                        .get("continue")
                        .and_then(Value::as_object)
                        .map(|continue_params| {
                            continue_params
                                .iter()
                                .map(|(key, value)| {
                                    (key.to_owned(), value.as_str().unwrap().to_owned())
                                })
                                .collect()
                        });

                parse_tasks(&result)
            })
            .map_err(|err| println!("Error parsing response: {:?}", err))
            .ok()
    }
}

pub fn all_tasks() -> Vec<Task> {
    Category::new("Programming Tasks").flatten().collect()
}

pub fn unimplemented_tasks(lang: &str) -> Vec<Task> {
    let all_tasks = all_tasks().iter().cloned().collect::<HashSet<_>>();
    let implemented_tasks = Category::new(lang).flatten().collect::<HashSet<_>>();
    let mut unimplemented_tasks = all_tasks
        .difference(&implemented_tasks)
        .cloned()
        .collect::<Vec<Task>>();
    unimplemented_tasks.sort_by(|a, b| a.title.cmp(&b.title));
    unimplemented_tasks
}


fn main() {
    for task in find_unimplemented_tasks::unimplemented_tasks("Rust") {
        println!("{:6} {}", task.id, task.title);
    }
}
Output:
  2973 Active Directory/Search for a user
  2135 Add a variable to a class instance at runtime
 22638 Bioinformatics/Sequence mutation
 23073 Biorhythms
  3219 Bitmap/Bézier curves/Cubic
  3213 Bitmap/Bézier curves/Quadratic
  3226 Bitmap/Histogram
  3218 Bitmap/Midpoint circle algorithm
  3217 Bitmap/PPM conversion through a pipe
  3225 Bitmap/Read a PPM file
  3246 Bitmap/Read an image through a pipe
 10244 Break OO privacy
  7508 Bulls and cows/Player
  9832 Calendar - for "REAL" programmers
 11471 Canny edge detector
  5279 Catmull–Clark subdivision surface
 12552 Check Machin-like formulas
 22349 Chernick's Carmichael numbers
 22212 Chowla numbers
 23287 Cistercian numerals
  4268 Color of a screen pixel
 10293 Color quantization
  9749 Colour pinstripe/Display
  9748 Colour pinstripe/Printer
 13300 Combinations and permutations
 17481 Commatizing numbers
  2438 Compare sorting algorithms' performance
 21167 Compiler/AST interpreter
 21169 Compiler/code generator
 21046 Compiler/lexical analyzer
 21137 Compiler/syntax analyzer
 21170 Compiler/virtual machine interpreter
 22714 Cyclotomic polynomial
 22500 De Bruijn sequences
  9404 Death Star
  6107 Deconvolution/1D
  6110 Deconvolution/2D+
 14060 Deming's Funnel
 21228 Determine if two triangles overlap
 17509 Digital root/Multiplicative digital root
  9965 Dinesman's multiple-dwelling problem
 22595 Display an outline as a nested table
  2102 Distributed programming
 21206 Diversity prediction theorem
  3273 Doubly-linked list/Definition
  4888 Doubly-linked list/Traversal
  8974 Draw a cuboid
 19095 Draw a rotating cube
  4297 Dynamic variable names
 21942 EKG sequence convergence
 22189 Eban numbers
 21218 Eertree
 17421 Elementary cellular automaton/Infinite length
 22032 Elliptic Curve Digital Signature Algorithm
 12635 Elliptic curve arithmetic
  9371 Executable library
  2843 Execute SNUSP
 23157 Exponentiation with infix operators in (or operating on) the base
 22649 Faces from a mesh
 22098 Factorial base numbers indexing permutations of a collection
 22459 Factorions
 19860 Faulhaber's formula
 21408 Faulhaber's triangle
 21786 Feigenbaum constant calculation
 12308 Find largest left truncatable prime in a given base
 17454 Find palindromic numbers in both binary and ternary bases
  9996 First class environments
 22334 First perfect square in base n with n unique digits
 22699 First power of 2 that has leading decimal digits of 12
  1788 Flow-control structures
  2783 Formal power series
  2420 Forward difference
 22506 Fraction reduction
 17107 Fractran
 21109 French Republican calendar
 10768 Function frequency
 10110 Function prototype
 19505 Functional coverage tree
  8058 GUI component interaction
  8059 GUI enabling/disabling of controls
  8843 GUI/Maximum window dimensions
  9552 Galton box animation
  3996 Gamma function
 22619 Gapful numbers
 21753 Gauss-Jordan matrix inversion
  4996 Go Fish
 22793 Graph colouring
  3224 Grayscale image
  9751 Greyscale bars/Display
  4291 HTTPS/Client-authenticated
 10707 Hofstadter Figure-Figure sequences
  6245 Hofstadter-Conway $10,000 sequence
  7622 Holidays related to Easter
  9782 Honeycombs
  7588 Horizontal sundial calculations
  5346 Hough transform
 22492 Humble numbers
 17428 Idiomatically determine all the characters that can be used for symbols
  3228 Image convolution
  8370 Image noise
 21308 Imaginary base numbers
 17613 Index finite lists of positive integers
 22565 Intersecting number wheels
  1998 Introspection
  9828 Inverted syntax
 23001 Isqrt (integer square root) of X
  9763 Joystick position
  9722 Jump anywhere
  9891 Kaprekar numbers
  8432 Keyboard input/Flush the keyboard buffer
  8434 Keyboard input/Keypress check
  4263 Keyboard macros
  6046 Knapsack problem/Bounded
  3196 Knapsack problem/Unbounded
 19210 Knuth's power tree
 21302 Kosaraju
 22467 Lah numbers
 21584 Largest number divisible by its digits
 22424 Latin Squares in reduced form
 22003 Law of cosines - triples
 19103 List rooted trees
  2228 Literals/String
 22821 Long literals, with continuations
  3851 Long multiplication
 21733 Loops/Increment loop index within loop body
 21990 Loops/With multiple ranges
 21994 Loops/Wrong ranges
 17325 Lucky and even lucky numbers
 22107 Matrix digital rain
  3230 Median filter
  1991 Memory layout of a data structure
 23353 Merge and aggregate datasets
 22710 Mertens function
 22608 Metallic ratios
 10462 Metronome
 22215 Mian-Chowla sequence
 22664 Minimal steps down to 1
 23296 Minkowski question-mark function
 23539 Modified random distribution
 12952 Modular arithmetic
 20014 Monads/List monad
 20016 Monads/Maybe monad
 20022 Monads/Writer monad
 18481 Multi-dimensional array
 12576 Multifactorial
  4456 Multiple regression
  2400 Multiplicative order
  9299 Multisplit
 13149 Musical scale
  4451 Named parameters
  9454 Natural sorting
 12953 Nautical bell
 21855 Nested templated data
  2778 Non-continuous subsequences
 23075 Non-transitive dice
 16746 Nonogram solver
 10185 Numeric error propagation
 22048 Numerical and alphabetical suffixes
  9805 Numerical integration/Gauss-Legendre Quadrature
 10147 OLE automation
 10773 Odd word problem
 18243 One-time pad
 11982 OpenWebNet password
 12237 Operator precedence
 17599 Order disjoint list items
  9223 Ordered partitions
 23454 P-Adic numbers, basic
 23470 P-Adic square roots
 21652 P-value correction
 23570 Padovan n-step number sequences
 23149 Pancake numbers
 10974 Paraffins
  4878 Parametrized SQL statement
 10993 Parsing/RPN to infix conversion
  9391 Partial function application
 19012 Pascal matrix generation
  2770 Pascal's triangle/Puzzle
 20044 Pathological floating point problems
 22237 Peaceful chess queen armies
 22161 Pell's equation
 19037 Pentagram
 15821 Percolation/Bond percolation
 15850 Percolation/Mean cluster density
 15846 Percolation/Mean run density
 15836 Percolation/Site percolation
 22093 Perfect totient numbers
 12099 Permutations by swapping
  9631 Permutations/Derangements
 12454 Permutations/Rank of a permutation
 22476 Pierpont primes
 12298 Pig the dice game/Player
  9745 Pinstripe/Display
  9746 Pinstripe/Printer
  4366 Play recorded sounds
 13455 Playfair cipher
  2435 Plot coordinate pairs
  1784 Pointers and references
  3094 Polymorphic copy
  1968 Polymorphism
  4397 Polynomial long division
  2436 Polynomial regression
 20435 Polyspiral
 10639 Pragmatic directives
 22678 Primality by Wilson's theorem
 18777 Primes - allocate descendants to their ancestors
  7941 Problem of Apollonius
 23045 Pseudo-random numbers/Combined recursive generator MRG32k3a
 23039 Pseudo-random numbers/PCG32
 23038 Pseudo-random numbers/Xorshift star
 10734 Pythagoras tree
  9939 QR decomposition
 22293 Ramanujan's constant
 22365 Random Latin squares
 23477 Random sentence from book
 17751 Ranking methods
  5179 Rate counter
 21939 Recaman's sequence
  9054 Record sound
 21019 Reflection/Get source
 21022 Reflection/List methods
 21023 Reflection/List properties
  3559 Rendezvous
 10354 Resistor mesh
  4317 Respond to an unknown method call
 21365 Retrieve and search chat history
  3149 Roots of a quadratic function
  3357 Rosetta Code/Find unimplemented tasks
 21688 Rosetta Code/Rank languages by number of users
  3315 Rosetta Code/Rank languages by popularity
  3557 Runtime evaluation
  3556 Runtime evaluation/In an environment
  1678 SOAP
  1912 SQL-based authentication
  4723 Safe addition
 22006 Safe primes and unsafe primes
 19083 Sailors, coconuts and a monkey problem
 12228 Same fringe
  4362 Scope modifiers
 12940 Scope/Function names and labels
 23112 Self numbers
 10406 Send an unknown method call
  4467 Send email
 19255 Sequence of primorial primes
 22268 Sequence: nth number with exactly n divisors
 22259 Sequence: smallest number greater than previous term with exactly n divisors
 11690 Set consolidation
 10590 Set of real numbers
 12906 Set puzzle
  4679 Seven-sided dice from five-sided dice
 21557 Shoelace formula for polygonal area
 12961 Shortest common supersequence
 10750 Simple database
  2501 Singleton
  9801 Sokoban
 17663 Solve a Holy Knight's tour
 17657 Solve a Hopido puzzle
 17656 Solve a Numbrix puzzle
 18017 Solve the no connection puzzle
 23050 Sort an outline at every level
  8099 Sorting algorithms/Bead sort
 15995 Sorting algorithms/Patience sort
  2853 Sorting algorithms/Permutation sort
  9526 Sorting algorithms/Strand sort
  4966 Soundex
  2227 Special characters
  9850 Special variables
  9468 Speech synthesis
 23564 Square Form Factorization
  7892 Stable marriage problem
  4197 Stack traces
  4924 Stair-climbing puzzle
 10077 Start from a main routine
 10410 State name puzzle
 10159 Statistics/Normal distribution
  5219 Stem-and-leaf plot
 18358 Stern-Brocot sequence
 22465 Stirling numbers of the first kind
 22466 Stirling numbers of the second kind
  9882 Straddling checkerboard
 20956 Stream merge
  8644 Strip block comments
  9875 Strip control codes and extended characters from a string
 22088 Strong and weak primes
 19060 Subleq
 19649 Substitution cipher
 10198 Subtractive generator
 22295 Successive prime differences
 22055 Suffixation of decimal numbers
 19053 Sum and product puzzle
 21263 Sum to 100
 10366 Summarize and say sequence
 21914 Sunflower fractal
 19672 Superellipse
 18234 Superpermutation minimisation
  1676 Table creation/Postal addresses
 23375 Tau function
 10052 Terminal control/Cursor movement
  8413 Terminal control/Cursor positioning
  8423 Terminal control/Dimensions
  8596 Terminal control/Display an extended character
  8595 Terminal control/Hiding the cursor
  8597 Terminal control/Inverse video
  8418 Terminal control/Positional read
  9380 Terminal control/Preserve screen
 10505 Terminal control/Unicode output
 17719 Test integerness
  3104 Text processing/1
  3111 Text processing/2
 21761 The Name Game
 20692 Tonelli-Shanks algorithm
 12844 Topic variable
 12627 Topswops
 12310 Total circles area
 22586 Tree datastructures
 23450 Tree from nesting levels
 12318 Twelve statements
 22636 UPC
 23467 Untouchable numbers
  9733 Update a configuration file
  4482 User input/Graphical
  9349 Van der Corput sequence
  1986 Variable size/Set
  8488 Variable-length quantity
  4470 Variables
  2868 Variadic function
  4688 Verify distribution uniformity/Chi-squared test
  4680 Verify distribution uniformity/Naive
  9889 Video display modes
 16103 Vogel's approximation method
 22228 Weird numbers
  3109 Window creation/X11
  4266 Window management
 20673 Word search
 22991 Word wheel
 17721 World Cup group stage
  2433 Write float arrays to a text file
  1760 XML/DOM serialization
  1643 XML/XPath
  3998 Xiaolin Wu's line algorithm
  4124 Yahoo! search interface
  9410 Yin and yang
 10989 Zebra puzzle
 12489 Zeckendorf arithmetic
 12371 Zeckendorf number representation
 16497 Zhang-Suen thinning algorithm

Scala

Add to `build.sbt`

     libraryDependencies ++= Seq(
     "org.json4s"%%"json4s-native"%"3.6.0",
     "com.softwaremill.sttp"%%"core"%"1.5.11",
     "com.softwaremill.sttp"%%"json4s"%"1.5.11")
import com.softwaremill.sttp.json4s._
import com.softwaremill.sttp.quick._

implicit val serialization = org.json4s.native.Serialization
import org.json4s.DefaultFormats
implicit val formats = DefaultFormats

case class Task(pageid: Int, title: String)
case class Category(categorymembers: List[Task])
case class Query(query: Category)

List("Programming Tasks", "Scala")
  .map { title =>
    sttp
      .get(uri"http://www.rosettacode.org/mw/api.php?action=query&list=categorymembers&cmtitle=Category:${title}&cmlimit=1000&format=json")
      .header("User-Agent", mozillaUserAgent)
      .response(asJson[Query])
      .send()
      .body
  }
  .map {
    case Right(r) => r.query.categorymembers.toSet
    case Left(s) => Set.empty[Task]
  }
  .foldRight(Set.empty[Task])((acc: Set[Task], ele: Set[Task]) => acc -- ele)

Tcl

First, find all members of the Programming_Tasks category, then find all members of the $lang category. The difference is the list of unimplemented tasks.

Library: Tcllib (Package: json)
Library: Tcllib (Package: struct::set)
package require Tcl 8.5
package require http
package require json
package require struct::set
 
fconfigure stdout -buffering none

# Initialize a cache of lookups
array set cache {}
proc log msg {
    #puts -nonewline $msg
}
 
proc get_tasks {category} {
    global cache
    if {[info exists cache($category)]} {
	return $cache($category)
    }
    set base_url http://www.rosettacode.org/mw/api.php
    set query {
	action	query
	list	categorymembers
	cmtitle	Category:%s
	format	json
	cmlimit	500
    }
    set query [list {*}$query]; # remove excess whitespace
    set this_query [dict create {*}[split [format $query $category]]]
    set tasks [list]
 
    while {1} {
        set url [join [list $base_url [http::formatQuery {*}$this_query]] ?]
        while 1 {
            set response [http::geturl $url]
	    # Process redirects
            if {[http::ncode $response] == 301} {
                set newurl [dict get [http::meta $response] Location]
                if {[string match http://* $newurl]} {
                    set url $newurl
                } else {
                    set url [regexp -inline {http://[^/]+} $url]
                    append url $newurl
                }
                continue
            }
	    # Check for oopsies!
            if {
		[set s [http::status $response]] ne "ok"
		|| [http::ncode $response] != 200
	    } then {
                error "Oops: url=$url\nstatus=$s\nhttp code=[http::code $response]"
            }
            break
        }

	# Get the data out of the message
        set data [json::json2dict [http::data $response]]
        http::cleanup $response
 
        # add tasks to list
        foreach task [dict get $data query categorymembers] {
            lappend tasks [dict get [dict create {*}$task] title]
        }
 
        if {[catch {
	    dict get $data query-continue categorymembers cmcontinue
	} continue_task]} then {
            # no more continuations, we're done
            break
        }
        dict set this_query cmcontinue $continue_task
    }
    return [set cache($category) $tasks]
}
 
proc get_unimplemented {lang} {
    set tasks [get_tasks Programming_Tasks]
    set collected [get_tasks Collection_Members]
    set doneTasks [get_tasks $lang]
    set omittedTasks [get_tasks $lang/Omit]

    # Map generic collection task categories to specific ones
    set tasks [regsub -all {Category:(\S+)} $tasks "\\1/$lang"]

    set collectOfLang [struct::set intersect $collected $doneTasks]
    set ignorable [struct::set union $doneTasks $omittedTasks $collectOfLang]
    set unimplemented [struct::set difference $tasks $ignorable]

    puts "\n$lang has [llength $unimplemented] unimplemented programming tasks:"
    if {[llength $unimplemented]} {
	puts "  [join [lsort $unimplemented] "\n  "]"
    }
}
 
catch {console show}
catch {wm withdraw .}
foreach lang {Perl Python Ruby Tcl} {
    get_unimplemented $lang
}

VBScript

The program creates a dictionary with all tasks then adds the draft tasks to it then checks the language page and removes the tasks listed as implemented. At the end it prints a tab separed list of names and urls, ready to be cut and pasted in any spreadsheet. Changing the constant lang allows to check for other languages. Don't forget to run it with CScript!!

Set http= CreateObject("WinHttp.WinHttpRequest.5.1")
Set oDic = WScript.CreateObject("scripting.dictionary")

start="https://rosettacode.org"
Const lang="VBScript"
Dim oHF 

gettaskslist "about:/wiki/Category:Programming_Tasks" ,True
print odic.Count
gettaskslist "about:/wiki/Category:Draft_Programming_Tasks",True
print "total tasks " & odic.Count
gettaskslist "about:/wiki/Category:"&lang,False
print "total tasks  not in " & lang & " " &odic.Count & vbcrlf
For Each d In odic.keys
   print d &vbTab &  Replace(odic(d),"about:", start)
next
WScript.Quit(1)

Sub print(s): 
  On Error Resume Next
  WScript.stdout.WriteLine (s)  
  If  err= &h80070006& Then WScript.echo " Please run this script with CScript": WScript.quit
End Sub 

Function getpage(name)
  Set oHF=Nothing
  Set oHF = CreateObject("HTMLFILE")
  http.open "GET",name,False  ''synchronous!
  http.send 
  oHF.write "<html><body></body></html>"
  oHF.body.innerHTML = http.responsetext 
  Set getpage=Nothing
End Function

Sub gettaskslist(b,build)
  nextpage=b
  While nextpage <>""
  
    nextpage=Replace(nextpage,"about:", start) 
    WScript.Echo nextpage
    getpage(nextpage)
    Set xtoc = oHF.getElementbyId("mw-pages")
    nextpage=""
    For Each ch In xtoc.children
      If  ch.innertext= "next page" Then 
        nextpage=ch.attributes("href").value
        ': WScript.Echo nextpage
      ElseIf ch.attributes("class").value="mw-content-ltr" Then
        Set ytoc=ch.children(0) 
        'WScript.Echo ytoc.attributes("class").value  '"mw-category mw-category-columns"
        Exit For
      End If   
    Next
    For Each ch1 In ytoc.children 'mw-category-group
      'WScript.Echo ">" &ch1.children(0).innertext &"<"
      For Each ch2 In ch1.children(1).children '"mw_category_group".ul
        Set ch=ch2.children(0)
        If build Then
           odic.Add ch.innertext , ch.attributes("href").value
        else    
           if odic.exists(ch.innertext) then odic.Remove ch.innertext
        End if   
           'WScript.Echo ch.innertext , ch.attributes("href").value
      Next 
    Next
  Wend  
End Sub
Output:

15 puzzle solver	https://rosettacode.org/wiki/15_puzzle_solver
2048	https://rosettacode.org/wiki/2048
21 game	https://rosettacode.org/wiki/21_game
24 game	https://rosettacode.org/wiki/24_game
24 game/Solve	https://rosettacode.org/wiki/24_game/Solve
4-rings or 4-squares puzzle	https://rosettacode.org/wiki/4-rings_or_4-squares_puzzle
9 billion names of God the integer	https://rosettacode.org/wiki/9_billion_names_of_God_the_integer
Abbreviations, easy	https://rosettacode.org/wiki/Abbreviations,_easy
.....

Wren

Library: libcurl
Library: Wren-pattern

An embedded program so we can use the libcurl library.

/* Rosetta_Code_Find_unimplemented_tasks.wren */

import "./pattern" for Pattern

var CURLOPT_URL = 10002
var CURLOPT_FOLLOWLOCATION = 52
var CURLOPT_WRITEFUNCTION = 20011
var CURLOPT_WRITEDATA = 10001

foreign class Buffer {
    construct new() {}  // C will allocate buffer of a suitable size

    foreign value       // returns buffer contents as a string
}

foreign class Curl {
    construct easyInit() {}

    foreign easySetOpt(opt, param)

    foreign easyPerform()

    foreign easyCleanup()
}

var curl = Curl.easyInit()

var getContent = Fn.new { |url|
    var buffer = Buffer.new()
    curl.easySetOpt(CURLOPT_URL, url)
    curl.easySetOpt(CURLOPT_FOLLOWLOCATION, 1)
    curl.easySetOpt(CURLOPT_WRITEFUNCTION, 0)  // write function to be supplied by C
    curl.easySetOpt(CURLOPT_WRITEDATA, buffer)
    curl.easyPerform()
    return buffer.value
}

var p1 = Pattern.new("title/=\"[+1^\"]\"")
var p2 = Pattern.new("cmcontinue/=\"[+1^\"]\"")

var findTasks = Fn.new { |category|
    var url = "https://www.rosettacode.org/w/api.php?action=query&list=categorymembers&cmtitle=Category:%(category)&cmlimit=500&format=xml"
    var cmcontinue = ""
    var tasks = []
    while (true) {
        var content = getContent.call(url + cmcontinue)
        var matches1 = p1.findAll(content)
        for (m in matches1) {
            var title = m.capsText[0].replace("&#039;", "'").replace("&quot;", "\"")
            tasks.add(title)
        }
        var m2 = p2.find(content)
        if (m2) cmcontinue = "&cmcontinue=%(m2.capsText[0])" else break
    }
    return tasks
}

var tasks1 = findTasks.call("Programming_Tasks") // 'full' tasks only
var tasks2 = findTasks.call("Draft_Programming_Tasks")
var lang = "Wren"
var langTasks = findTasks.call(lang) // includes draft tasks
curl.easyCleanup()
System.print("Unimplemented 'full' tasks in %(lang):")
for (task in tasks1) {
    if (!langTasks.contains(task)) System.print("  " + task)
}
System.print("\nUnimplemented 'draft' tasks in %(lang):")
for (task in tasks2) {
    if (!langTasks.contains(task)) System.print("  " + task)
}


which we embed in the following C program, build and run.

/* gcc Rosetta_Code_Find_unimplemented_tasks.c -o Rosetta_Code_Find_unimplemented_tasks -lcurl -lwren -lm */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <curl/curl.h>
#include "wren.h"

struct MemoryStruct {
    char *memory;
    size_t size;
};

/* C <=> Wren interface functions */

static size_t WriteMemoryCallback(void *contents, size_t size, size_t nmemb, void *userp) {
    size_t realsize = size * nmemb;
    struct MemoryStruct *mem = (struct MemoryStruct *)userp;
 
    char *ptr = realloc(mem->memory, mem->size + realsize + 1);
    if(!ptr) {
        /* out of memory! */
        printf("not enough memory (realloc returned NULL)\n");
        return 0;
    }

    mem->memory = ptr;
    memcpy(&(mem->memory[mem->size]), contents, realsize);
    mem->size += realsize;
    mem->memory[mem->size] = 0;
    return realsize;
}

void C_bufferAllocate(WrenVM* vm) {
    struct MemoryStruct *ms = (struct MemoryStruct *)wrenSetSlotNewForeign(vm, 0, 0, sizeof(struct MemoryStruct));
    ms->memory = malloc(1);
    ms->size = 0;
}

void C_bufferFinalize(void* data) {
    struct MemoryStruct *ms = (struct MemoryStruct *)data;
    free(ms->memory);
}

void C_curlAllocate(WrenVM* vm) {
    CURL** pcurl = (CURL**)wrenSetSlotNewForeign(vm, 0, 0, sizeof(CURL*));
    *pcurl = curl_easy_init();
}

void C_value(WrenVM* vm) {
    struct MemoryStruct *ms = (struct MemoryStruct *)wrenGetSlotForeign(vm, 0);
    wrenSetSlotString(vm, 0, ms->memory);
}

void C_easyPerform(WrenVM* vm) {
    CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
    curl_easy_perform(curl);
}

void C_easyCleanup(WrenVM* vm) {
    CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
    curl_easy_cleanup(curl);
}

void C_easySetOpt(WrenVM* vm) {
    CURL* curl = *(CURL**)wrenGetSlotForeign(vm, 0);
    CURLoption opt = (CURLoption)wrenGetSlotDouble(vm, 1);
    if (opt < 10000) {
        long lparam = (long)wrenGetSlotDouble(vm, 2);
        curl_easy_setopt(curl, opt, lparam);
    } else if (opt < 20000) {
        if (opt == CURLOPT_WRITEDATA) {
            struct MemoryStruct *ms = (struct MemoryStruct *)wrenGetSlotForeign(vm, 2);
            curl_easy_setopt(curl, opt, (void *)ms);
        } else if (opt == CURLOPT_URL) {
            const char *url = wrenGetSlotString(vm, 2);
            curl_easy_setopt(curl, opt, url);
        }
    } else if (opt < 30000) {
        if (opt == CURLOPT_WRITEFUNCTION) {
            curl_easy_setopt(curl, opt, &WriteMemoryCallback);
        }
    }
}

WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
    WrenForeignClassMethods methods;
    methods.allocate = NULL;
    methods.finalize = NULL;
    if (strcmp(module, "main") == 0) {
        if (strcmp(className, "Buffer") == 0) {
            methods.allocate = C_bufferAllocate;
            methods.finalize = C_bufferFinalize;
        } else if (strcmp(className, "Curl") == 0) {
            methods.allocate = C_curlAllocate;
        }
    }
    return methods;
}

WrenForeignMethodFn bindForeignMethod(
    WrenVM* vm,
    const char* module,
    const char* className,
    bool isStatic,
    const char* signature) {
    if (strcmp(module, "main") == 0) {
        if (strcmp(className, "Buffer") == 0) {
            if (!isStatic && strcmp(signature, "value") == 0)           return C_value;
        } else if (strcmp(className, "Curl") == 0) {
            if (!isStatic && strcmp(signature, "easySetOpt(_,_)") == 0) return C_easySetOpt;
            if (!isStatic && strcmp(signature, "easyPerform()") == 0)   return C_easyPerform;
            if (!isStatic && strcmp(signature, "easyCleanup()") == 0)   return C_easyCleanup;
        }
    }
    return NULL;
}

static void writeFn(WrenVM* vm, const char* text) {
    printf("%s", text);
}

void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
    switch (errorType) {
        case WREN_ERROR_COMPILE:
            printf("[%s line %d] [Error] %s\n", module, line, msg);
            break;
        case WREN_ERROR_STACK_TRACE:
            printf("[%s line %d] in %s\n", module, line, msg);
            break;
        case WREN_ERROR_RUNTIME:
            printf("[Runtime Error] %s\n", msg);
            break;
    }
}

char *readFile(const char *fileName) {
    FILE *f = fopen(fileName, "r");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    rewind(f);
    char *script = malloc(fsize + 1);
    fread(script, 1, fsize, f);
    fclose(f);
    script[fsize] = 0;
    return script;
}

static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleResult result) {
    if( result.source) free((void*)result.source);
}

WrenLoadModuleResult loadModule(WrenVM* vm, const char* name) {
    WrenLoadModuleResult result = {0};
    if (strcmp(name, "random") != 0 && strcmp(name, "meta") != 0) {
        result.onComplete = loadModuleComplete;
        char fullName[strlen(name) + 6];
        strcpy(fullName, name);
        strcat(fullName, ".wren");
        result.source = readFile(fullName);
    }
    return result;
}

int main(int argc, char **argv) {
    WrenConfiguration config;
    wrenInitConfiguration(&config);
    config.writeFn = &writeFn;
    config.errorFn = &errorFn;
    config.bindForeignClassFn = &bindForeignClass;
    config.bindForeignMethodFn = &bindForeignMethod;
    config.loadModuleFn = &loadModule;
    WrenVM* vm = wrenNewVM(&config);
    const char* module = "main";
    const char* fileName = "Rosetta_Code_Find_unimplemented_tasks.wren";
    char *script = readFile(fileName);
    WrenInterpretResult result = wrenInterpret(vm, module, script);
    switch (result) {
        case WREN_RESULT_COMPILE_ERROR:
            printf("Compile Error!\n");
            break;
        case WREN_RESULT_RUNTIME_ERROR:
            printf("Runtime Error!\n");
            break;
        case WREN_RESULT_SUCCESS:
            break;
    }
    wrenFreeVM(vm);
    free(script);
    return 0;
}
Output:
Unimplemented 'full' tasks in Wren:

Unimplemented 'draft' tasks in Wren:
  Continued fraction convergents

zkl

Uses shared libraries YAJL and cURL.

var [const] YAJL=Import("zklYAJL")[0], CURL=Import("zklCurl");

fcn getTasks(language){
   continueValue,tasks:="",Data(0,String);  // "nm\0nm\0...."
   do{
      page:=CURL().get(("http://rosettacode.org/mw/api.php?"
         "action=query&cmlimit=500"
	 "&format=json"
	 "&list=categorymembers"
	 "&cmtitle=Category:%s"
	 "&cmcontinue=%s").fmt(language,continueValue));
      page=page[0].del(0,page[1]);  // get rid of HTML header
      json:=YAJL().write(page).close();
      json["query"]["categorymembers"].pump(tasks,T("get","title"));
      continueValue=json.find("continue") //continue:-||,cmcontinue:page|954|19)
          .toList().apply("concat","=").concat("&");
   }while(continueValue);
   tasks
}

allTasks:=getTasks.future("Programming_Tasks");  // thread
language:="zkl";
tasks:=getTasks(language);
langTasks:=Dictionary(); tasks.pump(Void,langTasks.add.fp1(Void));
unimplementedTasks:=allTasks.filter('wrap(nm){ (not langTasks.holds(nm)) });
println("Found %d unimplemented tasks for %s:"
      .fmt(unimplementedTasks.len(1),language));
unimplementedTasks.pump(Console.println);
Output:
Found 166 unimplemented tasks for zkl:
15 Puzzle Game
2048
Address of a variable
Animate a pendulum
...
Zeckendorf arithmetic
Zhang-Suen thinning algorithm