using System;
namespace AAX
{
public class Program
{
public static void Main(string[] args)
{
int[] a = new int[4];
unsafe
{
fixed (int* hack = &a[0])
{
for(int i = 0; i < 5; i++)
{
hack[i] = i;
Console.WriteLine(i);
}
}
}
}
}
}
0
1
2
3
4
unsafe { } clearly reveal that something fishy is going on.
On 2025-11-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
int[] a = new int[4];
unsafe
{
fixed (int* hack = &a[0])
{
for(int i = 0; i < 5; i++)
{
hack[i] = i;
Console.WriteLine(i);
}
}
}
0
1
2
3
4
unsafe { } clearly reveal that something fishy is going on.
The unsafe keyword is a hack implemented in languages that have not been designed correctly. The Ada approach, of disabling checks on a specific reference to a variable instead of disabling checks within a whole block
of code, is far superior.
For example, this is how you do an unsafe conversion in Ada:
https://adaic.org/resources/add_content/docs/95style/html/sec_5/5-9-1.html
Also note the availability of the 'Valid attribute to make sure that what
is in the variable after the unsafe conversion is actually a valid value.
Likewise, 'Unchecked_Access is a way that Ada allows you to do unsafe things with pointers:
https://www.adaic.org/resources/add_content/docs/95style/html/sec_5/5-9-3.html
On 2025-11-12, Arne Vajhoj <arne@vajhoej.dk> wrote:
using System;
namespace AAX
{
public class Program
{
public static void Main(string[] args)
{
int[] a = new int[4];
unsafe
{
fixed (int* hack = &a[0])
{
for(int i = 0; i < 5; i++)
{
hack[i] = i;
Console.WriteLine(i);
}
}
}
}
}
}
0
1
2
3
4
unsafe { } clearly reveal that something fishy is going on.
The unsafe keyword is a hack implemented in languages that have not been designed correctly. The Ada approach, of disabling checks on a specific reference to a variable instead of disabling checks within a whole block
of code, is far superior.
For example, this is how you do an unsafe conversion in Ada:
https://adaic.org/resources/add_content/docs/95style/html/sec_5/5-9-1.html
Also note the availability of the 'Valid attribute to make sure that what
is in the variable after the unsafe conversion is actually a valid value.
Likewise, 'Unchecked_Access is a way that Ada allows you to do unsafe things with pointers:
https://www.adaic.org/resources/add_content/docs/95style/html/sec_5/5-9-3.html
Simon.
Simon Clubley wrote :
On 2025-11-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
using System;
namespace AAX
{
-a-a-a-a public class Program
-a-a-a-a {
-a-a-a-a-a-a-a-a public static void Main(string[] args)
-a-a-a-a-a-a-a-a {
-a-a-a-a-a-a-a-a-a-a-a-a int[] a = new int[4];
-a-a-a-a-a-a-a-a-a-a-a-a unsafe
-a-a-a-a-a-a-a-a-a-a-a-a {
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a fixed (int* hack = &a[0])
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a {
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a for(int i = 0; i < 5; i++)
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a {
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a hack[i] = i;
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a Console.WriteLine(i);
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a }
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a }
-a-a-a-a-a-a-a-a-a-a-a-a }
-a-a-a-a-a-a-a-a }
-a-a-a-a }
}
0
1
2
3
4
unsafe { } clearly reveal that something fishy is going on.
The unsafe keyword is a hack implemented in languages that have not been
designed correctly. The Ada approach, of disabling checks on a specific
reference to a variable instead of disabling checks within a whole block
of code, is far superior.
For example, this is how you do an unsafe conversion in Ada:
https://adaic.org/resources/add_content/docs/95style/html/
sec_5/5-9-1.html
Also note the availability of the 'Valid attribute to make sure that what
is in the variable after the unsafe conversion is actually a valid value.
Likewise, 'Unchecked_Access is a way that Ada allows you to do unsafe
things
with pointers:
https://www.adaic.org/resources/add_content/docs/95style/html/
sec_5/5-9-3.html
Simon.
IS this the same as the [unsafe] attribute in OpenVMS Pascal ?
Simon Clubley wrote :
On 2025-11-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
-a-a-a-a-a-a-a-a-a-a-a-a int[] a = new int[4];
-a-a-a-a-a-a-a-a-a-a-a-a unsafe
-a-a-a-a-a-a-a-a-a-a-a-a {
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a fixed (int* hack = &a[0])
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a {
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a for(int i = 0; i < 5; i++)
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a {
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a hack[i] = i;
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a Console.WriteLine(i);
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a }
-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a-a }
-a-a-a-a-a-a-a-a-a-a-a-a }
unsafe { } clearly reveal that something fishy is going on.
The unsafe keyword is a hack implemented in languages that have not been
designed correctly. The Ada approach, of disabling checks on a specific
reference to a variable instead of disabling checks within a whole block
of code, is far superior.
For example, this is how you do an unsafe conversion in Ada:
https://adaic.org/resources/add_content/docs/95style/html/
sec_5/5-9-1.html
Also note the availability of the 'Valid attribute to make sure that what
is in the variable after the unsafe conversion is actually a valid value.
Likewise, 'Unchecked_Access is a way that Ada allows you to do unsafe
things
with pointers:
https://www.adaic.org/resources/add_content/docs/95style/html/
sec_5/5-9-3.html
IS this the same as the [unsafe] attribute in OpenVMS Pascal ?
On 11/14/2025 6:14 AM, Marc Van Dyck wrote:
Simon Clubley wrote :Sorta.-a Pascal's [UNSAFE] is mostly used in writing generic routines
On 2025-11-12, Arne Vajh|+j <arne@vajhoej.dk> wrote:
unsafe { } clearly reveal that something fishy is going on.
The unsafe keyword is a hack implemented in languages that have not been >>> designed correctly. The Ada approach, of disabling checks on a specific
reference to a variable instead of disabling checks within a whole block >>> of code, is far superior.
For example, this is how you do an unsafe conversion in Ada:
https://adaic.org/resources/add_content/docs/95style/html/
sec_5/5-9-1.html
Also note the availability of the 'Valid attribute to make sure that
what
is in the variable after the unsafe conversion is actually a valid
value.
Likewise, 'Unchecked_Access is a way that Ada allows you to do unsafe
things
with pointers:
https://www.adaic.org/resources/add_content/docs/95style/html/
sec_5/5-9-3.html
Simon.
IS this the same as the [unsafe] attribute in OpenVMS Pascal ?
that can accept many different "shapes" of a type.-a It also helps on RECORDs by giving you an invisible/free union of bytes around the entire record.-a I would say between Pascal's [UNSAFE] and the type-cast "::" operator, you can get Ada's unchecked_conversion.-a The nice thing about
Ada is that unchecked_conversion is easy to search for and jumps out at you.-a Pascal's "::" operator is harder for a human to see.-a C's type-
cast operator is essentially invisible.
Languages like Rust and C# with "unsafe" routines/blocks, turns those
into "collection of bugs"
C's type-cast operator is essentially invisible.
On 11/14/2025 6:14 AM, Marc Van Dyck wrote:
Simon Clubley wrote :
For example, this is how you do an unsafe conversion in Ada:
https://adaic.org/resources/add_content/docs/95style/html/
sec_5/5-9-1.html
IS this the same as the [unsafe] attribute in OpenVMS Pascal ?
If not the same then at least similar.
It disables some checks.
But it seems to do a little more.
Example based on example in the docs:
procedure hexdump(v : [unsafe] packed array [b1..b2:integer] of char);
-a-a hexdump(257);
-a-a hexdump(1.0);
-a-a hexdump('ABCD');
-a-a hexdump(v);
-a01 01 00 00
-a00 00 80 3F
-a41 42 43 44
-a01 01 00 00 00 00 80 3F 41 42 43 44
Cute!
On 2025-11-12, Arne Vajhoj <arne@vajhoej.dk> wrote:
using System;
namespace AAX
{
public class Program
{
public static void Main(string[] args)
{
int[] a = new int[4];
unsafe
{
fixed (int* hack = &a[0])
{
for(int i = 0; i < 5; i++)
{
hack[i] = i;
Console.WriteLine(i);
}
}
}
}
}
}
0
1
2
3
4
unsafe { } clearly reveal that something fishy is going on.
The unsafe keyword is a hack implemented in languages that have not been >designed correctly.
The Ada approach, of disabling checks on a specific
reference to a variable instead of disabling checks within a whole block
of code, is far superior.
For example, this is how you do an unsafe conversion in Ada:
https://adaic.org/resources/add_content/docs/95style/html/sec_5/5-9-1.html
Also note the availability of the 'Valid attribute to make sure that what
is in the variable after the unsafe conversion is actually a valid value.
Likewise, 'Unchecked_Access is a way that Ada allows you to do unsafe things >with pointers:
https://www.adaic.org/resources/add_content/docs/95style/html/sec_5/5-9-3.html
On 11/14/2025 11:47 AM, John Reagan wrote:
On 11/14/2025 6:14 AM, Marc Van Dyck wrote:
Simon Clubley wrote :Sorta.a Pascal's [UNSAFE] is mostly used in writing generic routines that >> can accept many different "shapes" of a type.a It also helps on RECORDs by >> giving you an invisible/free union of bytes around the entire record.a I
On 2025-11-12, Arne Vajhoj <arne@vajhoej.dk> wrote:
unsafe { } clearly reveal that something fishy is going on.
The unsafe keyword is a hack implemented in languages that have not been >>>> designed correctly. The Ada approach, of disabling checks on a specific >>>> reference to a variable instead of disabling checks within a whole block >>>> of code, is far superior.
For example, this is how you do an unsafe conversion in Ada:
https://adaic.org/resources/add_content/docs/95style/html/
sec_5/5-9-1.html
Also note the availability of the 'Valid attribute to make sure that what >>>> is in the variable after the unsafe conversion is actually a valid value. >>>>
Likewise, 'Unchecked_Access is a way that Ada allows you to do unsafe >>>> things
with pointers:
https://www.adaic.org/resources/add_content/docs/95style/html/
sec_5/5-9-3.html
Simon.
IS this the same as the [unsafe] attribute in OpenVMS Pascal ?
would say between Pascal's [UNSAFE] and the type-cast "::" operator, you
can get Ada's unchecked_conversion.a The nice thing about Ada is that
unchecked_conversion is easy to search for and jumps out at you.a Pascal's >> "::" operator is harder for a human to see.a C's type- cast operator is
essentially invisible.
Languages like Rust and C# with "unsafe" routines/blocks, turns those into >> "collection of bugs"
The important distinction is between:
can use unsafe constructs anywhere without any special syntax
and:
can use unsafe constructs when using a syntax that clearly identifies something as unsafe
So for VMS Pascal:
* search for "::"
* search for "UNSAFE"
* multi line regex search for "RECORD.*CASE.*END"
and setup extra code reviews for all hits.
Anything else to look for?
Ada is clearer, but ...
Arne
$ type usaf.pas
program usaf(input,output);
var
c : [unsafe] char;
begin
c := 65;
writeln(c);
end.
$ pas usaf
$ link usaf
$ run usaf
A
and:
$ type usaf.adb
with Unchecked_Conversion;
with Ada.Text_IO, Ada.Integer_Text_IO;
use Ada.Text_IO, Ada.Integer_Text_IO;
procedure USaf is
function i2c is new Unchecked_Conversion(Source => integer, Target => character);
c : character;
begin
c := i2c(65);
Put(c);
New_Line;
end USaf;
$ gnat make usaf
gcc -c usaf.adb
usaf.adb:9:01: warning: types for unchecked conversion have different sizes gnatbind -x usaf.ali
gnatlink usaf.ali
$ run usaf
A
In article <10f4oi1$25lkk$2@dont-email.me>,
Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
The unsafe keyword is a hack implemented in languages that have not been >>designed correctly.
Wait, Simon, tell me how you really feel.
The Ada approach, of disabling checks on a specific
reference to a variable instead of disabling checks within a whole block
of code, is far superior.
It's unclear to me how this is materially different.
In Rust, blocks return the value of the last expression they
contain, so an `unsafe` block may refer to a single expression.
However, I disagree with the above in the sense that the ability
to introduce scope when doing something `unsafe` can be
incredibly useful. But what if the expression is really a
statement?
For example:
```rust
unsafe {
use core::intrinsics::volatile_copy_memory;
let src = entry.virt_page_addr() as *const arch::Page;
volatile_copy_memory(page, src, 1);
}
```
There's no need to leak the existence of `src` or that one is
using the volatile memcpy intrinsic here. I suppose could could
also write this as,
```rust
{
use core::intrinsics::volatile_copy_memory;
let src = entry.virt_page_addr() as *const arch::Page;
unsafe {
volatile_copy_memory(page, src, 1);
}
}
```
etc.
For example, this is how you do an unsafe conversion in Ada:
https://adaic.org/resources/add_content/docs/95style/html/sec_5/5-9-1.html
This example seems equivalent to an `unsafe fn` in Rust. An
unsafe conversion of this nature might use `std::mem::transmute`
in that world.
On 2025-11-14, Arne Vajh|+j <arne@vajhoej.dk> wrote:
These two examples _appear_ to do different things.
$ type usaf.pas
var
c : [unsafe] char;
c := 65;
This one appears to say that _all_ writes to the variable "c" are not checked.
$ type usaf.adb
with Unchecked_Conversion;
function i2c is new Unchecked_Conversion(Source => integer, Target =>
character);
c : character;
c := i2c(65);
Put(c);
However, with this one, you get to choose which writes to "c" are checked
by Ada.
Have I understood the Pascal code correctly or is there something
I am missing ?
Arne Vajh|+j wrote on 14/11/2025 :
So for VMS Pascal:
* search for "::"
* search for "UNSAFE"
* multi line regex search for "RECORD.*CASE.*END"
and setup extra code reviews for all hits.
Anything else to look for?
For languages that are supported, would VAXset's Source Code Analyzer be
of any help to identify such potential weaknesses ? I have been using
it regularly, but never for that...
On 11/17/2025 3:25 AM, Marc Van Dyck wrote:
Arne Vajh|+j wrote on 14/11/2025 :
So for VMS Pascal:
* search for "::"
* search for "UNSAFE"
* multi line regex search for "RECORD.*CASE.*END"
and setup extra code reviews for all hits.
Anything else to look for?
For languages that are supported, would VAXset's Source Code Analyzer be
of any help to identify such potential weaknesses ? I have been using
it regularly, but never for that...
It do not see anything in the SCA manual.
And when SCA was created the focus was on other things.
But I have never used SCA myself, so maybe there is something.
Arne
Ada is generally pretty good.
But I don't know if you noticed that the example gave a
warning.
The warning did not have an impact.
But the same warning in another context can indicate
huge problem.
And I was surprised.
On 17/11/2025 19:58, Arne Vajh|+j wrote:
On 11/17/2025 3:25 AM, Marc Van Dyck wrote:
Arne Vajh|+j wrote on 14/11/2025 :
So for VMS Pascal:
* search for "::"
* search for "UNSAFE"
* multi line regex search for "RECORD.*CASE.*END"
and setup extra code reviews for all hits.
Anything else to look for?
For languages that are supported, would VAXset's Source Code Analyzer be >>> of any help to identify such potential weaknesses ? I have been using
it regularly, but never for that...
It do not see anything in the SCA manual.
And when SCA was created the focus was on other things.
But I have never used SCA myself, so maybe there is something.
I used SCA a bit in the past, and I never saw, or read about anything
like that. However I may missed it...
On 2025-11-17, Arne Vajh|+j <arne@vajhoej.dk> wrote:
But the same warning in another context can indicate
huge problem.
And I was surprised.
Interesting, but I've never encountered this because I never allow
compiler warnings to stand.
The GNAT RM has more information:
https://docs.adacore.com/gnat_rm-docs/html/gnat_rm/gnat_rm/standard_library_routines.html
Search for "Ada.Unchecked_Conversion (13.9)". It also tells you what happens, at least in the case of GNAT, if you do try to use different sizes.
Once you read that, you will see where the value "1" is coming from.
On 2025-11-15, Dan Cross <cross@spitfire.i.gajendra.net> wrote:
In article <10f4oi1$25lkk$2@dont-email.me>,
Simon Clubley <clubley@remove_me.eisner.decus.org-Earth.UFP> wrote:
The unsafe keyword is a hack implemented in languages that have not been >>>designed correctly.
Wait, Simon, tell me how you really feel.
Well, Simon is known to have opinions. :-)
The Ada approach, of disabling checks on a specific
reference to a variable instead of disabling checks within a whole block >>>of code, is far superior.
It's unclear to me how this is materially different.
In Rust, blocks return the value of the last expression they
contain, so an `unsafe` block may refer to a single expression.
However, I disagree with the above in the sense that the ability
to introduce scope when doing something `unsafe` can be
incredibly useful. But what if the expression is really a
statement?
For example:
```rust
unsafe {
use core::intrinsics::volatile_copy_memory;
let src = entry.virt_page_addr() as *const arch::Page;
volatile_copy_memory(page, src, 1);
}
```
And that is exactly the kind of thing I am talking about. :-)
Of those three statements, only the last one appears to be the unsafe one.
It is also the kind of thing I was reacting to when I saw Arne's
example and went YUCK!, YUCK!, YUCK! :-)
There's no need to leak the existence of `src` or that one is
using the volatile memcpy intrinsic here. I suppose could could
also write this as,
If that is important, I would have placed the whole sequence inside a
local block as you do below.
```rust
{
use core::intrinsics::volatile_copy_memory;
let src = entry.virt_page_addr() as *const arch::Page;
unsafe {
volatile_copy_memory(page, src, 1);
}
}
```
And this example is much closer to the Ada way. Related statements still
get checked and only one specific statement, the actual statement that is >unsafe, has checks disabled.
etc.
For example, this is how you do an unsafe conversion in Ada:This example seems equivalent to an `unsafe fn` in Rust. An
https://adaic.org/resources/add_content/docs/95style/html/sec_5/5-9-1.html >>
unsafe conversion of this nature might use `std::mem::transmute`
in that world.
The Ada example localises the unsafe bit down to a specific operation
within a statement, not a full statement, and certainly not a full function.
On 11/17/2025 3:25 AM, Marc Van Dyck wrote:
Arne Vajh|+j wrote on 14/11/2025 :
So for VMS Pascal:
* search for "::"
* search for "UNSAFE"
* multi line regex search for "RECORD.*CASE.*END"
and setup extra code reviews for all hits.
Anything else to look for?
For languages that are supported, would VAXset's Source Code Analyzer be
of any help to identify such potential weaknesses ? I have been using
it regularly, but never for that...
It do not see anything in the SCA manual.
And when SCA was created the focus was on other things.
But I have never used SCA myself, so maybe there is something.
(assuming Option in Rust is what it is in other languages)Also note the availability of the 'Valid attribute to make sure that what
is in the variable after the unsafe conversion is actually a valid value.
Sum types make this trivial:
impl SomeType {
fn try_from(i: i32) -> Option<Self> {
// if valid, return `Some(whatever`),
// else return `None`.
}
}
On 11/15/2025 9:16 PM, Dan Cross wrote:
(assuming Option in Rust is what it is in other languages)Also note the availability of the 'Valid attribute to make sure that
what
is in the variable after the unsafe conversion is actually a valid
value.
Sum types make this trivial:
-a-a-a-a impl SomeType {
-a-a-a-a-a-a-a-a fn try_from(i: i32) -> Option<Self> {
-a-a-a-a-a-a-a-a-a-a-a-a // if valid, return `Some(whatever`),
-a-a-a-a-a-a-a-a-a-a-a-a // else return `None`.
-a-a-a-a-a-a-a-a }
-a-a-a-a }
Option and Ada Valid are somewhat different.
Option is a way for a function/method to either return
a value or return the fact that there is no value.
A much better way to do that than traditional
return null or -1 or whatever to indicate there
is no value.
Ada valid attribute is a runtime check on the result from
an unsafe conversion to see if it meets the constraints
of the data type.
On 11/15/2025 9:16 PM, Dan Cross wrote:
(assuming Option in Rust is what it is in other languages)Also note the availability of the 'Valid attribute to make sure that what >>> is in the variable after the unsafe conversion is actually a valid value. >>Sum types make this trivial:
impl SomeType {
fn try_from(i: i32) -> Option<Self> {
// if valid, return `Some(whatever`),
// else return `None`.
}
}
Option and Ada Valid are somewhat different.
Option is a way for a function/method to either return
a value or return the fact that there is no value.
A much better way to do that than traditional
return null or -1 or whatever to indicate there
is no value.
Ada valid attribute is a runtime check on the result from
an unsafe conversion to see if it meets the constraints
of the data type.
On 11/18/2025 2:04 PM, Arne Vajh|+j wrote:
On 11/15/2025 9:16 PM, Dan Cross wrote:
(assuming Option in Rust is what it is in other languages)Also note the availability of the 'Valid attribute to make sure that
what
is in the variable after the unsafe conversion is actually a valid
value.
Sum types make this trivial:
-a-a-a-a impl SomeType {
-a-a-a-a-a-a-a-a fn try_from(i: i32) -> Option<Self> {
-a-a-a-a-a-a-a-a-a-a-a-a // if valid, return `Some(whatever`),
-a-a-a-a-a-a-a-a-a-a-a-a // else return `None`.
-a-a-a-a-a-a-a-a }
-a-a-a-a }
Option and Ada Valid are somewhat different.
Option is a way for a function/method to either return
a value or return the fact that there is no value.
A much better way to do that than traditional
return null or -1 or whatever to indicate there
is no value.
Ada valid attribute is a runtime check on the result from
an unsafe conversion to see if it meets the constraints
of the data type.
Option is in fashion in recent years.
There are not that many languages on VMS supporting
Option.
Scala does - Option[T].
And Java 8 Optional<T> is almost the same.
In article <10fig54$1n41a$3@dont-email.me>,That does not follow.
Arne Vajh_+j <arne@vajhoej.dk> wrote:
On 11/18/2025 2:04 PM, Arne Vajh_+j wrote:
On 11/15/2025 9:16 PM, Dan Cross wrote:
(assuming Option in Rust is what it is in other languages)Also note the availability of the 'Valid attribute to make sure
that what
is in the variable after the unsafe conversion is actually a
valid value.
Sum types make this trivial:
_a_a_a_a impl SomeType {
_a_a_a_a_a_a_a_a fn try_from(i: i32) -> Option<Self> {
_a_a_a_a_a_a_a_a_a_a_a_a // if valid, return `Some(whatever`),
_a_a_a_a_a_a_a_a_a_a_a_a // else return `None`.
_a_a_a_a_a_a_a_a }
_a_a_a_a }
Option and Ada Valid are somewhat different.
Option is a way for a function/method to either return
a value or return the fact that there is no value.
A much better way to do that than traditional
return null or -1 or whatever to indicate there
is no value.
Ada valid attribute is a runtime check on the result from
an unsafe conversion to see if it meets the constraints
of the data type.
Option is in fashion in recent years.
Algebraic data types have been used in functional languages
since the 1970s, starting with the "Hope" language from
Edinburgh. ML took them from Hope and popularized them, and
they leaked into Miranda, Haskell, and OCaml from there. Now
many languages support them; even C++ (`std::optional`).
Hope was first described in a paper in 1980, but the work of
course predated that.
That makes them about as old as VMS, and older than Ada. In
other words, they've been "In Fashion" since the 70s,
which as
far as all things fashion goes, is a pretty good run;
particularly considering some of the things that were popular in
that decade.
There are not that many languages on VMS supporting
Option.
Scala does - Option[T].
And Java 8 Optional<T> is almost the same.
More's the pity.
- Dan C.
In article <10fig54$1n41a$3@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> wrote:
Option is in fashion in recent years.
Algebraic data types have been used in functional languages
since the 1970s, starting with the "Hope" language from
Edinburgh. ML took them from Hope and popularized them, and
they leaked into Miranda, Haskell, and OCaml from there. Now
many languages support them; even C++ (`std::optional`).
Hope was first described in a paper in 1980, but the work of
course predated that.
That makes them about as old as VMS, and older than Ada. In
other words, they've been "In Fashion" since the 70s, which as
far as all things fashion goes, is a pretty good run;
particularly considering some of the things that were popular in
that decade.
On 11/19/2025 11:12 AM, Dan Cross wrote:
In article <10fig54$1n41a$3@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> wrote:
Option is in fashion in recent years.
Algebraic data types have been used in functional languages
since the 1970s, starting with the "Hope" language from
Edinburgh. ML took them from Hope and popularized them, and
they leaked into Miranda, Haskell, and OCaml from there. Now
many languages support them; even C++ (`std::optional`).
Hope was first described in a paper in 1980, but the work of
course predated that.
That makes them about as old as VMS, and older than Ada. In
other words, they've been "In Fashion" since the 70s, which as
far as all things fashion goes, is a pretty good run;
particularly considering some of the things that were popular in
that decade.
I would not consider Haskell, OCaml to ever have been in fashion.
Scala 2.0 in 2006, Rust in 2012, Swift in 2014, Java 8 in 2014,
Python 3.5 in 2015 (only type hint!), C++ 17 are more mainstream
and more recent.
On Wed, 19 Nov 2025 16:12:32 -0000 (UTC)
cross@spitfire.i.gajendra.net (Dan Cross) wrote:
In article <10fig54$1n41a$3@dont-email.me>,
Arne Vajh_+j <arne@vajhoej.dk> wrote:
On 11/18/2025 2:04 PM, Arne Vajh_+j wrote:
On 11/15/2025 9:16 PM, Dan Cross wrote:
(assuming Option in Rust is what it is in other languages)Also note the availability of the 'Valid attribute to make sure
that what
is in the variable after the unsafe conversion is actually a
valid value.
Sum types make this trivial:
_a_a_a_a impl SomeType {
_a_a_a_a_a_a_a_a fn try_from(i: i32) -> Option<Self> {
_a_a_a_a_a_a_a_a_a_a_a_a // if valid, return `Some(whatever`),
_a_a_a_a_a_a_a_a_a_a_a_a // else return `None`.
_a_a_a_a_a_a_a_a }
_a_a_a_a }
Option and Ada Valid are somewhat different.
Option is a way for a function/method to either return
a value or return the fact that there is no value.
A much better way to do that than traditional
return null or -1 or whatever to indicate there
is no value.
Ada valid attribute is a runtime check on the result from
an unsafe conversion to see if it meets the constraints
of the data type.
Option is in fashion in recent years.
Algebraic data types have been used in functional languages
since the 1970s, starting with the "Hope" language from
Edinburgh. ML took them from Hope and popularized them, and
they leaked into Miranda, Haskell, and OCaml from there. Now
many languages support them; even C++ (`std::optional`).
Hope was first described in a paper in 1980, but the work of
course predated that.
That makes them about as old as VMS, and older than Ada. In
other words, they've been "In Fashion" since the 70s,
That does not follow.
Something existing for a long time is not the same as being fashionable
for a long time.
Options became fashionable relatively recently, as result of growing >dissatisfaction with previous fashionable item - exceptions.
Parts of programming community that are less concerned with fashion of
the day ignored both of this things. They use error codes, either in
crude form (like C) or more refined (like Go).
In article <10fkvfr$2d2kr$1@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> wrote:
On 11/19/2025 11:12 AM, Dan Cross wrote:
In article <10fig54$1n41a$3@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> wrote:
Option is in fashion in recent years.
Algebraic data types have been used in functional languages
since the 1970s, starting with the "Hope" language from
Edinburgh. ML took them from Hope and popularized them, and
they leaked into Miranda, Haskell, and OCaml from there. Now
many languages support them; even C++ (`std::optional`).
Hope was first described in a paper in 1980, but the work of
course predated that.
That makes them about as old as VMS, and older than Ada. In
other words, they've been "In Fashion" since the 70s, which as
far as all things fashion goes, is a pretty good run;
particularly considering some of the things that were popular in
that decade.
I would not consider Haskell, OCaml to ever have been in fashion.
In your world of business software programming? That's probably
true. In the world of research and systems? Definitely not
true.
On 11/19/2025 1:19 PM, Dan Cross wrote:
In article <10fkvfr$2d2kr$1@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> wrote:
On 11/19/2025 11:12 AM, Dan Cross wrote:
In article <10fig54$1n41a$3@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> wrote:
Option is in fashion in recent years.
Algebraic data types have been used in functional languages
since the 1970s, starting with the "Hope" language from
Edinburgh. ML took them from Hope and popularized them, and
they leaked into Miranda, Haskell, and OCaml from there. Now
many languages support them; even C++ (`std::optional`).
Hope was first described in a paper in 1980, but the work of
course predated that.
That makes them about as old as VMS, and older than Ada. In
other words, they've been "In Fashion" since the 70s, which as
far as all things fashion goes, is a pretty good run;
particularly considering some of the things that were popular in
that decade.
I would not consider Haskell, OCaml to ever have been in fashion.
In your world of business software programming? That's probably
true. In the world of research and systems? Definitely not
true.
Hmm.
I would say that the main area for Haskell and OCampl outside of
university CS departments is in finance, which is business software.
Just still just a niche in those companies overall IT landscape.
In article <10fig0p$1n41a$2@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> wrote:
On 11/15/2025 9:16 PM, Dan Cross wrote:
(assuming Option in Rust is what it is in other languages)Also note the availability of the 'Valid attribute to make sure that what >>>> is in the variable after the unsafe conversion is actually a valid value. >>>Sum types make this trivial:
impl SomeType {
fn try_from(i: i32) -> Option<Self> {
// if valid, return `Some(whatever`),
// else return `None`.
}
}
Option and Ada Valid are somewhat different.
Option is a way for a function/method to either return
a value or return the fact that there is no value.
A much better way to do that than traditional
return null or -1 or whatever to indicate there
is no value.
Ada valid attribute is a runtime check on the result from
an unsafe conversion to see if it meets the constraints
of the data type.
I'm afraid this misses the point.
If a language supports sum types, then general solutions like
`Option` or `Result` types can be employed to represent the
return type of the conversion operation. If the conversion is
invalid, then one returns `None` (or, perhaps, the `Err` variant
of a `Result` if one wants to capture what the actual failure
was). That is, the conversion operation itself subsumes the
functionality of the valid attribute, and both the value and
whether the conversion was valid are represented in the return
type.
Again, taking Rust just as an example, there is a standard way
to represent such conversions; the `TryFrom` trait (and it's
dual, `TryInto`). Consider this silly example problem: I have a
type representing colors; perhaps the only colors I care about
are Red, Green, and Blue. I can label these with integers, say
1, 2 and 3, and I can represent this in Rust using an
enumeration.
Now further suppose that I have a file of 8-bit bytes that
contain the (raw, integral) representation of these color
values; I'd like to convert these into proper objects of the
enumeration type, but of course, not all 8-bit byte values
represent valid colors, so the proper tool in this case is
`TryFrom`. Note, however, that converting back, from a color to
its 8-bit value, is _always_ valid, so I just use `From` in that
case (which also, conveniently, gives me `into`).
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum Colors {
Red = 1,
Green = 2,
Blue = 3,
}
impl TryFrom<u8> for Colors {
type Error = String;
fn try_from(raw: u8) -> Result<Self, Self::Error> {
match raw {
1 => Ok(Self::Red),
2 => Ok(Self::Green),
3 => Ok(Self::Blue),
_ => Err(format!("unsupported value '{raw}'")),
}
}
}
Note the unit tests. Note also, that, as a result of the way
that the conversion is structured, as aided by the return type,
the conversion operation itself is safe.
Of course, this example is trivial, but the same principle
applies for more comple conversions as well, including unsafe
conversions.
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.
-a-a temp := BitI2C(I);
-a-a if temp'Valid then
-a-a-a-a-a-a res := (Valid => True, Value => temp);
-a-a else
-a-a-a-a-a-a res := (Valid => False);
-a-a end if;
-a-a return res;
But you can do the same in Ada.
Both doing similar to above and by using Unchecked_Conversion
and Valid.
Procedure ColorFul is
On 11/19/2025 11:02 AM, Dan Cross wrote:
In article <10fig0p$1n41a$2@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> wrote:
On 11/15/2025 9:16 PM, Dan Cross wrote:
(assuming Option in Rust is what it is in other languages)Also note the availability of the 'Valid attribute to make sure that what >>>>> is in the variable after the unsafe conversion is actually a valid value. >>>>Sum types make this trivial:
impl SomeType {
fn try_from(i: i32) -> Option<Self> {
// if valid, return `Some(whatever`),
// else return `None`.
}
}
Option and Ada Valid are somewhat different.
Option is a way for a function/method to either return
a value or return the fact that there is no value.
A much better way to do that than traditional
return null or -1 or whatever to indicate there
is no value.
Ada valid attribute is a runtime check on the result from
an unsafe conversion to see if it meets the constraints
of the data type.
I'm afraid this misses the point.
If a language supports sum types, then general solutions like
`Option` or `Result` types can be employed to represent the
return type of the conversion operation. If the conversion is
invalid, then one returns `None` (or, perhaps, the `Err` variant
of a `Result` if one wants to capture what the actual failure
was). That is, the conversion operation itself subsumes the
functionality of the valid attribute, and both the value and
whether the conversion was valid are represented in the return
type.
Again, taking Rust just as an example, there is a standard way
to represent such conversions; the `TryFrom` trait (and it's
dual, `TryInto`). Consider this silly example problem: I have a
type representing colors; perhaps the only colors I care about
are Red, Green, and Blue. I can label these with integers, say
1, 2 and 3, and I can represent this in Rust using an
enumeration.
Now further suppose that I have a file of 8-bit bytes that
contain the (raw, integral) representation of these color
values; I'd like to convert these into proper objects of the
enumeration type, but of course, not all 8-bit byte values
represent valid colors, so the proper tool in this case is
`TryFrom`. Note, however, that converting back, from a color to
its 8-bit value, is _always_ valid, so I just use `From` in that
case (which also, conveniently, gives me `into`).
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum Colors {
Red = 1,
Green = 2,
Blue = 3,
}
impl TryFrom<u8> for Colors {
type Error = String;
fn try_from(raw: u8) -> Result<Self, Self::Error> {
match raw {
1 => Ok(Self::Red),
2 => Ok(Self::Green),
3 => Ok(Self::Blue),
_ => Err(format!("unsupported value '{raw}'")),
}
}
}
Note the unit tests. Note also, that, as a result of the way
that the conversion is structured, as aided by the return type,
the conversion operation itself is safe.
Of course, this example is trivial, but the same principle
applies for more comple conversions as well, including unsafe
conversions.
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.
Both doing similar to above and by using Unchecked_Conversion
and Valid.
[snip code segment for brevity]
A bit verbose. But if one want short code, then
Ada is not the right language choice.
I am printing instead of asserting, because assertions was first
to Ada 20 years ago and the VMS GNAT I have is over 25 years old.
In article <10flqou$2l1qc$1@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> 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.
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.
It would probably not be as convenient to use because Ada lacksValid is still a way - probably the best way - to produce
Rust-style pattern matching and destructuring, but it would more
or less obviate the need for `Valid`.
On 11/20/2025 6:54 AM, Dan Cross wrote:
In article <10flqou$2l1qc$1@dont-email.me>,
Arne Vajh|+j <arne@vajhoej.dk> 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.
It is not a replacement for Option/Result.
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.
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.
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".
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.
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.
[snip]
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 54 |
| Nodes: | 6 (1 / 5) |
| Uptime: | 21:16:02 |
| Calls: | 742 |
| Files: | 1,218 |
| D/L today: |
6 files (8,794K bytes) |
| Messages: | 186,029 |
| Posted today: | 1 |