Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
pokeyman
Nov 26, 2006

That elephant ate my entire platoon.
Swift generics are cool.

Adbot
ADBOT LOVES YOU

Falcorum
Oct 21, 2010

eth0.n posted:

Rust has great generics. As easy to use as Java's, but get compiled and optimized like C++ templates. They're modeled after Haskell, but not as flexible.

It can't be a good generics system without HKT. :colbert:

Presto
Nov 22, 2002

Keep calm and Harry on.

Plorkyeran posted:

Seems pretty obvious what the error is?

It really isn't. In fact, I still don't know what the problem with the original example is. :saddowns:

Absurd Alhazred
Mar 27, 2010

by Athanatos

Presto posted:

It really isn't. In fact, I still don't know what the problem with the original example is. :saddowns:

It was a vector of vectors of ints, and it was trying to find a particular int in it; it failed because int is not comparable to a vector of ints.

SupSuper
Apr 8, 2009

At the Heart of the city is an Alien horror, so vile and so powerful that not even death can claim it.

Plorkyeran posted:

This is a 7-year-old compiler. Let's take a look at the error with something a bit more recent:
Seems pretty obvious what the error is?
I'm glad in 7 years the actual source line is still just a footnote buried under template errors, how far we've come.

Absurd Alhazred
Mar 27, 2010

by Athanatos

SupSuper posted:

I'm glad in 7 years the actual source line is still just a footnote buried under template errors, how far we've come.

Mods change my name to "template error footnote"

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
I mean, it's the same thing you do when diagnosing an exception in library code - ignore the stuff at the top, and look down the stack trace until you see a filename that's part of your code.

What it really needs is a way to output errors that's more than just "a massive dump of plain text", so that the compiler can immediately show you the failing line and then let you drill down into the details if you need them in order to figure out what's up.

Simulated
Sep 28, 2001
Lowtax giveth, and Lowtax taketh away.
College Slice

Bruegels Fuckbooks posted:

i like generics in C# the best. C#/java create generic objects on runtime and deal with all this poo poo using the best language feature in the history of language features, reflection.

No they don't. C# generics are real generics and the runtime is aware of them. The IL JIT/AOT compiler does in fact generate generic instantiations for value types, though as an optimization all reference types share an implementation. The runtime reflection model is also aware of generics. You can dynamically create instances of generic types and inspect the types of generic parameters at runtime.

Java generics are garbage because the runtime isn't aware of them at all. The compiler throws it all away and everything is Object at runtime, which is also why Java generics don't support value types (or more accurately primitive types since Java doesn't have user-defined value types).

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Presto posted:

It really isn't. In fact, I still don't know what the problem with the original example is. :saddowns:

The actual error message is error: invalid operands to binary expression ('std::vector<int, std::allocator<int> >' and 'const int'). In then prints the stack trace of the error, and the first line that isn't inside library code is the call to std::find(). This tells you that the things you passed to std::find are not comparable.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Simulated posted:

No they don't. C# generics are real generics and the runtime is aware of them. The IL JIT/AOT compiler does in fact generate generic instantiations for value types, though as an optimization all reference types share an implementation. The runtime reflection model is also aware of generics. You can dynamically create instances of generic types and inspect the types of generic parameters at runtime.

Java generics are garbage because the runtime isn't aware of them at all. The compiler throws it all away and everything is Object at runtime, which is also why Java generics don't support value types (or more accurately primitive types since Java doesn't have user-defined value types).

ok yeah, I was loose about how this stuff works in java because frankly i don't care about java and not surprisingly it did something asinine. let me try to explain
how i think C++/C# work.

say you're using templates in C++.

whenever you use a type in a template, the code has to be generated for that specific use. so there will be a copy of the code in the binary for type1, type 2, type 3 that is used in a template (of course there's a feature called template folding that will identify templates with common implementation and use that same implementation from every template)

in c#, there are generic "types", and the substitution of these types is done at JIT - but the generic type actually exists. you may have to provide constraints on what you an pass in as a type.

the effect is that in C#, the generics aren't rocket science to use.

Bruegels Fuckbooks fucked around with this message at 14:21 on Sep 30, 2018

ulmont
Sep 15, 2010

IF I EVER MISS VOTING IN AN ELECTION (EVEN AMERICAN IDOL) ,OR HAVE UNPAID PARKING TICKETS, PLEASE TAKE AWAY MY FRANCHISE

Simulated posted:

Java generics are garbage because the runtime isn't aware of them at all. The compiler throws it all away and everything is Object at runtime, which is also why Java generics don't support value types (or more accurately primitive types since Java doesn't have user-defined value types).

Bruegels Fuckbooks posted:

ok yeah, I was loose about how this stuff works in java because frankly i don't care about java and not surprisingly it did something asinine.

Generics were retrofitted into Java 8 years after the original release, so it was significantly easier to make them a compiler-only feature.

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Plorkyeran posted:

The actual error message is error: invalid operands to binary expression ('std::vector<int, std::allocator<int> >' and 'const int'). In then prints the stack trace of the error, and the first line that isn't inside library code is the call to std::find(). This tells you that the things you passed to std::find are not comparable.

I love how even once you vector in on the most useful line of the error spew, you still have to learn to ignore the "std::allocator" junk to read it.

Carbon dioxide
Oct 9, 2012

Simulated posted:

Java generics are garbage because the runtime isn't aware of them at all. The compiler throws it all away and everything is Object at runtime, which is also why Java generics don't support value types (or more accurately primitive types since Java doesn't have user-defined value types).

Of course, Scala supports value types no problem. If you start from scratch you can do bytecode basically anything the java compiler can't because of backwards compatibility.

You'll just need to read up on covariant and contravariant types and upper and lower type bounds and all that poo poo because Scala generics are so much more powerful than Java ones, but that also means the more powerful features are more complicated to use.

Linear Zoetrope
Nov 28, 2011

A hero must cook

eth0.n posted:

Rust has great generics. As easy to use as Java's, but get compiled and optimized like C++ templates. They're modeled after Haskell, but not as flexible.


I'd say Rust has very good generics, but atm they fall short of "great" because there aren't type-level numerics yet. This may not seem like a big deal, but it causes some issues with tuples and arrays, as well as makes any attempt to implement matrices and vectors really clunky to work with. This mainly affects math code, but I've seen it bleed into other arenas as well on occasion. There's also a need for some subset of HKTs, especially wrt lifetimes, because you can't express a few things that would be very helpful. For instance, you can't create create streaming iterators where the borrow duration is tied to the loop rather than the entire iterator.

Obviously all generics systems have limitations, even the really great ones, but it's pretty easy to hit a wall in Rust. The first time I hit one was when trying to unroll a recursive tree search into a loop and had to go full-unsafe to do it. Trees and graphs in Rust are a pain in general, but it was really the limitations on lifetimes in iterators that got me here.

Linear Zoetrope fucked around with this message at 17:15 on Sep 30, 2018

qsvui
Aug 23, 2003
some crazy thing
Generics in C# seem so limited that in a lot of cases I just resort to downcasting liberally :shrug:

Eela6
May 25, 2007
Shredded Hen

Linear Zoetrope posted:

I'd say Rust has very good generics, but atm they fall short of "great" because there aren't type-level numerics yet. This may not seem like a big deal, but it causes some issues with tuples and arrays, as well as makes any attempt to implement matrices and vectors really clunky to work with. This mainly affects math code, but I've seen it bleed into other arenas as well on occasion. There's also a need for some subset of HKTs, especially wrt lifetimes, because you can't express a few things that would be very helpful. For instance, you can't create create streaming iterators where the borrow duration is tied to the loop rather than the entire iterator.

Obviously all generics systems have limitations, even the really great ones, but it's pretty easy to hit a wall in Rust. The first time I hit one was when trying to unroll a recursive tree search into a loop and had to go full-unsafe to do it. Trees and graphs in Rust are a pain in general, but it was really the limitations on lifetimes in iterators that got me here.

I just want to say that I appreciate this post and agree. Rust is not perfect.

Horse Clocks
Dec 14, 2004


How do I make microservices and microrepos not a coding horror?

My current gig has broken it down to nearly one repo for one file (one project has 85 lines of code and 200 lines of packaging and boilerplate :downsgun:).

There’s no integration tests to speak of, People make changes to libraries, and then some schmuck gets to work out what broke what when they go work on something that depends on it.

As far as I can tell, people mostly work on one repo at a time. But I’m working on three or four at a time as I’ve been tasked with expanding their coding-horror-of-it’s-own of an api gateway (one of three?).

I don’t really have the clout to roll in and change everything. But there’s got to be something I can suggest to make it less of a clusterfuck of making GBS threads code into a fan and hoping you miss the blades, and certainly something more worthy of developer time than their current plan to rename all the repos and code :psyduck:.

I am building a suite of BDD style integration tests for the API gateway, but I’d wager they’ll never get run once I leave, let alone expanded to test other components.

Linear Zoetrope
Nov 28, 2011

A hero must cook
Personally I'd make a repo called ci that contains scripts you can run generically from any of the repos to fetch the latest release version of every service (except the current repo, which is modified obv) and then run tests. Then you can add a small CI file (er... I hope CI is available to you), where on push it pulls the CI repository and runs the suite. This ensures the integration tests for the entire drat thing are sorted out whenever a change is made.

Obviously breaking changes can happen, but that's easier to handle intentionally and should be the rare case.

Linear Zoetrope fucked around with this message at 18:38 on Sep 30, 2018

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


Are the powers that be open to process improvements and at least a little bit sane? If not, save your energy.

If so, you need to have some concept of a released version of a library. Instead of building against source, you build against the copy in some location that has versions of libraries that have been through a release process. And then you put all of the tests you want into the release process.

Horse Clocks
Dec 14, 2004


Libraries and services are versioned, so there’s no rolling breakages. It’s not a total shitshow.

But running tests against the latest, and not the pinned version makes sense. If not on each build, at least nightly. This would point out breaking changes in any dependencies.

ultrafilter posted:

Are the powers that be open to process improvements and at least a little bit sane? If not, save your energy.
The lead dev is quitting. But so far treats most questions as to “why is x like y” as a personal attack. Hoping when he’s gone I can make some suggestions that won’t get shot down.

Carbon dioxide
Oct 9, 2012

Horse Clocks posted:

Libraries and services are versioned, so there’s no rolling breakages. It’s not a total shitshow.

But running tests against the latest, and not the pinned version makes sense. If not on each build, at least nightly. This would point out breaking changes in any dependencies.

The lead dev is quitting. But so far treats most questions as to “why is x like y” as a personal attack. Hoping when he’s gone I can make some suggestions that won’t get shot down.

If all else fails, you can go the Netflix way.

Netflix has a test server running the latest versions of their microservices. It has a special setup, where it only runs those services deemed essential (whitelisted) and blocks connections to anything else. Every couple minutes, a test script on that server tries to login to the local Netflix instance and start a movie. That's it.

If, at any point it fails, it's most likely that someone added functionality that makes something that isn't whitelisted essential (or someone just broke a thing).

When this happens, the ops team responsible for the test server finds the dev who made the change, and gives them a simple choice:
Either make your service non-essential, for instance by building in a graceful fallback... or prepare your team for 24/7 devops customer support because any downtime would cost too much. If you do the latter, we'll add your thing to the test server as a whitelisted essential service.

For some reason, in over 90% of cases, devs manage to find a way to make their thing non-essential.

feedmegin
Jul 30, 2008

Plorkyeran posted:

Seems pretty obvious what the error is?

Stockholm syndrome strikes again :shobon:

LOOK I AM A TURTLE
May 22, 2003

"I'm actually a tortoise."
Grimey Drawer
Haskell's generic programming features are basically perfect. My only complaint is the lack of some sort of variadic type parameter support for tuples. Haskell libraries always seem to end up with a series of functions/types called foo2, foo3, foo4, one for each tuple size. Look at this nonsense: https://hackage.haskell.org/package/lens-4.17/docs/Control-Lens-Tuple.html.

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug
Is there a term for building a lovely replacement for an existing platform on top of that platform? For example, building your own web portal in front of a service that already provides a fully functional web portal?

I can't match it up to any of the common anti-patterns like the inner platform effect. I guess it's a form of "not invented here".

Xik
Mar 10, 2011

Dinosaur Gum
Pretty sure it's just called "hiring a project manager"

1337JiveTurkey
Feb 17, 2005

New Yorp New Yorp posted:

Is there a term for building a lovely replacement for an existing platform on top of that platform? For example, building your own web portal in front of a service that already provides a fully functional web portal?

I can't match it up to any of the common anti-patterns like the inner platform effect. I guess it's a form of "not invented here".

I've used "buying a car to crush into a wheel-shaped object" before. Oh god, rolling their own AOP.

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


LOOK I AM A TURTLE posted:

Haskell's generic programming features are basically perfect. My only complaint is the lack of some sort of variadic type parameter support for tuples. Haskell libraries always seem to end up with a series of functions/types called foo2, foo3, foo4, one for each tuple size. Look at this nonsense: https://hackage.haskell.org/package/lens-4.17/docs/Control-Lens-Tuple.html.

If you have nineteen elements in a tuple you should probably be using a record type. Maybe two.

xtal
Jan 9, 2011

by Fluffdaddy

New Yorp New Yorp posted:

Is there a term for building a lovely replacement for an existing platform on top of that platform? For example, building your own web portal in front of a service that already provides a fully functional web portal?

I can't match it up to any of the common anti-patterns like the inner platform effect. I guess it's a form of "not invented here".

I think that's called "software development." For example, every REST or GraphQL web app right now would have been faster and more secure as a database that properly uses authentication, authorization, triggers, relations and constraints. But once a problem is solved, you need to start coming up with more problems. So let's just use the database as a key-value store and rewrite all the rest in slow-as-hell, insecure-as-poo poo Rails.

xtal fucked around with this message at 01:20 on Oct 1, 2018

New Yorp New Yorp
Jul 18, 2003

Only in Kenya.
Pillbug

xtal posted:

I think that's called "software development." For example, every REST or GraphQL web app right now would have been faster and more secure as a database that properly uses authentication, authorization, triggers, relations and constraints. But once a problem is solved, you need to start coming up with more problems. So let's just use the database as a key-value store and rewrite all the rest in slow-as-hell, insecure-as-poo poo Rails.

I'm thinking more along the lines of something like the Azure portal. Everything you can do with the portal, you can do with REST APIs. I keep seeing people rebuilding their own Azure portal that calls the same REST APIs as the existing portal. I can't fathom why, other than "not invented here" and I was looking for a term to use to describe it when I'm telling people "that's dumb, don't do it".

xtal
Jan 9, 2011

by Fluffdaddy

New Yorp New Yorp posted:

I'm thinking more along the lines of something like the Azure portal. Everything you can do with the portal, you can do with REST APIs. I keep seeing people rebuilding their own Azure portal that calls the same REST APIs as the existing portal. I can't fathom why, other than "not invented here" and I was looking for a term to use to describe it when I'm telling people "that's dumb, don't do it".

Sounds precisely like NIH in that case!

Presto
Nov 22, 2002

Keep calm and Harry on.

Absurd Alhazred posted:

It was a vector of vectors of ints, and it was trying to find a particular int in it; it failed because int is not comparable to a vector of ints.

Ok, see, now that's an error message I can get behind.

Presto
Nov 22, 2002

Keep calm and Harry on.

Plorkyeran posted:

The actual error message is error: invalid operands to binary expression ('std::vector<int, std::allocator<int> >' and 'const int'). In then prints the stack trace of the error, and the first line that isn't inside library code is the call to std::find(). This tells you that the things you passed to std::find are not comparable.
All right, but why doesn't it just say "The things you passed to std::find are not compatible"?

bob dobbs is dead
Oct 8, 2017

I love peeps
Nap Ghost

New Yorp New Yorp posted:

I'm thinking more along the lines of something like the Azure portal. Everything you can do with the portal, you can do with REST APIs. I keep seeing people rebuilding their own Azure portal that calls the same REST APIs as the existing portal. I can't fathom why, other than "not invented here" and I was looking for a term to use to describe it when I'm telling people "that's dumb, don't do it".

the second dipshit azure portal was entirely due to microsoft infighting. the last company i was at scored an ex-microsoftie manager from that clusterfuck

and then, given impetus by a second azure portal, other fools started makin third party ones

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


Presto posted:

All right, but why doesn't it just say "The things you passed to std::find are not compatible"?

That is what it's saying.

xtal
Jan 9, 2011

by Fluffdaddy

ultrafilter posted:

That is what it's saying.

Yes, you just need to scroll all the way to the right.

quote:

invalid operands to binary expression ('std::vector<int, std::allocator<int> >' and 'const int')

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

Presto posted:

All right, but why doesn't it just say "The things you passed to std::find are not compatible"?

C++ currently doesn't have a way to express "the two types passed to this function have to be comparable" (that's maybe finally coming in C++20 after over a decade of delays). As a result, the compiler doesn't know what point in the call stack is incorrect, and just prints the whole thing. As with any time you get an error stack starting in library code, you usually want to start with looking at the first one not in the library.

xtal posted:

Yes, you just need to scroll all the way to the right.

That's mostly just a result of compiler explorer having really long paths.

brap
Aug 23, 2004

Grimey Drawer

bob dobbs is dead posted:

the second dipshit azure portal was entirely due to microsoft infighting. the last company i was at scored an ex-microsoftie manager from that clusterfuck

and then, given impetus by a second azure portal, other fools started makin third party ones

Wait what? Where's the second azure portal?

bob dobbs is dead
Oct 8, 2017

I love peeps
Nap Ghost

brap posted:

Wait what? Where's the second azure portal?

i think they successfully migrated off but portal.azure.com and manage.windowsazure.com had two separate existing portals. they didn't have proper iam in the manage.windowsazure.com, which was the old one, and it was also poo poo in lots of other ways but the deprecation was a big fight

https://stackoverflow.com/questions/32902089/manage-windowsazure-com-vs-portal-azure-com

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

xtal posted:

I think that's called "software development." For example, every REST or GraphQL web app right now would have been faster and more secure as a database that properly uses authentication, authorization, triggers, relations and constraints. But once a problem is solved, you need to start coming up with more problems. So let's just use the database as a key-value store and rewrite all the rest in slow-as-hell, insecure-as-poo poo Rails.

I don't understand what you're saying here.

Are you saying REST and GraphQL do not use a database to store their data?

Adbot
ADBOT LOVES YOU

Steve French
Sep 8, 2003

Thermopyle posted:

I don't understand what you're saying here.

Are you saying REST and GraphQL do not use a database to store their data?

I think he is saying that they are useless layers on top of a database. Which is, uh, an interesting argument if I'm reading it right.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply