Nike-Inc / hal

hal provides an AWS Lambda Custom Runtime environment for your Haskell applications.
BSD 3-Clause "New" or "Revised" License
238 stars 13 forks source link

Eliminate Possible Laziness Between Executions #136

Open IamfromSpace opened 9 months ago

IamfromSpace commented 9 months ago

130 address an issue where exceptions weren’t caught in the runtime code because of laziness, but the next step is to try an eliminate this happening in user code too. There’s little reason for laziness to delay evaluation beyond the current execution—or it should be GC’d, knowing it could never be evaluated at all.

@kokobd, it sounded like your suggestion was to add an NFData constraint?

kokobd commented 9 months ago

@kokobd, it sounded like your suggestion was to add an NFData constraint?

  1. For dealing with exceptions thrown in pure functions in user code, there is another way without using NFData. At this line: try (fn (either error id eCtx) event), currently we don't call toJSON or Aeson.encode. If we convert the result to json within this expression, we are effectively forcing evaluation.
  2. For dealing exceptions thrown by hal's library code, I suggest a refactor of error handling: a. Use explicit throwIO instead of error b. Make error type customizable - not limited to the current User error.
IamfromSpace commented 9 months ago

Is (1) enough for all possible user code? I was imagining that if hal code for parsing could get tripped up by this, other kinds of user errors could too. A user with error in their pure runtime likely doesn’t expect that the runtime would exit, and it seems like it would? I’ve been planning to see if I can recreate this.

kokobd commented 9 months ago

The user is free to create any bottom value (infinite list or error) in their data structure as long as it's irrelant for ToJSON. After we get the result Aeson.Value, no user code will be forced to run anymore, so no new pure error could be thrown. The only other place where the user can throw an error is their IO monad, but that is catchable by try. So the runtime won't be crashed.