News for hackers. Stuff that matters.
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.