July 27, 2012
On Friday, 27 July 2012 at 14:03:05 UTC, Marco Leise wrote:
> Also when I have a sequence of steps to be done and some steps may jump back a few steps, I prefer labels with good names + goto, over blocks of for/while/if, which distract from the sequential nature of the code.

Huh, but such code is not sequential, it's spaghetti.
July 27, 2012
On Fri, 27 Jul 2012 15:09:14 +0100, Kagamin <spam@here.lot> wrote:

> On Friday, 27 July 2012 at 14:03:05 UTC, Marco Leise wrote:
>> Also when I have a sequence of steps to be done and some steps may jump back a few steps, I prefer labels with good names + goto, over blocks of for/while/if, which distract from the sequential nature of the code.
>
> Huh, but such code is not sequential, it's spaghetti.

Spaghetti goes in many directions, the code above always flows downhill but sometimes jumps/loops back up.  As long as the jumps are in one direction and not both, it's typically easy enough to follow.

IMO, goto is a tool like any other, in the wrong hands it can make bad code, in the right hands, used sparingly and only when it makes code easier to follow it's the right tool and avoiding it due to dogma is just plain silly.

My main use in the past has been to jump to clean up code, which is not always necessary with D as we have finally and scope(exit).

If I have the choice between a loop construct which only ever executes once with 'break' to simulate goto vs using goto, I will chose the latter because it's clearer what the intent of the code is, it actually makes the code cleaner and easier to follow.

I tend to code in the style of check for error and fail/return/exit vs layered scopes (if inside if inside if ..) because the flatter the code the easier I find it to reason about code paths and logic, goto can help to keep a piece of code flat and make it easier to reason about.

I almost always use goto to jump down a function, and almost never up.  Loop constructs are with 'continue' are a better match for the latter.

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
July 27, 2012
On 7/27/12 9:10 AM, Stuart wrote:
> On Friday, 27 July 2012 at 03:00:25 UTC, Brad Anderson wrote:
>>
>> D equivalent: iota(0, int.max, 2).map!(a => /* do something with even
>> numbers */)();
>
> I think you're missing the point. The purpose isn't to generate a
> sequence of numbers, but to illustrate how the Yield keyword is used in
> VB.NET. Sure, getting a sequence of numbers may be straightforward, but
> what about a lazy-populated list of all files on a computer? That can be
> done using Yield - and more importantly, WRITTEN like a normal
> synchronous function. Let's see you do that with map.

I think it's fair to say yield makes some things easier to do than ranges, and ranges makes some other things easier to do than yield. Of course, ideally you'd have both, but for the time being we don't have yield.

Andrei
July 27, 2012
On Friday, 27 July 2012 at 13:10:46 UTC, Stuart wrote:
> On Friday, 27 July 2012 at 03:00:25 UTC, Brad Anderson wrote:
>>
>> D equivalent: iota(0, int.max, 2).map!(a => /* do something with even numbers */)();
>
> I think you're missing the point. The purpose isn't to generate a sequence of numbers, but to illustrate how the Yield keyword is used in VB.NET. Sure, getting a sequence of numbers may be straightforward, but what about a lazy-populated list of all files on a computer? That can be done using Yield - and more importantly, WRITTEN like a normal synchronous function. Let's see you do that with map.

That's easy:

import std.file, std.stdio, std.algorithm;

void main()
{
  static BASE_DIR = "/path/to/base";
  static SIZE_CUTOFF = 100;

  // 'entries' is an InputRange

  auto entries = dirEntries(BASE_DIR, SpanMode.breadth);

  // filter the range; map to a range of filenames

  auto smallFileNames = entries
    .filter!(e => e.size < SIZE_CUTOFF)
    .map!(e => e.name);

  // note, the filesystem hasn't been touched yet;
  // we have full laziness.

  foreach(name; smallFileNames)
    writeln(name);
}


And check out this example, where you can process the entries in parallel:

http://dlang.org/phobos/std_file.html#dirEntries

You should spend some time using ranges before drawing conclusions about them.

Graham

July 27, 2012
On 27-07-2012 14:56, Stuart wrote:
> On Friday, 27 July 2012 at 02:41:21 UTC, Nick Sabalausky wrote:
>> On Fri, 27 Jul 2012 04:09:36 +0200
>> "Stuart" <stugol@gmx.com> wrote:
>>
>>> I can't think of ANY situation where goto would be the only viable
>>> option.
>>
>> Duff's device.
>
> According to Wikipedia, Duff's device (about which, until just now, I
> knew nothing) can be implemented without goto. Then again, this might be
> due to "features" of C++ that are not present in D.
>
> In any case, isn't it the job of the compiler to unroll loops? Why
> should the coder have to do this himself? Unless of course he's using a
> thin shitty wrapper over assembly language that claims falsely to be a
> high-level language - i.e. C.

It was a high-level language at the time it was created.

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
July 27, 2012
On Jul 27, 2012, at 8:05 AM, Andrei Alexandrescu <SeeWebsiteForEmail@erdani.org> wrote:

> On 7/27/12 9:10 AM, Stuart wrote:
>> On Friday, 27 July 2012 at 03:00:25 UTC, Brad Anderson wrote:
>>> 
>>> D equivalent: iota(0, int.max, 2).map!(a => /* do something with even
>>> numbers */)();
>> 
>> I think you're missing the point. The purpose isn't to generate a sequence of numbers, but to illustrate how the Yield keyword is used in VB.NET. Sure, getting a sequence of numbers may be straightforward, but what about a lazy-populated list of all files on a computer? That can be done using Yield - and more importantly, WRITTEN like a normal synchronous function. Let's see you do that with map.
> 
> I think it's fair to say yield makes some things easier to do than ranges, and ranges makes some other things easier to do than yield. Of course, ideally you'd have both, but for the time being we don't have yield.

core.thread.Fiber has yield and has been used as the basis for this style of iterator.  See Mikola Lysenko's talk from the D conference a few years ago.
July 27, 2012
On Thursday, 26 July 2012 at 23:59:13 UTC, Stuart wrote:

> How good is the Entice Designer? I'd like to write some GUI apps in D, but I need to know that the designer won't fall over halfway through; and I'll be damned if I'm writing my GUI code by hand. Even MFC programmers have a "dialog designer".

Entice is pretty good, but I can't comment much on its capability as I've only used it to get me some code started for writing a gui. And while it is no where near VS, I don't really like the VS designer so I guess you can take my opinion of GUI designers with an atom of salt.

Entice also hasn't gotten a much/any updates for D2 code generation, so it is likely to fall down at some point.
July 27, 2012
On Friday, July 27, 2012 16:05:07 Kagamin wrote:
> On Friday, 27 July 2012 at 01:45:35 UTC, Jonathan M Davis wrote:
> > It's a useful construct when used
> > properly. It just shouldn't be used when there are better
> > alternatives.
> 
> Hmm... do you have a use case besides Duff's device and porting legacy code?

There's quite a bit of code out there which uses it to jump to a common set of error handling code, which can actually make functions cleaner in some cases. Phobos even does this a few places (though not many).

Also, as I understand it, there are cases in low level code (where you need every cycle that you can get) that using a goto to get out of a section of code can be more efficient than getting out of it in the ways that you would more typically do. I haven't personally run into that sort of thing though, since I don't generally write code that low level.

And just because you or I don't use it much, doesn't mean that people programming in other domains don't need it for use cases that we never run into. goto is just one of those things that a systems language is bound to have.

- Jonathan M Davis
July 27, 2012
Kagamin:

> Hmm... do you have a use case besides Duff's device and porting legacy code?

To implement certain quick finite state machines, it's a quite important use case for me. At the moment I am even using computed gotos in GCC-C, for similar purposes.

Bye,
bearophile
July 27, 2012
On Friday, 27 July 2012 at 13:10:46 UTC, Stuart wrote:
> On Friday, 27 July 2012 at 03:00:25 UTC, Brad Anderson wrote:
>>
>> D equivalent: iota(0, int.max, 2).map!(a => /* do something with even numbers */)();
>
> I think you're missing the point. The purpose isn't to generate a sequence of numbers, but to illustrate how the Yield keyword is used in VB.NET. Sure, getting a sequence of numbers may be straightforward, but what about a lazy-populated list of all files on a computer? That can be done using Yield - and more importantly, WRITTEN like a normal synchronous function. Let's see you do that with map.

You wouldn't use map for that, that would be silly.

Taking a look at DirIteratorImpl[1] in std.file suggest there is a lot of setup to navigate the filesystem on Windows. How does Yield help with that logic?

1. https://github.com/D-Programming-Language/phobos/blob/master/std/file.d#L2397

Seriously I'll take my composing ranges over iterators any day.