7 ms·
Go seems like a rehash of Ada, without the option to dynamically linked. Maybe an improved version of Ada. I liked some feature of Ada a lot, it was safe, inp
by acomjean 14y ago
Go seems like a rehash of Ada, without the option to dynamically linked. Maybe an improved version of Ada.
I liked some feature of Ada a lot, it was safe, input, output, in/out parameters for functions. Of course to make itself useful as a lower level language you need to be able to call OS functions, which in unix means C. So then you have to start wrapping... Some parts of Ada were terrible (string handling comes to mind.)
I think its worth a look, but I'm still not sure what problem its trying to solve.
- Peaker 14y agoGo repeats the mistake of Boolean Blindness [1] so I think it disqualifies it from "safe", though. [1] http://existentialtype.wordpress.com/2011/03/15/boolean-blindness/ http://existentialtype.wordpress.com/2011/03/15/boolean-blin...
- drivebyacct2 14y agoYou posted this a few days ago, I didn't understand it and still don't understand after another read through. Can you give either a dumbed down summary or a scenario or an example of a language that doesn't do this?
- zemo 14y agothe last time he posted this was in response to me, so I'll join the discussion here to avoid duplication. This was his response when I asked for some clarification: >My problem with Go is that it does not have sum-types and pattern-matching. This means that branching (conditionals) in Go do not gain any type-information. And that means that programmers have to manually keep track of the invariants that hold true in each of their conditionals, and if they get them wrong, they get no help from the compiler.
- Peaker 14y agoBasically, the idea is that when you branch on a conditional, information is gained. This information may be represented in the type system and used by the compiler to verify safety, or it can be ignored. If it is ignored, the language is said to have "boolean blindness". Example: if (ptr == NULL) { ... a ... } else { ... b ... } In branch a and branch b, different invariants about ptr hold. But the language/compiler are not verifying any of these invariants. Instead, consider: data Maybe a = Nothing | Just a This defines a type "Maybe", parameterized by a type variable "a", and it defines two "data constructors" that can make a Maybe value: "Nothing" which contains nothing, and "Just" which contains a value of type "a" inside it. This is known as a "sum" type, because the possible values of the type are the sum of all data constructor values. We could still use this sum data-type in a boolean-blind way: if isJust mx then .. use fromJust mx .. -- UNSAFE! else .. can't use content of mx .. However, using pattern-matching, we can use it in a safe way. Assume "mx" is of type "Maybe a": case mx of Nothing -> ... There is no value of type "a" in our scope Just x -> ... "x" of type "a" is now available in our scope! So when we branch on the two possible cases for the "mx" type, we gain new type information that gets put into our scope. "Maybe" is of course a simple example, but this is also applicable for any sum type at all. If your language does branching without giving you back any new type information, it means you have to manually track the invariants and conditionals your program is in. If you get it wrong, your program will die at runtime. Instead, the language can almost always provide you some kind of proof that you can pass along of the conditional's truthness, which makes it safe to rely on it.
- zemo 14y agoI may be mistaken, but I believe type switches in Go address this criticism: type Fruit struct { Name string Species string } // define a method on Fruit structs named Rename func (f *Fruit) Rename(s string) { f.Name = s } type Candy struct { Name string Company string } // define a method on Candy structs named Rename func (c *Candy) Rename(s string) { c.Name = s } // any type that defines a method named Rename is also // of type Renamable. type Renamable interface { Rename(string) } // produce something that implements Renamable. Its // fields will be unknown, but the method Rename will be // known to exist. func SomeProducer(...) Renamable { ... } x := SomeProducer(...) // at this point, x is of type Renamable. We do not // know what fields it has. The only thing we know is // that it has some method named Rename that takes a // single string for its only argument and returns // nothing. switch t := x.(type) { case Fruit: // T is of type Fruit, while x is of type Renamable fmt.Print(t.Species) case Candy: // T is of type Candy, while x is of type Renamable fmt.Print(t.Company) default: // some other type. } it's in the Switch section of the Go spec: http://golang.org/ref/spec#Switch_statements http://golang.org/ref/spec#Switch_statements
- ralph 14y agoSorry, but having had some dealings with Ada many years ago I'm sure Go is little like it. Go has CSP in its ancestry, what with channels and goroutines, and both are fundamental to it whereas Ada has nothing similar?
- pjmlp 14y agoGoroutines -> tasks channels -> rendezvous
- ralph 14y agoAda's tasks aren't defined to be greenlets; an implementation can make then OS threads or processes, limiting their number. And rendezvousing is more cumbersome than channels, e.g. passing a channel over a channel.
- pjmlp 14y agoI can be wrong, but as far as I know, Go language's specification also does not define how goroutines are to be implemented. Google's implementation makes use of greenlets, while gccgo is using OS threads. Further implementations might decide on others approaches. As for channels/rendezvous you might be correct, as I only played a bit with Ada.
- ralph 14y agoYou could be right about the spec. I think gccgo no longer does one OS thread per goroutine as of Go 1.0 but I've been unable to find a clear definition to point to.
- pjmlp 14y ago> Go seems like a rehash of Ada, without the option to dynamically linked. Maybe an improved version of Ada. Go has more in common with Oberon and Component Pascal than Ada