we've tagged a number of issues as Good First Issue
: https://github.com/rtfeldman/roc/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22
if anyone's interested in trying to take on one of those, that would be really awesome! If you start a new thread in #contributing about the issue you're interested in taking on, an experienced contributor can help you out with it. :smiley:
if anyone's looking for a good first issue, here's a nice one! https://github.com/rtfeldman/roc/issues/2826
if you're interested in working on it, just start a new topic about it here and link to the issue - plenty of folks can help you out, even if you have no previous experience with Rust, with compilers in general, or with Roc's code base!
as an aside, I'm signal boosting this one because I want to get it in for a talk I'm giving in a week and a half, so now's the perfect time! :big_smile:
If nobody wants to claim it in the next 16 hours or so, I'd be interested. I will need guidance, particularly around calling roc_panic
(since it seems it's not currently actually used?), but I believe I have a reasonable idea about where other bits live, and because I'm also new to Rust/Zig(/Roc).
Would you be down to split it in half with me? I could do the division-related ones while you do the rest. What do you think?
I'm definitely happy to do any kind of split you want :)
Let's do it! I'll create the topic
just added a couple of new Good First Issues!
https://github.com/rtfeldman/roc/issues/2847
https://github.com/rtfeldman/roc/issues/2848
https://github.com/rtfeldman/roc/issues/2846 (probably the easiest - see the first comment!)
if anyone's interested in them and would like some guidance or other help on them, feel free to start a new topic about them in #contributing!
Adding
https://github.com/rtfeldman/roc/issues/2844
https://github.com/rtfeldman/roc/issues/2845
to the above list ^
I'm supposed to do my vacation homework, why you guys tempting me with these
fine if I take a stab at https://github.com/rtfeldman/roc/issues/2646 ?
for sure, that’s an important one to fix!
Here is a good "intermediate issue" related to type checking, if you want to dive into something related to that! https://github.com/rtfeldman/roc/issues/2686 I'm marking it "intermediate" because there are a few pieces to it. Happy to dive in and talk through it if you want to pick it up.
Hey I'm trying to build from source to pick one of these issues. I got a nix-shell, however I got an error related to glibc Screenshot-from-2022-04-14-16-54-29.png
What's your PATH look like?
indeed my system's glibc is 2.31, but I thought this wouldn't matter inside the nix shell
If you have statements in your pathrc/bashrc/etc that modify the PATH or library path, make sure to put them at the end, so that it doesn't clobber the paths set by nix
You could also try nix-shell --pure
Ayaz Hafiz said:
If you have statements in your pathrc/bashrc/etc that modify the PATH or library path, make sure to put them at the end, so that it doesn't clobber the paths set by nix
Oh I have some of those
I'll try nix-shell --pure
The compile errors don't seem to tell which file has the error:
🔨 Rebuilding host...
── UNUSED IMPORT ───────────────────────────────────────────────────────────────
Nothing from Terminal is used in this module.
5│ pf.Terminal,
^^^^^^^^^^^
Since Terminal isn't used, you don't need to import it.
────────────────────────────────────────────────────────────────────────────────
Done!
I'd like to add support for this assuming it just hasn't been a priority yet? If so, any preferences on where /how it gets displayed?
Hopefully this can be done in a general way that puts the file name on all error messages. It is probably good to have in general
Hi @Rígille Scherrer Borges Menezes, this issue should no longer occur if you use the nix flake (flake.nix).
Thanks @Anton, the problem also disappeared after updating from Ubuntu 20.04 to Ubuntu 20.10
@Jared Cone elm formats it as
── UNUSED IMPORT ───────────────────────────────────────────── foo/bar/Baz.roc ─
That's probably a good initial goal
we can worry about exact formatting later, but having the above work means that the path information is available when the error messages are constructed
if anyone's interested in adding a new builtin, I'd love to have these for a talk I'm giving on Tuesday!
Num.min : Num a, Num a -> Num a
Num.max : Num a, Num a -> Num a
they'd work the same way min
and max
do in most languages
maybe don't do this?
with builtins in roc this is trivial
but today you'd need to do nasty things with hardcoding ASTs
surely you can hide min = \a, b -> if a < b then a else b
somewhere in your file?
oh good point!
yeah nm let's hold off on this for now
At least in [docs/Num.roc](ttps://github.com/rtfeldman/roc/blob/80f3a29ed436eeaced4f5dbbf8fd245fb50bc791/comp
iler/builtins/docs/Num.roc#L1266-L1276) there's already Num.lower
and Num.higher
. They don't appear to be implemented though
a rare type checker bug with Good First Issue
appears! :smiley:
https://github.com/rtfeldman/roc/issues/3298
If anyone is interested in the type checker or type-related projects, we have a number of good starter projects open!
This one in particular is blocking some larger progress on a CLI platform, and will be super valuable for future Roc code:
https://github.com/rtfeldman/roc/issues/3314
Here's a nice bugfix for anyone interested in the LLVM code generator
https://github.com/rtfeldman/roc/issues/3318
Unless someone else picks it [the type-checker good first issue(s)] up in the meantime, I'd love to work on it. But I'm not going to claim it before finishing what I'm currently busy with :blush:
feel free to pick it up anytime you like! :heart_eyes:
that one's blocking me right now, so I'd love to see it fixed - by all means, go for it! :smiley:
(once you've wrapped up other things you'd like to wrap up first, of course!)
here's a quick one - just a string change! :big_smile:
https://github.com/roc-lang/roc/issues/3875
I wrote a fix for this one and then realized I cannot create a branch in the roc repo anymore. Maybe this is because the repo has moved to the org recently? Or has the no PRs from forks policy changed?
Edit: if nothing extra has changed, can someone please add me to the org/repo? I am @dit7ya
on GitHub.
Or has the no PRs from forks policy changed?
Yes indeed, forks are required now.
I'll update CONTIBUTING.md :)
Does anyone want to move some files and update some path references? These apps are referenced a lot, so shortening their paths like this would be much appreciated :) https://github.com/roc-lang/roc/issues/3912
I'd like to take a stab at #3912. Anything I should know beyond the comments on the issue before submitting a PR?
I don't think so! But if you do encounter any surprises, I'm here for you in this chat & PR comments.
try cargo test --test cli_run
to verify that it worked, and you should be good I think
It should be a simple find-and-replace... although updating the tests might be the most nuanced if there's some expected directory, idk
Thank you, @Bryce Miller!
Well, If I break something it will be a good opportunity to learn!
Yeah, even if your PR broke other people's work that'd be a great find!
#BlameSystemsNotPeople
And local breakages are definitely educational - you'll see how narrow/wide Roc's forgiveness is currently, and if you get any ugly error messages then let us know because they can always be improved!
I really do hope it's uneventful, but of course weird issues pop up when you least expect them.
Hey all, just wondering about issue #4052. Have there been any takers?
It's all you!
Is Rust nightly an option? There's an ErrorKind available in nightly called "IsADirectory" that I think would fit nicely here
I don't think we want to go that route. From what I've heard that stuff also won't be stabilized any time soon
so I guess the best approach is to check for permission here, and look at the metadata of the path to see if it is a file
Fair enough, thank you. I'll see what I can do!
Hi! I was looking for a nice first issue, and was wondering about issue #4726. From what I can see it might have been resolved already? At least I tried the nightly build and could not reproduce the crashes mentioned. All the suggested tests pass!
yes this was fixed recently
Johan Lövgren has marked this topic as resolved.
Johan Lövgren has marked this topic as unresolved.
I'm not sure what other open stdlib issues we have.
in the package space, if you are familiar with elm, we'd like to port over its parser package
Not really familiar with Elm but I am familiar with Haskell and I gather the syntax is pretty similar. I have a little familiarity with Parsers as well
https://github.com/elm/parser/tree/1.1.0 is the package. we don't have custom operators, so |.
will be |> skip
and |=
will be |> keep
there is examples/parser/Parser/Core.roc
already which has some ideas for the type signatures, but in terms of implementation I think the elm approach is much better
it handles backtracking in a really nice way, and has some support for custom error messages
Thanks! Sounds fun, I'll take a look
Johan, when you implement the low-level JavaScript functions in https://github.com/elm/parser/blob/1.1.0/src/Elm/Kernel/Parser.js, take a look at issue #53 where I describe a bug, PR #54 shows a possible fix...
Folkert de Vries said:
there is
examples/parser/Parser/Core.roc
already which has some ideas for the type signatures, but in terms of implementation I think the elm approach is much better
By the way, I have some questions about this already. I see the Elm parser only parses strings, and does so by "chomping" one or more Chars at a time. But the concept of a Char does not exist in roc. Also I see that the Core parser in our examples can parse arbitrary input.
Would the idea be to continue with the roc approach of arbitrary inputs, but change the representation of error-handling / context and so on to match the elm implementation?
that sounds nice and flexible, and only being able to parse strings is a limitation that I hear about on the elm slack. So it would be nice to lift that restriction.
I do wonder where there are cases where performance would be better by just specializing to a list of bytes
I guess that is possible... For sure the most elegant way would be if the core parser is generic and performance depends on what type you implement a parser for in the end.
yes so let's try that first
(the generic approach)
and just see where we miss opportunities
I'm super interested to see how this develops. :sunglasses:
I think it's actually really good if the parser works on bytes (so, List U8
in Roc terms)
because then you can use it to implement both things like CSV parsers as well as binary format parsers like protobuf!
yes but not anything where you do custom tokenization
sure
so what I hope to find out is: what is the price we actually pay for generality (vs. just working on bytes)
maybe it's big, maybe it's small. I don't have a good idea really
Hmm after thinking about this some more I think I will start by porting the Elm parser to work for List U8
first. Then after that I can think about how it should look for generic input.
If I understand correctly, the advanced Elm parser keeps track of state by moving a cursor and not like the Roc parser which "consumes" the source string bit by bit. And I think this is necessary for the good error messaging and for backtracking. I am not sure what a movable cursor would even mean for generic inputs.
it's also way more efficient to just use indices into the input
It may be interesting to discuss the proposal for seamless slices? Does that impact on the design on a Roc parser?
I think most likely we should assume that will be implemented as described in the issue
even though that probably won't happen soon (because it's pretty involved and there are other higher priorities at the moment)
I guess it does mean that as long as you aren't modifying a List
, it should be equally fast to take sub slices of it as it would be to use an index. Or at least in the same ball pack.
if anyone's looking for a beginner-friendly way to get into compiler contributions, https://github.com/roc-lang/roc/pull/5218 will need 128-bit integers to work on the WASM development backend so that https://www.roc-lang.org/repl will still work if you enter things like 1 + 2
- we already have all the ingredients in place for this to work, it's just a matter of wiring them up
which is a fairly mechanical task, but if you're new to the code base, a fairly mechanical task is a gentle introduction to how things work! :smiley:
so if anyone's interested in that, just mention it here and we can help you get started on it!
hi @Richard Feldman , pretty new to the project, just joined Zulip and followed along from your talks on Youtube and your Rust course on FrontendMasters and I got pretty excited!! This week I have time off on Thursday 6th and Friday 7th and if you see fit for a totally newcomer to the project I gladly will take this task :D
awesome, thank you for taking it on! :tada:
@Brian Carroll any advice on where's the best starting point?
Great, thanks for helping, @Mauro Martinez !
Let's start with some links!
Here's the issue listing all the operations to be implemented: https://github.com/roc-lang/roc/issues/2324
Here's the file where they are implemented: https://github.com/roc-lang/roc/blob/main/crates/compiler/gen_wasm/src/low_level.rs
Here are the tests for numeric operations: https://github.com/roc-lang/roc/blob/main/crates/compiler/test_gen/src/gen_num.rs
I suggest you explore for a while, and ask some questions here, and we'll take it from there.
The gen_wasm readme might also be good to look at. A lot of the information isn't directly relevant to this task, but a bit of context is good!
thanks for sharing @Brian Carroll, I will take a look and come back here soon!!
hey folks couple of questions,
IntWidth::I128 | IntWidth::U128
width for matching like NumMulWrap
, is that only necessary for Wrap operations ? gen_wasm_readme
pretty good explanation, I'm not too sure if I completely understood the section for linking_host_to_app_calls, but if what I understood is right, that is what Roc is using to successfully use memory for stuff that is not built-in on WASM, or am I wrong?No, it's the opposite! The ticked ones are fully implemented, including whatever "wiring" is needed! The unticked ones need to be done.
The pattern IntWidth::I128 | IntWidth::U128
means it is generating the same Wasm instructions for both signed and unsigned numbers. That makes sense for wrapped ops. You might discover it also makes sense for some other ops. I don't know, it's hard to tell without going through them all!
Linking host to app calls is not about memory, it's about how we take some code compiled by Roc, and some code compiled by some "foreign language" compiler, and link them together into a single program. The foreign language part of the platform is called the "host". The hard part of that is where the host is calling the Roc app. Because we actually have to modify some of the instruction bytes inside the host to make it work.
This linking stuff is totally unrelated to what you're working on, so don't worry if you're not following everything yet!
gotcha! I understand now what is needed to implement, and thanks for clarifying the linking of the wasm_generation. Moving on, what do you think should be the first methods to tackle? I think I could star with >, >=, < and <=
, but let me know if you have another suggestion!
I was also able to follow the BUILDING_FROM_SOURCE_README and I can start a nix shell with roc using nix develop
That's great!
Those ones seem good to start with, yes. Mostly you should go wherever your interest takes you!
Oh there's one more thing you should know about: the compiler-rt
library.
This is a C library that implements some very low level operations that compilers can "just use". It's part of the LLVM project and we are basically borrowing from it in a few places. It contains a lot of 128-bit ops. They have weird shortened names like __lshrti3
, which apparently does a right shift, and is called here
To see which of its functions to use, you could try compiling some Zig or Rust code and see what they do. I recommend Compiler Explorer by Matt Godbolt.
You can also have a look around in the source code. https://github.com/llvm/llvm-project/tree/main/compiler-rt
Hello folks! How are you? As I mentioned in my introduction in the #beginners stream, I really want to contribute to Roc for it to achieve its goals, but I don't have a lot of knowledge in Rust nor compilers, but I'm totally willing to learn, in fact I want to use my will to contribute as a driver to learn what is needed in order to be able to take the more advanced tasks. But for now, is there anything that you think I can help with? Even if it's documenting what is missing. I'm a software engineer with knowledge in functional programing, currently I work with clojure, but I have personal projects in Elm, Haskell, Elixir, Rescript etc.. I have a lot of experience also with regular languages like, JS, Python etc..
Hi Matheus, there are issues labelled "Good first issue" you could brosw through. I've been working on making examples for roc-lang/examples which you could always help with. Basically any introductory or common cs algorithms or datastructures would be helpful, like implementing Dijkstra's etc.
Hello, everyone!
I am very interested in the project. I am very familiar with Haskell and Elm, but not at all familiar with Rust. Therefore, I want to contribute in Roc itself.
I picked this issue as my first one: https://github.com/roc-lang/roc/issues/5138
My question is: how best to test the builtin libraries? Are there even tests for the standard library? Or is the best way to compile the roc executable and running a file with tests?
Hi @iko,
We have this guide on how to add builtins, I'm not sure if it is still completely up to date but it might suffice :)
we have some basic tests for the builtin functions in this file crates/compiler/test_gen/src/gen_list.rs
. These are mostly to check that the function is defined and does the right thing for some common cases
This PR may also be useful to see what you need to change in which places
Hey everyone!
I am interested in contributing to the project. I already have some experience with Haskell, Rust and a bit of Zig as well.
When building the project and trying out the repl I stumbled upon a bug which I've reported here https://github.com/roc-lang/roc/issues/5337. And in order to get familiar with the project I implemented a simple fix that I think might do the job. Should I open a PR?
Yep
Contributions are always welcome.
Worst case, a review may give comments about a different way we would prefer the issue to be solved.
Here is the PR, https://github.com/roc-lang/roc/pull/5339 I don't know if I've removed some corner case handling so please let me know what you think.
I kicked off CI. Hopefully someone familiar with the repl code can take a look soon.
Hey, I've been working on some issues in the last couple of days and found that the error reporting code uses a lot of format!()
macro calls and I can't figure out why allocate all these strings. Isn't it equivalent to doing alloc.as_string(format_args!(...))
on the DocAllocator
? Using format_args!()
can avoid many allocations since it doesn't perform any allocations and as_string
may choose to store the data in a SmallString
. Additionally, in the future RocDocAllocator
can itself override as_string
and use an arena allocator, in order to store the strings. To make this more readable, we could add a macro text!(alloc, ...)
that would use format_args!()
.
Is this something worth changing? Should I open an issue in order to address this?
well, the good thing is that error reporting is out of the hot path.
but changing this to be more efficient might be fun. I would like to see some benchmarks of error reporting though, to verify whether it actually helps
Since it is not on the hot path, it may be difficult to benchmark the compiler end-to-end in a way that the improvements actually show up. But it is possible to benchmark the RocDocAllocator
in isolation in order to measure the differences. In general, I think this is more about preventing a needles allocation without pretty much any additional complexity. The change would delegate the allocation to the allocator and so, if we never need to use a different allocation strategy for this, nothing needs to be changed (continue to allocate strings on the heap). But if at some point it becomes a worthwhile improvement, it can be done in a single spot!
This issue also might make people new to the project more familliar to the codebase and set a better example for people who are just copy-pasting things around. If RocDocAllocator
is then used to do a lot more work in the future (for example, GHC used to use a similar strattegy for printing ASM code, and eventually they had to change that) then it's easier to optimize, since we're essentially delegating allocation to the actual allocator.
I think it's a worthwhile change, since your implementation suggestion sounds like it would not introduce additional complexity. More macros are a slower to compile the compiler itself but I think that's entirely negligible. if you'd like to open a PR I think we'd be happy to review! Thanks for the suggestion.
Done https://github.com/roc-lang/roc/pull/5374
a new Good First Issue appears!
https://github.com/roc-lang/roc/issues/5377
another Good First Issue: https://github.com/roc-lang/roc/issues/5379
If anyone is interested in a task that is larger but very well scoped, we have #5388.
Fundamentally, the task is just to upgrade the compiler from clap 3 to clap 4. Clap is used for parsing command line arguments for the compiler. This means the update is limited to a very few number of files within the compiler. You really don't have to know anything about the rest of the compiler. It definitely would be helpful to have some decent knowledge of rust given this will mostly be updating and dealing with changes in api. Hopefully a simple compiler error driven update.
If you are interested, comment here and/or on the issue.
Just doing the upgrade to clap 4 and ignoring the rest of the issue would be super helpful.
this one requires no compiler knowledge, it's scoped only to CLI stuff https://github.com/roc-lang/roc/issues/5394
roc help
(=./target/release/roc help
) recently stopped working. I've made a "good first issue" for it: #5418
this is a pretty reasonable first issue for getting into the compiler a bit: https://github.com/roc-lang/roc/issues/6027
it involves the compiler because the place where this needs to change is not in a .roc file, but it's a good first issue because we already do this behavior for integer division by 0, so there's already a template you can follow for how the logic should look!
a new good first issue for anyone interested in getting into a bit of machine code generation!
https://github.com/roc-lang/roc/issues/6169
also, here's a very easy one: adding Set.keepIf
and Set.dropIf
- https://github.com/roc-lang/roc/issues/6171
these can be added to Set.roc by following the pattern of this PR which added Str.contains
(don't worry about the test_mono/generated
stuff - those get automatically regenerated and then checked in)
If anyone is interesting, #beginners > Is sqrt implemented? would be a good first issue for working on our zig bitcode that powers the standard library. Turns our we missed a few functions on our custom Dec
type.
This is another good first issue if anyone is interested. It is two pieces:
Num.round
, Num.floor
, Num.ceil
to the dev backend (ultra simple, just add a call to existing zig bitcode i'm pretty sure) I guess Num.div
and dec also needs a wrapper here from the issue.Dec
type. This should just require adding a few zig bitcode functions that essential convert Dec to a number (division) and then check the fractional part to decide how round/increment afterwards.Context: https://github.com/roc-lang/roc/issues/6212
Feel free to claim 1, 2, or both.
a new good first issue! Adding constants to the Num
module for infinity, -infinity, and NaN https://github.com/roc-lang/roc/issues/6709
I had a stab at the first part of this at https://github.com/roc-lang/roc/pull/6711. It is working but I got stuck on assert_evals_to!
not believing that NaN == NaN
. Is there a way to seperate the assertion and the eval?
in this particular case, Rust is correct! :big_smile:
NaN
is defined at the hardware level to be unequal to NaN
so I think we'd need to special-case that one, to use is_nan
instead of the usual assert_evals_to!
macro
might be easiest to duplicate the macro except make the new version assert_evals_to_nan
instead of assert_evals_to
, and the only change is checking for is_nan
instead of equality
no the quicker way I think is to use a mapping function
much like
#[test]
#[cfg(any(feature = "gen-llvm", feature = "gen-wasm"))]
fn f64_log_negative() {
assert_evals_to!("Num.log -1f64", true, f64, |f: f64| f.is_nan());
}
that sounds good!
Hot off the press... another Good First Issue https://github.com/roc-lang/roc/issues/7425
If anyone is interested in having a go at this, please let us know and we'd be happy to help.
Wouldn’t be able to take this on until Monday, but I’d love to take a stab at it
Yeah no rush or anything. If/when you leave a comment in the GH Issue I can assign it to you.
Freshly minted Good First Issue -- https://github.com/roc-lang/roc/issues/7515
Replace Result.map
with Result.map_ok
in the builtins.
Let us know if you are interesting in implementing this change. I'm happy to help.
Last updated: Jul 06 2025 at 12:14 UTC