Discussion:
[fpc-pascal] Option type
denisgolovan via fpc-pascal
2021-06-01 18:20:26 UTC
Permalink
Hi all

I am trying to implement Option<T> type in FPC.

type
generic TOption<T> = record
case IsSome:boolean of
true: ( some: T );
false: ();
end;

However fpc just emits errors:
Error: Type parameters may require initialization/finalization - cannot be used in variant records

Could anybody suggest some sane workaround for the problem?

-- Regards,
Denis Golovan
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.o
Ryan Joseph via fpc-pascal
2021-06-01 18:51:03 UTC
Permalink
Post by denisgolovan via fpc-pascal
Hi all
I am trying to implement Option<T> type in FPC.
type
generic TOption<T> = record
case IsSome:boolean of
true: ( some: T );
false: ();
end;
You need to use a constraint like:

type
generic TOption<T: TObject> = record
case IsSome:boolean of
true: ( some: T );
false: ();
end;

Not sure why though.

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/
Ryan Joseph via fpc-pascal
2021-06-01 19:02:27 UTC
Permalink
That would limit supported types to class instances.
I'll like to avoid that.
Ideally TOption type should allow any type (primitives, strings, objects, class instances, etc).
What are you trying to make that requires a variant record? I don't know what "TOption" is.

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.org/
Henry Vermaak via fpc-pascal
2021-06-01 23:05:34 UTC
Permalink
On Tue, 1 Jun 2021, 23:39 Ryan Joseph via fpc-pascal, <
That would limit supported types to class instances.
I'll like to avoid that.
Ideally TOption type should allow any type (primitives, strings,
objects, class instances, etc).
What are you trying to make that requires a variant record? I don't know what "TOption" is.
https://en.wikipedia.org/wiki/Option_type

Henry
Ryan Joseph via fpc-pascal
2021-06-02 01:33:24 UTC
Permalink
Post by Henry Vermaak via fpc-pascal
https://en.wikipedia.org/wiki/Option_type
Yeah just use Nullable<T> then since it sounds like that's the closest we're going to get in FPC.

Regards,
Ryan Joseph

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/
Dennis Lee Bieber via fpc-pascal
2021-06-01 23:26:21 UTC
Permalink
On Wed, 2 Jun 2021 00:05:34 +0100, Henry Vermaak via fpc-pascal
Post by Henry Vermaak via fpc-pascal
https://en.wikipedia.org/wiki/Option_type
Which explicitly calls out the same solution as another response in the
thread did...
"""
A distinct, but related concept outside of functional programming, which is
popular in object-oriented programming, is called nullable types (often
expressed as A?). The core difference between option types and nullable
types is that option types support nesting (Maybe (Maybe A) ? Maybe A),
while nullable types do not (String?? = String?).
"""

https://en.wikipedia.org/wiki/Nullable_type
"""
Nullable types are a feature of some programming languages which allow the
value to be set to the special value NULL instead of the usual possible
values of the data type. In statically typed languages, a nullable type is
an option type[citation needed], while in dynamically typed languages
(where values have types, but variables do not), equivalent behavior is
provided by having a single null value.

NULL is frequently used to represent a missing value or invalid value, such
as from a function that failed to return or a missing field in a database,
as in NULL in SQL.

Primitive types such as integers and Booleans cannot generally be null, but
the corresponding nullable types (nullable integer and nullable Boolean,
respectively) can also assume the NULL value.[jargon][citation needed
"""
--
Wulfraed Dennis Lee Bieber AF6VN
***@ix.netcom.com http://wlfraed.microdiversity.freeddns.org/

_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists
Sven Barth via fpc-pascal
2021-06-01 20:40:07 UTC
Permalink
Post by denisgolovan via fpc-pascal
Hi all
I am trying to implement Option<T> type in FPC.
type
generic TOption<T> = record
case IsSome:boolean of
true: ( some: T );
false: ();
end;
Error: Type parameters may require initialization/finalization - cannot be used in variant records
You simply can't use managed types in a variant clause and as T could be
a managed type the compiler does not allow it.
Post by denisgolovan via fpc-pascal
Could anybody suggest some sane workaround for the problem?
Use Nullable.TNullable<T>.

Regards,
Sven
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.o
denisgolovan via fpc-pascal
2021-06-02 01:45:48 UTC
Permalink
Post by Sven Barth via fpc-pascal
You simply can't use managed types in a variant clause and as T could be
a managed type the compiler does not allow it.
Well. I thought it should be precisely the case for variant clause to properly handle.
Compiler knows IsSome field is used to determine if some contains initialized value.

On drop/free it would insert check:
if IsSome then finalize(some);
Post by Sven Barth via fpc-pascal
Use Nullable.TNullable<T>.
Thanks. It's something close to what I need.

-- Regards,
Denis Golovan
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo
Sven Barth via fpc-pascal
2021-06-02 05:30:19 UTC
Permalink
Post by denisgolovan via fpc-pascal
Post by Sven Barth via fpc-pascal
You simply can't use managed types in a variant clause and as T could be
a managed type the compiler does not allow it.
Well. I thought it should be precisely the case for variant clause to properly handle.
Compiler knows IsSome field is used to determine if some contains initialized value.
if IsSome then finalize(some);
No, because to use a field is not a requirement, it can be without a
name as well. Also the RTL would need to do checks each time the record
is assigned to another as there could be multiple managed entries.

It's not allowed for good reason.

Regards,
Sven
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lis
Martin Frb via fpc-pascal
2021-06-02 10:51:54 UTC
Permalink
Post by denisgolovan via fpc-pascal
I am trying to implement Option<T> type in FPC.
type
   generic TOption<T> = record
     case IsSome:boolean of
     true: ( some: T );
     false: ();
   end;
Well as already discovered type like strings can not go into a "record case"

But... The above record is anyway of constant size. I.e. the memory for
the field is always included, even if it is not used.

Since the "false" block is empty, you can do

type
   generic TOption<T> = record
     IsSome:boolean;
     some: T;
   end;

It is not as expressive to the reader of the code. But it leads to the
same data in memory.

There is only a diff, if the other blocks of the record (the false
block) also has/have data.
With case the memory will overlap.
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal.
denisgolovan via fpc-pascal
2021-06-02 11:28:46 UTC
Permalink
Post by Martin Frb via fpc-pascal
Well as already discovered type like strings can not go into a "record case"
But... The above record is anyway of constant size. I.e. the memory for
the field is always included, even if it is not used.
Since the "false" block is empty, you can do
type
generic TOption<T> = record
IsSome:boolean;
some: T;
end;
It is not as expressive to the reader of the code. But it leads to the
same data in memory.
Yes.
Except that "some" is still initialized with something (some default) and dropped and copied and assigned despite conceptually being empty.

-- Regards,
Denis Golovan
_______________________________________________
fpc-pascal maillist - fpc-***@lists.freepascal.org
https://lists.freepascal
Sven Barth via fpc-pascal
2021-06-02 12:20:10 UTC
Permalink
Post by denisgolovan via fpc-pascal
Post by Martin Frb via fpc-pascal
Well as already discovered type like strings can not go into a "record
case"
Post by Martin Frb via fpc-pascal
But... The above record is anyway of constant size. I.e. the memory for
the field is always included, even if it is not used.
Since the "false" block is empty, you can do
type
generic TOption<T> = record
IsSome:boolean;
some: T;
end;
It is not as expressive to the reader of the code. But it leads to the
same data in memory.
Yes.
Except that "some" is still initialized with something (some default) and
dropped and copied and assigned despite conceptually being empty.
That would have to be the case otherwise as well. And even worse: the RTL
would need to decide at runtime if it would need to manage that entry.
With the suggested solution (which is essentially what TNullable<> provides
as well) this will be rather cheap if the element is Nil (aka empty)
anyway.

Regards,
Sven
Loading...