Jump to page: 1 2
Thread overview
[your code here]
Jan 29, 2019
qjnr
Jan 29, 2019
Paul Backus
Jan 29, 2019
H. S. Teoh
Jan 29, 2019
Neia Neutuladh
Jan 29, 2019
H. S. Teoh
Jan 29, 2019
Stefan Koch
Jan 30, 2019
H. S. Teoh
Jan 30, 2019
Adam D. Ruppe
Jan 30, 2019
Stefan Koch
Jan 30, 2019
bauss
Jan 30, 2019
Jonathan M Davis
Jan 30, 2019
Stefan Koch
Jan 30, 2019
Neia Neutuladh
January 29, 2019
/* This is a very basic implementation of cat in the D programming language.
   For more info about the D programming language, visit https://dlang.org .

   Copyright (c) 2018 qjnr */

import std.stdio : readln, write, writef;
import std.file : readText, exists;

void main(string[] args)
{
  if (args.length is 2)
  {
    string fname = args[1];
    if (!exists(fname))
    {
      writef("cat: %s: No such file or directory", fname);
    }
    else
    {
      string content = readText(fname);
      write(content);
    }
  }
  else
  {
    string line;
    while ((line = readln()) !is null)
    {
      write(line);
    }
  }
}
January 29, 2019
On Tuesday, 29 January 2019 at 21:13:16 UTC, qjnr wrote:
> /* This is a very basic implementation of cat in the D programming language.
>    For more info about the D programming language, visit https://dlang.org .
>
>    Copyright (c) 2018 qjnr */
>
> [...]

It's more concise (and more efficient) to use ranges for this. Here's an example from the documentation of std.stdio.File [1]:

// Efficient file copy, 1MB at a time.
import std.algorithm, std.stdio;
void main()
{
    stdin.byChunk(1024 * 1024).copy(stdout.lockingTextWriter());
}

[1] https://dlang.org/phobos/std_stdio.html#.File.byChunk
January 29, 2019
On Tue, Jan 29, 2019 at 09:13:16PM +0000, qjnr via Digitalmars-d wrote:
> /* This is a very basic implementation of cat in the D programming language.
>    For more info about the D programming language, visit https://dlang.org .
> 
>    Copyright (c) 2018 qjnr */
> 
> import std.stdio : readln, write, writef;
> import std.file : readText, exists;
> 
> void main(string[] args)
> {
>   if (args.length is 2)
                   ^^^^
That's a syntax error.


>   {
>     string fname = args[1];
>     if (!exists(fname))
>     {
>       writef("cat: %s: No such file or directory", fname);
>     }
>     else
>     {
>       string content = readText(fname);
>       write(content);
>     }
>   }
>   else
>   {
>     string line;
>     while ((line = readln()) !is null)
>     {
>       write(line);
>     }
>   }
> }

Mmm, too verbose, has syntax errors, doesn't handle multiple files, and inefficient.

This is better:

	import std.algorithm : copy;
	import std.stdio;

	void main(string[] args)
	{
		auto w = stdout.lockingBinaryWriter;
		if (args.length > 1)
			foreach (f; args[1 .. $])
			{
				File(f, "r").byChunk(4096).copy(w);
			}
		else
			stdin.byChunk(4096).copy(w);
	}


T

-- 
The computer is only a tool. Unfortunately, so is the user. -- Armaphine, K5
January 29, 2019
On Tue, 29 Jan 2019 13:48:11 -0800, H. S. Teoh wrote:
> On Tue, Jan 29, 2019 at 09:13:16PM +0000, qjnr via Digitalmars-d wrote:
>>   if (args.length is 2)
>                    ^^^^
> That's a syntax error.

Compiles just fine on my end.
January 29, 2019
On Tue, Jan 29, 2019 at 10:07:23PM +0000, Neia Neutuladh via Digitalmars-d wrote:
> On Tue, 29 Jan 2019 13:48:11 -0800, H. S. Teoh wrote:
> > On Tue, Jan 29, 2019 at 09:13:16PM +0000, qjnr via Digitalmars-d wrote:
> >>   if (args.length is 2)
> >                    ^^^^
> > That's a syntax error.
> 
> Compiles just fine on my end.

But does it do what's intended, though?


T

-- 
Prosperity breeds contempt, and poverty breeds consent. -- Suck.com
January 29, 2019
On Tuesday, 29 January 2019 at 23:04:33 UTC, H. S. Teoh wrote:
> On Tue, Jan 29, 2019 at 10:07:23PM +0000, Neia Neutuladh via Digitalmars-d wrote:
>> On Tue, 29 Jan 2019 13:48:11 -0800, H. S. Teoh wrote:
>> > On Tue, Jan 29, 2019 at 09:13:16PM +0000, qjnr via Digitalmars-d wrote:
>> >>   if (args.length is 2)
>> >                    ^^^^
>> > That's a syntax error.
>> 
>> Compiles just fine on my end.
>
> But does it do what's intended, though?
>
>
> T

Yes.

`is` is the same as `==` except for array and classes where it does pointer comparisons.
since values like integers have no pointer identity.
January 29, 2019
On Tue, Jan 29, 2019 at 11:45:58PM +0000, Stefan Koch via Digitalmars-d wrote:
> On Tuesday, 29 January 2019 at 23:04:33 UTC, H. S. Teoh wrote:
> > On Tue, Jan 29, 2019 at 10:07:23PM +0000, Neia Neutuladh via Digitalmars-d wrote:
> > > On Tue, 29 Jan 2019 13:48:11 -0800, H. S. Teoh wrote:
> > > > On Tue, Jan 29, 2019 at 09:13:16PM +0000, qjnr via > Digitalmars-d
> > > wrote:
> > > >>   if (args.length is 2)
> > > >                    ^^^^
> > > > That's a syntax error.
> > > 
> > > Compiles just fine on my end.
> > 
> > But does it do what's intended, though?
> > 
> > 
> > T
> 
> Yes.
> 
> `is` is the same as `==` except for array and classes where it does
> pointer comparisons.
> since values like integers have no pointer identity.

Wow.  I can't believe I've been coding in D for so long and never knew this. :-D


T

-- 
Don't drink and derive. Alcohol and algebra don't mix.
January 29, 2019
On Tuesday, January 29, 2019 4:45:58 PM MST Stefan Koch via Digitalmars-d wrote:
> On Tuesday, 29 January 2019 at 23:04:33 UTC, H. S. Teoh wrote:
> > On Tue, Jan 29, 2019 at 10:07:23PM +0000, Neia Neutuladh via
> >
> > Digitalmars-d wrote:
> >> On Tue, 29 Jan 2019 13:48:11 -0800, H. S. Teoh wrote:
> >> > On Tue, Jan 29, 2019 at 09:13:16PM +0000, qjnr via
> >> >
> >> > Digitalmars-d wrote:
> >> >>   if (args.length is 2)
> >> >>
> >> >                    ^^^^
> >> >
> >> > That's a syntax error.
> >>
> >> Compiles just fine on my end.
> >
> > But does it do what's intended, though?
> >
> >
> > T
>
> Yes.
>
> `is` is the same as `==` except for array and classes where it
> does pointer comparisons.
> since values like integers have no pointer identity.

That's not quite true. To be precise, is does a bitwise comparison. In the case of integers, that's the same as ==, but for floating point values, it's not the same (most notably with NaN). Also, it's definitely different for structs. So, it's not just arrays and classes that differ for == and is.

For this code, both is or == would work, but it's certainly more idiomatic to use == - to the point that if I saw someone using the is operator with integers, I would be wondering if they understood what they were doing or were trying to do something other than what they were actually doing.

- Jonathan M Davis



January 30, 2019
On Wednesday, 30 January 2019 at 00:48:37 UTC, Jonathan M Davis wrote:
> On Tuesday, January 29, 2019 4:45:58 PM MST Stefan Koch via Digitalmars-d wrote:
>> [...]
>
> That's not quite true. To be precise, is does a bitwise comparison. In the case of integers, that's the same as ==, but for floating point values, it's not the same (most notably with NaN). Also, it's definitely different for structs. So, it's not just arrays and classes that differ for == and is.
>
> For this code, both is or == would work, but it's certainly more idiomatic to use == - to the point that if I saw someone using the is operator with integers, I would be wondering if they understood what they were doing or were trying to do something other than what they were actually doing.
>
> - Jonathan M Davis

Oh really, darn looks like I need to fix newCTFE then.
January 30, 2019
On Tue, 29 Jan 2019 23:45:58 +0000, Stefan Koch wrote:
> `is` is the same as `==` except for array and classes where it does
> pointer comparisons.
> since values like integers have no pointer identity.

`is` does bitwise comparisons for structs too, bypassing opEquals. And it's weird for interfaces.

Weirdness #1: the same object through different interfaces, where one interface inherits from the other, isn't the same as itself.

    interface A {}
    interface B: A {}
    class C : B {}
    A a = new C;
    B b = cast(B)a;
    writeln(a is b);  // false

This is because interfaces are implemented as lightweight adapter objects. An interface requires a specific vtable pointer. You can't just mutate an object's vtable pointer, so the compiler allocates a tiny adapter object inline with the primary object. The adapter has functions that locate the primary object and call the interface's functions on it.

The main other way to implement interfaces that I'm aware of is to pass a tuple of (object pointer, vtable) instead of a single pointer.

Compiling `a is b` down to `cast(Object)a is cast(Object)b` when the operands are interfaces would make this code work as one might naively expect.

Submitted https://issues.dlang.org/show_bug.cgi?id=19633

Weirdness #2: the same object through different unrelated interfaces can't be compared with `is`.

    interface A {}
    interface B {}
    class C : A, B {}
    A a = new C;
    B b = cast(B)a;
    writeln(a is b); // Error: incompatible types for (a) is (b):
                     // scratch.A and scratch.B

You can only compare things with `is` if they have a common base type. The spec doesn't state that outright.

Submitted https://issues.dlang.org/show_bug.cgi?id=19634
« First   ‹ Prev
1 2