November 19, 2013
On 2013-11-18 23:33, Andrei Alexandrescu wrote:

> So that would be two empty lines between statements :o). Anyhow,
> assuming you only meant one, that would be excessive if done for _all_
> statements (i.e. everything ending with a semicolon). It would make code
> look like a doc printed by someone who didn't know how to turn double
> spacing off.

I don't agree. And not having any empty newlines in the code would be like reading a text without paragraphs, as I've already said.

Instead, take a look at some code I've written and you're free to thinking whatever you like, but I like that style.

https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/Translator.d

-- 
/Jacob Carlborg
November 19, 2013
On 2013-11-18 23:21, Jonathan M Davis wrote:

> For when you're not in release mode. You want the more informative AssertError
> in that case. HLT is just for when assertions get compiled out.

I'm talking about release mode.

-- 
/Jacob Carlborg
November 19, 2013
On 2013-11-18 23:45, Andrei Alexandrescu wrote:

> The question is what's "program" and what's "input". Consider:
>
> int a = fun();
> std.gun(a);
>
> There are two possible takes on this:
>
> 1. The standard library is considered part of the user's program, and
> the whole thing is a unit. In that case, passing the wrong int to
> std.gun is an PROGRAM error and 100% blame goes to the programmer who
> wrote the caller code. In that case, assert/assert(0)/contracts are the
> appropriate constructs to be used inside std.gun.
>
> This is the approach taken by the C standard library, which is free to
> do whatever it wants (including crashing the program) upon calls such as
> strlen(NULL) etc.

In D, we can start by saying that all private and package functions should use asserts.

> 2. The standard library is a separate entity from the PROGRAM, and as
> far as it cares, any data from the user is INPUT. So the standard
> library with SCRUB the input, in which case enforce() and throwing
> exceptions are appropriate.
>
> This is the approach taken by the Windows API, Java, C#, and to a good
> extent the newer parts of C++'s standard library.
>
> To claim that one approach is exactly right and the other is exactly
> wrong would miss important insights.

I agree, it's not easy to just pick one. Say you have a library that queries a database. Is it the user's responsibility to validate any input that it doesn't contain SQL injections. Or should the library do that?

I would say that it would be quite cumbersome and verbose to for the user to constantly validate the input. If the library didn't validate the user would most likely create a wrapper function that does this. Most users would want to have a function like this and implement it. When we come to this, one can ask, isn't this the job of the library? If every user needs it, shouldn't it be put in the library?

-- 
/Jacob Carlborg
November 19, 2013
On Tuesday, November 19, 2013 08:30:56 Jacob Carlborg wrote:
> On 2013-11-18 23:33, Andrei Alexandrescu wrote:
> > So that would be two empty lines between statements :o). Anyhow, assuming you only meant one, that would be excessive if done for _all_ statements (i.e. everything ending with a semicolon). It would make code look like a doc printed by someone who didn't know how to turn double spacing off.
> 
> I don't agree. And not having any empty newlines in the code would be like reading a text without paragraphs, as I've already said.
> 
> Instead, take a look at some code I've written and you're free to thinking whatever you like, but I like that style.
> 
> https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/Transla tor.d

That looks pretty good overall, though there are probably a few places where I'd favor having fewer newlines. e.g. the body of the foreach in translateFunction is formatted similarly to what I'd do by default, but the overall feel is that it has too much vertical space. So, I might be inclined to remove some of the newlines, much as I'd want them by default. The fact that you have braces on the first version block doesn't help either. But the formatting is okay.

While I suspect that Andrei would definitely want to remove many of those newlines if he were formatting the code, what I think Andrei was really objecting to in your comments said that you wanted to put a newline after _every_ statement (which you're not actually doing in your code), and then you wanted separate lines between "paragraphs of code," implying that you'd end up with two newlines separating out sections of your functions. And that would be a lot of extraneous newlines. What you actually seem to have is putting a newline around "paragraphs" but not a newline between every statement, which is a lot more reasonable (though if your "paragraphs" are too small, you run into the exact problem that Andrei was commenting on in my code that started this discussion).

By the way, you have a lot of useless breaks in your code. A break isn't actually required if there's a return statement or other control statement such as continue at the end of the case statement. Maybe it's a stylistic thing? But in case you didn't know, they're completely unnecessary, and personally, I'd consider them to be clutter. It's your code though, not mine.

- Jonathan M Davis
November 19, 2013
On 2013-11-19 11:32, Jonathan M Davis wrote:

> That looks pretty good overall, though there are probably a few places where
> I'd favor having fewer newlines. e.g. the body of the foreach in
> translateFunction is formatted similarly to what I'd do by default, but the
> overall feel is that it has too much vertical space. So, I might be inclined
> to remove some of the newlines, much as I'd want them by default. The fact
> that you have braces on the first version block doesn't help either. But the
> formatting is okay.

That particular version block is from a pull request and doesn't follow the overall formatting. I wasn't so picky about the formatting in this case.

> While I suspect that Andrei would definitely want to remove many of those
> newlines if he were formatting the code, what I think Andrei was really
> objecting to in your comments said that you wanted to put a newline after
> _every_ statement (which you're not actually doing in your code), and then you
> wanted separate lines between "paragraphs of code," implying that you'd end up
> with two newlines separating out sections of your functions. And that would be
> a lot of extraneous newlines. What you actually seem to have is putting a
> newline around "paragraphs" but not a newline between every statement, which
> is a lot more reasonable (though if your "paragraphs" are too small, you run
> into the exact problem that Andrei was commenting on in my code that started
> this discussion).

Looking at code in Phobos I would suspect Andrei wanting to remove all empty newlines inside functions.

No, I don't want two empty newlines next to each other. I guess I didn't phrase my self very clearly. Your explanation of putting a newline around "paragraphs" seems better.

> By the way, you have a lot of useless breaks in your code. A break isn't
> actually required if there's a return statement or other control statement
> such as continue at the end of the case statement. Maybe it's a stylistic
> thing? But in case you didn't know, they're completely unnecessary, and
> personally, I'd consider them to be clutter. It's your code though, not mine.

Hmm, I don't remember how I ended up with that. I do know that they're not required. Perhaps it was a stylistic choice. I think it groups things nicely, just as braces do.

-- 
/Jacob Carlborg
November 19, 2013
19-Nov-2013 02:45, Andrei Alexandrescu пишет:
> On 11/18/13 2:04 PM, Walter Bright wrote:
>> On 11/18/2013 1:02 PM, Jacob Carlborg wrote:
>>> I really don't understand the point in having some functions thrown
>>> and others
>>> assert.
>>
>> That's a red flag that there is a faulty design somewhere, in this case
>> I think it's not having a separation between input data validation and
>> program bug detection.
>
> The question is what's "program" and what's "input". Consider:
>
> int a = fun();
> std.gun(a);
>
> There are two possible takes on this:
>
> 1. The standard library is considered part of the user's program, and
> the whole thing is a unit. In that case, passing the wrong int to
> std.gun is an PROGRAM error and 100% blame goes to the programmer who
> wrote the caller code. In that case, assert/assert(0)/contracts are the
> appropriate constructs to be used inside std.gun.
>
> This is the approach taken by the C standard library, which is free to
> do whatever it wants (including crashing the program) upon calls such as
> strlen(NULL) etc.
>
> 2. The standard library is a separate entity from the PROGRAM, and as
> far as it cares, any data from the user is INPUT. So the standard
> library with SCRUB the input, in which case enforce() and throwing
> exceptions are appropriate.
>

3. The standard library handles all input, the wrong input is eliminated as a class by providing meaningful output on error. So called soft-errors. An example would be returning a 0xFFFD when decoding a broken UTF-8 codepoint. Arguably bad examples include fopen/malloc returning 0.

All three cases can and should be judiciously mixed and matched.

It's also interesting to see that some primitives are better be designed to work with untrusted input see utf.decode.
While others are designed not. What I mean by _designed_ is that encountering wrong inputs in a correct program is unavoidable and to be expected. Also (2) and (3) can be constructed on top of (1) by widening the interface.

Compare hypothetical:
Date parseDate(string str);
vs:
Date date(Year year, Month month, Day day);

The first better be designed to scrub input, while the second is designed to accept verified values (hence Year, Month and not naked ints).


-- 
Dmitry Olshansky
November 19, 2013
19-Nov-2013 02:49, Walter Bright пишет:
> On 11/18/2013 2:37 PM, Andrei Alexandrescu wrote:
>> On 11/18/13 1:50 PM, Walter Bright wrote:
>>> I believe this is solving the problem in the wrong place. The function
>>> being called should not be throwing, and should be defined as not
>>> throwing. See my other posts in this thread on the topic.
>>
>> I think a stance of unceremoniously halting the program upon passing
>> the wrong
>> parameters to a standard library function is a bit excessive.
>
> Dang, I gotta argue this with you too? :-)
>
> Forget the philosophical argument for the moment and let's try a
> pragmatic one - code that doesn't check its arguments and doesn't throw
> is going to inline better, run faster, and be smaller. To have a high
> performance language, we have to have this.
>
> This is why we have a -release switch: so we can run with or without
> checking the arguments for bugs.
>
> Input data validation is where exceptions come in. Those are relatively
> rare compared with processing validated data, and so separating out the
> slow data validation path from the validated high speed path makes
> pragmatic sense.
>
> Rejecting this approach throws (!) out the whole concept of contract
> programming.
>

There is a whole class of functions where validation is ~ the same amount of work as scrubbing the input. Do I need to provide an example of parser? :)

-- 
Dmitry Olshansky
November 19, 2013
On Monday, 18 November 2013 at 20:49:48 UTC, Walter Bright wrote:
> Most architectures I've used supported a HLT, and there's always something the back end could construct if it had to, even:
>
>      ...
>      call halt
>      ...

I am pretty sure on my x86_64 Linux `assert(0)` results in termination via SIGILL (Illegal Instruction). Well, it is still a hard crash so no big deal but probably in not an expected way.
November 19, 2013
On 11/18/13 11:30 PM, Jacob Carlborg wrote:
> On 2013-11-18 23:33, Andrei Alexandrescu wrote:
>
>> So that would be two empty lines between statements :o). Anyhow,
>> assuming you only meant one, that would be excessive if done for _all_
>> statements (i.e. everything ending with a semicolon). It would make code
>> look like a doc printed by someone who didn't know how to turn double
>> spacing off.
>
> I don't agree. And not having any empty newlines in the code would be
> like reading a text without paragraphs, as I've already said.
>
> Instead, take a look at some code I've written and you're free to
> thinking whatever you like, but I like that style.
>
> https://github.com/jacob-carlborg/dstep/blob/master/dstep/translator/Translator.d

That doesn't have an empty line after each statement.

Andrei

November 19, 2013
On 2013-11-19 16:01, Andrei Alexandrescu wrote:

> That doesn't have an empty line after each statement.

If an expression or another statement follows, then yes. But not if a closing brace follows. I guess I didn't phrase myself very clearly.

-- 
/Jacob Carlborg