Just wanted to let everyone know that I've updated my lukewilliamboswell/aoc-template with something much simpler and easier to use.
We now have module params and other nice features, so it's as easy as importing a package in a basic-cli app to get started.
Here's a starting template
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.16.0/O00IPk-Krg_diNS2dVWlI0ZQP794Vctxzv0ha96mK0E.tar.br",
aoc: "https://github.com/lukewilliamboswell/aoc-template/releases/download/0.1.0/DcTQw_U67F22cX7pgx93AcHz_ShvHRaFIFjcijF3nz0.tar.br",
}
import pf.Stdin
import pf.Stdout
import pf.Utc
import aoc.AoC {
stdin: Stdin.readToEnd,
stdout: Stdout.write,
time: \{} -> Utc.now {} |> Task.map Utc.toMillisSinceEpoch,
}
main = AoC.solve { year: 2020, day: 1, title: "Report Repair", part1, part2 }
## Implement your part1 and part1 solutions here
part1 : Str -> Result Str _
part1 = \_ -> Err TODO
part2 : Str -> Result Str _
part2 = \_ -> Err TODO
I've been going back through my solutions to previous years, and upgrading those to use this template to test it out. But if you find any issues, or have ideas to improve this please let me know :smiley:
Looking forward to another AoC :christmas: :holiday_tree: ... well, getting prepped for it now.
Preemptively, can we switch this over to the roc ascii package instead of Str.
@Brendan Hansknecht
I tried it briefly and mentioned it here https://roc.zulipchat.com/#narrow/channel/304641-ideas/topic/AoC.20template.20idea.20--.20using.20module.20params/near/481219400
The short answer is it didn't feel nice to work with when I tried updating a few examples.
I'm happy to improve the template in future if we can find a nicer experience.
Ah, missed that
I've shared a link on the AoC reddit... link to post
If you have a reddit account, it'd be great if you made a comment or like to help promote the post. I'm not farming Karma or anything, just keen for new people to see the link and hopefully try roc out. :D
I'm not sure if it's best to navigate by the link, or from the New list -- for the sake of the ranking algorithm
And I definitely accidentally wrote Advent of Roc :sweat_smile: unfortunate typo for that subreddit
mind is less fancy than yours https://github.com/drewolson/aoc-roc
it's basically the same thing i have in all other FP languages i've used for aoc
now that you merged the fix for my bug, i might try roc in addition to gleam this year
is there anything written on module params anywhere? are they basically functors from ocaml?
There's the original design doc https://docs.google.com/document/d/110MwQi7Dpo1Y69ECFXyyvDWzF4OYv1BLojIm08qDTvg/edit?tab=t.0#heading=h.cxx7dzgwu0ye
thanks
Then there's the actual cli tests in the repo https://github.com/roc-lang/roc/tree/main/crates/cli/tests/test-projects/module_params
related to the bug fix, do you know when new releases are created?
The syntax changed slightly in discussions post that proposal
Which bug fix? -- sorry I've looked at a lot of bugs today :bug:
Luke Boswell said:
Which bug fix? -- sorry I've looked at a lot of bugs today :bug:
ha, no problem. you literally just merged it like 30 mins ago, it was the bug related to running roc check
on a single module
Ah https://github.com/roc-lang/roc/pull/7283
yep
So the Nightlies get created manually by @Anton. They're not really every night... it's more like every other day. I'm not 100% on what time, it's usually while I'm asleep :smiley:
cool, np
I imagine he will probable make a new one in about 12hours from now... just a random pluck though.
awesome, good luck on aoc!
Thanks, you too
1 min to go :tada:
finally an easy day 1 :smile:
(that is, easy like normal, not like last year)
Am I the only one who's stuck on reading the entire file? It broke my brain all the day on why my day2 didn't work before seeing that my file was not entirely read :sob:
My file is 16578 char long and it stops at 16384.
I'm running the code with:
$ roc dev 02.roc < ../input/02.txt
by running cat
it works well:
$ cat < ../input/02.txt | wc -c
16578
Ah yes, this is a limitation of Stdin.bytes
, I've said before that we should change it's name to make that limitation clear. Can you try with Stdin.readToEnd
instead?
Yes, it works well! Thank you!
how we change that function to accept the number of bytes you want to read? I think that would remove the footgun :big_smile:
Ghislain said:
Am I the only one who's stuck on reading the entire file? It broke my brain all the day on why my day2 didn't work before seeing that my file was not entirely read :sob:
I immediately changed from stdin to reading the file directly.
I was quite happy that, because the template just expects an effectful function that returns bytes you can pass in a function that containing a file read for that days file.
Eli Dowling said:
Ghislain said:
Am I the only one who's stuck on reading the entire file? It broke my brain all the day on why my day2 didn't work before seeing that my file was not entirely read :sob:
I immediately changed from stdin to reading the file directly.
I was quite happy that, because the template just expects an effectful function that returns bytes you can pass in a function that containing a file read for that days file.
This works I unreasonably well, just don’t forget about that trailing newline
because the template just expects an effectful function that returns bytes you can pass in a function that containing a file read
Even though I know this was one of the main motivations for module params... it still feels amazing that this works so nicely. Thank you for sharing. :smiley:
Maybe I should rename it from stdin
to something like input
and also include a couple of different examples (reading from stdin, reading from a file, embedding a file in the binary etc)
What do you think @Eli Dowling
Yeah, it's a cool way to gently introduce the power of module params in a subtle way.
I think it definitely helps to ease folks in to just see them being used without having to really understand too much so I like it.
you could even mention along with the example options.
"if you wanted to, you could even do something fancy like a web request that gets your results with your token"
https://github.com/lukewilliamboswell/aoc-template/issues/7
The unison template does everything via your AOC token and it's pretty damn impressive. you can get the inputs, and submit the output, I think next year it would be cool to have something similar.
It's, again a really cool way to just ease folks into understanding how to do some more advanced things in roc with a real world working example.
Like with unison the first thing I did was open up the template and see how you make bindings to a web api in unison. It's great, because the goal is extremely simple, and I already know what it's going to be doing, it makes understanding the code in a new language much more achievable.
"if you wanted to, you could even do something fancy like a web request that gets your results with your token"
The downside with that is that then you'd be making a request each time you run your code which they definitely don't want poeple to do
True, We'd definitely want to cache your results. Maybe we can provide an example of that to ensure they properly use caching.
This is my personal setup script and template:
# setup.roc
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.17.0/lZFLstMUCUvd5bjnnpYromZJXkQUrdhbva4xdBInicE.tar.br" }
import pf.Stderr
import pf.Http
import pf.Arg
import pf.File
import pf.Env
main =
args = Arg.list! {}
when args is
[] | [_] -> Stderr.line "Please pass in the day you would like to set up"
[_, day, ..] ->
session = Env.var! "AOC_SESSION"
_ =
Http.defaultRequest
|> &url "https://adventofcode.com/2024/day/$(day)/input"
|> &headers [{ key: "Cookie", value: "session=$(session)" }]
|> Http.send!
|> .body
|> File.writeBytes! "input/$(day).txt"
File.readUtf8! "template.roc"
|> Str.replaceEach "{{DAY}}" day
|> File.writeUtf8! "$(day).roc"
# template.roc
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.17.0/lZFLstMUCUvd5bjnnpYromZJXkQUrdhbva4xdBInicE.tar.br" }
import pf.Stdout
import pf.File
main =
input = File.readUtf8! "input/{{DAY}}.txt" |> Str.trim
Stdout.line!
"""
Part 1: $(Inspect.toStr (part1 input))
Part 2: $(Inspect.toStr (part2 input))
"""
part1 = \input ->
"wip"
part2 = \input ->
"wip"
oh, cool! We could totally just whack most of your first script into a function, and either read the file or download it depending on if it exists
how we change that function to accept the number of bytes you want to read? I think that would remove the footgun :big_smile:
I've made a note to write up a proposal for several changes to stdin
Something I think would be super cool for next year, is if we can get a really standardised format for the aoc template it'd be fun to make a bot/github actions something or rather that downloads peoples entries and then runs them and gives performance results.
Maybe something as simple a command that you run "aoc! http://mygithub/day4.roc"
Then it gives a performance result.
2 days after it could announce the fastest run.
Last updated: Jul 06 2025 at 12:14 UTC