July 11, 2012
On Sunday, 8 July 2012 at 19:28:11 UTC, Walter Bright wrote:
> On 7/8/2012 6:49 AM, bearophile wrote:
>> I think in Go the function stack is segmented and growable as in Go. This saves
>> RAM if you need a small stack, and avoids stack overflows where lot of stack is
>> needed.
>
> The trouble with segmented stacks are:
>
> 1. they have a significant runtime penalty
Why?

> 2. interfacing to C code becomes problematic
Isn't it possible to auto-commit new pages when C code needs it? I see that *moving* the stack would be a problem unless you have a means to adjust all pointers that point into the stack. If you need to call C code in 32-bit, you'd have to specify a maximum stack size.

July 11, 2012
On 07/11/2012 06:45 PM, David Piepgrass wrote:
> ...
> These benefits (except 3) all exist for "function" as well as "fn", but
> while many languages use "fun", requiring "function" for all functions
> is almost unheard of (at least I haven't heard of it), why? It's too
> damn long! We write functions constantly, we don't want to type
> "function" constantly.

You could have a look at JavaScript.
July 11, 2012
On Wednesday, 11 July 2012 at 17:09:27 UTC, Timon Gehr wrote:
> On 07/11/2012 06:45 PM, David Piepgrass wrote:
>> ...
>> These benefits (except 3) all exist for "function" as well as "fn", but
>> while many languages use "fun", requiring "function" for all functions
>> is almost unheard of (at least I haven't heard of it), why? It's too
>> damn long! We write functions constantly, we don't want to type
>> "function" constantly.
>
> You could have a look at JavaScript.

... and CoffeeScript as an attempt to fix that.
July 11, 2012
On 11-07-2012 19:09, Timon Gehr wrote:
> On 07/11/2012 06:45 PM, David Piepgrass wrote:
>> ...
>> These benefits (except 3) all exist for "function" as well as "fn", but
>> while many languages use "fun", requiring "function" for all functions
>> is almost unheard of (at least I haven't heard of it), why? It's too
>> damn long! We write functions constantly, we don't want to type
>> "function" constantly.
>
> You could have a look at JavaScript.

And Lua. And PHP. Possibly others I'm forgetting.

It's not that unheard of, really.

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
July 11, 2012
On Sunday, 8 July 2012 at 21:04:05 UTC, jerro wrote:
>> As someone that values readable code, I don't understand this desire to turn every programming language into APL.
>
> I would expect the abbreviations that rust uses to be perfectly
> readable once you know the langauge.

I like a lot ML languages (Haskell, F#, OCaml), so I should probably not be complaining like that.

But those languages don't have as one of their goals to restrict the keywords to maximum 5 letters,

Who knows, maybe if Rust catches on, I will be eating my own words and even using it.

--
Paulo
July 11, 2012
> Rust has type classes from Haskell (with some simplifications for higher kinds), uniqueness typing, and typestates.

As nice as kinds, typestates, typeclasses and several pointer types may be, I was in the Rust mailing list and felt unable to participate because they kept using terminology that only PhD in type systems understand. And googling for "kind" doesn't tell me a darn thing ;)

That's why have gravitated to D, it's so much more familiar (sometimes too much so, e.g. I still need to 'break' in 'switch'? how many meanings for 'static'?) as well as very powerful. I would still like to learn about the mumbo-jumbo, though, and I know how nice pattern-matching can be from one Haskell-based course in university :)

> This seems a bit overkill to me:
> This is very strict, maybe too much strict:
Agreed about the int suffixes, but I wonder what Marco meant about "mass-casts" in D.

> The safe pointer types are @T for shared, reference-counted boxes, and ~T, for uniquely-owned pointers.
I wonder how well these could be simulated in D. It seems to me Rust is carefully designed for performance, or at least real-time performance by avoiding garbage collection in favor of safely tracking ownership. That's good, but only now are they developing things like OOP support that I take for granted.

> ++ and -- are missing
Rust, like Go, seems very focused on making a "simple" language. Another reason that I prefer D.

> the logical bitwise operators have higher precedence. In C, x & 2 > 0 comes out as x & (2 > 0), in Rust, it means (x & 2) > 0, which is more likely to be what you expect (unless you are a C veteran).
Oh, I can't tell you what a pet peeve PITA the C precedence is. Ugh! I know it's against D philosophy to change the precedence w.r.t. C, but how about a compromise: give a warning or error for "x&2 > 0", with error message: "add parenthesis around x&2 to clarify your intention."

> Enums are datatypes that have several different representations. For example, the type shown earlier:
>
> enum shape {
>     circle(point, float),
>     rectangle(point, point)
> }
> fn angle(vec: (float, float)) -> float {
>     alt vec {
>       (0f, y) if y < 0f { 1.5 * float::consts::pi }
>       (0f, y) { 0.5 * float::consts::pi }
>       (x, y) { float::atan(y / x) }
>     }
> }
> alt mypoint {
>     {x: 0f, y: y_name} { /* Provide sub-patterns for fields */ }
>     {x, y}             { /* Simply bind the fields */ }
> }
> let (a, b) = get_tuple_of_two_ints();

Records, tuples, and destructuring go so well together. I would love to have this.

I am particularly a fan of structural typing. I don't know if Rust uses it but Opa and other functional languages often do. You see, there's a problem that pops up in .NET all the time, and probably the same problem exists in D.

Any time two libraries want to use the same concept, but the concept is not in the standard library, they need to define it. For instance if there is no "Point" type in the standard library, but two unrelated libraries need points, they will both define their own (amazingly, Points are poorly thought out in .NET and tightly bound to GUI libraries, so people define their own in some cases):

// JoesLibrary
struct Point!T { T x, y; /* followed by some manipulation functions */ }

// FunkyLibrary
struct Point!T { T x, y; /* followed by other manipulation functions */ }

Sadly, the two point types are not compatible with each other. A client that wants to use both libraries now has an interoperability problem when he wants to pass data between the.

Even a client that uses only one of the library, let's call it "JoesLibrary" has to import Point from "JoesLibrary", even if its functionality is not quite what the client wants. It would be much nicer if the client could define his own Point struct that seamlessly interoperates with Joes'. In D this is currently impractical, but I would enjoy designing a way to make it work (before you point out that "what if x and y are in a different order in the two structs" and "it could be T X,Y in one and T x,y in the other", yes, I know, It's on my list of problems to cleverly solve)

A similar problem exists with interfaces, where two unrelated libraries expose two similar classes with some common functions, but you can't cast them to a common type in D. This is a solved problem in Go (http://www.airs.com/blog/archives/277) and it's actually pretty easy for a compiler to magically cast a class to an interface that the class did not declare--if the underlying language is designed for that, anyway.

In fact, in .NET at least, the same problem exists even if the libraries DO know about each other and are even written by the same person and use identical interfaces. The problem is, if I write two libraries A and B, and I want them to be interoperable, then I need to factor out the common structs and interfaces to a microscopic third library, I. But from the client's perspective, if a client only knows about A or B, he will think it's stupid that I require him to use and deploy two DLLs/so's (A and I, or B and I) instead of one. In D I guess it's not the same, though.

> Stack-allocated closures:
>
> There are several forms of closure, each with its own role. The most common, called a stack closure, has type fn& and can directly access local variables in the enclosing scope.
>
> let mut max = 0;
> [1, 2, 3].map(|x| if x > max { max = x });

I seem to recall that D has the ability to optimize closures to make them stack-based when calling generic methods, or if the called method happens to be inlined, am I right? However, Rust's approach seems more powerful:

- Since it uses explicit notation, it could work across library and DLL boundaries. The called function can promise it will not save a reference to the closure, so the closure can always be stack-based.
- I think Rust developed a "do" syntax that allows "break" and "continue" (cont?) so that closures can be used in loops, so I guess you could write your own while-loop for example. The syntax is something like

do While(|| x > 0) { ... if (...) cont; ... }

if I'm not mistaken and going senile.

> Unique closures, written fn~ in analogy to the ~ pointer type (see next section), hold on to things that can safely be sent between processes. They copy the values they close over, much like boxed closures, but they also 'own' them—meaning no other code can access them. Unique closures are used in concurrent code, particularly for spawning tasks.

Hmm, hmm. Is there anything analagous in D?

> By default, a module exports everything that it defines. This can be restricted with export directives at the top of the module or file.
>
> mod enc {
>     export encrypt, decrypt;
>     const super_secret_number: int = 10;
>     fn encrypt(n: int) -> int { n + super_secret_number }
>     fn decrypt(n: int) -> int { n - super_secret_number }
> }

I much prefer D's approach. It's much more convenient for the code writer, and Rust's approach is better or worse for someone reading the code depending on whether one wants to know "what functions are public?" or "is this function I'm looking at public?"

> For some info on the typestate system, from the Rust manual:
> http://dl.rust-lang.org/doc/rust.html#typestate-system

Oh, do I ramble on or what? I'd love to talk about that, but would you look at the time...

July 11, 2012
On Wednesday, 11 July 2012 at 17:09:27 UTC, Timon Gehr wrote:
> On 07/11/2012 06:45 PM, David Piepgrass wrote:
>> ...
>> These benefits (except 3) all exist for "function" as well as "fn", but
>> while many languages use "fun", requiring "function" for all functions
>> is almost unheard of (at least I haven't heard of it), why? It's too
>> damn long! We write functions constantly, we don't want to type
>> "function" constantly.
>
> You could have a look at JavaScript.

Ack! You got me. Dynamic languages aren't my thing. But JS being dynamically typed, it's not as bad since you don't have to specify the return type in addition.
July 11, 2012
Marco Leise:

> Yes, this is the single most important Rust feature to me when typing. I've just had too many cases of mass-casts to ubyte or short where a suffix to the literal would only have cost one or two letters. 255ub = byte, 32000s = short

I am writing a lot of D2 code, but in my code the need of
explicit short or byte literals is very uncommon. That's why
those Rust suffixes seem overkill to me. Do you want to show us
some of your use cases?

Bye,
bearophile
July 11, 2012
On 07/11/2012 08:00 PM, David Piepgrass wrote:
> ...
> Oh, I can't tell you what a pet peeve PITA the C precedence is. Ugh! I
> know it's against D philosophy to change the precedence w.r.t. C, but
> how about a compromise: give a warning or error for "x&2 > 0", with
> error message: "add parenthesis around x&2 to clarify your intention."
>

That is what D does : )



July 11, 2012
On 7/11/2012 9:57 AM, David Piepgrass wrote:
> On Sunday, 8 July 2012 at 19:28:11 UTC, Walter Bright wrote:
>> On 7/8/2012 6:49 AM, bearophile wrote:
>>> I think in Go the function stack is segmented and growable as in Go. This saves
>>> RAM if you need a small stack, and avoids stack overflows where lot of stack is
>>> needed.
>>
>> The trouble with segmented stacks are:
>>
>> 1. they have a significant runtime penalty
> Why?

Extra instructions generated for each function.


>> 2. interfacing to C code becomes problematic
> Isn't it possible to auto-commit new pages when C code needs it? I see that
> *moving* the stack would be a problem unless you have a means to adjust all
> pointers that point into the stack. If you need to call C code in 32-bit, you'd
> have to specify a maximum stack size.

There's no way to predict how much stack arbitrary C code will use.