-
Notifications
You must be signed in to change notification settings - Fork 10
Add support for solving using Elixir 1.17 #91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThis update introduces a comprehensive Elixir starter and solution template for the "Build your own Interpreter" challenge, following the "Crafting Interpreters" book. It adds project scaffolding, including Elixir Mix configuration, formatting, and version control settings, as well as scripts for compiling and running the interpreter both locally and on the CodeCrafters platform. The initial implementation of the command-line interface in Elixir is provided, handling file reading and basic command parsing with placeholder logic for future stages. Docker and configuration files are also included to support reproducible builds and platform integration. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CLI
participant FileSystem
User->>CLI: Run interpreter with arguments
CLI->>CLI: Parse arguments
alt Command is "tokenize" and filename provided
CLI->>FileSystem: Read file
alt File read successful
CLI->>CLI: Check file content length
alt Content is empty
CLI->>User: Output "EOF null"
else Content not empty
CLI->>User: Output "TODO: Implement scanner!" (stderr)
end
else File read error
CLI->>User: Output error (stderr)
end
else Unknown command or no arguments
CLI->>User: Output usage or unknown command message
CLI->>CLI: Exit with status 1
end
Poem
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
compiled_starters/elixir/codecrafters.yml (1)
5-11
: Duplicate: Verify version consistency with the Mix project
Ensure thatlanguage_pack: elixir-1.17
here aligns with theelixir
requirement inmix.exs
.
🧹 Nitpick comments (3)
solutions/elixir/01-ry8/code/.gitattributes (1)
1-1
: Consider enforcing LF line endings for Elixir sources
Currently all files are normalized withtext=auto
. To guarantee consistent LF endings for source files across platforms, you might add explicit rules:* text=auto +*.ex eol=lf +*.exs eol=lfstarter_templates/elixir/code/.codecrafters/run.sh (1)
9-9
: Strengthen error handling flags in shell scripts (optional).
Consider usingset -euo pipefail
instead of justset -e
to catch unset variables and pipeline failures for more robust execution:-set -e # Exit on failure +set -euo pipefailsolutions/elixir/01-ry8/code/README.md (1)
9-9
: Add comma for improved readabilityIn this sentence, a comma should be added after "In this challenge" for better grammatical flow.
-In this challenge you'll build an interpreter for +In this challenge, you'll build an interpreter for🧰 Tools
🪛 LanguageTool
[typographical] ~9-~9: It appears that a comma is missing.
Context: ...eters.com/) by Robert Nystrom. In this challenge you'll build an interpreter for [Lox](h...(DURING_THAT_TIME_COMMA)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
compiled_starters/elixir/.elixir_ls/build/test/lib/codecrafters_interpreter/ebin/codecrafters_interpreter.app
is excluded by!**/*.app
📒 Files selected for processing (30)
compiled_starters/elixir/.codecrafters/compile.sh
(1 hunks)compiled_starters/elixir/.codecrafters/run.sh
(1 hunks)compiled_starters/elixir/.formatter.exs
(1 hunks)compiled_starters/elixir/.gitattributes
(1 hunks)compiled_starters/elixir/.gitignore
(1 hunks)compiled_starters/elixir/README.md
(1 hunks)compiled_starters/elixir/codecrafters.yml
(1 hunks)compiled_starters/elixir/lib/main.ex
(1 hunks)compiled_starters/elixir/mix.exs
(1 hunks)compiled_starters/elixir/your_program.sh
(1 hunks)dockerfiles/elixir-1.17.Dockerfile
(1 hunks)solutions/elixir/01-ry8/code/.codecrafters/compile.sh
(1 hunks)solutions/elixir/01-ry8/code/.codecrafters/run.sh
(1 hunks)solutions/elixir/01-ry8/code/.formatter.exs
(1 hunks)solutions/elixir/01-ry8/code/.gitattributes
(1 hunks)solutions/elixir/01-ry8/code/.gitignore
(1 hunks)solutions/elixir/01-ry8/code/README.md
(1 hunks)solutions/elixir/01-ry8/code/codecrafters.yml
(1 hunks)solutions/elixir/01-ry8/code/lib/main.ex
(1 hunks)solutions/elixir/01-ry8/code/mix.exs
(1 hunks)solutions/elixir/01-ry8/code/your_program.sh
(1 hunks)solutions/elixir/01-ry8/diff/lib/main.ex.diff
(1 hunks)solutions/elixir/01-ry8/explanation.md
(1 hunks)starter_templates/elixir/code/.codecrafters/compile.sh
(1 hunks)starter_templates/elixir/code/.codecrafters/run.sh
(1 hunks)starter_templates/elixir/code/.formatter.exs
(1 hunks)starter_templates/elixir/code/.gitignore
(1 hunks)starter_templates/elixir/code/lib/main.ex
(1 hunks)starter_templates/elixir/code/mix.exs
(1 hunks)starter_templates/elixir/config.yml
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
compiled_starters/elixir/lib/main.ex (2)
solutions/elixir/01-ry8/code/lib/main.ex (1)
main
(2-24)starter_templates/elixir/code/lib/main.ex (1)
main
(2-28)
starter_templates/elixir/code/lib/main.ex (2)
compiled_starters/elixir/lib/main.ex (1)
main
(2-28)solutions/elixir/01-ry8/code/lib/main.ex (1)
main
(2-24)
solutions/elixir/01-ry8/code/lib/main.ex (2)
compiled_starters/elixir/lib/main.ex (1)
main
(2-28)starter_templates/elixir/code/lib/main.ex (1)
main
(2-28)
🪛 markdownlint-cli2 (0.17.2)
solutions/elixir/01-ry8/explanation.md
12-12: Fenced code blocks should have a language specified
null
(MD040, fenced-code-language)
🪛 Hadolint (2.12.0)
dockerfiles/elixir-1.17.Dockerfile
[error] 10-10: invalid flag: --exclude
(DL1000)
🪛 LanguageTool
compiled_starters/elixir/README.md
[typographical] ~9-~9: It appears that a comma is missing.
Context: ...eters.com/) by Robert Nystrom. In this challenge you'll build an interpreter for [Lox](h...
(DURING_THAT_TIME_COMMA)
solutions/elixir/01-ry8/code/README.md
[typographical] ~9-~9: It appears that a comma is missing.
Context: ...eters.com/) by Robert Nystrom. In this challenge you'll build an interpreter for [Lox](h...
(DURING_THAT_TIME_COMMA)
🔇 Additional comments (35)
compiled_starters/elixir/.gitattributes (1)
1-1
: .gitattributes ensures consistent line endings
The* text=auto
directive will automatically normalize line endings across all files in this directory, preventing spurious diffs on different platforms.starter_templates/elixir/code/.gitignore (1)
1-27
: Comprehensive .gitignore for the Elixir starter template
The patterns cover escript binaries, Mix build artifacts, test coverage, dependencies, documentation, crash dumps, and archive files—keeping transient files out of version control.solutions/elixir/01-ry8/code/.gitignore (1)
1-27
: Consistent .gitignore for the Elixir solution code
This mirrors the starter template’s ignore rules, ensuring/codecrafters_interpreter
,/_build/
,/cover/
,/deps/
,/doc/
, crash dumps, and archive artifacts are excluded.solutions/elixir/01-ry8/code/mix.exs (1)
1-30
: Mix project configuration aligns with Elixir 1.17 and escript requirements
- The
elixir: "~> 1.17"
version constraint matches the PR objective.start_permanent: Mix.env() == :prod
is correctly set.escript: [main_module: CLI]
points to the CLI entry module.
Everything looks good for building and running the escript.solutions/elixir/01-ry8/code/.formatter.exs (1)
1-4
: Formatter inputs correctly include all source files
The glob patterns covermix.exs
,.formatter.exs
, and all.ex
/.exs
files underconfig
,lib
, andtest
. This will enforce consistent code styling across the project.starter_templates/elixir/config.yml (1)
1-3
: Ensure correct configuration for user-editable file
Therequired_executable: "mix"
anduser_editable_file: "lib/main.ex"
settings align with the Mix project scaffolding undercode/
.compiled_starters/elixir/.formatter.exs (1)
1-4
: Formatting configuration is correct
Theinputs
list properly coversmix.exs
,.formatter.exs
, and all.ex
/.exs
files underconfig
,lib
, andtest
.solutions/elixir/01-ry8/code/codecrafters.yml (1)
5-11
:✅ Verification successful
Verify version consistency with the Mix project
Ensure thatlanguage_pack: elixir-1.17
here matches theelixir
requirement inmix.exs
. A mismatch could break the build on CodeCrafters.Run this script to confirm the version in
mix.exs
:
🏁 Script executed:
#!/bin/bash # Verify Elixir version in mix.exs matches the codecrafters.yml setting rg -A2 'elixir:' solutions/elixir/01-ry8/code/mix.exsLength of output: 141
Version consistency confirmed
Thelanguage_pack: elixir-1.17
insolutions/elixir/01-ry8/code/codecrafters.yml
matches theelixir: "~> 1.17"
requirement insolutions/elixir/01-ry8/code/mix.exs
. No changes needed.starter_templates/elixir/code/.formatter.exs (1)
1-4
: Formatter configuration is correctly specified.
The input patterns ("{mix,.formatter}.exs"
and"{config,lib,test}/**/*.{ex,exs}"
) align with standard Elixir projects and match the Mix config,.formatter.exs
, and all source/test files.solutions/elixir/01-ry8/explanation.md (1)
12-12
: Add a language specifier to the fenced code block.
The second code fence (around the Git commands) is missing a language tag, which improves readability and lint compliance. For example, change-``` +```bash[ suggest_nitpick ]
🧰 Tools
🪛 markdownlint-cli2 (0.17.2)
12-12: Fenced code blocks should have a language specified
null(MD040, fenced-code-language)
compiled_starters/elixir/.codecrafters/compile.sh (1)
1-13
: Compile script is correct and consistent.
The script setsset -e
for immediate failure, builds the escript withmix escript.build
, and moves it to the expected temporary path. This aligns with CodeCrafters conventions.compiled_starters/elixir/.codecrafters/run.sh (1)
1-12
: Run script follows CodeCrafters conventions.
The shebang,set -e
, andexec /tmp/codecrafters-build-interpreter-elixir "$@"
correctly invoke the built interpreter and propagate exit codes.starter_templates/elixir/code/.codecrafters/compile.sh (1)
1-12
: Well-structured compile script for ElixirThe shell script correctly sets up the compilation process for the Elixir interpreter on the CodeCrafters platform. It builds the escript and moves it to the expected location for execution.
solutions/elixir/01-ry8/code/.codecrafters/run.sh (1)
1-11
: Run script looks goodThe run script correctly uses
exec
to replace the current process with the compiled Elixir interpreter, properly passing all command line arguments with"$@"
.solutions/elixir/01-ry8/code/.codecrafters/compile.sh (1)
1-12
: Compile script is properly implementedThis compile script matches the one in the starter templates and follows the CodeCrafters convention for building Elixir projects.
compiled_starters/elixir/.gitignore (1)
1-27
: Comprehensive .gitignore for Elixir projectsThis .gitignore file properly excludes all standard Elixir build artifacts, dependencies, and temporary files with clear, helpful comments explaining each section.
compiled_starters/elixir/lib/main.ex (1)
1-29
: Good starter implementation for the CLI moduleThe CLI module provides a well-structured entry point for the interpreter with proper argument handling and error reporting. The commented line for passing the first stage is a nice touch that guides users toward the initial implementation step.
compiled_starters/elixir/your_program.sh (3)
1-9
: Skip shebang and header comments
No changes needed here; the shebang and descriptive comments are clear.
15-19
: Approve local compilation step
The script correctly changes directory, builds the escript, and moves the executable to/tmp
. This aligns with the remote compile script.
21-25
: Approve local execution step
Usingexec
to run the interpreter from/tmp
with all passed arguments is appropriate and consistent with the remote run script.compiled_starters/elixir/README.md (1)
1-51
: Approve README content
The README clearly explains the challenge, prerequisites, and how to run stages locally and remotely. The formatting, links, and instructions are well structured.🧰 Tools
🪛 LanguageTool
[typographical] ~9-~9: It appears that a comma is missing.
Context: ...eters.com/) by Robert Nystrom. In this challenge you'll build an interpreter for [Lox](h...(DURING_THAT_TIME_COMMA)
compiled_starters/elixir/mix.exs (1)
1-30
: Approve Mix project configuration
Themix.exs
correctly defines the application, dependencies placeholder, and escript settings for Elixir 1.17. The defaults are appropriate for a starter template.solutions/elixir/01-ry8/code/your_program.sh (3)
1-9
: Skip shebang and comments
The shebang and documentation comments in the solution script are clear and need no modifications.
15-19
: Approve solution compilation step
The solution script correctly builds the escript and moves it to/tmp
, mirroring the starter template.
21-25
: Approve solution execution step
The use ofexec
to delegate execution to the compiled escript with passed arguments is correct.solutions/elixir/01-ry8/code/README.md (1)
1-51
: README is clear and comprehensiveThe README effectively introduces the "Build your own Interpreter" challenge, explains the connection to "Crafting Interpreters" book, outlines prerequisites, and provides clear instructions for getting started and progressing through stages.
🧰 Tools
🪛 LanguageTool
[typographical] ~9-~9: It appears that a comma is missing.
Context: ...eters.com/) by Robert Nystrom. In this challenge you'll build an interpreter for [Lox](h...(DURING_THAT_TIME_COMMA)
starter_templates/elixir/code/mix.exs (2)
1-30
: Mix configuration looks goodThe project configuration properly defines the escript entry point (CLI module), version, and basic application settings. The commented dependency examples provide helpful guidance for users who might need to add dependencies later.
9-9
:✅ Verification successful
Verify Elixir version compatibility
The project requires Elixir ~> 1.17, which is a very recent version (released in 2024). Make sure this aligns with the development environment requirements for your users. Some users might need to update their Elixir installation.
🌐 Web query:
When was Elixir 1.17 released and what are its key new features?
💡 Result:
Elixir 1.17 was released on June 12, 2024[1][6]. This version introduced several significant new features and improvements to the programming language.
Key New Features
Set-theoretic Data Types
Elixir 1.17 introduced set-theoretic types into language constructs, representing an important milestone in the language's evolution. This feature enables the compiler to infer types from patterns and use them for type checking, allowing it to detect and warn about common mistakes within the same function, particularly for binaries, maps, and atoms[1][6].Duration Data Type
A newDuration
data type was added to the language, along with calendar-related functions for handling time intervals[1][6]. This data type is essential for building intervals, recurring events, and modeling scheduling complexities.Calendar Shifting Functions
The release includes new "shift" functions for calendar types:
Date.shift/2
DateTime.shift/2
NaiveDateTime.shift/2
Time.shift/2
These functions allow shifting dates and times by a given duration while properly handling different calendars and time zones[1][4][6].
Erlang/OTP 27 Support
Elixir 1.17 added support for Erlang/OTP 27, the latest Erlang release available at the time[1][9].Additional Enhancements
- New
Kernel.is_non_struct_map/1
guard to help with the common pitfall of matching on%{}
, which also matches structs[1][4][6]Kernel.get_in/1
with safe nil-handling for access and structs[4][6]Access.find/1
that mirrorsEnum.find/2
[4][6]Keyword.intersect/2,3
functions to mirror the equivalent in theMap
module[1][6]Process.set_label/1
for process labeling[4][6]String.byte_slice/3
to slice a string to a maximum number of bytes while keeping it UTF-8 encoded[4][6]- New Mix profiler
mix profile.tprof
, which uses the new tprof profiler from Erlang/OTP 27[1]Updates Since Initial Release
Shortly after the initial release, Elixir 1.17.1 was released in September 2024[3] with performance enhancements for Mix compilation, particularly improving compilation times for large projects when changing only a few files[2].
The Elixir team has continued development with version 1.18 already released and 1.19 in development as of April 2025[2][5].
Citations:
- 1: https://elixir-lang.org/blog/2024/06/12/elixir-v1-17-0-released/
- 2: https://github.com/elixir-lang/elixir/releases
- 3: https://endoflife.date/elixir
- 4: https://elixirforum.com/t/elixir-v1-17-0-rc-0-released/63764
- 5: https://github.com/elixir-lang/elixir/blob/main/CHANGELOG.md
- 6: https://elixirforum.com/t/elixir-v1-17-0-released/64151
- 7: https://elixirmerge.com/p/discussion-about-elixir-1-17-rc-release-and-other-community-updates
- 8: https://elixirforum.com/t/elixir-v1-17-0-rc-0-released/63764/6
- 9: https://podcast.thinkingelixir.com/208
- 10: https://devdocs.io/elixir~1.17/
Elixir 1.17 Release & Compatibility
Elixir 1.17 was released on June 12, 2024, introducing major enhancements—set-theoretic types, a native Duration type, new calendar shift functions, OTP 27 support, and several ergonomics APIs (e.g.
Kernel.is_non_struct_map/1
,String.byte_slice/3
, Mix’smix profile.tprof
, etc.).Requiring
elixir: "~> 1.17"
in mix.exs ensures you can leverage these features and guarantees OTP 27 compatibility. To finalize:
- Confirm your CI and developer environments run Elixir 1.17 or later.
- Update project documentation (e.g. README) to note Elixir ≥ 1.17 as a prerequisite.
File requiring attention:
- starter_templates/elixir/code/mix.exs (line 9)
solutions/elixir/01-ry8/diff/lib/main.ex.diff (1)
4-15
: Main function changes look goodThe changes correctly:
- Remove the debug output message that was meant for initial template setup
- Uncomment the line for handling empty files, which enables passing the first stage
These modifications align perfectly with the instructions in the README.
starter_templates/elixir/code/lib/main.ex (2)
11-13
: Instructive comment for first challenge stageThe commented line and accompanying instructions effectively guide users on what they need to do to pass the first stage of the challenge. This matches the instructions in the README.
1-29
: CLI module is well-structuredThe CLI module implements a clean command-line interface with proper error handling:
- Effectively uses pattern matching to handle different command scenarios
- Provides clear error messages for unknown commands and missing arguments
- Includes appropriate file handling with error reporting
- Follows Elixir idioms with nested case expressions
This provides a solid foundation for users to build upon as they progress through the challenge.
solutions/elixir/01-ry8/code/lib/main.ex (4)
1-25
: Implementation looks good - provides essential CLI structure for the interpreter.The module establishes a solid foundation for the interpreter challenge following Elixir conventions. The command handling is properly structured with pattern matching on arguments and proper error handling.
8-8
: Good - Enabled the empty file handling logic.You've uncommented this line from the starter template to correctly handle empty files by outputting "EOF null", which will pass the first stage of the challenge.
9-9
: Placeholder for future scanner implementation.This error message correctly indicates that scanner implementation will be done in a future stage. The use of stderr is appropriate for this development note.
12-14
: Error handling follows Elixir conventions.The error handling for file read operations is well-implemented, using pattern matching on the result tuple and IO.inspect with appropriate formatting.
# .git & README.md are unique per-repository. We ignore them on first copy to prevent cache misses | ||
COPY --exclude=.git --exclude=README.md . /app | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Invalid COPY flags
The --exclude
flags are not supported by the Docker COPY
instruction and will cause build failures. Use a .dockerignore
file to exclude .git
and README.md
, or remove the flags.
Apply this diff:
-COPY --exclude=.git --exclude=README.md . /app
+COPY . /app
Then add a .dockerignore
at the repo root:
.git
README.md
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
# .git & README.md are unique per-repository. We ignore them on first copy to prevent cache misses | |
COPY --exclude=.git --exclude=README.md . /app | |
# .git & README.md are unique per-repository. We ignore them on first copy to prevent cache misses | |
COPY . /app |
🧰 Tools
🪛 Hadolint (2.12.0)
[error] 10-10: invalid flag: --exclude
(DL1000)
Summary by CodeRabbit
New Features
Chores