Something to consider: if people come to rely on the logging in production (not just for debugging), and then you later do performance optimizations like memoization which skip calling a pure function because you know what answer it will give, then it'll break people's production code.
You can discourage it in the docs of course, but Hyrum's Law (plus my own experience with seeing how the equivalent Debug.log has been used in Elm) makes it safe to assume it'll happen!
With that said- I'm seeing this as purely a `console.log` feature, not a generic logging feature that could go to some arbitrary logging service. And become a part of a company's infrastructure. I guess in a server context even console logging could be abused that way... but at a certain point there's only so much you can do to protect the user from themselves :)
However, I will say that I generally dislike exceptions and try/catch, and I think JavaScript's implementation of it is possibly the worst one out there, so I'm definitely going to deviate from that here
Pure code should generally be free of errors, except for a handful of special cases like network requests which will almost certainly be handled as values. This will require some kind of story for nominals/enums/discriminated unions, which I'd planned to work out anyway
Things are more up in the air for procedures. Errors could become the only thing procedures "return", or I might do a(n improved) version of JavaScript's try/catch, or I might just do "nuclear" panics like Rust with no ability to catch. Gonna have to do some experimenting here to see how it fits into Bagel's split paradigm
Re: numbers, all the core data types are going to have the exact same semantics as those in JavaScript, which includes numbers
Logging won't be disallowed in pure functions; I hadn't mentioned it but I plan to include a log() pure function that does nothing but log a value and return it, so you can insert it into any expression for debugging. Technically this breaks with the "no side-effects" rule, but I think it's an acceptable compromise since the effect would never have any chance of coming back around and impacting your code's behavior later on. It's fully external.
Another thing that will help with writing pure code is "let expressions" (I'll probably use the const keyword for consistency), which allow you to set aside intermediate values during a pure expression