News for hackers. Stuff that matters.
Re:The Next Step for Generics by nine_k on Tuesday June 16, 2020 @04:56PM (#23543997)
The cost you pay for appeasing the type system is the cost you're not paying writing more tests around corner cases ("this function never returns null"), debugging segfaults, null pointer exceptions, "attribute not found" errors, memory leaks (lifetimes help here), etc.

The type system may not always help you get your code out the door faster, but when you finally ship it, you have much easier time running it.

Re:The Next Step for Generics by whatshisface on Tuesday June 16, 2020 @05:00PM (#23544046)
>The cost you pay for appeasing the type system is the cost you're not paying writing more tests around corner cases

I have spent a lot of time in Rust getting carried away with type system stuff that is not required for the actual program I am writing. I realize this when I go over it a second time and reduce line counts drastically by replacing my gee-whiz generics with primitive types. This is balanced out by an equal number of times where I've reduced line counts drastically by using the advanced type stuff to reduce the repetition that comes along with using primitives to represent a type that has way more structure than the primitive.

Re:The Next Step for Generics by beefsack on Tuesday June 16, 2020 @08:17PM (#23546065)
I feel obsessing over types is often just a form of procrastination, as it feels more interesting than the real work that needs to be done. This seems to be a bigger issue in Rust because the type system is powerful.

I write a lot of Rust nowadays, so I often need to keep myself in check and make sure I'm not getting sidetracked. When I'm writing internal code, the priority is to just get it done but still avoiding shortcuts. This is mainly avoiding .unwrap() / .clone() / taking care to handle Result correctly, as well as regularly running clippy to pick up the obviously silly stuff.

I find the most painful part of this strategy is when you want to revisit completed code to reduce copying as that generally requires a lot of type changes. At least when you get to this point though and haven't taken shortcuts, you've got functioning software and it should be fairly fault tolerant.

Re:The Next Step for Generics by CGamesPlay on Tuesday June 16, 2020 @10:49PM (#23547172)
> I feel obsessing over types is often just a form of procrastination, as it feels more interesting than the real work that needs to be done. This seems to be a bigger issue in Rust because the type system is powerful.

This is interesting, because I generally feel like getting the types right actually IS most of the work that needs to be done, and once the types are correct the implementation code just follows from the available operations necessary. I've never used Rust, so perhaps it's different in this language (I understand memory management is quite onerous there?), but this is how things feel for me in C# or TypeScript.

Re:The Next Step for Generics by zadler on Tuesday June 16, 2020 @11:52PM (#23547569)
Try Haskell, the ceiling is so high for the type system that you can spend a lot of time trying to golf an interface until you are happy that it is maximally elegant. Banal is better in some regards, hense Go. But it’s always a trade off where the extremes are pushing your boundaries and getting stuff done.
Re:The Next Step for Generics by pwm on Wednesday June 17, 2020 @04:28AM (#23549137)
This misses the point of why expressive type systems matter. Beginners and hobbyist (and i’m using these labels in the best possible sense) play with these things, push bounderies, etc... Professionals (in the literate sense, ie. people getting paid for it) tend to just solve problems whilst being fully aware that they have many powerful tools in their arsenal if/when the need arises. If you have a pro who is constantly lost in type-golfing land then that’s a problem.
Re:The Next Step for Generics by exdsq on Wednesday June 17, 2020 @07:59AM (#23550351)
Check out type-driven development (there’s some good F# example blogs) - honestly it’s like TDD on steroids. Having no type system scares me now, having worked in a Python startup before moving to a Haskell shop and seeing the difference in development quality (speed is surprisingly similar too).
Re:The Next Step for Generics by pwm on Wednesday June 17, 2020 @10:26AM (#23551786)
I think we are on the same page. I also write Haskell for food. What I'm saying is that if you write Haskell professionally and types slow you down, ie. you always try to come up with the best possible abstraction for everything, then that's a problem. It should do the opposite: give you wings while prototyping, iterating fast and refactoring(!!) as well as great comfort knowing that you have all its amazingly powerful tools in your arsenal if and when you need them.
Re:The Next Step for Generics by zadler on Wednesday June 17, 2020 @06:22PM (#23557516)
That seems to idealize professionals quite a bit. In reality, professionals are capable of much pedantry, not to mention political posturing. Some languages give greater scope for these than others.
Re:The Next Step for Generics by closeparen on Wednesday June 17, 2020 @12:13PM (#23553090)
If you just don’t need the assurances, that seems true.

In my world, anything the type system doesn’t do for me, I must do myself in unit tests.

It’s actually possible to learn a type system and get good/fast at it. But typing out all those goddamn test cases never gets any easier, and updating them when the code changes is a nightmare.

Re:The Next Step for Generics by eru on Wednesday June 17, 2020 @02:57AM (#23548565)
Go is making the wrong trade-offs.

My example for something that's simpler than Haskell but useful would be OCaml.

Re:The Next Step for Generics by earthboundkid on Wednesday June 17, 2020 @01:37PM (#23554239)
Name some OSS:

- Written in Haskell

- Not a tool for manipulating Haskell

- With a substantial user base

- Other than Pandoc, xmonad, or shellcheck

Partial credit if you can name closed source software instead.

For Go, off the top of my head, Docker/K8s would qualify, but if we want to eliminate that, Hugo, Caddy, Gogs, etcd, fzf…

https://github.com/search?q=stars%3A%3E1000+language%3AGo&ty...

https://github.com/search?l=&o=desc&q=stars%3A%3E1000+langua...

Re:The Next Step for Generics by eru on Thursday June 18, 2020 @03:00AM (#23560510)
Huh? What does Haskell's (lack of) adoption have to do with any merits of Go? PHP, Visual Basic (perhaps?) and Javascript have even better adoption than Go, if you want to go down that route.

If anything, you should have asked about the prospects of OCaml, shouldn't you? (Spoiler alert: they are grimmer than Haskell's.)

Mostly, Go is full of wasted opportunities. It would have perhaps been a worthwhile language had they come up with Go instead of C in the 1970s. https://github.com/ksimka/go-is-not-good is a good summary.

I would suggest having a look at D as an example of what an evolution of C could look. An evolution with fewer wasted opportunities.

Re:The Next Step for Generics by still_grokking on Thursday June 18, 2020 @07:52AM (#23562182)
Funny that I also always claim D being "the better Go". It has a very similar compilation and runtime model. But D is a much more powerful language, it's not "dumbed down to the max". For people that like Go's runtime model but don't see "simplified at all costs" as an advantage D could be just right.
Re:The Next Step for Generics by aldanor on Thursday June 18, 2020 @06:25AM (#23561704)
OCaml is used, for instance, as a main language in Jane Street which is a top prop trading firm. They also are the main sponsors of the language and contribute a lot to the compiler, but that doesn't invalidate the point.
Re:The Next Step for Generics by eru on Thursday June 18, 2020 @10:42AM (#23563517)
Yes.

We also used OCaml at Bloomberg quite a bit. (And they are still using it, but I'm not there anymore.)

But there's not that much more in the commercial OCaml world.

Haskell has actually a bit of a broader adoption. The open source library situation is also better.

(For the record, I like both OCaml and Haskell. And Janestreet are doing a great job.

And commercial and open source adoption are important. But they are not the end to every discussion.)

Re:The Next Step for Generics by stevefan1999 on Thursday June 18, 2020 @05:50AM (#23561515)
[Hasura GraphQL Engine](https://hasura.io/)
Re:The Next Step for Generics by thayne on Thursday June 18, 2020 @01:29AM (#23560054)
Git-annex, darcs, postgREST. I might have cheated and used google, but those are all projects I've heard of before. And it's not really fair to exclude big projects for haskell, but not for go.
Re:The Next Step for Generics by earthboundkid on Thursday June 18, 2020 @11:00AM (#23563685)
I explicitly excluded the big Go projects of Docker/K8s.

I think I've heard the name darcs, but have no idea what it is or does. I may have heard of postgrest but I think the whole category of a thin layer over the DB is dumb, so I refuse to learn about it. :-) (If you want to talk to your DB, use the native SQL drivers. Don't just invent the same thing but as REST or GraphQL for no reason. Backend system should connect SQL to SQL. If you want a browser to be able to talk to your DB, then you will need auth and want bundling of calls and object translation and suddenly the thin translation layer isn't thin anymore.)

Anyway, the point is that Haskell has been around for a long time and is very popular with HN/Reddit users, but unlike Go and Rust, it has produced a very small amount of OSS.

Re:The Next Step for Generics by eru on Thursday June 18, 2020 @11:31PM (#23570669)
Darcs is a distributed version control system. It predates git.

I tried using darcs for a bit. But the designers were a bit too ambitious: they had an elegant concept to solve all rebases automatically at least in principle. Alas, the early implementations sometimes ran into corner cases that had exponential runtime. Which in practice meant that it hang forever for all a user could tell.

As far as I can recall, that behaviour is fixed now. But they missed their window of opportunity, when other dvcs became really popular. Like git.

Interestingly, git had the opposite philosophy: they explicitly only resolve simple conflicts in a simple way, and bubble up anything slightly more complicated to the user.

About SQL: Haskell users wouldn't want to use SQL directly. They want their compiler to yell at them when they get their database interactions wrong.

So they don't want some much to have a layer on top of SQL that hides things, but they'd rather want some support to forbid nonsensical SQL queries.

Interestingly, at one of my previous jobs we had 'relational object mappers' in our Haskell code. What that means is that we used relations as data structures inside our Haskell code, but had to interact with a mostly object oriented world on the outside.

Relations make fabulous data structures for expressing business logic. Take the leap in expressivity coming from eg dumb C to Python's ad-hoc dicts and tuples, and then imagine making a similar step again, and you arrive at relations.

Especially the various kinds of joins are good at expressing many business concerns. But projections and maps etc as well. Basically, everything that makes SQL useful, but embedded in a better language and just as a datastructure.

Codd's paper on relational algebra (https://www.seas.upenn.edu/~zives/03f/cis550/codd.pdf) is just as relevant to in-memory programming as it is to data bases.

> Anyway, the point is that Haskell has been around for a long time and is very popular with HN/Reddit users, but unlike Go and Rust, it has produced a very small amount of OSS.

The ML family of languages that Haskell is a part of has been around for even longer, and many of the beloved features of Haskell stem from that older legacy.

I don't have high hopes of the ML family becoming more mainstream. But I am really glad to see many advances born in the land of functional programming, and ML or Haskell in particular, making it out into the wider world.

The poster child is garbage collection. Which was invented for Lisp in the first place.

(You can do functional programming without garbage collection, but it requires much more finesse and understanding than they had when Lisp was young. And even then, garbage collection is probably still the right trade-off when you programme is not resource constrained.)

Garbage collection is pretty much the default for new languages these days. People expect a good rationale for any deviation.

More recently we have seen first class functions, closures and lambdas make it out into the wider world. Even Java and C++ have picked up some of those.

First class functions belong relate to a wider theme of 'first class' elements of your programming language. I remember that eg in Perl you had to jump through extra hoops to make an array of arrays. That's because arrays were not by default treated the same as any other value.

I think Python did a lot for the mainstream here: Python is pretty good at letting you assign many of its constructs (like classes or functions or ints or tuples etc) to variables and pass them around just like any other value. In the understanding of the Python community, they see that just as good OOP, of course.

Combinators like map and filter have become popular in mainstream languages.

Algebraic data types have made it to a few languages. With that comes structural pattern matching, and the compiler complaining when you miss a case.

Tuples are pretty much expected in any new language these days.

The very article we are commenting on talks about generics.

Immutable data types are something every new language is supposed to have thought about. Even C++ has const and Java has final. Go's designers were asked to justify their very limited support for immutability.

Many people go so far as suggesting immutability should be the default in new languages. (And you could very well imagine a dialect of C++ where 'const' is implied, and you need 'mutable' everywhere, if you want to override that.)

There's quite a few more examples. Of course, correlation is not causation, and so not everything that showed up in functional programming languages before it showed up in the mainstream means that the mainstream actually got it from FP.

---

In summary, you are right that Haskell has not been used in OSS or commercial products as much as eg Go, but I am just happy that the rest of the world is moving in the Right Direction.

Re:The Next Step for Generics by earthboundkid on Friday June 19, 2020 @12:40PM (#23576112)
I’ll agree with that: while Haskell/FP has had a ton of OSS, it has had a huge, positive impact on other languages. Eg Rust would never exist without Haskell being around first.
Re:The Next Step for Generics by earthboundkid on Monday June 22, 2020 @10:53AM (#23600868)
* "has not had"
Re:The Next Step for Generics by jacobr1 on Wednesday June 17, 2020 @12:48PM (#23553557)
Which design choices made for OCaml do you think would be worthwhile to consider making in Go?
Re:The Next Step for Generics by eru on Thursday June 18, 2020 @03:51AM (#23560798)
I wasn't thinking of any specific design choices, but rather the overall feeling of pragmatism one gets from OCaml when coming from Haskell.

Most of my favourite design choices are the ones that make OCaml a functional programming language. So mostly not apt for Go. But here's a list of what I think one could adapt while staying true to the idea of a C-like language:

C had unions. They had some obvious problems. Go's solution was to get rid of them. OCaml instead went for discriminated unions (https://www.drdobbs.com/cpp/discriminated-unions/240009296) and made the compiler check that you are handling all cases correctly. In OCaml parlance, they are called algebraic data types.

C had null pointers. Go inherited them. OCaml uses the general mechanism of discriminated unions to represent cases like 'end of a linked list' or 'no data' or 'unknown' instead. And the compiler will check for you that you either handled those cases (when declared) or that you don't create those cases (when not explicitly declared to be there).

Some of C's constructs are generic. Like accessing arrays or taking the address of a value or dereferencing a pointer. To give an example, p works for a pointer of any type and does the right thing. And the compiler will tell you off, if you mix up the types.

As a user of C you can not add your own generic operations. You can use copy-and-paste or cast to and fro void or sometimes use function pointers in a clever way.

Go goes the same route. For example the built-in datastructures are generic, like maps or arrays.

Similar to C, a user of Go can not add their own generic operations. Go's sorting https://golang.org/pkg/sort/#Interface demonstrates what I mean by clever use of function pointers. (Note, how even that sorting interface still has lots of copy-and-paste when implementing and how it only really works for in-place sorting algorithms. I'm not sure how much trouble it would give in a multi threaded environment.)

I suspect Go's aversion to user-creatable generics comes from C++. C++'s templates confuse ad-hoc polymorphism and parametric polymorphism.

If C++'s unholy mess were the only game in town, Go's stance of restricting generics to the grownups (ie language implementors) would be perfectly reasonable.

OCaml carefully separates these two kinds of polymorphism.

Parametric polymorphism basically means 'this function or data structure works identically with any type'. That's what we also call generics. Eg the length of an array doesn't depend on what's in the array. (See https://en.wikipedia.org/wiki/Parametric_polymorphism)

When compiling you only need to create code once regardless of type. (Modulo unboxed types.)

Examples of ad-hoc polymorphism (https://en.wikipedia.org/wiki/Ad_hoc_polymorphism) are things like function overloading to do different things for different data types.

An infamous example are the bitshift operators from C whose cute looks got them roped into IO duty in C++.

In OCaml parametric polymorphism is handled as the simple concept it is. Ad hoc polymorphism (and unboxing for parametric polymorphism) are more complicated, and rightly make up the more complicated bits of OCaml types system.

Go could have gone with parametric polymorphism and left out ad-hoc polymorphism to stay simple.

(Parametric polymorphism synergises well with algebraic data types. Eg you can model the possibility of a null-pointer via an 'option' type, and have generic functionality to handle it. Same for the slightly richer concept of a value that's 'either an error message or a proper value'.)

But discussions about generics are a bit of a mine-field in Go.

Type inference. Go's type inference only goes one way, and is very limited. OCaml type inference goes backwards and forwards. Rust's system is perhaps a good compromise: it has similar machinery to OCaml, but they intentionally restrict it to only consider variable usage information from inside the same function.

(Generics restricted to parametric-polymorphism-only don't make type inference any harder.)

Back to something uncontroversial: Go allows tuples and pattern matching against them only when returning from functions and has lots of specialised machinery like 'multiple return types'.

OCaml just allows you tuples anywhere any other value could occur. You can pattern match against tuples and arbitrary other types. The compiler ensures that your pattern matching considers all cases.

I am sure there are more things to learn. But those few examples shall suffice for now. I feel especially strong about tuples as a wasted opportunity that wouldn't impact how the language feels at all. (From a practical point of view discriminated unions would probably make a bigger impact.)

Re:The Next Step for Generics by tialaramex on Wednesday June 17, 2020 @01:18AM (#23548080)
> This is interesting, because I generally feel like getting the types right actually IS most of the work that needs to be done

When I was much younger, I was told by my elders that to a first approximation a function doesn't need a name because it's defined by its range and domain. If it's hard to discern what the function does just by the range and domain then your type system isn't powerful enough. This insight is as powerful as it is superficially wrong.

Re:The Next Step for Generics by cousin_it on Wednesday June 17, 2020 @03:10AM (#23548659)
That insight is wrong. Not just superficially; it goes against the whole point of types.

1) Consider easing functions in animation (see easings.net for examples). They all have domain and range "real numbers between 0 and 1", yet they are all meaningfully different.

2) Consider filters in audio processing. They all have domain and range "streams of real numbers", yet they are all meaningfully different. The fact that they have the same type is important - it allows composition of filters, which I'd hope would sound exciting to a typed programmer!

3) Consider sorting algorithms. Even under a very advanced type system, the domain would be "arrays of numbers" and the range would be "sorted arrays of numbers". Yet there are tons of sorting algorithms that are meaningfully different. The fact that they have the same type is important - it allows a sorting library to evolve without breaking applications.

See the common thread? Types enable mixing and matching functionality. If a type allows only one functionality, it's useless for that purpose.

Re:The Next Step for Generics by MaxBarraclough on Wednesday June 17, 2020 @11:35AM (#23552663)
> They all have domain and range "real numbers between 0 and 1", yet they are all meaningfully different.

I was thinking a similar thought: sine vs cosine. But I think that falls under 'superficially wrong'.

Re:The Next Step for Generics by ummonk on Wednesday June 17, 2020 @03:18AM (#23548716)
I think the "only types matter" applies when you're simply applying natural transformations between isomorphic types.
Re:The Next Step for Generics by franga2000 on Wednesday June 17, 2020 @02:05AM (#23548289)
> I feel obsessing over types is often just a form of procrastination

Can confirm, this happened to me in Java constantly. I once spent an hour writing a big utility class using generics, even though I needed it for only one type in the code. "What if I need it for something else? Copying the code and replacing the types is very inefficient!"

Turned out that Java, being Java, was unable to instantiate an empty array of a generic type, so the very elegant code in the utility class now meant having to handle a bunch of special null cases in the application. I actually left it in for a while, but thankfully changed my mind before merging it as I'm sure the team wouldn't have appreciated having to deal with even more null in unexpected places because I got attached to my shiny generic code.

Re:The Next Step for Generics by eru on Wednesday June 17, 2020 @03:00AM (#23548590)
That sounds like a problem with Java more than a problem with generics.

In general, I agree with your sentiment. Though in some cases, an abstraction can be justified even when used only once.

Take the simple case of a function. Generally a function only communication with its surroundings via parameters and returned values. A function that respects those conventions makes reading code much easier, and can be worth it even if used only once.

In contrast, a code block inside a much larger stretch of code doesn't give the reader any explicit guidance one how it intends to interact with the rest of the system. Even if it's exactly the same code as in the function.

Similarly, a for-loop can do almost anything. But using map or filter immediately tells you that only a few things are possible here. Even a fold is more restricted than a general for-loop.

'Theorems for free' makes a very similar argument for generics. https://people.mpi-sws.org/~dreyer/tor/papers/wadler.pdf

Re:The Next Step for Generics by alkonaut on Wednesday June 17, 2020 @03:56AM (#23548950)
For me that type golfing is how I explore the problem. A lot of times you realize things about the problem that you didn’t understand before.

This is especially true with Rust where you also need to consider who owns what data. With C# it’s much too to model things that make sense as a type zoo but where the more important problems like ownership and access patterns is lost in the cracks.

The typical sign in Rust is when you need a lifetime on a struct so you realize it has someone else’s data. That usually means I stop to think before progressing. In C# it’s very easy to miss that big red flag.

Obviously it’s always worth revisiting and simplifying a design, but I still don’t think the initial design or designs were a waste of time if it gave me an understanding of the problem space.

Re:The Next Step for Generics by DaiPlusPlus on Tuesday June 16, 2020 @08:48PM (#23546331)
> I feel obsessing over types is often just a form of procrastination, as it feels more interesting than the real work that needs to be done.

I spent 2 days implementing a (terrible) discriminated union struct type in C# (for types I don’t control, so I can’t just add an interface) rather than just return `Object` from a couple of methods.

Type systems need to be more expressive if we’re going to be able to increase developer productivity without costing program safety.

Re:The Next Step for Generics by pwm on Wednesday June 17, 2020 @04:33AM (#23549173)
There are expressive type systems around, it’s the industry at large that needs to use them more and educate future generations on why these are useful tools. I 100% agree that spending 2 days on that task is lunacy. But imagine if youcould do it instantly with 0 ceremony. At that point it would 100% worth your while.
Re:The Next Step for Generics by DaiPlusPlus on Wednesday June 17, 2020 @09:23AM (#23551054)
So, part of those 2 days was spent toying with Roslyn code-generation to try to re-implement C++ templates in C# - but I ran out of time and reverted back to using T4.

The .NET CLI itself places limits on what .NET-based languages can actually do: for example, structural-typing at method boundaries in CIL is only possible by having the compiler generate build-time adapter classes and interfaces - which means that methods accepting structural-types can’t be easily called by non-strucutural-typing-aware languages. The CLI also imposes single-inheritance - so a .NET language cannot implement multiple inheritance at all - and because non-virtual calls cannot be intercepted at all (without hacks like abusing .NET Remoting’s special-cases in the CLR) it’s not possible to have a “every call is virtual” system like Java’s in the CLR (note to self: find out how J# did it). Implementing Go-style composition is hamstrung by the fact we can’t patch the vtable at runtime either (reified vtables would be nice...).

I dare say it - but I think 2020 marks the decline of C# and the CLR because we’re held-back by decisions made over 15 years ago. .NET 5 isn’t showing any sign of significant improvements to the CLR’s type system or fundamental concepts.

Re:The Next Step for Generics by moreaccountspls on Tuesday June 16, 2020 @09:57PM (#23546862)
Or, you know, just return Object from a couple of methods. It's not the end of the world.
Re:The Next Step for Generics by rob74 on Wednesday June 17, 2020 @03:27AM (#23548778)
...or interface{} in Go
Re:The Next Step for Generics by dragonwriter on Wednesday June 17, 2020 @01:56PM (#23554491)
> I spent 2 days implementing a (terrible) discriminated union struct type in C#

A type system without native or at least low-impedance support for discriminated unions is, well, not a very good type system.

> Type systems need to be more expressive if we’re going to be able to increase developer productivity without costing program safety.

Lots of type systems support discriminated unions directly, or at least make it trivial to implement them. C# perhaps doesn’t, but that's a problem with C#, not typed programming in general.

Re:The Next Step for Generics by jiggawatts on Tuesday June 16, 2020 @08:14PM (#23546038)
One of the most pleasant parts of programming in C# is that an 'int' is an 'int'. If some function takes an integer input, that's exactly what it takes.

In C/C++, the base type system is so weak and squishy that everything redefines every type. You can no longer pass an 'int', but instead pass a "FOO_INT" or a "BARLONG" where FOO and BAR are trivial libraries that shouldn't need to redefine the concept of an integer.

Like C#, Rust has well-defined basic types, which eliminates a crazy amount of boilerplate and redefining the basics.

Re:The Next Step for Generics by DaiPlusPlus on Tuesday June 16, 2020 @08:52PM (#23546371)
C++ itself has well-defined (if verbose-named) types (e.g. uint32_t ) the problem is as soon as you interface with any large library or platform API with a long history: Win32 and Qt comes to mind. It’s 2020 and Windows.h still has macros for 16-bit FAR pointers. I’m disappointed Microsoft hasn’t cleaned-up Win32 and removed all of the unnecessary macros (they can start with T()!)

C# and Java might seem to have escaped that problem - but now it means that because `int` was defined back in 32-bit days programs can’t use `int` (System.Int32) when the intent is to use - what is presumably - “the best int-type for the platform” (I.e. C++’s fast-int types) - or the context (.NET’s arrays are indexed by Int32 instead of size_t, so you can’t have a Byte[] array larger than 2GB without some ugly hacks).

(I know this is moot for function locals as those will be word-aligned and so should behave the same as a native/fast int, but this isn’t guaranteed, especially when performing operations on non-local ints, such as in object instance fields).

Re:The Next Step for Generics by throwaway8941 on Wednesday June 17, 2020 @01:20AM (#23548091)
>I’m disappointed Microsoft hasn’t cleaned-up Win32 and removed all of the unnecessary macros

Considering how seriously they take backward compatibility, the only way to do that would be to design a completely separate API, like they did with UWP. I'm 99.999% certain these macros are still being used somewhere out there. And who usually takes the blame when some badly written application stops working or compiling properly? Microsoft. (And I don't even like Microsoft.)

Re:The Next Step for Generics by DaiPlusPlus on Wednesday June 17, 2020 @03:56AM (#23548951)
(UWP isn't Win32 though)

What I'm proposing isn't really a new API - but you're right about it having to be separate. It avoids the work of having to design a new API (and then implement it!) - what I'm proposing would keep the exact same Win32 binary API, but just clean-up all of the Win32 header files and remove as many #define macros and typedefs as possible - and redefining the headers for Win32's DLLs/LIBs using raw/primitive C types wherever possible.

There's just no need for "LPCWSTR" to exist anymore, for example. And I don't see anything wrong with calling the "real" function names (with the "W" suffix) instead of every call being a macro over A or W functions (which is silly as most of the A functions now cause errors when called).

This would only be of value for new applications written in C and C++ (which can directly consume Win32's header files) where the author wouldn't need to worry about missing macros. It would certainly make Win32 more self-describing again and reduce our dependence on the documentation.

Re:The Next Step for Generics by pjmlp on Wednesday June 17, 2020 @04:15AM (#23549050)
Which is exactly why UWP ended up being an adoption failure to demise of us that were quite welcoming to its design goals, and I still believe that UWP is what .NET v1.0 should have been all along.

Now we have Project Reunion as official confirmation of what has been slowly happening since Build 2018, as Microsoft pivoted into bringing UWP ideas into Win32.

Breaking backwards compatibility is a very high price to pay, as many of its proponents end up discovering the hard way.

Re:The Next Step for Generics by DaiPlusPlus on Wednesday June 17, 2020 @05:30AM (#23549496)
> Breaking backwards compatibility is a very high price to pay, as many of its proponents end up discovering the hard way.

I don't believe breaking back-compat was ever the problem: there were (and are) two main problems with UWP (and its predecessors[1]) going back to Windows 8:

* UWP were/are unnecessarily and very artificially restricted in what they could do: not just the sandboxing, but the app-store restrictions almost copied directly from Apple's own store.

* And because the then-new XAML-based "Jupiter" UI for UWP did not (and still doesn't, imo) ship with control library suitable for high-information-density, mouse-first UIs - and because XAML is still fundamentally unchanged since its original 2005 design with WPF in .NET Framework 3.5 - the XAML system is now far less capable (overall) than HTML+CSS in Electron now (the horror). Microsoft had a choice to maintain progress on XAML or let Electron overrun it for desktop application UIs - instead they've decided to keep XAML alive but for what gain? There simply isn't any decent exit-strategy for Microsoft now: they've just re-committed themselves to a dead-end UI system that needs significant amounts of re-work just to keep it competitive with Electron, while simultaneously using Electron for new headline first-party applications like Teams, Skype, Visual Studio Code, and more.

Microsoft has completely wasted the past ~10 years of progress they could have made on Windows and the desktop user-experience, letting Apple stay competitive with macOS while still funneling billions into iOS and iPad OS - further weakening the Windows value-proposition).

[1] Metro Apps, Modern Apps, Microsoft Store Apps, Windows Store Apps...

Re:The Next Step for Generics by pjmlp on Wednesday June 17, 2020 @05:36AM (#23549532)
Windows Community Toolkit has taken care of that.

Skype uses React Native, and given that React Native for Windows bashes Electron in every talk that they give with its 300x overheard bar charts, expect that when React Native for macOS and Linux get mature enough, which MS is also contributing for, that eventually all Electron in use gets replaced with React Native.

Also React Native is built on top of UWP.

Re:The Next Step for Generics by DaiPlusPlus on Wednesday June 17, 2020 @07:22AM (#23550140)
> Skype uses React Native

I can't speak for the iOS and Android mobile-apps, but the Skype software on my Windows 10 desktop is still an Electron app.

EDIT: This article from March 2002 says as much - Microsoft is moving away from React Native and sticking with Electron: https://www.windowscentral.com/latest-skype-preview-version-...

Re:The Next Step for Generics by pjmlp on Wednesday June 17, 2020 @07:59AM (#23550354)
Using the classical desktop version?

> Microsoft Skype is one of the largest React Native applications in the world.

https://blog.dashlane.com/exploring-react-native-on-windows/

Re:The Next Step for Generics by DaiPlusPlus on Wednesday June 17, 2020 @09:00PM (#23558680)
The iOS and Android apps are using React Native - not the Windows Desktop Skype app.
Re:The Next Step for Generics by alkonaut on Wednesday June 17, 2020 @03:52AM (#23548927)
I admire their efforts in backwards compatibility, but I never saw the point of extreme source compatibility. If I don’t want to recompile then I don’t need to worry that some names were changed. If I do rebuild my app then I’m happy to spend the time fixing the errors, or build agains an old library or language version.
Re:The Next Step for Generics by stickfigure on Wednesday June 17, 2020 @01:08AM (#23548024)
As someone who does a lot of work in Java (which lacks typedef), I feel the opposite. I don't like "stringly typed" APIs where everything is a String or int or whatnot - it's only slightly better than Object; you're basically giving up on typechecking.

With generics or typedefs (or a willingness to create lots of classes), you can be certain you never pass an Id<Foo> someplace that expects an Id<Bar>.

Re:The Next Step for Generics by anoncake on Wednesday June 17, 2020 @01:43AM (#23548198)
Not having typedefs wouldn't be much of an issues if we could at least inherit from String and int (or Integer).
Re:The Next Step for Generics by smichel17 on Tuesday June 16, 2020 @07:14PM (#23545504)
I haven't used Rust before, but I can relate to the experience.

In general I lean towards it not being a waste. That's not to say it's always useful for that project but it is usually useful as a learning exercise, that allows me to better identify similar patterns later (including whether generics are worth using compared to primitive types, in situations like that).

For example, I spent a good year or two forcing all of my iteration into functional styles. Now I am much better at coding in that style... and at knowing when a for loop is the more appropriate tool.

Re:The Next Step for Generics by chewbacha on Tuesday June 16, 2020 @06:09PM (#23544902)
> I realize this when I go over it a second time and reduce line counts drastically by replacing my gee-whiz generics with primitive types.

I do this too, but I’ve also come to realize that fresh perspectives and newly learned patterns may be more of the reason than being a little over zealous.

Edit: forgot to mention that this happens to me in most languages, not just rust.

Re:The Next Step for Generics by hinkley on Tuesday June 16, 2020 @05:22PM (#23544339)
A year from now, isn't it the 'reduced line count' that will have value to you, rather than the churn?
Re:The Next Step for Generics by WJW on Tuesday June 16, 2020 @05:30PM (#23544458)
Sometimes. Often the reduced line counts contain way more complexity per line and understanding it is just as hard. There's something to be said for code churn, as it keeps it fresh in the mind of whomever is on the team right now as opposed to "a guy that left eight years ago wrote this".
Re:The Next Step for Generics by hinkley on Tuesday June 16, 2020 @05:47PM (#23544650)
As simple as possible, but no simpler.

I sometimes use the analogy of haiku versus short story.

You can pack a lot of meaning into a haiku, but few will be able to unpack it in the manner intended. A short story can get you to the point without filling a whole book to do so. And a lot more people can write a reasonable short story.

Re:The Next Step for Generics by pragmatic on Tuesday June 16, 2020 @09:03PM (#23546454)
Exactly, the maintenance tax, you have to load the crazy type into your head and once you get to 2 or 3 layers of generics is just painful. C# and typescript both have this.

The question is, what is beyond generics? We need a humane alternative that still provides the type safe guard rails.

Re:The Next Step for Generics by Thaxll on Tuesday June 16, 2020 @05:11PM (#23544167)
That's up to debate, you have to prove that in x.y.z language the time spend for maintenance would have been avoided if x.y.z had that feature from the start. Especially language like Rust that have a big learning curve / blockers, is it justified on the end? I'm not sure.

In Go I never felt that omg it misses some big features we're screwed, we're going to pay the cost of running that in Prod. All the services I worked on while not being perfect ran like a clock without issues on the long term, and it has to do with Go "simplicity", eventhough you never wrote the code you can actually jump into any code base without issues, there is no weird abstraction layer / complexity that takes you day to understand.

For me the fact that Go is a "simple" language is very powerful because on the long run it's much easier to maintain.

Re:The Next Step for Generics by throwaway894345 on Tuesday June 16, 2020 @05:20PM (#23544316)
Moreover, not all domains require you to catch every error. In many applications, it's just fine to ship a few bugs and it's much better to ship a few bugs here and there rather than slow down dramatically to appease a pedantic type checker. This is especially true when bugs can be found and fixed in a matter of minutes or hours and when the bugs are superficial. And I also contend that the more pedantic the type checker, the more likely that the additional bugs that it finds are of diminishing importance--they are less and less likely to be a downtime issue, they are increasingly likely to be in very rarely hit paths.

I like Rust a lot and I hope to get to use it more, but "added type safety at the expense of iteration velocity" is not a good tradeoff for my domain and I suspect many others (although its iteration velocity is improving monotonically!).

Re:The Next Step for Generics by kenhwang on Tuesday June 16, 2020 @05:58PM (#23544773)
Strangely, I found Go to be one of the least productive languages I've ever used, 2nd only to Java. It just makes the programmer do so much of the work for common tasks, and it's incredibly repetitive and while it generally generates a fast program, the quality/fault rate isn't any better than any other iterative language.
Re:The Next Step for Generics by throwaway894345 on Tuesday June 16, 2020 @07:47PM (#23545766)
I’ve used Python and Go (and JS to a lesser extent) extensively and Go has been consistently faster to iterate with, much better performance, much less headache with build/deploy/dependency issues, much better for teamwork (less pedantry in code review, docs don’t get out of date as easily, types keep people from doing as much pointless magic, etc). Note that the performance point is hard to overstate since with Python it means you run into performance issues far sooner and your options for optimizing are in a much different complexity ballpark which completely eats any iteration velocity gains that you might have had from Python in the first place (in case it was ever a question).
Re:The Next Step for Generics by ummonk on Wednesday June 17, 2020 @03:21AM (#23548745)
I mean if you're comparing it against a language with an even weaker type system...
Re:The Next Step for Generics by lenkite on Wednesday June 17, 2020 @03:30AM (#23548794)
Python is not a great productivity language. I find Python less productive than enterprise Java. The tooling in Python is still in the dark ages.
Re:The Next Step for Generics by loxs on Wednesday June 17, 2020 @05:06AM (#23549357)
Yeah, although Python was my first language and I used to love it, now I realize it's "the worst of all worlds". It's superficially easy, but it both runs slower than "real" languages and programmer productivity scales much, much worse than them. Of course "real" languages are also a scale and I think they too become worse further the scale. Go, C# and Java are probably around the sweet spot, although I myself prefer stricter languages like OCaml. Definitely something like Haskell is "too much" for my taste, probably will have to try Rust soon to figure out where it stands in my scale.
Re:The Next Step for Generics by sethammons on Tuesday June 16, 2020 @06:19PM (#23544994)
curious what other languages and domains you are working in. In my experience, Go has been a boon to productivity. I do networked services mostly. Projects that are maintained for years with lots of tweaks. Rewrites, greenfield. Lots of focus on operability, maintainability, and high availability. My work started in php, became more serious under perl (anyevent), and python (twisted), and toss in a smattering of other things here and there (some C, C++, ruby, javascript, lua). The main work horses were perl and python though. I've been using Go now since 1.2 (around 2013/2014). Every time I go back to these other languages in the same domain it is like taking a giant leap backwards.
Re:The Next Step for Generics by didibus on Wednesday June 17, 2020 @01:03AM (#23547998)
Interesting, I'd say the ones to challenge in the backend space are Java, C#, Scala, F#, OCaml, Erlang, Kotlin, Clojure, Elixir and Haskell.

Those are the stapled languages in the backend space which Go competes in. You could give some of them a try.

Re:The Next Step for Generics by zozbot234 on Tuesday June 16, 2020 @06:27PM (#23545068)
Go is most often preferable to any of the languages you mentioned, no doubt about it. It's just that Rust is generally held to an even higher standard.
Re:The Next Step for Generics by bjourne on Tuesday June 16, 2020 @07:38PM (#23545713)
I think that is your preference and not a generally accepted fact.
Re:The Next Step for Generics by Ericson2314 on Tuesday June 16, 2020 @06:28PM (#23545071)
So you've only used untyped languages, C++? No wonder you think Go is productive...

Not that Java is even good, but that beats go. The history of Go is the history of Java, repeated as farce. It's even some of the same academic lineage come to bail things out with the type system for generics!

Re:The Next Step for Generics by throwaway894345 on Tuesday June 16, 2020 @10:45PM (#23547148)
Go is quite a lot different than Java. Go has held to its promise of simplicity and consistency remarkably well. No need to learn groovy to configure Gradle to build your application; just use ‘go build’. No need to learn javadoc or configure your CI pipeline to build and deploy documentation packages. No need to figure out how to statically link your code, it’s the default. No need to figure out how to compile your code ahead of time, it’s the default. No need to figure out how to tune your GC for low latency and low memory usage, it’s the default. Plus Go has value types; Java is maybe going to get them, but they’ll never be idiomatic. On top of all of this are the misfeatures and antipatterns that are pervasive in Java but which don’t exist in ago—things like inheritance, objects, and the “you just want a banana, but the banana has a reference to the gorilla holding it and the whole damn jungle” design pattern. I know, I know “that’s just bad design and you can have that in any language!”—true in theory, but Go doesn’t have this in practice. Nor gratuitous inheritance hierarchies or anything else. And while Java folks don’t have to use those patterns/features if they don’t want to, the must still interface with them because their coworkers probably write code like that and if not your coworkers’ code, then the dependency library and even the standard library.

Go is a dramatically nicer programming experience than Java. There are some benefits in Java however: sometimes JIT is nice and Go has no analog to Spring. But these are very circumstantial benefits and not good tradeoffs in the general case.

Re:The Next Step for Generics by throwaway8941 on Wednesday June 17, 2020 @02:00AM (#23548263)
Most of the things you listed are not a problem in C#. And you don't have to be tied deeply to Microsoft to use it these days — I develop stuff full-time on top of .NET Core under Linux (and host it on Linux).

>No need to learn groovy to configure Gradle to build your application

I rarely have to configure msbuild, mostly to do some relatively advanced stuff like auto-installing npm dependencies for an SPA.

>No need to learn javadoc

Just use

    /** */
>No need to figure out how to statically link your code

You can build pseudo-statically linked executables by adding one line to .csproj (which builds a single executable file, but it's really a self-extracting archive), and real static linking is in the works. I have no need for it personally though.

>how to compile your code ahead of time

Same thing — AOT compilation is one configuration line away. You don't need it very much though, as the CLR is very performant these days and beats Go in most benchmarks:

https://benchmarksgame-team.pages.debian.net/benchmarksgame/...

>No need to figure out how to tune your GC for low latency and low memory usage

I would argue CLR's GC is ahead of Go's GC at least for latency. Memory usage, not so much, but damn, look at the execution times above. It depends on your priorities I guess.

>Plus Go has value types

C# has had them since before Go was a thing. Unlike Java, it also has real structs, which you can configure the alignment of, and map a raw chunk of memory to them (which you received from a COM port, for example). This came in handy more often than I care to remember.

As for your forest/banana analogy, I'd argue it's never been as bad in .NET world as it's been in Java world. I have personally never found anything similar to the insane class hierarchies they have in Spring.

Re:The Next Step for Generics by pjmlp on Wednesday June 17, 2020 @08:33AM (#23550596)
> I have personally never found anything similar to the insane class hierarchies they have in Spring.

Try to do something with stuff like XAML Workflows, Bizztalk, WCF, SharePoint, or MVVM. :)

Re:The Next Step for Generics by zmmmmm on Thursday June 18, 2020 @01:00AM (#23559934)
I think people get causation and correlation a bit confused here ... Java code is like it is not just because of it's nature as a language but because a gigantic number of huge corporations use it. And they have bajillions of dollars to pay developers to figure out a gradle build, or navigate a typ e hierachy etc. That's why equivalents of Spring etc., have appeared for .Net etc.

Btw, did you know the default Gradle configuration for compiling a Java app is literally 1 line?

    apply plugin: 'java'
I'm not that much a fan of Gradle (too much magic), but it's one of the least verbose and easiest to figure out parts of working with java.
Re:The Next Step for Generics by logeprog on Thursday June 18, 2020 @02:30AM (#23560360)
Having spent way too much years in java I’d have to say that the build systems are really the weakest part of java. We have „maven“ (wtf) and „gradle“ (powerful but yikes) oh and “ant” (dead now)

Wrt gradle: While it’s super easy to get started, any slight modification is a major pain.

Note to other tooling guys for other languages:

- I don’t want to write in a new language just for my build system

- I don’t want freaking xml hell like maven

And don’t get me even started with Maven as a package manager. But to be honest... it’s at least better than NPM :-)

Re:The Next Step for Generics by zmmmmm on Friday June 19, 2020 @12:01AM (#23570840)
So I assume you don't like many of the popular build tools at all - Make, bazel, etc all define a custom DSL effectively. At least Groovy or Kotlin are actual languages you can learn and use for other things, not something that has no alternative purpose so is completely wasted. And their syntax is very close to Java so you have a head start on learning it.

In general the concept of a "cross platform" build tool and "not having to learn another language" are at odds with each other, for anybody who isn't lucky enough to already work in the language the build tool is written in.

Re:The Next Step for Generics by sethammons on Tuesday June 16, 2020 @09:23PM (#23546610)
My only java experience was in college nearly two decades ago, so I def don’t have a valid opinion on Go vs Java. I’ve worked with dozens of former Java devs that were now working in Go. The majority felt it was a breath of fresh air and did not want to return to Java in the future. Granted that was not all of them. The plural of anecdote is not data, so I’d be interested in a larger poll to know how folks feel who have experienced both.
Re:The Next Step for Generics by philosopher1234 on Tuesday June 16, 2020 @10:59PM (#23547234)
More anecdata for you. I'm a professional Java dev, and I spend my off-hours writing tools for work in Go. It feels so much nicer to use.
Re:The Next Step for Generics by kortex on Tuesday June 16, 2020 @10:05PM (#23546912)
Were you using an IDE? For me, yeah go has a lot of boilerplate, but with autocomplete, because the type system is so simple, the autocomplete is super savvy and code just flies onto the screen. Still a fair amount of plumbing, but it's easy plumbing.

I can easily see it being tedious if you have to type every character.

Re:The Next Step for Generics by erik_seaberg on Wednesday June 17, 2020 @12:29AM (#23547793)
The trouble with boilerplate is that we have tools that write it for you but almost nothing that reads it for you, much less reviews it for manual edits. Anything that can be generated from a high level description and then thrown away, should be.
Re:The Next Step for Generics by tsimionescu on Wednesday June 17, 2020 @02:33AM (#23548428)
The IDE side is in my experience the worse part for Go (unless you pay for JetBrains GoLand).

Code navigation is extremely basic (can only find references in the same package!), often breaks, and can't handle stuff like finding all interfaces that a type implements, or finding all implementations of an interface.

Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @11:22AM (#23552509)
It used to be really good across the board, but I think modules broke a lot of things and they never fully repaired? I'm not sure, but I get the feeling that the quality of these editor integrations dropped a year or two ago.
Re:The Next Step for Generics by tsimionescu on Wednesday June 17, 2020 @02:35PM (#23554981)
As far as I can tell, they never had support for finding usages across packages, never had support for finding implementations of an interface, never had support for finding what interfaces a certain type matches/implements. These are basic features in any IDE for a language that has packages and interfaces.

Really good IDE support would include refactoring (more than renaming a local variable/struct field, e.g. Extract Function, extract parameter), advanced navigation/analysis (analyze data flow to/from variable, find call stack etc).

Go is somewhat decent in the tooling area, and you can get your job done with it, but it really doesn't have anything I would call good support in any area of tooling except the compiler (not code analysis, not debugging, not monitoring, not profiling, not package management).

Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @03:16PM (#23555512)
> As far as I can tell, they never had support for finding usages across packages, never had support for finding implementations of an interface, never had support for finding what interfaces a certain type matches/implements. These are basic features in any IDE for a language that has packages and interfaces.

I suppose it depends on what you're used to. I've never found myself wanting to do these things, but I'm also strictly from a Python and C++ background so my standards are admittedly lower than Java and C# people. Hopefully gopls solves for these problems.

Re:The Next Step for Generics by tsimionescu on Wednesday June 17, 2020 @03:46PM (#23555854)
In C++, you have never tried to go to the definition vs declaration of a function? Or find calls to your class through a superclass?
Re:The Next Step for Generics by justinclift on Wednesday June 17, 2020 @04:01AM (#23548982)
Which Go IDE's have you tried?
Re:The Next Step for Generics by tsimionescu on Wednesday June 17, 2020 @09:32AM (#23551149)
I tried GoLand, which was great.

Then, I tried VSCode with the Go plugin, both the default version and the go pls based one; and Emacs with the LSP package and go pls.

Re:The Next Step for Generics by qtplatypus on Wednesday June 17, 2020 @01:25AM (#23548112)
The boilerplate still has to be read and so the boilerplate still gets in the way of understanding "What is this supposed to do"
Re:The Next Step for Generics by alexbanks on Tuesday June 16, 2020 @05:51PM (#23544705)
I feel like Rust and Go are fundamentally different use cases and I wish people would stop the language debate.

Rust: For code that isn't meant to be iterated upon, that must be safe/correct while also being performant.

Go: For code that is meant to be iterated upon frequently, that must be performant and easy to maintain.

I would like my tools to be written in Rust, and I would like to interface with them in Go.

Re:The Next Step for Generics by necubi on Tuesday June 16, 2020 @07:31PM (#23545645)
I think that's totally backwards. A good type system _improves_ iteration speed, it doesn't slow you down. When I refactor a Rust program, I have very high confidence that if it compiles, I haven't accidentally introduced a bug.

I don't write much Go code, but my company does. I have seen so many incidents and bugs whose root cause was: someone changed a library, that broke the semantics that users were relying on, but everything still compiled fine, so nobody noticed the subtly wrong behavior for a long time. An incredible amount of money has been lost like this.

Go simply does not give you the tools to prevent these issues in the type system, you have to rely on really thorough unit tests (which inevitably don't get written in the spirit of "moving fast".)

Re:The Next Step for Generics by parhamn on Tuesday June 16, 2020 @09:18PM (#23546559)
Wait what?! Most of the major go libs (std and not) have been stable for years. Rust is merging random syntaxes and random packages get upgraded to std lib all the time.

The package ecosystem was so stable that go didn’t ship with a package manager (not saying it’s good but definitely a sign of relative stability).

Besides nil pointers (typesystem could do better here) and bad logic (can’t do better but language simplicity reduces this), what you’re saying is definitely not the experience of the majority. People constantly talk about being able to go to a golang program from 8 years ago and run it with no problems. Rust changes every few weeks.

Re:The Next Step for Generics by pcwalton on Tuesday June 16, 2020 @11:00PM (#23547248)
> People constantly talk about being able to go to a golang program from 8 years ago and run it with no problems. Rust changes every few weeks.

You stated that "Rust is merging random syntaxes and random packages get upgraded to std lib all the time" as though it were incompatible with "being able to go to a program from 8 years ago and run it with no problems". But there's no incompatibility here. Rust adds new features at a faster rate than Go does, but it also maintains backwards compatibility ("stability without stagnation").

Re:The Next Step for Generics by parhamn on Wednesday June 17, 2020 @10:44AM (#23552038)
Sure, I conflated 'still compiles' with 'still the right pattern'. Its sorta like Javascript, ECMAscript has been backwards compatible but the ecosystem is a consistently moving target that users have to adopt their code to or feel left behind. E.g crossbeam and parkinglot. Also the bunch of nightly features that disappear but many use.

Sure the mainline stays clean but thats not what matters in practice.

Re:The Next Step for Generics by Keats on Wednesday June 17, 2020 @08:24AM (#23550516)
> The package ecosystem was so stable that go didn’t ship with a package manager (not saying it’s good but definitely a sign of relative stability).

Which also explains why you can git clone a Go library/tool and have it not building because some dependencies introduced some breaking changes in the master branch. That happened the last 3 times I wanted to fix something in a Go project.

Re:The Next Step for Generics by gbear605 on Tuesday June 16, 2020 @10:29PM (#23547057)
I don’t know what Rust you’ve been using, but they’ve been explicitly having all changes be backwards compatible since 2016 - when they hit 1.0 - with a few small changes in 2018.
Re:The Next Step for Generics by aliceryhl on Wednesday June 17, 2020 @08:33AM (#23550595)
> Rust is merging random syntaxes and random packages get upgraded to std lib all the time.

I really don't know where this is coming from. The only package that was included into std like this is replacing the hashmap with hashbrown, and this didn't even change the public api of the standard library at all, besides improving performance of the hashmap.

Re:The Next Step for Generics by kortex on Tuesday June 16, 2020 @10:10PM (#23546943)
Not to mention go compiles at the speed of light, so CI pipes are usually just rebuild and rerun the entire suite on every commit, so idk how such bugs would lurk unless the tests were lackluster. Which happens, I totally understand.
Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @05:28PM (#23557005)
> don't write much Go code, but my company does. I have seen so many incidents and bugs whose root cause was: someone changed a library, that broke the semantics that users were relying on, but everything still compiled fine, so nobody noticed the subtly wrong behavior for a long time. An incredible amount of money has been lost like this.

In all likelihood, that "incredible amount" is a small fraction of the money your company saved in iteration velocity by not using Rust in the first place. This might not be true depending on your domain--if you're writing space shuttle software, bugs can be really expensive. If you're writing ordinary web app backend code, you're probably much better off with Go than Rust.

Re:The Next Step for Generics by Thaxll on Tuesday June 16, 2020 @08:36PM (#23546229)
I'm not sure I understand how this can happen in Go, it's a strongly type language, if for example you change a method / function signature, the code won't compile.
Re:The Next Step for Generics by necubi on Tuesday June 16, 2020 @09:20PM (#23546583)
Go is strongly typed (you can't pass an int to a function expecting a string), but its type system is not very powerful, and it cannot express many of the types people need in practice. Back to the discussion at hand (generics), Go programmers usually work around this lack by using interface{} types, which can point to anything and are essentially dynamic typing.

As another example, Go makes it impossible to create a Maybe/Option type which leads to a bunch of issues around returning failing or empty values from functions. In one particularly costly example, there was a function in a library that was getting some price information from a file. Originally this returned nil when the price information could not be loaded, but a refactoring caused it instead to return 0 which the client happily used. This was not caught for _weeks_.

Re:The Next Step for Generics by Thaxll on Tuesday June 16, 2020 @10:47PM (#23547159)
I've never seen those claims about heavy usage of empty interface in the real world, and in the few case we have it, there is type assertion that is safe and well known.

As for the second example I don't think it's a language issue but more a programmer one, how Rust would have saved you in that case, anyone could have returned 0 for the price instead of a proper type. Using Rust doesn't magically turn programmer into good ones. You still have to know how to properly design your code and best use the language and its features.

I'm often reading code in various language and I'm baffled at what a giant lib.rs looks like from someone that never really used Rust.

Re:The Next Step for Generics by thedufer on Wednesday June 17, 2020 @07:42AM (#23550236)
> how Rust would have saved you in that case, anyone could have returned 0 for the price instead of a proper type

You've missed the problem that was posed. It wasn't returning 0 to indicate an error, it was changing the error value from nil to 0. In rust that would've been a type change (from Option<int> to int). Because the context here was about how stronger type systems (like rust's) allow you to be more specific about your types, and thus many code changes that would not involve the type changing in other more weakly-type languages do cause a type change in rust.

Re:The Next Step for Generics by eshyong on Wednesday June 17, 2020 @03:11PM (#23555460)
Except that in Go, you always return the error alongside the value, like this:

    return 0, errors.New("unable to get price")
It's less elegant than Options but still, very common practice. GP's company clearly hasn't bought into Go if they're using a library that doesn't follow well-known conventions.
Re:The Next Step for Generics by XorNot on Wednesday June 17, 2020 @03:22AM (#23548749)
This is what strikes me: the situation is a programmer being lazy.

They wanted to do: something(getPrice()), but if getPrice can actually fail the then either something needs to accept an error, or they need to handle the error.

No type system imagined can save you from someone who's decided returning 0 is the correct way indicate an error in this scenario.

Re:The Next Step for Generics by eshyong on Wednesday June 17, 2020 @02:27AM (#23548401)
Sounds like your company is just using a unidiomatic library. It's poor practice to return a zero value as an error instead of, well, returning the error. As someone else said, it's standard practice in the vast majority of all go code to return a value, error tuple and check at each call site. In fact, it's so common that it's the number 2 complaint about go code after not having generics (error handling too verbose).

Go has its problems, and it isn't a perfect language, but I have never felt unproductive using it. In fact, my company uses it for all backend services. It has a great stdlib and first class tooling. Most of the discussion in this thread seems to be coming from people who barely use it or have only dabbled with go.

As a tangent, it's really tiring to see HN engage ad nauseum in these pointless language debates. Every language has its place; use it when it's appropriate.

Re:The Next Step for Generics by alexbanks on Tuesday June 16, 2020 @10:33PM (#23547079)
What you're describing comes down to "Bad programmers do bad things", which literally no language can or will solve. If your code has lots of interface{} in it, you're not really using the language as intended. Pretty much every Go styleguide/linter/whatever will throw up at interface{} usage.

You can write unsafe code in Rust. Does that mean that Rust is bad too?

Re:The Next Step for Generics by logeprog on Thursday June 18, 2020 @02:45AM (#23560425)
100% agree. Same with :any in typescript. When it comes to bugs... I tend to think that a good configured linter is more important than the degree of the type system. It’s nice to have a strong type system but people forget that a lot of programmers are bad and a good type system won’t change that fact.
Re:The Next Step for Generics by Mawr on Tuesday June 16, 2020 @10:43PM (#23547141)
>Originally this returned nil when the price information could not be loaded, but a refactoring caused it instead to return 0 which the client happily used.

Hard to feel sympathetic, as this practice violates the Go convention of adding an additional return value to the function to indicate failure, either of type error or bool, as appropriate.

>Go makes it impossible to create a Maybe/Option type

It's very much possible: https://play.golang.org/p/MCxGcZ-rJRU.

Of course, it's not generic, but I have a feeling that might change soon :)

Re:The Next Step for Generics by ummonk on Wednesday June 17, 2020 @03:28AM (#23548784)
The Option type there isn't type safe. E.g. https://play.golang.org/p/CiQLf4yWhCO doesn't throw a type error for the Get function even though I've omitted the null check.
Re:The Next Step for Generics by Mawr on Wednesday June 17, 2020 @03:16PM (#23555508)
Sorry, but that's just ridiculous. Obviously the language can't prevent you from defining your Option type incorrectly. The point is that it's not possible to misuse it.
Re:The Next Step for Generics by ummonk on Wednesday June 17, 2020 @07:54PM (#23558251)
Okay let me rephrase. The type checker doesn't make sure you've checked the value of ok e.g. you can do this: https://play.golang.org/p/x18Rh2iwd2E

Go constantly requires boiler-plate checks for errors, null values etc. without the type checker helping ensure you've checked for an error or null value.

Re:The Next Step for Generics by geodel on Tuesday June 16, 2020 @08:12PM (#23546021)
Maybe you need to think why your company is not writing in Rust. Is there some quality of Rust that individual users prefer more than companies in general.

Whenever I hear about Rust in companies same dozen or so companies get mentioned every time.

Re:The Next Step for Generics by necubi on Tuesday June 16, 2020 @08:39PM (#23546257)
The specifics of what languages my company writes are mostly historical, and I would say that Rust was not ideal for writing high-throughput network services until this year with the release of async/await.

But in general, companies adopt Go for the same reason they adopt MongoDB [0]: it's really easy to get started with, and get something that "works." The pain comes months or years down the road, and by then you're stuck with it.

[0] A company I previously worked for starting using MongoDB as a small startup, starting finding the limitations about 6 months later, but ending up spending an incredible amount of engineering time over 5 years getting rid of it.

Re:The Next Step for Generics by alexbanks on Tuesday June 16, 2020 @10:35PM (#23547094)
You're a person that really does not like the Go programming language, and that's okay, but to try and paint a perfectly fine tool as bad because someone used it incorrectly, and then compare it to a pretty objectively bad product is silly.

We get it. You don't like Go. Don't use it. That's a perfectly fine option. Plenty of very successful companies, open source projects and services all work with Go (and literally every language) without issue. You not liking something does not make it bad.

Re:The Next Step for Generics by alexbanks on Tuesday June 16, 2020 @07:45PM (#23545756)
And you're welcome to think that. YMMV.
Re:The Next Step for Generics by zozbot234 on Tuesday June 16, 2020 @06:22PM (#23545026)
What's wrong with iterating on Rust? Comprehensive type checking makes refactorings a lot easier than something like Go. And you can iterate starting from a simple, working solution that relies on marginally more expensive features, such as .clone(), Rc<…>, Cell<…> or RefCell<…>, Any for dynamic data etc. etc.
Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @05:39PM (#23557089)
Refactoring is safer with Rust, but in generaly Go is not so unsafe that refactoring costs more than it saves on the frontend. You can write a lot of Go (and contrary to the memes in this thread, you can still leverage the type system to great effect wrt safety) in the time it takes to get a little Rust to compile; however, Rust is getting better all the time.
Re:The Next Step for Generics by Ericson2314 on Tuesday June 16, 2020 @06:25PM (#23545049)
I think you are missing the point of type systems. Our current economy doesn't value correctness at all. Code is rushed out, and usually live longer than it was designed too. This mimicks the the largest infrastructure debt of America (and to a lesser extent, the western world as a whole).

But the same shoddy system is also constantly changing the requirements, precisely because nothing is built for posterity and there's tons of make-work churn. Good type systems make code far easier to refactor, and refactoring (as opposed to slapped-on new code) is the only way to handle shifting requirements without being crushed under ones own weight.

Re:The Next Step for Generics by alexbanks on Tuesday June 16, 2020 @06:34PM (#23545122)
I'm not missing anything. I'm well aware of the value of type systems, as I am our current cultural decision to value speed over correctness.

I'm not confident that average level developers are able to ship features in Rust as quickly as they would in Go, which is the root of my point. Those building tools, which generally do not have the same success metrics with respect to speed and correctness, should use the language with a focus on safety and correctness. Those whose positions do not lend themselves to safety and correctness should not use that tool.

Re:The Next Step for Generics by zozbot234 on Tuesday June 16, 2020 @06:49PM (#23545276)
> I'm not confident that average level developers are able to ship features in Rust as quickly as they would in Go

Even if this was a genuine concern, they should still use Rust. Because it will be far easier to refactor the code that they ship into something that is safe and correct, compared to rewriting a Go codebase.

Re:The Next Step for Generics by alexbanks on Tuesday June 16, 2020 @06:52PM (#23545307)
We can agree to disagree. The whole point of my post is that I do not agree with your statement.
Re:The Next Step for Generics by ameixaseca on Tuesday June 16, 2020 @06:33PM (#23545115)
Which code is not meant to be correct?
Re:The Next Step for Generics by alexbanks on Tuesday June 16, 2020 @06:47PM (#23545249)
This is a silly strawman. All code is meant to be correct, but often times close enough to correct is good enough (as is literally the whole point of my post). Most businesses operate on code that is close enough to correct for their individual risk tolerance, and increasing that correctness would reduce speed/throughput and increase cost.
Re:The Next Step for Generics by Gepsens on Wednesday June 17, 2020 @09:11AM (#23550918)
I hope you are kidding mate. I've been solo maintaining 50k lines of Rust iterating over a few months and it's a breeze.
Re:The Next Step for Generics by dnautics on Tuesday June 16, 2020 @11:12PM (#23547326)
This. Let me give an example. When booting a system you can get errors as concurrently booted subsystems (we're talking tens of thousands of them potentially) don't necessarily finish in the order you want, inducing effectively dependency error race conditions. You can either write a totally checked system that is brittle to these race conditions, and many nightmares worth of debugging, testing, and giving up, or you can write floopy logic that accepts the problem, fails, and restarts, and moreover very likely gives you lowered downtime overall. What do you do?
Re:The Next Step for Generics by nine_k on Tuesday June 16, 2020 @05:40PM (#23544563)
(1) This is why you can even ship code written in JS or Python. (2) This is why Typescript and mypy exist.
Re:The Next Step for Generics by throwaway894345 on Tuesday June 16, 2020 @07:50PM (#23545804)
I agree, although my experience with Mypy has been miserable. I’m not sure the costs are less than the gains. Also there are other tradeoffs, like performance and artifact size (numpy and pandas alone are 100mb).
Re:The Next Step for Generics by pjmlp on Wednesday June 17, 2020 @02:35AM (#23548439)
Only because liability still isn't a sure thing with proper fines for those that ship faulty products.
Re:The Next Step for Generics by AnimalMuppet on Wednesday June 17, 2020 @03:40PM (#23555782)
1. There's lots of software that doesn't "ship" - it's used internally.

2. There's lots of software that "ships" as a web service, often used by people who are not paying for the web service.

If you're talking about defects for an actual product that render it unsafe or unsuitable for the intended purpose, then I can see your point (though even there I'm not sure that I completely agree). But there's much more software than that.

Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @05:21PM (#23556929)
Note that the whole point of my post is that there are different risk profiles for different kinds of software (or even within one kind of software--e.g., the data security subsystems in saas apps have a different profile than the UI widget library). If the parent's point is "some bugs are serious!" then that's not a rebuttal to my post--don't use weak type systems for those projects or those parts of the project. You don't rebut "You don't have to write all software like it is space shuttle software" with "some software is space shuttle software!".
Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @03:23PM (#23555600)
Nonsense. No one is served by fining companies for superficial issues. Customers are nearly always better off getting features faster at the expense of superficial issues. Any other take ignores economic reality (I say this with much chagrin, as I would rather move slower and release finely crafted features).
Re:The Next Step for Generics by amelius on Tuesday June 16, 2020 @06:56PM (#23545341)
Ideally, you'd have a language that allowed you to do both. Generics/type safety when you want them (e.g. for stuff that is hard to maintain), and total freedom otherwise.
Re:The Next Step for Generics by pdehaan on Tuesday June 16, 2020 @08:02PM (#23545919)
Python with type annotations is the closest I've used to that, and I hate it. It beats no type annotations, but only barely.

As soon as I need to use someone else's code, all bets are off. Half the reason I want types is because it makes my life easier when I'm trying to use something written by someone else -- instead I find myself needing to experiment with a debugger to figure out what functions are actually doing.

Re:The Next Step for Generics by ummonk on Wednesday June 17, 2020 @03:34AM (#23548820)
Plenty of languages allow you to do this, either by opting into type checking only when you add type annotations, or by using "any" / "dynamic" or unchecked typecasts as an escape hatch when you don't feel like going through the trouble of how to make the typechecker happy.
Re:The Next Step for Generics by int_19h on Wednesday June 17, 2020 @02:35AM (#23548444)
C# with liberal use of "dynamic" would be pretty close to that.
Re:The Next Step for Generics by g5becks on Thursday June 18, 2020 @03:37AM (#23560711)
So basically typescript?
Re:The Next Step for Generics by atdt on Tuesday June 16, 2020 @06:09PM (#23544894)
[[citation needed]]. "Everyone knows" that type systems reduce bugs, but actual evidence for that is pretty weak.

https://danluu.com/empirical-pl/

Re:The Next Step for Generics by sethammons on Tuesday June 16, 2020 @06:24PM (#23545035)
That study calls out significant issues. I can go from personal experience. Porting python to Go. In python, we had to have tests dedicated to ensuring the right types were handled the right way. Is it a string or an array passed in? Welp, need a new test to cover that. Whole classes of tests go away with more advanced type systems. Those tests were needed to prevent those classes of bugs. So better type system == removing of whole class of bugs.
Re:The Next Step for Generics by sixstringtheory on Tuesday June 16, 2020 @06:51PM (#23545295)
Came here to say I've had this exact same debate. We were writing long Python test suites to check types. I constantly (and playfully, I don't care to die on this hill) pointed out this is fully automatable with a static typing system. I remember many times being told to just read thousands of lines of uncommented tests in order to understand some thing I was trying to debug. (Don't get me started on Python stack traces!)
Re:The Next Step for Generics by viraptor on Tuesday June 16, 2020 @07:23PM (#23545571)
I've started applying `mypy --strict` to my new python code. It caught so many issues already it's definitely worth it. Mostly in cases of uncommon error handling, some in code which was tested but under wrong assumptions and would actually fail on production. (This is a problem with "you can test types approach")
Re:The Next Step for Generics by SnowflakeOnIce on Tuesday June 16, 2020 @11:01PM (#23547254)
Yes, mypy is terrific, and has changed the way I write Python programs.

Taking this gradual typing tool a step further, you can run your tests with the typeguard plugin for pytest, which will dynamically check the types of most values, pointing out places where your types are a lie.

https://typeguard.readthedocs.io/en/latest/userguide.html#us...

Re:The Next Step for Generics by viraptor on Wednesday June 17, 2020 @12:20AM (#23547748)
That's amazing. Thank you for mentioning this.
Re:The Next Step for Generics by waheoo on Tuesday June 16, 2020 @07:44PM (#23545749)
This is where the type system debate breaks down.

What you point out is a developer error. Mixing variable types in a dynamically typed language is, like generics, a code smell.

Using a dynamically typed language is all about not having to babysit the compiler, its not about playing dumb about types.

If you design your functions in a way that that function will never receive an array, you dont have to test for it. And if some idiot tries one day, it should error very loudly that something is wrong.

Too many abuse dynamic typing to the point they feel safer offloading this headwork to a compiler.

That is, they get the compiler to make sure nobody will ever send an array into that function that takes a string.

All generics do is bring back the lack of typesafety and all the manual typechecking that comes with muddying generalizing the parameter typeset.

I actually dont hate generics, they are super powerful, but I question every usage as suspicious.

I also wish people would remember human brains arent all the same. We have different ways of thinking about problems. Some people need to have a compiler to busy work, some people need to do busy work while they think.

I just wish people shitting on dynamic typed languages would remember they came to solve the mess and monotomy that arose from typesafety.

Someone mentioned they felt go was going backwards from rust, i think both languages are massive steps backward from python.

Re:The Next Step for Generics by icholy on Tuesday June 16, 2020 @08:39PM (#23546254)
> If you design your functions in a way that that function will never receive an array, you dont have to test for it. And if some idiot tries one day, it should error very loudly that something is wrong.

Then you've moved it from a test to a runtime assertion. You're still re-implementing the type-checker, poorly.

Re:The Next Step for Generics by bonestormii_ on Tuesday June 16, 2020 @10:26PM (#23547038)
And on top of this, it's usually not "some idiot" calling the function from a REPL. It's "some idiot's code", which may not be executed until the program is running in production somewhere if it is rare. "Oh, someone uploaded THAT kind of file? Well, let me see... AttributeError: Type SomeObject does not have attribute append. Here's a list of 47 functions that were called between the action you took and this error being raised. None of them guarantee the types going in or out, so you should probably get going waking through all this logic. You're welcome! -Python <3, XOXOXO"
Re:The Next Step for Generics by waheoo on Tuesday June 16, 2020 @11:16PM (#23547354)
Well if a functions first run is in production youve got other problems. The idiot ref would be right.
Re:The Next Step for Generics by pansa2 on Wednesday June 17, 2020 @02:54AM (#23548546)
“Compile-time and runtime are less relevant notions than before-shipping and after-shipping” - Rich Hickey

https://twitter.com/richhickey/status/1063086406980026370

Re:The Next Step for Generics by bonestormii_ on Wednesday June 17, 2020 @03:39AM (#23548856)
Hehe. But has anyone ever shipped code that won't compile? I think not.

A compile time error is a caught error. A run time error may be, or perhaps not.

Re:The Next Step for Generics by logeprog on Thursday June 18, 2020 @02:57AM (#23560495)
This!
Re:The Next Step for Generics by bonestormii_ on Tuesday June 16, 2020 @11:59PM (#23547614)
It ran fine with all the file types we tested! A dependency loads the file into a custom type, but it handles this file type differently! Now it's a stinky old NoneType. :( :( :(
Re:The Next Step for Generics by randomdude402 on Wednesday June 17, 2020 @12:16AM (#23547725)
Yeah Python has its points where it doesn't shine, but the stacktrace does a consistently good job of telling you exactly where the logic broke down.
Re:The Next Step for Generics by bonestormii_ on Wednesday June 17, 2020 @12:21AM (#23547752)
I love Python, and generally I agree, but the place where an error is raised can be significantly distant from the event that occurred which caused it. The lack of static typing can really make it difficult to find such bugs sometimes.

A statically typed language with compile-time type checking would flag that immediately, and chances are your IDE will show the error before it even gets to that point.

Type hints are a thing, but then you are already moving in that direction while remaining in python.

Re:The Next Step for Generics by randomdude402 on Wednesday June 17, 2020 @12:57AM (#23547966)
Agree that there's a big difference between the error happening at compile time vs. happening at run time in prod, but I personally find the python stacktrace much more descriptive of how we got to the error than a lot of other languages.

A certain amount of it is probably a familiarity thing, but I do usually find myself able to parse it to the point of what line in which file things started to go wrong.

Re:The Next Step for Generics by unrealhoang on Wednesday June 17, 2020 @10:52AM (#23552123)
Other languages can do the same, they just deliberately make the decision not to because of performance. Ruby has the same nice stacktrace (even nicer).
Re:The Next Step for Generics by eru on Thursday June 18, 2020 @04:22AM (#23560975)
There was some work that took ML compile time errors and created Python-like stacktraces of how this specific error could blow up at runtime in a Python-like fashion. Students found those concrete errors with concrete values easier to reason about than abstract compile time errors.
Re:The Next Step for Generics by travv0 on Tuesday June 16, 2020 @11:54PM (#23547584)
> All generics do is bring back the lack of typesafety and all the manual typechecking that comes with muddying generalizing the parameter typeset.

I'm not sure if I'm misunderstanding you here, but generics are type safe. They're statically checked at compile-time.

Re:The Next Step for Generics by dragonwriter on Wednesday June 17, 2020 @11:15AM (#23552415)
> If you design your functions in a way that that function will never receive an array, you dont have to test for it. And if some idiot tries one day, it should error very loudly that something is wrong.

That's naïve. Unless you code extra defensively (which is the same type of overhead as excessive testing, and needs itself to be verified by testing), there's very little guarantee that type errors will result in loud failure consistently at the first point that the bad value is passed (because functions that don't do unnecessary work often pass their arguments along without doing a lot of work dependent on the very specific type.)

And, in any case, failing consistently at compile time (or, with a modern code editor, at writing time) with static type checking is better than failing at runtime, even if it is loud and consistent.

Of course things like mypy and TypeScript (especially, in the latter case, because it powers tools that work pretty well when the actual immediate source is plain JS, or JS with JSDoc comments from which type information can be extracted, when consuming libraries with TS typings) mean that some popular dynamic languages have static type checking available with more expressive type systems than a number of popular statically-typed languages.

Re:The Next Step for Generics by throwaway894345 on Tuesday June 16, 2020 @11:03PM (#23547267)
In Python, it’s entirely idiomatic to take different types of input and do different things. Look at the pandas dataframe constructor or just about anything in the datascience ecosystem (e.g., matplotlib). Look at the open() builtin—the value of the second string argument changes the return value type. Things aren’t much better in JS land where a function might take an arg or a list or a config object, etc. We see dozens of type errors in production every day.
Re:The Next Step for Generics by waheoo on Tuesday June 16, 2020 @11:23PM (#23547388)
For what its worth, the datascience ecosystem is probably the worst place to get general idioms from. They tend to err towards their own domain language and build stuff for people who arent programmers. i.e. for caller flexibility instead of maintainability.

Besides that, i only said it was a code smell, i dont debate that its useful sometimes. Just that its a signal to be careful, check you really need itor there is t some other constraint you can break.

My only advice is that narrowing your parameter types at the earliest opportunity is a good practice and results in much easier to understand code.

Re:The Next Step for Generics by nyanpasu64 on Wednesday June 17, 2020 @05:36AM (#23549530)
I kinda wish Python took the Rust approach of having multiple factory static-methods, rather than one constructor that does different things based on what arguments you pass in.
Re:The Next Step for Generics by duckerude on Wednesday June 17, 2020 @06:34AM (#23549863)
It does that sometimes, e.g. the classmethods in https://docs.python.org/3/library/datetime.html .

But perhaps not enough.

Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @11:19AM (#23552473)
Yeah, it seems not very idiomatic. I regularly see "senior engineers" doing I/O, throwing exceptions, etc in constructors. I staunchly believe a constructor should take exactly one parameter per member variable and set the member variable. For conveniences, make static methods that invoke that constructor. This will make your code far more understandable and testable (you can initialize your object in any state without having to jump through hoops). This is language agnostic advice, but some language communities adhere to it better than others. Python is not very good about this.
Re:The Next Step for Generics by duckerude on Wednesday June 17, 2020 @01:13PM (#23553905)
I wonder if dataclasses might change this. They provide an __init__ that does what you describe, and though you can supply your own __init__ instead, classmethods seem the easier way to add custom initialization logic.
Re:The Next Step for Generics by throwaway894345 on Wednesday June 17, 2020 @03:07PM (#23555411)
Yeah, it would be a very good thing for the Python community if dataclasses became idiomatic and vanilla classes came to be regarded as a code smell. Basically what every language should have is the concept of a "struct" or a "struct pointer". Constructors imply that there is one right way to construct an object which is rarely true except in the one-param-per-member-field sense.

"Convenience constructors" (i.e., static methods for creating instances from a set of parameters) are fine, but should often not be in the same module (or perhaps even the same package) as the class anyway. For example, if you have a Book class and it has a convenience constructor for creating a book from a database connection string and a book ID, this is probably reasonable for certain applications, but if it's likely that others would want to use your book class in non-database applications, then it would be a travesty to make the non-database application take a dependency on sqlalchemy, a database driver, etc (especially since database drivers tend to be C-extensions which may or may not be difficult to install on various target platforms).

Re:The Next Step for Generics by entha_saava on Tuesday June 16, 2020 @11:27PM (#23547416)
I just wish people shitting on statically typed languages would remember they came to solve the mess that arose from dynamic typing.
Re:The Next Step for Generics by waheoo on Wednesday June 17, 2020 @12:08PM (#23553023)
Im sorry you feel like i was shitting on statically typed languages.

I can assure you I do beleive they have their purpose and place in the world where raw performance or closer to metal abstractions can take place.

Personally, my brain much prefers to use a dynamic type system to infer what i mean leaving the thinking part up to me.

I just find defining a string is a string when im only ever going to put a string in there kind of redundant.

There are other arguments about readability, refactorability, and similar and I think they have some weight in large doverse systems with many many teams interacting.

Personally, that isnt a large issue for me. Im working at the scope I can maintain a standard and a level of consitency that alleviates these problems to the point the type safety is simply not wareanted from a return on investment point of view.

I do not, for instance, think the kernel or chrome should be rewritten in javascript. Despite what some react developers seem to think.

Re:The Next Step for Generics by entha_saava on Wednesday June 17, 2020 @11:41PM (#23559593)
> I just find defining a string is a string when im only ever going to put a string in there kind of redundant.

There are 2 problems with this kind of thinking.

1) you aren't going to be so sure. Humans are imperfect and as codebase grows, everyone commits such errors. Eg comparing a string to int without converting it to int in python. It always returns false (IIRC) and it is hard to detect where the problem is.

2) Most type systems aren't that verbose. I guess you got the impression from java / mediaeval C++. But most statically typed languages have local variable type inference. OCaml / Haskell / F# / Swift etc.. have varying degrees of type inference. At this point, types in method signatures, in languages that require it, serve as documentation. And many of these languages are terser than python/javascript.

Re:The Next Step for Generics by waheoo on Thursday June 18, 2020 @01:44AM (#23560121)
Thanks for taking the time to respond.

1) I work on a typescript codebase for work. There is a real need for types in this case because the definitions are about 3 layers of abstraction away from their use. It drives me up the wall because I know when you keep definitions close to use, or have some basic conventions this problem melts away. At least to the point of diminishing returns where types are no longer relevant.

So, i guess over the years ive been caught out by int + string = 0 all of like, 1-2 times in production, maybe a few more while in dev. Either way its rare enough for me to call FUD on the argument. Stop mixing types and this really doesnt happen. To be fair to your point, at work, i know of a recurring error in production where this is almost certainly the same class of error. Nobody can be bothered fixing it because its too hard to track down and the cost benefit isnt there.

2) Type inference is problematic for me. Doesnt it just open you up to type errors of a different class?

2.5) terse code is not the point, I find rust cryptic and dense to say the least. I prefer something like go wgere readability is a priority over density.

Re:The Next Step for Generics by tluyben2 on Friday June 19, 2020 @07:23AM (#23573268)
> 2) Type inference is problematic for me. Doesnt it just open you up to type errors of a different class?

It's at compile time, so not really? It will tell you exactly what it expects vs what you provided at compile time. These kind of languages read like dynamic languages (for the most part) but they are completely static.

Re:The Next Step for Generics by dragonwriter on Wednesday June 17, 2020 @10:55AM (#23552166)
> In python, we had to have tests dedicated to ensuring the right types were handled the right way. Is it a string or an array passed in? Welp, need a new test to cover that

  def foo(arg: str) -> int
vs.

  def foo(arg: List[Union[Set[int],Optional[Dict[str, Any]]]]) -> str
But...Python has a static type checker with a more expressive type system than Go.

Also, IIRC, better type inference.

Re:The Next Step for Generics by pfdietz on Tuesday June 16, 2020 @06:51PM (#23545301)
But, do you really save tests? You have to test your code anyway. Does a type system buy you anything more in code that's going to be heavily tested for other reasons?
Re:The Next Step for Generics by kenhwang on Tuesday June 16, 2020 @07:07PM (#23545443)
So many tests it's not even funny. A huge chunk of tests in dynamic/softly typed languages just end up being input/output validations where in a strongly typed language you don't bother since you know the compiler would refuse to compile it.
Re:The Next Step for Generics by pfdietz on Tuesday June 16, 2020 @07:24PM (#23545580)
Except if you are comprehensively testing your code for things other than what's caught by type checking, you get those validations for free.

In my view, type checking lulls one into thinking the code is better than it actually is, just because it compiles. But it doesn't test the algorithms. And testing the algorithms exercises the code enough to reveal the shallow type errors.

Re:The Next Step for Generics by kenhwang on Tuesday June 16, 2020 @07:33PM (#23545675)
Positive vs negative testing. Checking the algorithm is generally positive testing. You still should have negative testing, and in a strong type system language the compiler can be leveraged to do much more of that for you.

But yes, there's a lull with type checking that makes people believe only negative testing is sufficient, which is as foolish as thinking only positive testing is sufficient.

Re:The Next Step for Generics by Polylactic_acid on Tuesday June 16, 2020 @10:28PM (#23547050)
The evidence is pretty clear to anyone who writes in an untyped language. I can't count the number of bugs that I see in ruby code at work that would simply not exist in rust. The biggest one being unexpected nils.
Re:The Next Step for Generics by gorgoiler on Tuesday June 16, 2020 @07:29PM (#23545624)
In my experience I find it very common to write, rewrite and rerewrite code a lot when embarking on a new project. For various reasons, I embark on more new projects than I work on long term ones, which I think is a factor here.

It takes a while for something to settle down enough to say this version is going to be the code for the long run.

At that point, solidity in testing and gradual typing can be added, usually starting with the public interface.

Languages where I’ve had to satisfy all type errors in the various fragments of half brained code I’ve written for version 0.0.85 have always felt a little cumbersome. The compiler’s type checker is a perfectionist looking over my shoulder.

(Go is one of those languages. Ruby is not.)

Re:The Next Step for Generics by trixie_ on Tuesday June 16, 2020 @08:45PM (#23546304)
I'm the opposite. New applications are the ones you refactor the most, and refactoring is an order of magnitude easier/faster when the code is statically typed.

Refactoring any dynamically typed application (regardless of size) is a manual operation, and error prone.

But then again I rarely deal with type errors, when I do it's the compiler looking out for my often 'application ending' mistakes.

Re:The Next Step for Generics by randomdude402 on Wednesday June 17, 2020 @12:11AM (#23547689)
As a person who chooses Python whenever it seems reasonable, I agree.

Go, the language, is simple. Hard to argue with, and sounds great.

The code I have to write though, it's quite simpler to do it in Python more often than not.

Re:The Next Step for Generics by entha_saava on Tuesday June 16, 2020 @11:13PM (#23547336)
This is a generalized feeling about good static type systems.

What is missing is a language with good static type system (Algebraic data types, stream/iterators, generics), simple and having GC, for application domains where prototyping speed matters.

Re:The Next Step for Generics by neilparikh on Wednesday June 17, 2020 @04:13AM (#23549045)
I think Swift satisfies all of those those criteria, and doesn't have a steep learning curve since you can write in an imperative style if you want.

F#, OCaml and Haskell (and other ML-family languages) satisfy the first 3 criteria (type system, simple and GC) and depending on your familiarity with the language, can be fairly suitable for fast prototyping.

For example, I write most of my new personal projects in Haskell, and I'm able to iterate pretty rapidly once I have a skeleton of the system in place (with liberal use of typed holes to ignore things I don't care about implementing right now). For some projects, I find I'm actually able to prototype more rapidly than I would be able to in an untyped language, because the language helps me express the shape of the data through algebraic data types, and then the functions end up having "one obvious implementation" that follows the structure of the data.

Re:The Next Step for Generics by entha_saava on Wednesday June 17, 2020 @06:55AM (#23549985)
Reference counting still requires you to keep track of cycles. Also performance is less than GC, especially in multithreaded environments. And Swift is not a serious language outside apple ecosystem.

OCaml is actually very good language. I hate how people outright dismiss it mentioning multicore. Neither JS nor Python have great multicore story. And most applications don't need multicore.

Wish there was a good static compilation toolchain for .net core. F# would gain much more traction then.

Re:The Next Step for Generics by azernik on Wednesday June 17, 2020 @06:16PM (#23557458)
Both Javascript and Python are perfect for this, IMO - both languages have syntax for type annotations which are ignored by the intepreter, but are respected by external typecheckers.

Mypy for Python (https://mypy.readthedocs.io/en/stable/) and Flow for Javascript (https://flow.org/en/docs/) are my personal favorites, and have all the features you describe. And importantly, both languages have very strong library support.

Re:The Next Step for Generics by cageface on Tuesday June 16, 2020 @11:28PM (#23547422)
Types also are also massively useful in making better tooling. The ability to refactor with confidence and get meaningful autocompletes is already enough justification for a static typesystem.