Discussion:
void as type parameter
Elifant
2007-07-01 07:49:32 UTC
Permalink
Hello all.

In parsec library I have type Parser:

type Parser ['s, 't] = 's -> ParseResult['t]

i.e. it is a function which, given the state of type 's, returns result
which may contain value of type 't.
It works good for parsing strings, characters and so on. By what type
should 'eof' parser have?
Maybe some dummy type?

I know that 'void' was disabled to be used as type parameter some time
ago. But I can't find
corresponding discussion. Can you give me a link?
Dmitry Ivankov
2007-07-01 10:22:00 UTC
Permalink
Hi
Post by Elifant
I know that 'void' was disabled to be used as type parameter some time
ago. But I can't find
corresponding discussion. Can you give me a link?
It's just because current .Net denies void as parameter.
And so we have separate internal function types for void cases :(

Don't know if there was discussion earlier..
Maybe it is a good idea to have some standard pseudo void type.
Sandro Magi
2007-07-01 16:26:21 UTC
Permalink
Post by Elifant
Hi
I know that 'void' was disabled to be used as type parameter some time
ago. But I can't find
corresponding discussion. Can you give me a link?
It's just because current .Net denies void as parameter.
And so we have separate internal function types for void cases :(
Don't know if there was discussion earlier..
Maybe it is a good idea to have some standard pseudo void type.
This works well actually, and I use it in my FP# library where I have
Unit as an empty struct:

http://fpsharp.svn.sourceforge.net/viewvc/fpsharp/trunk/FP.Types/Unit.cs?view=markup

The JIT should be able to optimize this somewhat, but I haven't
performed any benchmarks to test the costs.

Sandro
Kamil Skalski
2007-07-01 16:32:23 UTC
Permalink
Well, last time we checked .NET 2.0 verifier complained that void
cannot be used as generic argument. I guess it also failed in runtime
if one used that.

See
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94226
Post by Sandro Magi
Post by Elifant
Hi
I know that 'void' was disabled to be used as type parameter some time
ago. But I can't find
corresponding discussion. Can you give me a link?
It's just because current .Net denies void as parameter.
And so we have separate internal function types for void cases :(
Don't know if there was discussion earlier..
Maybe it is a good idea to have some standard pseudo void type.
This works well actually, and I use it in my FP# library where I have
http://fpsharp.svn.sourceforge.net/viewvc/fpsharp/trunk/FP.Types/Unit.cs?view=markup
The JIT should be able to optimize this somewhat, but I haven't
performed any benchmarks to test the costs.
Sandro
_______________________________________________
https://nemerle.org/mailman/listinfo/devel-en
--
Kamil Skalski
http://nazgul.omega.pl
Sandro Magi
2007-07-01 16:40:08 UTC
Permalink
Yes, which is why I just created the empty "Unit" struct as a
pseudo-void type to fake it. :-)

Sandro
Post by Kamil Skalski
Well, last time we checked .NET 2.0 verifier complained that void
cannot be used as generic argument. I guess it also failed in runtime
if one used that.
See
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94226
Post by Elifant
Post by Elifant
Hi
I know that 'void' was disabled to be used as type parameter
some time
Post by Elifant
ago. But I can't find
corresponding discussion. Can you give me a link?
It's just because current .Net denies void as parameter.
And so we have separate internal function types for void cases :(
Don't know if there was discussion earlier..
Maybe it is a good idea to have some standard pseudo void type.
This works well actually, and I use it in my FP# library where I have
http://fpsharp.svn.sourceforge.net/viewvc/fpsharp/trunk/FP.Types/Unit.cs?view=markup
The JIT should be able to optimize this somewhat, but I haven't
performed any benchmarks to test the costs.
Sandro
_______________________________________________
https://nemerle.org/mailman/listinfo/devel-en
Michal Moskal
2007-07-03 10:35:06 UTC
Permalink
One can as well use Object and pass null. I guess the overhead would
be similar. This is actually what we have done some time ago, but I
guess there were some cases where it didn't work, so Dimitry comitted
a patch to just disallow it. Investigating this further is on my TODO
list, but it somehow cannot get to the top...
Post by Sandro Magi
Yes, which is why I just created the empty "Unit" struct as a
pseudo-void type to fake it. :-)
Sandro
Post by Kamil Skalski
Well, last time we checked .NET 2.0 verifier complained that void
cannot be used as generic argument. I guess it also failed in runtime
if one used that.
See
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94226
Post by Elifant
Post by Elifant
Hi
I know that 'void' was disabled to be used as type parameter
some time
Post by Elifant
ago. But I can't find
corresponding discussion. Can you give me a link?
It's just because current .Net denies void as parameter.
And so we have separate internal function types for void cases :(
Don't know if there was discussion earlier..
Maybe it is a good idea to have some standard pseudo void type.
This works well actually, and I use it in my FP# library where I have
http://fpsharp.svn.sourceforge.net/viewvc/fpsharp/trunk/FP.Types/Unit.cs?view=markup
The JIT should be able to optimize this somewhat, but I haven't
performed any benchmarks to test the costs.
Sandro
_______________________________________________
https://nemerle.org/mailman/listinfo/devel-en
_______________________________________________
https://nemerle.org/mailman/listinfo/devel-en
--
Micha³
Sandro Magi
2007-07-03 14:01:18 UTC
Permalink
That approach seems less-desirable for three reasons:

1. It's less type-safe: an unintended object reference might escape
since everything can be implicitly cast to "object". This reduces the
type safety when composing functions and values, as in parser
combinators (I have a C# parser combinator library based on FP# for
instance). A "Unit" struct can only be cast to object, so if we never
use object as a parameter, we know that the code will not have runtime
type errors and will not require runtime type checks (as long as we
avoid other techniques that require type checks, like reflection).

2. Efficiency: I wonder if "new object()" returns a singleton, or
allocates a new heap object every time. I would guess the latter. Might
as well just use a stack allocated value, but I'll have to run some
simple benchmarks soon to see what the impact actually is.

3. Nullable values are just less safe overall. I'm wary of using null
anywhere for obvious reasons I think.

I haven't focused much on efficiency in the FP# library; the focus has
been more on safety.

Sandro
Post by Michal Moskal
One can as well use Object and pass null. I guess the overhead would
be similar. This is actually what we have done some time ago, but I
guess there were some cases where it didn't work, so Dimitry comitted
a patch to just disallow it. Investigating this further is on my TODO
list, but it somehow cannot get to the top...
Post by Sandro Magi
Yes, which is why I just created the empty "Unit" struct as a
pseudo-void type to fake it. :-)
Sandro
Michal Moskal
2007-07-10 07:57:33 UTC
Permalink
Post by Sandro Magi
1. It's less type-safe: an unintended object reference might escape
since everything can be implicitly cast to "object". This reduces the
type safety when composing functions and values, as in parser
combinators (I have a C# parser combinator library based on FP# for
instance). A "Unit" struct can only be cast to object, so if we never
use object as a parameter, we know that the code will not have runtime
type errors and will not require runtime type checks (as long as we
avoid other techniques that require type checks, like reflection).
I don't quite get it: you need an explicit cast to cast from the
object type anyhow.
Post by Sandro Magi
2. Efficiency: I wonder if "new object()" returns a singleton, or
allocates a new heap object every time. I would guess the latter.
Yes.
Post by Sandro Magi
Might
as well just use a stack allocated value, but I'll have to run some
simple benchmarks soon to see what the impact actually is.
3. Nullable values are just less safe overall. I'm wary of using null
anywhere for obvious reasons I think.
I guess in this case the compiler would be able to ''prove'' that the
returned null would not be used anywhere.

Anyhow, I don't mind using something else, maybe except that you're
forcing program to link to Nemerle.dll once they use this feature.
Post by Sandro Magi
I haven't focused much on efficiency in the FP# library; the focus has
been more on safety.
Sandro
Post by Michal Moskal
One can as well use Object and pass null. I guess the overhead would
be similar. This is actually what we have done some time ago, but I
guess there were some cases where it didn't work, so Dimitry comitted
a patch to just disallow it. Investigating this further is on my TODO
list, but it somehow cannot get to the top...
Post by Sandro Magi
Yes, which is why I just created the empty "Unit" struct as a
pseudo-void type to fake it. :-)
Sandro
_______________________________________________
https://nemerle.org/mailman/listinfo/devel-en
--
Micha³
Sandro Magi
2007-07-10 16:29:51 UTC
Permalink
Post by Michal Moskal
Post by Sandro Magi
1. It's less type-safe: an unintended object reference might escape
since everything can be implicitly cast to "object". This reduces the
type safety when composing functions and values, as in parser
combinators (I have a C# parser combinator library based on FP# for
instance). A "Unit" struct can only be cast to object, so if we never
use object as a parameter, we know that the code will not have runtime
type errors and will not require runtime type checks (as long as we
avoid other techniques that require type checks, like reflection).
I don't quite get it: you need an explicit cast to cast from the
object type anyhow.
Yes, *from* the object type, but not *to* the object type. This is what
I meant by a wrong type inadvertently escaping with no type error.

"returnNothing" should be "int -> unit", such that no object ref escapes
the closure; MySpecialObject is an object you don't want exposed to
client code. Fun<T,U> is part of my FP# library.

Compare:

MySpecialObject x = ...;
Fun<int, object> returnNothing = delegate(int i) {
/* some complicated code */
return x; //no type error, succeeds
}

MySpecialObject x = ...;
Fun<int, Unit> returnNothing = delegate(int i) {
/* some complicated code */
return x; //type-error
}

I was saying that having an empty Unit struct is less error-prone
because nothing can be implicitly cast from OR to Unit, and if you have
to return an instance of Unit, who cares? Unit doesn't carry any state,
it's just an empty struct. The code is ensured safe at compile-time.
Post by Michal Moskal
Post by Sandro Magi
3. Nullable values are just less safe overall. I'm wary of using null
anywhere for obvious reasons I think.
I guess in this case the compiler would be able to ''prove'' that the
returned null would not be used anywhere.
Anyhow, I don't mind using something else, maybe except that you're
forcing program to link to Nemerle.dll once they use this feature.
My FP# library is C#-only, I was just pointing out the approach I used
for safety reasons. Returning object when you want a unit type just
isn't as safe as having an explicit void/unit type. Since we can't use
.NET's void type, I added my own Unit type.

Sandro
Michal Moskal
2007-07-12 07:17:08 UTC
Permalink
Post by Sandro Magi
My FP# library is C#-only, I was just pointing out the approach I used
for safety reasons. Returning object when you want a unit type just
isn't as safe as having an explicit void/unit type. Since we can't use
.NET's void type, I added my own Unit type.
Oh, I was missing the point that you're talking about C#. Clearly it's
more typesafe in C#.
--
Micha³
Loading...