{"id":13961561,"url":"https://github.com/exercism/scheme","last_synced_at":"2025-11-27T09:03:15.158Z","repository":{"id":26601672,"uuid":"30056632","full_name":"exercism/scheme","owner":"exercism","description":"Exercism exercises in Scheme.","archived":false,"fork":false,"pushed_at":"2024-04-25T07:04:23.000Z","size":1071,"stargazers_count":34,"open_issues_count":19,"forks_count":45,"subscribers_count":8,"default_branch":"main","last_synced_at":"2024-05-01T11:25:31.503Z","etag":null,"topics":["community-contributions-paused","exercism-track","lisp"],"latest_commit_sha":null,"homepage":"https://exercism.org/tracks/scheme","language":"Scheme","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/exercism.png","metadata":{"funding":{"github":["exercism"],"custom":["https://exercism.org/donate"]},"files":{"readme":"README","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-01-30T04:46:03.000Z","updated_at":"2024-05-02T13:43:54.099Z","dependencies_parsed_at":"2023-01-14T05:00:42.179Z","dependency_job_id":"32e6fd1a-8972-4dc3-bbc9-9c3e2e659157","html_url":"https://github.com/exercism/scheme","commit_stats":{"total_commits":297,"total_committers":40,"mean_commits":7.425,"dds":0.8013468013468014,"last_synced_commit":"c8de23e0c1f8f29cea0ac8a499699f857d630343"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exercism%2Fscheme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exercism%2Fscheme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exercism%2Fscheme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/exercism%2Fscheme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/exercism","download_url":"https://codeload.github.com/exercism/scheme/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241056166,"owners_count":19901725,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["community-contributions-paused","exercism-track","lisp"],"created_at":"2024-08-08T17:01:15.894Z","updated_at":"2025-11-27T09:03:10.114Z","avatar_url":"https://github.com/exercism.png","language":"Scheme","funding_links":["https://github.com/sponsors/exercism","https://exercism.org/donate"],"categories":["Scheme"],"sub_categories":[],"readme":"# -*- mode: org -*-\n\n#+TITLE: Exercism Scheme Track\n#+AUTHOR: Jason Lewis\n\n[![Configlet Status](https://github.com/exercism/scheme/workflows/configlet/badge.svg)]\n[![Exercise Test Status](https://github.com/exercism/scheme/workflows/scheme%20%2F%20main/badge.svg)]\n\nExercisms in scheme.\n\n** Overview\n\n   Welcome to the home of the exercism scheme track! Many parts of the\n   track are specified inside scheme and then output in various\n   formats. For example, exercism wants a =config.json= file, which is\n   actually specified in [[file:config/track.ss][config/track.ss]]. Everything including the\n   exercise implementations, and the documentation is also done from\n   scheme. In general, the way to modify the track is to edit\n   something in the [[file:input/][input/]] directory. Exercism problem implementations\n   live in [[file:input/exercises/][input/exercises/]]. Student facing documentation (like\n   resources and links) is built from files in [[file:input/docs/][input/docs/]].\n    \n** Setup\n\n    To work on the scheme track you'll need [[https://cisco.github.io/ChezScheme/][ChezScheme]] and [[https://www.gnu.org/software/guile/][GNU\n    Guile]]. The goal is for exercises to be implemented such that they\n    work in either scheme. Each exercise has tests and an example\n    solution and, as part of the build process, it is checked that\n    these tests pass in both schemes.\n\n    There is a small json library (borrowed from [[https://github.com/weinholt/packrat][packrat]]) in\n    =code/json.sls=, which relies on some modules from the [[https://github.com/fedeinthemix/chez-srfi][srfi]]\n    collection. ChezScheme finds libraries through an environment\n    variable =CHEZSCHEMELIBDIRS=. So, you'll need to make sure the\n    location of your downloaded srfi is added to\n    =CHEZSCHEMELIBDIRS=. Instructions for installing the srfi\n    collection can be found at [[https://github.com/fedeinthemix/chez-srfi/blob/master/srfi/INSTALL.chez][srfi/INSTALL.chez]]. If you're using\n    either the [[https://guix.gnu.org/][guix]] or [[https://nixos.org/nix/][nix]] package managers, you can find the srfis\n    pre-packaged.\n\n** Working on the Scheme track\n\n    To work the track, you should start by heading to this directory\n    and firing up a Scheme REPL. Enter =(load \"load.ss\")=, which\n    orchestrates loading the appropriate files.\n\n    Exercises are typically specified in [[https://github.com/exercism/problem-specifications][problem-specifications]], a\n    repository that has descriptions, versions, and tests described\n    through JSON files. The [[file:Makefile][Makefile]] will clone it; the scheme in\n    [[file:code/][code/]] will read problem information from that JSON. It is,\n    however, also possible to define novel exercises if you wish.\n\n*** Requirements\n\n    Exercises have a few required parts, taking the exercise\n    [[file:input/exercises/pascals-triangle/][input/exercises/pascals-triangle/]] as an example.\n    + The [[file:input/exercises/pascals-triangle/example.scm][example.scm]] file which is an example solution that must pass\n      the tests. It must also use only =r6rs= scheme features so that\n      it can run in both Guile and Chez scheme.\n    + A stub file [[file:input/exercises/pascals-triangle/pascals-triangle.scm][pascals-triangle.scm]] usually named after the problem\n      that the student will be given to write their solultion.\n    + The [[file:input/exercises/pascals-triangle/test.ss][test.ss]] which builds the test cases as well as problem\n      metadata (such as problem versions, read from the\n      specifications) and extra documentation (if needed). The crucial\n      part of this file is a call to ~put-problem!~, a procedure\n      defined in [[file:code/track.ss][code/track.ss]] that defines the problem whose name is\n      a symbol (eg ='pascals-triangle=) and an association list with\n      the following form\n\n#+begin_src scheme :exports code\n(let ((spec (get-test-specification 'pascals-triangle)))\n  (put-problem!\n   'pascals-triangle\n   `((test . ,(spec-\u003etests spec))\n     (stubs pascals-triangle)\n     (version . ,(lookup 'version spec))\n     (skeleton . \"pascals-triangle.scm\")\n     (solution . \"example.scm\")\n     (markdown . ,(splice-exercism 'pascals-triangle)))))\n#+end_src\n\n    The tests are parsed in a fairly horrible and ad-hoc way:\n\n#+begin_src scheme :exports code\n(define (spec-\u003etests spec)\n  (map parse-test\n       (lookup 'cases\n               (car\n                (lookup 'cases spec)))))\n#+end_src\n\n    due to the fairly irregular problem specifications. =parse-test=\n    is defined:\n\n#+begin_src scheme :exports code\n(define (parse-test test)\n  `(test-success ,(lookup 'description test)\n                 equal?\n                 pascals-triangle\n                 '(,(cdar (lookup 'input test)))\n                 ',(lookup 'expected test)))\n#+end_src\n\n    =pascals-triangle= has a fairly friendly specification. An example\n    of a less straightforward one from [[file:input/exercises/change/test.ss][change]] is the following:\n\n#+begin_src scheme\n(define (parse-test test)\n  (let ((expected (lookup 'expected test))\n        (input (lookup 'input test)))\n    (if (or (null? expected)\n            (number? (car expected)))\n        `(test-success ,(lookup 'description test)\n                       (lambda (out expected)\n                         (equal? (list-sort \u003c out) (list-sort \u003c expected)))\n                       change\n                       '(,(lookup 'target input)\n                         ,(lookup 'coins input))\n                       ',expected)\n        `(test-error ,(lookup 'description test)\n                     change\n                     '(,(lookup 'target input)\n                       ,(lookup 'coins input))))))\n#+end_src\n\n    There are test cases expected to fail and a more elaborate passing\n    predicate to allow students to return answers in any order.\n\n    Final requirement:\n\n     + Add the problem to the configuration expression in\n      [[file:config/track.ss][config/track.ss]]. You need to provide a uuid, which can be\n      generated from the scheme repl by calling =(configlet-uuid)=\n      (which is just a wrapper for the configlet binary). Finally,\n      include the problem in the list of implementations in the\n      [[https://github.com/exercism/scheme/blob/master/Makefile][Makefile]].\n\n    When [[file:Makefile][building]] the track, the makefile reads each exercise\n    directory and uses the =test.ss= files to generate the [[file:exercises/pascals-triangle/test.scm][test.scm]]\n    files that the students use. The procedure =spec-\u003etests= reads the\n    parsed specification json and turns that into runnable scheme\n    tests. The json is parsed through a procedure\n    ~get-test-specification~.\n\n    Basically, =test.ss= defines each problem as an instance of an\n    exercism problem, having the parts described above, which are used\n    to output the files that the students get.\n\n*** Extras\n    \n    Helpful and useful procedures include:\n\n     - To start a new exercise, use =(stub-exercism 'change)=. This\n       creates rough stubs for =test.ss=, =change.scm=, and\n       =example.scm= in the directory [[file:input/exercises/change/][input/exercises/change/]].\n     - =(verify-exercism 'change)= checks that the solution passes\n       generated test suite. It ought to work under both =Guile= and\n       =Chez=, with =(rnrs)= as the imported library.\n\n*** Adding problems not in exercism/problem-specifications\n\n    New problems from outside of the specifications are welcome as\n    well. Develop them as described above in the =code/exercises=\n    directory, following pretty much the same process as above. The\n    main difference is that instead of parsing test cases from the\n    problem-specifications repository, you'll write them by hand in a\n    =test.ss= file.\n\n** Scheme icon\n\n   The Scheme logo was created by\n https://en.wikipedia.org/wiki/User:Matthias.f and released under the\n Creative Commons Attribution-Share Alike 3.0 Unported license.  We\n adapted the logo, creating a pink/black version to use on Exercism.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexercism%2Fscheme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexercism%2Fscheme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexercism%2Fscheme/lists"}