4 ms·
You don't mention error handling at all. Will it have exceptions? Can I catch exceptions in functions, or will functions be limited to calling APIs that cannot
by iso8859-1 5y ago
You don't mention error handling at all. Will it have exceptions? Can I catch exceptions in functions, or will functions be limited to calling APIs that cannot fail? So no integer division in functions? Or will it just have floats everywhere like JavaScript had?
What is the rationale for disallowing logging in pure functions? It sounds like one would be forced to develop an algorithm as a procedure, and then remove all logging and convert it into a function when its done. Then, when you want to refactor it, you'll have to convert it back to being a procedure.
- brundolf 5y agoThat's a great point about error handling; it's something I haven't given much thought to yet for Bagel specifically 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
- deleted 5y ago[deleted]
- rad_gruchalski 5y agoMaybe scala Try type could be a good thing to look at.
- brundolf 5y agoIt looks similar to Rust's Result<> type, which is my current model for what errors-as-values might look like
- rtfeldman 5y ago> 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. 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!
- brundolf 5y agoI should look into Elm's approach; tbh I've been looking to Elm for battle-tested answers to lots of these questions, even though I'm also doing several things very differently from Elm 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 :)
- DylanSp 5y agoError handling is definitely something to think hard about. Personally, I like Maybe/Either types, especially combined with syntax to make them easier to work with, whether that's Haskell's do syntax or Rust's ? operator.