numbat icon indicating copy to clipboard operation
numbat copied to clipboard

Using procedures in functions

Open Goju-Ryu opened this issue 1 year ago • 6 comments

I found myself wishing to be able to call procedures inside a function today. My use case was to set up the arguments of an assert I planned to run in many different variations. I wanted to test mys implementation of human against the existing one and thought I'd write something like the following:

fn test_human(time: Time) = assert_eq(time -> human, time -> human_new)

fn test_human_range(times: List<Time>) = times |> map(test_human)

I think it would be very beneficial for testing if something like the first line at least was possible. The second line is probably a lot more involved, so I won't focus too much on it.

I imagine it might be difficult or undesirable to mix functions and procedures, in which case I would instead propose to introduce custom procedures, a function-like construct that can only call other procedures.

Goju-Ryu avatar Oct 10 '24 21:10 Goju-Ryu

I found myself wishing to be able to call procedures inside a function today.

Yes, I can understand the pain. I also wanted something like this in the past.

On the other hand, that would complicate the language / type system a lot, I'm afraid. For now, function bodys are simply expressions. With your suggestion, we would allow (arbitrary) statements in the function body.

I imagine it might be difficult or undesirable to mix functions and procedures

Right.

in which case I would instead propose to introduce custom procedures, a function-like construct that can only call other procedures.

… or dare I say ... a macro? :smile:

Let's think about it!

sharkdp avatar Oct 23 '24 18:10 sharkdp

I didn't even think about what I described in the end was basically just a macro. I would love for numbat to have a good macro system, but I think it takes quite a bit more thought than I originally imagined. For now, should I change the title and update the description to reflect that the issue will be about implementing macros?

Goju-Ryu avatar Oct 23 '24 18:10 Goju-Ryu

For now, should I change the title and update the description to reflect that the issue will be about implementing macros?

Macros would be one way to support your use case. Let's also think about other ways. The title of the ticket is good as it is, thanks.

sharkdp avatar Oct 23 '24 18:10 sharkdp

Hey, I'm late to the party sorry (but happy to be back)

I was wondering. What is the deal with procedures? Why not say they're not "magical" and are just normal functions that return nothing? I guess we need a new type to express nothing like the unit type () in rust, bottom, nil, None`, or anything else.

irevoire avatar Oct 05 '25 20:10 irevoire

I was wondering. What is the deal with procedures? Why not say they're not "magical" and are just normal functions that return nothing? I guess we need a new type to express nothing like the unit type () in rust, bottom, nil, None`, or anything else.

That's a really good question actually. I hadn't thought about it and I don't know. I would have guessed that function purity could have something to do with it, but the datetime functions are impure and can be used normally. I think @sharkdp will have to weigh in on this one. I think this is a really good idea as long as there isn't something we are overlooking.

Goju-Ryu avatar Oct 06 '25 21:10 Goju-Ryu

I was wondering. What is the deal with procedures? Why not say they're not "magical" and are just normal functions that return nothing? I guess we need a new type to express nothing like the unit type () in rust, bottom, nil, None`, or anything else.

I think there is a lot of value in keeping functions pure (without any side effects). I think it makes a lot of sense for a language like Numbat to have a concept of functions that is close to the mathematical meaning of a function. For example, it would allow us to do lazy evaluation semantics (see Haskell) or to add memoization of function return values.

On the other hand, we already violated that property by introducing FFI functions like now() and random() that can be called from within functions. If we'd really like to go down the route of pure functions, we would have to introduce an effect system or higher-kinded types so we could use monads. I'm not sure if that would really be a win for Numbat users.

sharkdp avatar Oct 12 '25 15:10 sharkdp