enable building proper with OTP-29#324
Conversation
mikpe
commented
Feb 18, 2026
- eliminate old-style catches
- resolve is_record/1 ambiguity
- fix variable exported from subexpression
- eliminate old-style catches - resolve is_record/1 ambiguity - fix variable exported from subexpression
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #324 +/- ##
==========================================
+ Coverage 85.27% 85.41% +0.14%
==========================================
Files 14 14
Lines 4590 4594 +4
==========================================
+ Hits 3914 3924 +10
+ Misses 676 670 -6 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
| R = [{M,T,A,proper_typeserver:demo_translate_type(M, stringify(T, A))} | ||
| || {M,T,A} <- MTs], | ||
| {OKs,Errors} = lists:partition(fun type_translation_is_ok/1, R), | ||
| {[Inst || TGen <- OKs, (Inst = pick_instance(TGen)) =/= ok], length(Errors)}. |
There was a problem hiding this comment.
I want to understand the rationale for this change and what exactly is wrong with this code in general and in the upcoming OTP 29. To me, this code besides being "valid Erlang", is perfectly understandable in what it does and how it achieves it. Moreover, it's the last statement in the body of this function, so there is not even a chance that variables will be used after it. So why is it better to have to write a new function of six lines for it?
Also, I've noticed that the release notes for the pre-releases of 29 advertise a "new language feature" that encourages such code. I quote from that page:
By enabling the compr_assign feature, it is now possible to bind variables in a comprehensions. For example:
[H || E <- List, H = erlang:phash2(E), H rem 10 =:= 0]
How does the PropEr code differ from this example and what am I missing?
There was a problem hiding this comment.
It's due to an unfortunate combination of two language changes:
- Exporting bindings from subexpressions is deprecated. In this case the lhs of
(Inst = ...) =/= oktriggers that. Plain matches don't count as subexpressions. - Previously you could write
[Y || X <- L, Y = f(X), predicate(Y)]and it would compile but give abad filterexception at runtime. The other change, enabled bycompr_assign, makes those bindings work.
I've experimented a bit and found a shorter workaround: instead of having a match (Y = f(X)) to bind the intermediate value, use a single-element generator (Y <- [f(X)]). I'm pushing an update with that change.
kostis
left a comment
There was a problem hiding this comment.
Thanks for the PR. I've left a comment concerning one of the changes.