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.
 
  • Locked thread
Shaggar
Apr 26, 2006

comedyblissoption posted:

you might not know what to cast it to at compile time and can only determine it at runtime

lol

Adbot
ADBOT LOVES YOU

comedyblissoption
Mar 15, 2006

i think the dynamic type shenanigans common w/ reflection in C#/java might be a symptom of problems w/ the subtyping system that causes you to want to do that

im not academic or experienced enough to know if that's a damnation of the entire approach though

Bloody
Mar 3, 2013

Dessert Rose posted:

well let's say you have three disparate objects which all derive from a common object, they're siblings, and all have separately defined a field which has the exact same name and contains the same data.

you can't very well pick one of the types and cast it to that because you'll be wrong 2/3 of the time and fail your cast, but if you could just go "hey i want whatever's in the field named foo" then you'd be fine

this is an actual problem i've had to solve in real code. sure, you could write some code that goes "is it type A? ok then cast it to type A. ok, is it type B?" but that is a loving mess and no way am i writing three if-elseif branches to handle every possible case because that is a goddamn mess and anyway asking if it is a specific type three times is probably about as performant as just asking if it defines a given field

also then someone adds yet another type that does the same goddamn thing and now my code has to be updated too


what language implements row polymorphism because that sounds incredible actually

that sounds like you need to fix the parent object then? like isn't that kind of the point of inheritance?

Brain Candy
May 18, 2006

comedyblissoption posted:

yah duck typing is only good for reducing boilerplate in narrow use cases. it's a horrible idea to make duck typing your entire typing system.

you could dynamically create a type that you don't know exists at compile time. it's argue-able whether or not this is a good idea, but it's common in java/c# w/ reflection based frameworks

crazy reflection frameworks are not necessary
Java code:
 <Foo extends BaseType & SomeInterface & SomeOtherInterface> String florp(Foo thing) {
particular type of Foo is not known at compile time, there may not be any type that meets all the constraints

MononcQc
May 29, 2007

rrrrrrrrrrrt posted:

Those studies aren't even worth mentioning. They're total garbage and even using them to say welp could go either way! is disingenuous. They aren't even good enough to make that weak rear end conclusion.

Right. That's the problem. If your studies don't prove poo poo, then as an industry we shouldn't parrot the results as if they were true just because they feel correct. See also: 10x engineers

MononcQc
May 29, 2007

comedyblissoption posted:

MononcQc, you're absolutely right that there are actually more important things than static vs dynamic typing in programming. Competency, education, and experience of developers is by far the most important factor. There's a whole class of problems that static type systems can never solve.

However, even you must admit static typing does a lot more than just prevent trivial runtime type errors.

I think static types have a bigger impact in how you approach program design. Static types help you take a data-centric approach where you consider the structure of things you'll operate on rather than how state will move around; that's powerful. But the type system is as useful as the programmers are ready to marry themselves to it. If all your integers are 'Int' types, the type system gives you jack poo poo. You have to evolve a useful taxonomy with them. Age and Picodollars are two types of integers that won't mix.

The classical example for this was that SSL libraries should have a Cert type, but two subtypes or compatible types: InvalidCert and ValidCert. The functions to send or receive data should only work on ValidCerts, not on invalid ones. But if you use your type system in a way that both certs are the same, you're skipping on an opportunity there.

In the end that's the big thing that makes me say "yeah types systems are cool, but..." -- they require as much discipline as anything else to actually be powerful in a way I think as very significant, rather than somewhat useful. A powerful type system you don't use is losing its power the way an incomplete test suite is losing its usefulness.

To make sure code doesn't explode, I so far stick to layered approaches: reviews, tests, type checks/linting, documenting, CI, and so on. Static typing is a tool in the toolbox, and I don't perceive it as more essential than the others at this point.

Brain Candy
May 18, 2006

Dessert Rose posted:

what language implements row polymorphism because that sounds incredible actually

surprise! third hit from google is "Chapter 11. Objects / Real World OCaml"

brap
Aug 23, 2004

Grimey Drawer
the type system is not a replacement for reflection. Reflection saves you boilerplate when you want to do something like serialization. in c# you just decorate a type with XmlSerializableAttribute and decorate properties you don't want to serialize with XmlNonSerializableAttribute, instead of manually enumerating the properties of your object and serializing them.

Notorious b.s.d.
Jan 25, 2003

by Reene

Awia posted:

contributing to an open source project sounds like a good way to start hating yourself and others

90% of my open source contributions are me fixing bugs in poo poo i use at work

getting paid to make open source a little less open sores is awesome. partly because it's cool, but mostly because it's good for the resume

MononcQc
May 29, 2007

JewKiller 3000 posted:

i'm interested to hear MononcQc's opinion here, because i haven't heard a single argument in favor of dynamic typing over static that doesn't boil down to "i don't understand static typing". but as an erlang expert i think he might have something actually useful to say (maybe related to hot code loading?)

I'm not in favor of dynamic typing much. I'm enjoying optional typing where I can program dynamically, but lift a (sadly weaker) type checker on the code otherwise (Dialyzer).

But full-blown static type systems lose some level of flexibility, especially if you look at axiomatic ones: they forbid some valid programs because they're not provably correct. My favorite example for this is the following program:

convert(Celcius) -> Fahrenheit;
convert(Fahrenheit) -> Celcius.

Your standard type system will be able, at most, to type this as:

convert(Celcius | Fahrenheit) -> Celcius | Fahrenheit.

But this signature is weak; it doesn't represent that 'toggle' factor, and believes that concert(Celcius) -> Celcius is a plausible result. So either the language needs to add new constructs to do it (object-style or whatever), or you need to defer to the runtime and reduce the reliability of your type system. Oops.

That's minor and easy to live without though. The major reason I don't mind not having static types much is that I work with the network a lot, and the network isn't typed. Hell, you need to be able to properly handle outdated versions of messages received and whatnot.

Cloud Haskell is the best example of a powerful type system ruining your day. It specifically has that problem where it tries to type messages that go around a clustered application. Why is it a problem? because to deploy new code with conflicting versions, you can't be allowed heterogenous clusters (the types will clash!) The only way to deploy a new backwards-incompatible node in cloud haskell is to boot a new cluster and swap it with the other one.

No way to have canary nodes, no way to progressively roll things out. Double your number of servers/instances and switch it at once.

That's loving bad.

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Dessert Rose posted:

what language implements row polymorphism because that sounds incredible actually

in elm, you can do this:
code:
butts : {a| farts : Int -> String} -> String
butts x = x.farts 10
which means butts takes a record (sort of like an object in javascript i guess) "x" where x has a field named farts, where farts is a function that takes an Int and returns a String, and then butts returns a String. the type signature here is totally optional because the type inference is good enough to statically figure out the types at compile time, so you could just write

code:
butts x = x.farts 10

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Bloody posted:

that sounds like you need to fix the parent object then? like isn't that kind of the point of inheritance?

oh sure, let me just fix the parent object in code i don't have access to.

Brain Candy
May 18, 2006

Dessert Rose posted:

oh sure, let me just fix the parent object in code i don't have access to.

tbf, if this was really the case you'd just wrap their type with YourType and get on with things

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
If all these distinct types have a set of methods in common, perhaps that commonality should be encoded in an interface.

Dessert Rose
May 17, 2004

awoken in control of a lucid deep dream...

Brain Candy posted:

tbf, if this was really the case you'd just wrap their type with YourType and get on with things

which means now i have to write a bunch of loving code to wrap all the types that i get to deal with into that type

or, i could write two lines of code with the word "dynamic" in one of them, and get on with things

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Brain Candy posted:

crazy reflection frameworks are not necessary

extensible software is pretty cool

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

fart simpson posted:

in elm, you can do this:
code:
butts : {a| farts : Int -> String} -> String
butts x = x.farts 10
which means butts takes a record (sort of like an object in javascript i guess) "x" where x has a field named farts, where farts is a function that takes an Int and returns a String, and then butts returns a String. the type signature here is totally optional because the type inference is good enough to statically figure out the types at compile time, so you could just write

code:
butts x = x.farts 10

also you can easily give these type aliases like this:

code:
type alias Fartable = {a| farts : Int -> String}

butts : Fartable -> String
butts x = x.farts 10

Bloody
Mar 3, 2013

Dessert Rose posted:

oh sure, let me just fix the parent object in code i don't have access to.

why can't you make a child object that extends the parent with that single field and then have all those siblings be a child of the child? you're still not describing a static typed limitation. you might have an implementation limitation or language limitation but this is still very much a solvable problem

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

fart simpson posted:

also you can easily give these type aliases like this:

code:

type alias Fartable = {a| farts : Int -> String}

butts : Fartable -> String
butts x = x.farts 10

so roughly the SFINAE sort of C++ template usage?

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Subjunctive posted:

so roughly the SFINAE sort of C++ template usage?

i've never used c++ so i have no idea what this means, so sure

triple sulk
Sep 17, 2014



i'm hoping that in my new company i can actually learn a lot from what should be a number of pretty intelligent people, and maybe also start contributing more, perhaps to .net stuff

i like c# is what i am saying

Bloody
Mar 3, 2013

my boss declared a fatwa against matlab this morning which owned but then started suggesting python instead and i was like no thats bad we should use c# but he, a person who does not write software literally ever, has seemingly decided that python is the thing we should use and not c#. i, as the only person who will ever write software for this program, am not pleased and will therefore be using c# because gently caress you

Shaggar
Apr 26, 2006

MononcQc posted:

I'm not in favor of dynamic typing much. I'm enjoying optional typing where I can program dynamically, but lift a (sadly weaker) type checker on the code otherwise (Dialyzer).

But full-blown static type systems lose some level of flexibility, especially if you look at axiomatic ones: they forbid some valid programs because they're not provably correct. My favorite example for this is the following program:

convert(Celcius) -> Fahrenheit;
convert(Fahrenheit) -> Celcius.

Your standard type system will be able, at most, to type this as:

convert(Celcius | Fahrenheit) -> Celcius | Fahrenheit.

But this signature is weak; it doesn't represent that 'toggle' factor, and believes that concert(Celcius) -> Celcius is a plausible result. So either the language needs to add new constructs to do it (object-style or whatever), or you need to defer to the runtime and reduce the reliability of your type system. Oops.

That's minor and easy to live without though. The major reason I don't mind not having static types much is that I work with the network a lot, and the network isn't typed. Hell, you need to be able to properly handle outdated versions of messages received and whatnot.

Cloud Haskell is the best example of a powerful type system ruining your day. It specifically has that problem where it tries to type messages that go around a clustered application. Why is it a problem? because to deploy new code with conflicting versions, you can't be allowed heterogenous clusters (the types will clash!) The only way to deploy a new backwards-incompatible node in cloud haskell is to boot a new cluster and swap it with the other one.

No way to have canary nodes, no way to progressively roll things out. Double your number of servers/instances and switch it at once.

That's loving bad.

in the temperature example are you using a single function to convert both or are they separate functions with different signatures?

if its the former how do you know you aren't going to get a Celsius out if you put one in? are you assuming user will assume there are only 2 valid conversions? what if someone puts in a kelvin?

if its the later then you don't really gain much advantage over separately named methods convertToC and ConvertToF

In a statically typed system you wouldn't have a stupid super function that does all the conversions anyways since that's really gross and you end up stuffing a billion different state checks into what is in reality a data conversion problem. Temperature is a fixed value and we represent it in different measurement systems. You store it as one and then convert it only for display. Flipping the stored value is really stupid and messy since its inconsistent. plus you never know when the French will change the definition of their totally not fake and bullshit measuring systems so conversions may change resulting in even bigger inconsistencies between stored values of different systems.

storing time is probably a better example because there are basically infinite, ever changing conversions of the core value.

fritz
Jul 26, 2003

Bloody posted:

my boss declared a fatwa against matlab this morning which owned but then started suggesting python instead and i was like no thats bad we should use c# but he, a person who does not write software literally ever, has seemingly decided that python is the thing we should use and not c#. i, as the only person who will ever write software for this program, am not pleased and will therefore be using c# because gently caress you

scripting numerics is the best reason to use python

Bloody
Mar 3, 2013

yeah except we mostly use matlab for instrument control

fritz
Jul 26, 2003

but if numpy/scipy/whatever aren't needs suiting than god help you because cython certainly wont

fritz
Jul 26, 2003

Bloody posted:

yeah except we mostly use matlab for instrument control

like sending bytes down a serial channel?

fritz
Jul 26, 2003

some people would say give forth a chance

Bloody
Mar 3, 2013

fritz posted:

like sending bytes down a serial channel?

yup.

Bloody
Mar 3, 2013

only ever wound up in matlab in the first place because a collaborator once wanted a matlab api for some hardware control so when we reused all that to turn some poo poo around quickly the new boss got uppity

like yeah dude matlab is bad but when you give me a literal half hour to turn something around i am going with the already-working system not ginning together something new because you have random hangups about certain pieces of software

MononcQc
May 29, 2007

Shaggar posted:

in the temperature example are you using a single function to convert both or are they separate functions with different signatures?

if its the former how do you know you aren't going to get a Celsius out if you put one in? are you assuming user will assume there are only 2 valid conversions? what if someone puts in a kelvin?

if its the later then you don't really gain much advantage over separately named methods convertToC and ConvertToF
They're a single function with many clauses. Think of them as functions that contain a switch in their declaration.
Right, it's an example. Consider any of these:

toggle(on) -> off;
toggle(off) -> on. <== pretty much the same as 'not' with booleans

to_format(xml, Data) -> "<mydata>...</mydata>";
to_format(json, Data) -> "...";
to_format(pdf, Data) -> call(...).

or whatever else could look like a declarative dispatch. As I said, there's other ways to do it and work around not being able to do that, but it's nice when you can.

Think of it as being able to track or properly represent different return types or values (especially if you support range types) based on the value of an Enum. Some time systems will artificially restrict you there, others will be powerful enough to do it. It's really a minor point, again, but it's a thing type systems do.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

fritz posted:

some people would say give forth a chance

if you can't push it, dup it, swap it, or pop it then you don't really need it

comedyblissoption
Mar 15, 2006

MononcQc posted:

They're a single function with many clauses. Think of them as functions that contain a switch in their declaration.
Right, it's an example. Consider any of these:

toggle(on) -> off;
toggle(off) -> on. <== pretty much the same as 'not' with booleans

to_format(xml, Data) -> "<mydata>...</mydata>";
to_format(json, Data) -> "...";
to_format(pdf, Data) -> call(...).

or whatever else could look like a declarative dispatch. As I said, there's other ways to do it and work around not being able to do that, but it's nice when you can.

Think of it as being able to track or properly represent different return types or values (especially if you support range types) based on the value of an Enum. Some time systems will artificially restrict you there, others will be powerful enough to do it. It's really a minor point, again, but it's a thing type systems do.
yeah but then you gotta come up with a bespoke document system to document what the hell types your function can take and return

that's one of the things i absolutely loathe about javascript

i always have to constantly search the documentation over and over again for things like this and each documentation has their own special snowflake way to notate the javascript type system

comedyblissoption
Mar 15, 2006

you say that static typing is generally better but not to the point it's the most dominating factor in any software project

and most people would agree that there are other factors that are way more important since you just have to simply look around for blindingly obvious examples of this

but uh that still doesn't really answer why you would choose dynamic typing over static typing if you had a choice

if there are institutional inertia to use a dynamically typed language, then yeah you would be really dumb to rewrite everything. emacs lisp is a great example. javascript on the web (although you could use it just as a compile target i guess). legacy php. whatever. but this is really a question in a situation where you have a choice, why the hell would you choose a tool that is inferior in almost every way?

Brain Candy
May 18, 2006

Subjunctive posted:

extensible software is pretty cool

plugins are neat and reflection is a necessary evil

but if you can look at

code:
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");

      obj.getMessage();
   }
}
and not find it revolting you've a stronger stomach than i

and the framework people want you to write everything like that. or at least sprinkle your code with annotations. spare me your loving magic @Beans!

comedyblissoption
Mar 15, 2006

it is kind of absurd how much boilerplate there is when you just want to call some drat state-less functions in some other module

C# is still decent enough though

Bloody
Mar 3, 2013

java is ugly

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Brain Candy posted:

plugins are neat and reflection is a necessary evil

but if you can look at

code:

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");

      obj.getMessage();
   }
}

and not find it revolting you've a stronger stomach than i

sure, that sucks (though my stomach is indeed probably stronger). both sides know the type, the system should let them express that without the "ALL THINGS ARE THINGS!" flattening in the middle.

I'm not sure that

code:

HelloWorld obj = context.getBean<HelloWorld>("helloWorld");

is a lot better, but I don't twitch as much reading it. I have a special relationship with Java reflection though, so I may not be well-calibrated here.

brap
Aug 23, 2004

Grimey Drawer
how else do you propose deserializing an object from some XML in a file
just wondering

Adbot
ADBOT LOVES YOU

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

fleshweasel posted:

how else do you propose deserializing an object from some XML in a file
just wondering

XML doesn't matter, you can deserialize type information from XML just as well as you can deserialize from a class file. the classloader can construct that type based on a zip file coming in over a socket, so it can do it based on a file on disk in a different format. (Java classloaders, last I did battle with them, were somewhat more constrained in terms of how they produce a type, but that's an artifact of Java's unfortunate implementation choices, not inherent to the idea of extensibility.)

the bean loader has to know that it's dealing with a HelloWorld because it has to create one into which to deserialize. the instantiating program has to know it's dealing with a HelloWorld because it's going to operate on one. it's just an artifact of Java's clumsy type system and history that two parts of a program with complete type information have to squash their communication through j.l.Object.

  • Locked thread