Currently there's expect-fx (IIRC?) - but I'd like to change that one for the same reason.
ok
A message was moved here from #ideas > more keywords in syntax by Richard Feldman.
A message was moved here from #ideas > more keywords in syntax by Richard Feldman.
so the reason behind the expect-fx naming is:
expect fx would be syntactically ambiguous with expect followed by a variable named fxexpectfx would introduce a new language keyword, which would set the precedent that whenever we have to introduce a new type of expect (I think there's a decent chance we'll want to use these for optimizations, e.g. expect-tco) we have to introduce a new language keyword, which is always a breaking syntax changeexpect-whatever can always be introduced as a nonbreaking syntax change because you can never write expect-blah for any value of blah since expect as a keyword already can't be followed by a -I'm open to alternative design ideas here!
I remember seeing something about a possible syntax to wrap around backpassing (similar to haskell's do notation) - could we just use expect + that new syntax?
The other thing that comes to mind is something like expect <- myTask
Supposing the 'do' like syntax is something like this:
with Task.await
a <- myTask
# ...
... then we could just allow that at global scope, and interpret any expects inside such a block as expect-fx's
and interpret any expects inside such a block as expect-fx's
with Task.await
a <- myTask
v = isValid a
expect v
I don't think that is an expect-fx. It is an expect That happens to run within a task.
Doesn't that accomplish basically the same thing? (at least, given the right interpretation of what a top-level 'with' block means?)
Doesn't expect-fx require an input that will generated by the task? Cause expect-fx is about mocking out tasks.
In this case, I would assume either, this expect is invalid, or it can happen at runtime as a verification.
If at runtime expect-fx doesn't make any sense.
but maybe I don't understand how expect-fx works.
oh expect-fx doesn't mock - it actually runs the task for real!
for the (planned but not yet implemented) simulated tasks, ordinary expect will most likely work fine
the point of expect-fx is when you actually want to run your effects during tests, e.g. you want to create a real tempfile, write to it, etc.
since they use the host, they each have to be run in their own separate process so that if they segfault (for example) it won't take down the whole test runner
oh, I miss understood expect-fx then. Cool. Thought it was roc only and didn't depend on the host.
yeah hopefully we can just use normal expect for the version that doesn't use the host, but we'll see when we get to the implementation stage on that! :smiley:
What if we made the side-effecting tests and mocked out tests the same thing? i.e. by default, running a new side-effecting test will run the side effects and automatically record all the tasks executed / results-of-host-calls into a file (which you're expected to check into your repo). All further test runs will by default run the test in fully-sandboxed mode, simply relying on the checked-in file.
If the test diverges from the expectation, you could (depending on config):
what if we called it expect.fx?
so it looks like normal roc syntax
it'd be a bit unusual in that you can give an expression to expect and also give an expression to expect.fx - so it would kinda look like expect is "a function but also a record somehow" if it were a variable, but of course it's actually a language keyword (which syntax highlighting should make clear) so of course it doesn't follow the rules variables do
expect.fx does not seem like it would address the original concerns of @Joshua Warner mentioned here.
yeah so I haven't tried it out yet, but I suspect the way we actually want lexing of identifiers to work, it will be better if we don't lex dots separately, but rather give the parser the entire contiguous foo.Bar.Baz.blah.0.1 and then parse that string one character at a time
because if the lexer emits tokens for dots, and it doesn't emit spaces, then the parser sees IDENT, DOT, IDENT for each of foo.bar, foo .bar, and foo . bar, and then it needs to do special things to distinguish between those cases because they're all supposed to parse differently
in the alternate design, where the entire chain of dotted things is one IDENT, then the parser sees expect.fx as a single token, and it's trivial to recognize it as a keyword
(just like any other keyword, which would be handled the same way)
Richard Feldman said:
it would kinda look like
expectis "a function but also a record somehow"
I have an intuitive negative reaction to this because my brain has trouble parsing it even if the compiler doesn't. It doesn't fit into some existing pattern in the language so it is complicating my mental model.
So I think expect-fx and expectFx are both better for this reason
Last updated: Jun 16 2026 at 16:19 UTC