Skip to content

std.algorithm betterC preparation#4937

Closed
9il wants to merge 1 commit intodlang:masterfrom
9il:betterc
Closed

std.algorithm betterC preparation#4937
9il wants to merge 1 commit intodlang:masterfrom
9il:betterc

Conversation

@9il
Copy link
Member

@9il 9il commented Dec 8, 2016

No description provided.

@9il 9il added the betterC label Dec 8, 2016
@JackStouffer JackStouffer requested a review from andralex December 8, 2016 17:53
@JackStouffer
Copy link
Contributor

Technically speaking the vast majority of these are breaking changes. Pinging @andralex on this

@9il
Copy link
Member Author

9il commented Dec 8, 2016

Technically speaking the vast majority of these are breaking changes. Pinging @andralex on this

Example please

@9il
Copy link
Member Author

9il commented Dec 8, 2016

I would say it fixes hundreds not filled bugs

@andralex
Copy link
Member

andralex commented Dec 8, 2016

Example please

Obviously changing exceptions to asserts does incur breakage. (For example this PR needed to modify unittests to keep them working.)

I would say it fixes hundreds not filled bugs

This is an exaggeration. Assuming user code does checking before an API call, vs. checking inputs compulsively, are well-explored choices with wide use in a variety of libraries. One could of course argue one is more appropriate for a specific library than the other etc.

@9il I have an idea for this, which would make things better without breakage. Implement this (pseudocode):

T singleton(T)() if (is(T == class)) @trusted
{
    static align(8) ubyte[pragma(classInstanceSize, T)] buffer;
    memcpy(buffer.ptr, T.init.ptr, buffer.length);
    auto result = cast(T) buffer.ptr;
    result.__ctor;
    return result;
}

Then whenever code would issue throw new RangeError() you replace that with throw singleton!RangeError. The current behavior is preserved without memory allocation. We can do this because we use a RangeError without arguments.

So this would go in its own PR, probably in std.typecons.

If you want to get rid of the thread-local buffer, you can make it __gshared and you need to do some basic synchronization to avoid races during initialization. But that can be done in a second step.

@9il
Copy link
Member Author

9il commented Dec 8, 2016

I would say it fixes hundreds not filled bugs

Oh, i miss the PR. It was about #4935
Agreed, it is breaking change

@9il
Copy link
Member Author

9il commented Dec 8, 2016

@9il I have an idea for this, which would make things better without breakage. Implement this (pseudocode):

It is not nothrow. The problem with current Phobos that a function may be nothrow in release mode and not nothrow in plain mode. It does not solve betterC because classes requires DRuntime. In other hand asserts can be replaced.

Agreed, it is breaking change

In the same time it would not break any user code if user ever runs it in release mode. Because errors are thrown only in non release mode. Honestly speaking it is not a breaking change

@andralex
Copy link
Member

andralex commented Dec 8, 2016

@9il the singleton function is nothrow so long as the constructor is nothrow. That's definitely the case for RangeError, so we're good there.

A nothrow function can throw RangeError as much as AssertError - both are in the Error hierarchy, outside Exception's cone.

@andralex
Copy link
Member

andralex commented Dec 8, 2016

In the same time it would not break any user code if user ever runs it in release mode. Because errors are thrown only in non release mode. Honestly speaking it is not a breaking change

Not getting this. enforce is active in release mode.

@9il
Copy link
Member Author

9il commented Dec 8, 2016

Not getting this. enforce is active in release mode.

Yes

A nothrow function can throw RangeError as much as AssertError - both are in the Error hierarchy, outside Exception's cone.

Ah, nice! But assert is betterC compatible (in the future) comparing with Errors.

@andralex
Copy link
Member

andralex commented Dec 8, 2016

Ah, nice! But assert is betterC compatible (in the future) comparing with Errors.

Why? At any rate, what I'm saying is singleton will allow us to push this forward without breakage, in addition with being a useful function on its own. It's the right step forward. BTW you may want to put the throw in a little private function a la onRangeError.

@9il
Copy link
Member Author

9il commented Dec 8, 2016

Why?

C has not any kind of exceptions.

@9il
Copy link
Member Author

9il commented Dec 8, 2016

Why?
C has not any kind of exceptions.

Plus classes (Errors are objects) requires DRuntime

@andralex
Copy link
Member

andralex commented Dec 8, 2016

@9il got it. Let's cross that bridge when we get to it.

@andralex
Copy link
Member

andralex commented Dec 8, 2016

Plus classes (Errors are objects) requires DRuntime

This we may be able to get rid of.

@9il 9il closed this Dec 8, 2016
@9il
Copy link
Member Author

9il commented Dec 8, 2016

@9il got it. Let's cross that bridge when we get to it.

It is years

@9il
Copy link
Member Author

9il commented Dec 8, 2016

@9il got it. Let's cross that bridge when we get to it.
It is years

90% of Phobos uses asserts for bounds checks. It looks weird to spent time to preserve RangeError here while we do not have a solid betterC solution for the problem

@andralex
Copy link
Member

andralex commented Dec 8, 2016

90% of Phobos uses asserts for bounds checks. It looks weird to spent time to preserve RangeError here while we do not have a solid betterC solution for the problem

As I said, RangeError and AssertError are the same thing - they are part of the same hierarchy.

There is no betterC solution to the problem of D having exceptions and C not having them. The D programming language has exceptions, and they are naturally used in certain places of the standard library. Granted, we may improve where and how they are used. But we can't cripple the entire standard library to make it work entirely without exceptions. A little good engineering here could go a long way, e.g. make exceptions not require the runtime etc.

@9il
Copy link
Member Author

9il commented Dec 8, 2016

90% of Phobos uses asserts for bounds checks. It looks weird to spent time to preserve RangeError here while we do not have a solid betterC solution for the problem
As I said, RangeError and AssertError are the same thing - they are part of the same hierarchy.

There is no betterC solution to the problem of D having exceptions and C not having them. The D programming language has exceptions, and they are naturally used in certain places of the standard library. Granted, we may improve where and how they are used. But we can't cripple the entire standard library to make it work entirely without exceptions. A little good engineering here could go a long way, e.g. make exceptions not require the runtime etc.

C has asserts, and D may have C asserts in BetterC mode too. But if one write throw, then it can not be implemented in C. So, with this PR I can use std.algorithm for my work. Without this PR i need to fork or reimplement from scratch std.algorithm.

@andralex
Copy link
Member

andralex commented Dec 8, 2016

Could you catch exceptions on the D side in the implementation of the C API?

@andralex
Copy link
Member

andralex commented Dec 8, 2016

(So again the scenario I'm discussing is: no allocation, use singleton (where is the PR?), and we manage to construct class objects without requiring druntime.)

@9il
Copy link
Member Author

9il commented Dec 8, 2016

Could you catch exceptions on the D side in the implementation of the C API?

No:

  1. Exceptions/Errors may not be implemented where I want my code to be able to run (!) If it can not run where LLVM has a backend, I will use C instead.
  2. They requires Runtime to be linked. Always. Inlining DRuntime into objects files is bad idea in this case.
  3. How I can understand what code may throw? Should I add version(assert) try ... catch {} else .. everywhere?
  4. One day one may add RangeErrors to ndslice. Should I preserve mir.ndslice and continue to improve it instead of std.ndslice?

(So again the scenario I'm discussing is: no allocation, use singleton (where the PR?), and we manage to construct class objects without requiring druntime.)

I want D be a powerful as it is but portable as C. Mir projects are proof of concept. The first language that will be ported for the new platform, new processor, new OS is C. I want be able to to run my D project the next day after that. It is possible with LLVM. DRuntime is constraints. Exception are platform dependent, I do not need them for numeric code and for system code.

I am interested to evaluate Phobos or its part to a only_source_BetterC library.

No one need a numeric library that can not be ported almost everywhere. If Phobos is a D only library then it is not what Mir need. Mir requires a thin standard D library with C runtime. If so, Mir's project can be easily ported, integrated with other languages and replace existing C analogs.

@dnadlinger
Copy link
Contributor

dnadlinger commented Dec 8, 2016

@9il: Exceptions are thrown by a call to a runtime function. You could just provide a small stub that aborts execution instead (which is what asserts do [1]). I'm quite convinced that this isn't as much of a problem as you make it out to be, neither or a fundamental or on a technical level.

[1] In fact, throwing an exception is equivalent to failing an assert, the only difference being that an object is passed to the corresponding runtime function instead of a string slice.

@jmdavis
Copy link
Member

jmdavis commented Dec 8, 2016

I'm quite convinced that this isn't as much of a problem as you make it out to be, neither or a fundamental or on a technical level.

Yeah, the situation with D isn't all that different from C++ except that C++ has a wider range of support, and the compilers that compile C usually compile C++. On a technical level, we're pretty much in the same boat.

@9il
Copy link
Member Author

9il commented Dec 9, 2016

@9il: Exceptions are thrown by a call to a runtime function. You could just provide a small stub that aborts execution instead (which is what asserts do [1]). I'm quite convinced that this isn't as much of a problem as you make it out to be, neither or a fundamental or on a technical level.

I do not understand a solid solution. throw new Error requires 3 things to be done:

  1. throw - a body for a druntime function. OK
  2. new - can be replaced with a singletone. How we can write a singletone without DRuntime? It is not clear to me.
  3. ***Error - Is a class, classes require DRuntime. Their internal design is not clear (monitors, default mutexes, typeid) and too complex. I don't understand how I can use classes without DRuntime.

Yeah, the situation with D isn't all that different from C++ except that C++ has a wider range of support, and the compilers that compile C usually compile C++. On a technical level, we're pretty much in the same boat.

Exactly. betterC++ != betterC. We need betterC.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants