Stream: beginners

Topic: function with no parameters


view this post on Zulip noonien (Nov 20 2023 at 16:19):

how can a function that has no parameters be defined? from what i can tell from the tutorial, values become functions when either they have parameters, or call other functions. am I misunderstanding something?

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:23):

It can't. The normal convention is to pass an empty record to the function.

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:23):

So it still has one argument

view this post on Zulip noonien (Nov 20 2023 at 16:24):

interesting

view this post on Zulip Richard Feldman (Nov 20 2023 at 16:24):

it should be a very rare use case, since Roc functions can't have side effects :big_smile:

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:24):

Simple example from builtins: https://www.roc-lang.org/builtins/Dict#empty

view this post on Zulip noonien (Nov 20 2023 at 16:25):

well, with no side effects, it would basically be useless, but I'm wondering what happens when calling platform functions that do have side effects

view this post on Zulip noonien (Nov 20 2023 at 16:25):

maybe something like getting the environment variables

view this post on Zulip noonien (Nov 20 2023 at 16:25):

or something simpler, like getting the time

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:27):

Getting the environment variables or or time actually ends up not hitting this due to needing to await a task. So it would be something like

Task.await Time.now \time -> ...

view this post on Zulip noonien (Nov 20 2023 at 16:28):

seems like the reason that function is a task is because of this

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:29):

I don't follow exactly what you mean.

view this post on Zulip noonien (Nov 20 2023 at 16:30):

I don't see any reason for Time.now to return a task on most platforms.

view this post on Zulip noonien (Nov 20 2023 at 16:30):

nor why it would receive a callback

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:31):

Oh, it has to in roc. There is no other option. It is not a pure function. Every I/o primitive in roc has to be wrapped in the effect API.

view this post on Zulip noonien (Nov 20 2023 at 16:31):

i see, and the effect API only works with tasks?

view this post on Zulip noonien (Nov 20 2023 at 16:31):

can the platform not supply no-argument functions to roc?

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:32):

Task is built on top of the effect API. It is just used everywhere for convenience of being able to handle errors.

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:33):

can the platform not supply no-argument functions to roc?

Time.now would be an example of an effect that takes no arguments. Stdout.line would be an example of the reverse. 1 input with no result.

view this post on Zulip noonien (Nov 20 2023 at 16:35):

ah, i see, i read that code wrong, the function was not an argument to Time.now, but to task.await

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:36):

Yes, sorry about the confusion.

view this post on Zulip noonien (Nov 20 2023 at 16:36):

but, how does Task.await call a function with no arguments?

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:38):

Effects aren't technically functions. They are more like futures. So Time.now would actually just be a constant. Eventually, this code will get to builtin effect stuff that the compiler implements internally to connect the platform to the application. I forget the exact function that is call, but it is similar to await and takes an effect and a callback.

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:39):

This will then call a roc_fx_TimeNow function that the platform exposes to roc and do what is necessary to wrap that up as an effect.

view this post on Zulip noonien (Nov 20 2023 at 16:40):

i see

view this post on Zulip noonien (Nov 20 2023 at 16:42):

hmm, are Tags functions? or can they just be called as functions?

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:44):

A tag name is also a function for generating that tag variant.

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:46):

Enable you to something like |> List.map Ok which should wrap all of the elements in a list with the Ok tag.

view this post on Zulip noonien (Nov 20 2023 at 16:47):

i'm guessing |> List.map None would not work, requiring |> List.map \_ -> None instead

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:50):

Correct, if you had a None variant that takes no args, I think it only gets a constant of the variant rather than a function cause there would be no valid way to generate it with a function.

view this post on Zulip noonien (Nov 20 2023 at 16:51):

the convention is that every identifier that starts with an uppercase letter is a tag, right?

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:54):

Uppercase is a Type in general. So you might see

Result ok err : [Ok ok, Err err]

But you would also see uppercase for a tuple or record:

Tup : (Str, U8)
Person : { height: U32, name: Str }

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:56):

Oh, I guess uppercase is also used for module names as in List.map

view this post on Zulip noonien (Nov 20 2023 at 16:57):

i was a bit confused about this in the repl

» foo = \n -> "hello \(n)"
 : Str -> Str

» foo
 : Str -> Str

» Bool
Bool : [Bool]

» Bool.true
Bool.true : Bool

view this post on Zulip noonien (Nov 20 2023 at 16:58):

you can refer to identifiers with lowercase first letter, but not with uppercase, because they are turned into tags

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 16:59):

Yes, all value identifiers are required to start with lower case letters in roc.

view this post on Zulip noonien (Nov 20 2023 at 16:59):

except type identifiers

view this post on Zulip noonien (Nov 20 2023 at 16:59):

and module identifiers

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 17:00):

So, roc will automatically infer types. If you just type an uppercase name into code somewhere, it has to be a variant of a tag.

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 17:00):

That is what happens when you just type a capital word into the repl.

view this post on Zulip noonien (Nov 20 2023 at 17:00):

yup

view this post on Zulip noonien (Nov 20 2023 at 17:01):

is there a way to find the definition of a type?

view this post on Zulip noonien (Nov 20 2023 at 17:02):

say you define the following type:

Tup : (Str, U8)

Is it possible to find out what a Tup is, in the repl?

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 17:02):

Hmm... I don't think so

view this post on Zulip noonien (Nov 20 2023 at 17:03):

fair enough

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 17:03):

Good feature idea though

view this post on Zulip Brendan Hansknecht (Nov 20 2023 at 17:04):

May be hard given we are a fully compiled language and not an interpreter though.

view this post on Zulip noonien (Nov 20 2023 at 17:05):

I'm actually working on a simple language myself, and I'm trying to understand how roc works and what tradeoffs have been made. simplicity always comes at a cost, but the cost can most of the time not be an issue

view this post on Zulip noonien (Nov 20 2023 at 17:05):

Brendan Hansknecht said:

May be hard given we are a fully compiled language and not an interpreter though.

yes, this would only be a repl feature

view this post on Zulip Jacob (Nov 20 2023 at 17:05):

Yeah this is one thing I miss from lean. Using #eval or #check in the editor and seeing live results in the editor is amazing.


Last updated: Jul 05 2025 at 12:14 UTC