Raison d'être of Iron #73
-
Hi, I was looking at this library and wondering what the use cases are when there is already a library like refined? What are the differences besides Iron being written from scratch in Scala 3? Thanks! |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hi. The use cases of Iron are rather the same as refined: securing your objects/values (usually domain models) by forbiding wrong values, using type constraints. Despite sharing the same goal, Iron and refined has differences in their approach.
Being written for Scala 3 allows Iron to use Dotty-specific features, especially opaque types, inlines and new macros. An opaque type is a type alias whose inner type is not known at compile-time in external files. Both Iron and refined (in Scala 3) use this feature for their refined type ( Iron: val x: Int :| Greater[0] = 5
println(x + 1) desugars into val x: Int = 5
println(x + 1) Refined: val x: Int Refined Positive = 5
println(x + 1) desugars into (in Scala 3) val x: Int = autoRefineV(5)
println(autoUnwrap(x) + 1) Another (bigger) difference is about API/metaprogramming itself: Refined uses shapeless to evaluate at compile-time constraints while Iron heavily relies on Scala 3's inline. Inline brings two main benefits to Iron compared to Refined:
For example, the following code works in Iron because it satisfies the above rule: transparent inline def abs(inline x: Int): Int =
inline if x >= 0 then x
else -x
inline val x = 5
inline val y = -7
val z: Int :| Greater[0] = abs(x) + abs(y)
println(z) If it doesn't (for example because whether [error] To test a constraint at runtime, use the `refined` extension method.
[error]
[error] Note: Due to a Scala limitation, already-refined types cannot be tested at compile-time (unless proven by an `Implication`).
[error]
[error] Inlined input: abs(x).+(abs(y))
[error] val z: Int :| Greater[0] = abs(x) + abs(y)
[error] ^^^^^^^^^^^^^^^ Note: here I made There are other differences (like constraint declaration) but they are in my opinion negligible. |
Beta Was this translation helpful? Give feedback.
Hi.
The use cases of Iron are rather the same as refined: securing your objects/values (usually domain models) by forbiding wrong values, using type constraints.
Despite sharing the same goal, Iron and refined has differences in their approach.
Being written for Scala 3 allows Iron to use Dotty-specific features, especially opaque types, inlines and new macros.
An opaque type is a type alias whose inner type is not known at compile-time in external files. Both Iron and refined (in Scala 3) use this feature for their refined type (
IronType
for Iron,Refined
for refined) to eleminate the overhead of a class. Howe…