home bbs files messages ]

Forums before death by AOL, social media and spammers... "We can't have nice things"

   comp.os.vms      DEC's VAX* line of computers & VMS.      264,096 messages   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]

   Message 263,812 of 264,096   
   Dan Cross to arne@vajhoej.dk   
   Re: Unsafe code blocks   
   21 Nov 25 03:03:25   
   
   From: cross@spitfire.i.gajendra.net   
      
   In article <10fob5c$3aj3s$1@dont-email.me>,   
   Arne Vajhøj   wrote:   
   >On 11/20/2025 6:54 AM, Dan Cross wrote:   
   >> In article <10flqou$2l1qc$1@dont-email.me>,   
   >> Arne Vajhøj   wrote:   
   >>> On 11/19/2025 11:02 AM, Dan Cross wrote:   
   >>>> Further, by localizing the unsafety inside of the conversion,   
   >>>> and using a return type that can represent failure, one can   
   >>>> construct a _safe_ interface to do _unsafe_ conversions.   
   >>>   
   >>>> In contrast, `Valid` is easy to misuse, primarily by not using   
   >>>> it at all, in which case you run the risk of raising a runtime   
   >>>> exception, or just having an incorrect program.  With either   
   >>>> `Option` or `Result`, you are forced to contend with the error   
   >>>> case.  The programmer can't forget to check.   
   >>>>   
   >>>> Finally, `Valid` is very limited in its applicability: it can   
   >>>> only be used with scalar types.  At least in Rust, `Option` and   
   >>>> `Result` are generic over essentially arbitrary types.   
   >>>>   
   >>>> Put another way, if the language supports something like an   
   >>>> `Option` type, then there is no need for a special-case facility   
   >>>> like Ada's `Valid` attribute.   
   >>>   
   >>> All fine.   
   >>>   
   >>> But you can do the same in Ada.   
   >>   
   >> Indeed, you can, but I never said you couldn't.   My point was   
   >> that Ada's `Valid` attribute is overly specific, underpowered,   
   >> and ultimately unnecessary in a language that supports proper   
   >> sum types over generics.  Ada's `Valid` attribute is neither as   
   >> general nor as robust as using an ADT like   
   >> Option/Result/Maybe/whatever it's called in any given langauge.   
   >   
   >Ada's valid does exactly what it is supposed to do: check if the   
   >output from an Unchecked_Conversion meet the constraints of the   
   >data type.   
      
   Again.  Ada's `Valid` attribute is overly specific (it cannot be   
   repurposed for other things), underpowered (it only applies to   
   scalars and, critically, can be ignored) and unnecessary if a   
   language has an `Option` (`Maybe`) or `Result` (`Either`) type.   
      
   >It is not a replacement for Option/Result.   
      
   No, it is not.  Indeed, it _cannot_ be since it is a strictly   
   weaker construct in all respects.   
      
   However, `Option` or `Result`, in conjunction with something   
   like `TryFrom`, _can_ be a replacement for `Valid`, because   
   things like `TryFrom` and `Option`/`Result` are more general and   
   more powerful than `Valid`.   
      
   >It can be used to implement Option/Result for those   
   >types that can be set with Unchecked_Conversion, but obviously   
   >not for other data types.   
      
   It could be, but it doesn't _need_ to be.   
      
   I can see how `Valid` might be _useful_.  Unfortunately, the   
   construct seems overly rooted in some fundamental assumptions   
   that Ada made about the world back in the 70s and 80s.  It's   
   just been passed by by the state of the art since then, as has   
   Ada more generally.  That's a pity; Ada isn't a _bad_ language,   
   but we have better alternatives now.   
      
   >A screwdriver is not good for hammering nails into wood,   
   >but that does not mean that a screwdriver is a bad tool - it   
   >is just not intended for that usage.   
      
   Non sequitur.  You seem to be arguing something nobody was   
   saying.  What I am saying is that `Valid` isn't a great tool for   
   its intended purpose.  It's like trying to turn a phillips-head   
   screw with a flat blade driver by sorta twisting it to the   
   side....   
      
   >Regarding the risk of not being checked, then it is inherent   
   >in the problem - no matter the mechanism used then the developer   
   >can chose not to do it right, because "there will always be   
   >a valid value here".   
      
   Nope, this is wrong.  The whole point of a Rust-style `Option`   
   or `Result` is that you are no longer working in terms of the   
   generic type T, but rather a wrapper around that type; if that   
   wrapper has the value `None` then there is no T, so the   
   statement, 'because "there will always be a valid value here"'   
   is, by definition, incorrect.  The programmer is forced to   
   contend with this possibility because because the programmer is   
   working in terms of the wrapper type (the `Option` itself, say)   
   and not the underlying value type.   
      
   That said, Cloudflare had a recent production outage because   
   somebody called `unwrap` on a `Result` that was `Err`.  Yeah,   
   that was unwise.  But note that this is qualitatively different:   
   here, the programmer _chose_ to ignore the safety guidelines and   
   unwrap something that wasn't known to be `Ok(...)`; this was an   
   _active_ thing.  That's different than omitting a check against   
   the valid attribute, through carelessness or ignorance; that's a   
   _passive_ thing..   
      
   >> Also not as general.  Note that in the Rust example, `Option` is   
   >> generic over some type `T`: your example is concrete over the   
   >> color enum, and just colocates it with a flag and a convenience   
   >> method that returns null if the flag is false (but now all   
   >> accesses are via reference).   
   >   
   >> But Ada supports generics (recall that Stepanov did the first   
   >> implementation of the STL in Ada).  You could use that to build   
   >> an actual `Option` type that would closer to the Rust version.   
   >   
   >Generics is one of those Ada features that I don't like to use.   
      
   That's silly.  It's a powerful construct that _should_ be used,   
   though of course it has its costs (monomorphization on concrete   
   types, primarily).   
      
   >But a generic version is attached below.   
   >   
   >> It would probably not be as convenient to use because Ada lacks   
   >> Rust-style pattern matching and destructuring, but it would more   
   >> or less obviate the need for `Valid`.   
   >   
   >Valid is still a way - probably the best way - to produce   
   >the Option.   
      
   Well, perhaps, provided that the concrete type embedded in the   
   `Option` will work with `Valid`; recall that `Valid` applies   
   only to scalars.  If the `Option` wraps a product type (records,   
   etc) then `Valid` won't work, as it's not applicable in that   
   context.   
      
   But for scalars, whether it's the "best" way or not seems highly   
   subjective.  There are probably categories of scalar values that   
   are difficult to represent using the language's type constraints   
   and so for which `Valid` would not meanigfully apply, but   
   something like, `TryFrom` might.  For example, one might define   
   a newtype over integers that represents primes; the invariant is   
   that if an instance of that type exists at all, then it is   
   guaranteed that the contained number must be prime.  This is the   
   sort of thing you _can_ check with an explicit conversion   
   function, but _not_ with `Valid`.   
      
   A nice property of using an `Valid` in your example `Option`   
   type, however is that because the check for validity is   
   encapsulated in the machinery built into the `Option` itself;   
   the programmer cannot misuse it because its use is hidden from   
   the programmer.   
      
   >[snip]   
      
   	- Dan C.   
      
   --- SoupGate-Win32 v1.05   
    * Origin: you cannot sedate... all the things you hate (1:229/2)   

[   << oldest   |   < older   |   list   |   newer >   |   newest >>   ]


(c) 1994,  bbs@darkrealms.ca