Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

What about extremely trivial expected conditions that occur all over the program? "expect()" would get tiring pretty quickly.

  Regex::new(r"\bstruct\b").unwrap()
  // vs.
  Regex::new(r"\bstruct\b").expect("bad regex string literal")


> For example, regular expressions. The regex crate uses a method called new that is used to prepare regular expressions. It is practically always called on a constant string, making any failure a logic error, which should result in a panic, as discussed above. However, this same new method returns a Result, necessitating an unwrap or an expect to make the logic error into a panic. Am I seriously suggesting that the poor user write .expect("bad regular expression") instead of .unwrap() every time?

> Well, that puts regex compilation in the same category as array indexing in my mind, and means that the default regex compilation function should panic on the user’s behalf (of course, the Result version should still be possible, just as get is a possible function for slices).


Except when you want to compile a regex at runtime from some input (like a config file for example).


But in that situation you'd want a Result because it absolutely could fail at runtime. And you wouldn't want to use unwrap on that because user input could tank your program.

I think it would make sense for there to be some kind of compile-time macro for regexes. If the regex is based on a constant string then it should be a build error when that regex isn't valid. And the existing API (result, unwrap and all) would work great for non-constant strings.


In this case at least it seems like one solution is just compile-time function evaluation?

Due to the literal, hypothetically that Regex::new's result can be pre-computed and the result encoded in the output binary, not the initialization.


Regex used to offer a regex!() macro that did compile-time compilation, but this was removed a while back as it was too much of a maintenance burden and was getting in the way of performance optimization.


Well, there we go, then. Nobody wants to do the work.


IIRC it required basically two separate implementations of the data structures, one that could be constructed at compile-time and was less efficient than the one that could be built at runtime. And the need to support both was becoming a problem.

I feel like there should be a middle ground here, a macro that validates at compile-time but still constructs at runtime. Hopefully the parser could still be shared between the macro and the runtime to ensure the macro can't get out of sync.


The author encourages something like:

Regex::new(r"\bstruct\b").some_custom_function_that_calls_expect()

or

Regex::new_or_panic(r"\bstruct\b") // Just calls Regex::new(r"\bstruct\b").expect("bad regex string literal")


Sounds very similar to annoying Java checked exceptions for stuff like 'new URL("http://example.com")' -- it can't fail, but you have to catch it.

The industry dealt with that by using your own utility functions like "create an Url and convert exceptions to runtime ones" (Java folks don't focus that much on quick pet projects, so don't mind extra work).


You want the "?" operator.


No, because propagating an error due to an incorrect static string to the caller is not the right thing to do.


Isn’t the point that in this case it cannot ever error because the string is static?


Yes, but if you use the `?` operator, as the comment I replied to suggested, then you have to return a `Result`, which the caller has to unwrap themselves or otherwise handle. Except the caller doesn't have this context about how it can't be an error because it's a static string. Propagating the (impossible) error up the call chain is the worst of all worlds in a case like this.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: