I wanted to try out the Nim language so I wrote a simple program to retrieve the top \$n\$ messages on a given subreddit in a given time frame and open them in the default browser.

I would really appreciate your feedback on how to do things more idiomatically.

import std/[strformat, rdstdin, parseutils]
import std/[httpclient, json, browsers]

    headers: HttpHeaders = newHttpHeaders({"User-Agent": "Mozilla/5.0"})

proc get_best_posts_url(subreddit: string, t: string = "week", count: int = 1): seq[string] =
    var url = fmt"https://www.reddit.com/r/{subreddit}/top.json?t={t}&limit={count}"
    var client = newHttpClient(headers=headers)
    var response = client.get(url)
    var json = parseJson(response.body)
    var posts = json["data"]["children"].getElems()
    for post in posts:

proc open_best_posts(subreddit: string, t: string = "week", count: int = 1) =
    for url in get_best_posts_url(subreddit, t, count):
        openDefaultBrowser url

when isMainModule:
    var subreddit = readLineFromStdin("Enter subreddit: ")
    var t = readLineFromStdin("Enter time period (day, week, month, year, all): ")
    var count: int
    discard readLineFromStdin("Enter number of posts: ").parseInt(count)
    open_best_posts(subreddit, t, count)

1 Answer 1

  • The code is straightforward to read and understand.

  • Nim idiomatically uses two spaces for indentation, not four (see e.g. the standard library style guide, or all code examples in the official tutorial).

  • The style guide advises to use camelCase for identifiers like function names, not snake_case (given Nim's style insensitivity this is more open to personal preference, however this feature is considered to be removed from the language).

  • Nim has two keywords for declaring variables: var and let. The difference is that variables declared with var can be changed after being declared (and they do not need to be initialized) and variables declared with let cannot (they are immutable). It is always a good idea to use immutable variables where possible, because this eliminates the mental load of tracking where a variable is changed during a program (it can also help the compiler optimize the program, but I think this is not important in this case). This is also covered in the standard library style guide.

    All variable declarations in your program can be changed to let, except count in the when isMainModule: block (it is declared uninitialized and then needs to be changed by parseInt).

  • The program allows the user to any string for the time period. I could not test what happens when the user enters nonsense, because I did not have SSL set up, but probably the program should do some input validation to avoid sending incorrect parameters to the Reddit API.

    After compiling with -d:ssl it seems to me that the Reddit API accepts any string for the time period and number of posts and uses default values, so the input validation might not be needed.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.