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
Notorious b.s.d.
Jan 25, 2003

by Reene
btw it should never be "intuitive" to work with unitless numbers in physics. christ, they taught me that in grade school.

you should be able to work out the units (or types) of all of your mathematical terms at every stage before you plug in any real numbers. in math, this is the only way to sanity-check your work if you don't have a rough estimate of where the numbers are supposed to come out

in computing, apparently correctness is nonessential so we just trade in type-less floating point numbers in python herp derp



edit: and, of course, the reason that teachers were obsessed with having us check the sanity of our equations by making sure that the units attached to terms made sense was specifically that we were stuck with awful lovely 1970s-type calculators

Adbot
ADBOT LOVES YOU

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

FamDav posted:

so is it like they're taking the swift approach to elevating certain novel types to special syntax within the language? i dont like that

is it really that different from dereferencing a pointer as *ptr? string literals and functions often get special syntax, it works pretty well.

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord

FamDav posted:

what if the only primitive given to the programmer for creating FilteredData was a function that filtered data for you? woah

ok then what if your FilteredData creator function is broken, that was my point. type checking doesn't ensure that FilteredData is in fact filtered

"but I'll test it to make sure it's right", and then it's no different than dynamic

Notorious b.s.d. posted:

this is what a type hierarchy is for! :fuckoff:

it is ridiculous to model all math problems as if you are stuck with a unitless digital calculator from the 70s. if you have a powerful compiler and type system, model your loving problem domain!

degrees C is a type!
degrees F is a type!
kinetic energy is a type!
mass is a type!

use the god drat type system to make it impossible to gently caress these things up, that's why it's there!

nah, I just don't see doing all my bespoken artisanal fortrans this way

Notorious b.s.d.
Jan 25, 2003

by Reene

Symbolic Butt posted:

nah, I just don't see doing all my bespoken artisanal fortrans this way

i love that you perceive the complexity of the problem, but laziness means you would rather cope with repeated bugs and errors than write correct code the first time

you are the rubyist in all of us symbolic butt

a modern-day prometheus, bringing the fire of incompetence to the masses

MononcQc
May 29, 2007

Arcsech posted:

that part is wrong but its not the implied error. the implied error is that in dynamically-typed code you could accidentally put a temp thats already in C into that function, but since your data is typed C or F already the compiler will yell at you if you try to do that. its like writing a tiny, automatically executed test that happens every time you use your function!

seems like the better solution is just to write a toFahrenheit function that takes a Temperature typeclass of either C or F and uses pattern matching to automatically do the correct thing tho:

code:
toFahrenheit :: Temp a => a -> Fahrenheit

Dynamic languages like Erlang (or anything that can support atoms/enums and tuples) would have you use an atom as a type tag. The runtime constraint will be enforced, and optional type checkers can run over it:


code:
-type celsius() :: {celsius, number()}.
-type fahrenheit() :: {fahrenheit, number()}.


%% @doc Convert °C to °F. Also support doing °F to °F.
-spec to_fahrenheit(celsius() | fahrenheit()) -> fahrenheit().
to_fahrenheit({celsius, N}) -> {fahrenheit, N * 1.8 + 32};
to_fahrenheit({fahrenheit, _} = T) -> T.
But because it's dynamic (and the type checker is not axiomatic) you can also do weird stuff like:

code:
-spec toggle(celsius()) -> fahrenheit()
      ;     (fahrenheit()) -> celsius().
toggle({celsius, _} = T) -> to_fahrenheit(T);
toggle({fahrenheit,_} = T -> to_celsius(T).
which afaik is not expressable in most axiomatic type systems, though not something you often need to do.

Vanadium
Jan 8, 2005

FamDav posted:

so is it like they're taking the swift approach to elevating certain novel types to special syntax within the language? i dont like that

It's gonna be tied to a trait like the other operators, so it can be implemented by other types too. It's part of a push to make it easier to get values out of ADTs so more functions can return ADTs to signal error conditions instead of failing and initiating stuck unwinding. (Some of them want to get rid of quasi-exception-like failure that unwinds completely, apparently.) The other part is promoting the try! { ... } macro to postfix ? that's basically an early-returning match ... { Ok(r) => { r }, Err(e) => { return Err(e); } } thing that kinda sorta resonates with the Either monad I guess.

There's someone else proposing the also-Swift-like-but-more-general if let Some(x) = an_option_value { ... } which strikes me as more reasonable, but I guess it doesn't go all the way towards equalizing the user experience of produce_value_or_fail() -> T and maybe_produce_value() -> Option<T>.

Vanadium
Jan 8, 2005

Another thing Rust is doing is excising the green-thread runtime with fake-nonblocking-IO completely for 1.0 and everybody is pretty happy about that. It's also gonna ship with no non-blocking or async IO, hope you like threads.

suffix
Jul 27, 2013

Wheeee!

Symbolic Butt posted:

but I feel like in this example it can easily descend to... too much work. intuitively to me temperature is just a number that I'll do things to it, I wouldn't care keeping track of specific types for every step in calculations. suddenly it'll be an average of things or maybe I'll multiply with another number and get kinetic energy and then later it becomes mass and and... I just don't see me juggling with a whole type hierarchy for these things

f# has a pretty cool units of measure system that keeps track of the correct unit
http://msdn.microsoft.com/en-us/library/dd233243.aspx

you can do all of that in a dynamically typed language too though so i think once again the debate is starting to conflate strong/weak and static/dynamic typing

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord

Notorious b.s.d. posted:

i love that you perceive the complexity of the problem, but laziness means you would rather cope with repeated bugs and errors than write correct code the first time

you are the rubyist in all of us symbolic butt

a modern-day prometheus, bringing the fire of incompetence to the masses

not gonna lie, I'm proud of what I accomplished here

but seriously, with all these posts in mind I'll eventually try again doing some numeric stuff in sml making the best use of the typing system that I can

Vanadium
Jan 8, 2005

https://github.com/rust-lang/meeting-minutes/blob/master/workweek-2014-08-18/Meeting-workweek-2014-08-18.md here's a bunch of rust core team chat transcriptions if you have the patience.

MononcQc
May 29, 2007

Vanadium posted:

Another thing Rust is doing is excising the green-thread runtime with fake-nonblocking-IO completely for 1.0 and everybody is pretty happy about that. It's also gonna ship with no non-blocking or async IO, hope you like threads.
I totally hoped Rust would keep green threads and am super disappointed by that decision.

Arcsech
Aug 5, 2008

MononcQc posted:

Dynamic languages like Erlang (or anything that can support atoms/enums and tuples) would have you use an atom as a type tag. The runtime constraint will be enforced, and optional type checkers can run over it:

this is neat

erlang (and the erlang ecosystem) seems like what happens when people who actually need + have the knowledge to make high reliability code write a plang

(not an insult to erlang at all, it just seems like it has some of the same design goals while actually having, y'know, a design)

suffix
Jul 27, 2013

Wheeee!

MononcQc posted:

I totally hoped Rust would keep green threads and am super disappointed by that decision.

with a sufficiently clever kernel scheduler,

MononcQc
May 29, 2007

Arcsech posted:

this is neat

erlang (and the erlang ecosystem) seems like what happens when people who actually need + have the knowledge to make high reliability code write a plang

(not an insult to erlang at all, it just seems like it has some of the same design goals while actually having, y'know, a design)

Yeah it's basically a functional/dynamic language that was developed with a tight feedback loop from the telco industry for 12 years before it got even released as open source. Then there's a healthy interaction between academia and industry at all conferences, where the most common question you'll get on a project or library you show is "has this been in production, and under what load?" I tend to enjoy the community a good bit in these places.

MononcQc
May 29, 2007

suffix posted:

with a sufficiently clever kernel scheduler,

well the drop of the scheduler was announced many months ago for performance reasons (manually scheduling poo poo is faster because you make decisions, but I consider it error prone and disappointing).

raminasi
Jan 25, 2005

a last drink with no ice

suffix posted:

f# has a pretty cool units of measure system that keeps track of the correct unit
http://msdn.microsoft.com/en-us/library/dd233243.aspx

you can do all of that in a dynamically typed language too though so i think once again the debate is starting to conflate strong/weak and static/dynamic typing

how do you implement an entirely compile-time type subsystem using dynamic typing

Vanadium
Jan 8, 2005

MononcQc posted:

I totally hoped Rust would keep green threads and am super disappointed by that decision.

They basically started out with a scheme (or at least plan?) for growable, segmented stacks for the green threads, then people started complaining that the mechanism for stack space checks in function prologues lead to thrashing around stack segment boundaries. When they moved to fixed-size stacks, people complained that allocating the stacks for green threads dominated their cost to the point that you might as well eat the context switch and use a native thread and also that having the entire IO library virtualized over which mode of scheduler you're using (ie. direct syscalls for native threads vs wrapped libuv calls for green threads) was too much of a penalty for programs that statically know they only use either mode. So now they're going to throw out the whole thing and baking in direct, non-green threads and direct, non-async, blocking IO calls.

Rust is really all about being a less kitchensinky C++ with memory safety more than anything inspired by Erlang at this point. Not even the thing where you're supposed to crash often and have another process respawn you is gonna be a thing anymore! There's shared memory everywhere too (though typesafe enough to avoid data races or w/e).

HappyHippo
Nov 19, 2003
Do you have an Air Miles Card?
coding in js more recently has got me thinking that static typing only catches the easiest to find and easiest to fix errors. i do run into type errors of course but they're very rarely headaches, because when the types don't match you've usually made a really basic mistake. the more subtle bugs are the kind a type system wouldn't catch anyway. that said, i do hate weak typing (by which i mean poo poo like coercing strings to numbers and vice versa, falsey and truthy values, etc), it only makes those type errors that do occur harder to find. it's unfortunate that so many dynamically typed languages are also weakly typed.

that doesn't mean static typing is useless though, it really helps you reason about the code; even if there's no comments it usually isn't difficult to figure out what's going on based on the types alone. they also allow for intellisense or it's equivalent. and the way languages like c# basically force you to design your code around a set of types is helpful in structuring complex projects. overall i think statically typed is better when the project is complex and you're working with a team

basically "catching errors" is the least significant advantage to static typing, imo

Vanadium
Jan 8, 2005

Of course the party line is that rust 1 point 0 is only the beginning, a place where the language is in a good enough shape to promise backwards compatibility and at least the most important standard library interfaces can be stabilized, and all that cool stuff might still come later somehow.

MononcQc
May 29, 2007

Vanadium posted:

Not even the thing where you're supposed to crash often and have another process respawn you is gonna be a thing anymore!

Nooooooooooooo. Crash-early with detection/links is one of the best things to have when doing concurrency. They could have dropped everything but kept this and it would have been cool :argh:

Vanadium posted:

Of course the party line is that rust 1 point 0 is only the beginning, a place where the language is in a good enough shape to promise backwards compatibility and at least the most important standard library interfaces can be stabilized, and all that cool stuff might still come later somehow.

Yeah. I can see why it makes more sense to go their way for desktop apps and client stuff. I keep having the perspective of implementing server stuff and yeah...

Malcolm XML
Aug 8, 2009

I always knew it would end like this.

Notorious b.s.d. posted:

this is what a type hierarchy is for! :fuckoff:

it is ridiculous to model all math problems as if you are stuck with a unitless digital calculator from the 70s. if you have a powerful compiler and type system, model your loving problem domain!

degrees C is a type!
degrees F is a type!
kinetic energy is a type!
mass is a type!

use the god drat type system to make it impossible to gently caress these things up, that's why it's there!

so it turns out that modeling units is a tricky thing. they are something like a graded algebra over a vector field

the fundamental problem with type systems is that they are very hard to program in, since at best you are "programming" in constructive logic (i.e. dependent types) and just look at how insane some of the stuff u need to convince the machine about in there

like if your domain maps easily onto a type hierarchy (hint: it won't) then it's easy

fwiw a lot of scientific calculations make 0 sense in units since the constants are chosen to make the units go away, and they are physically meaningless but i get ur point

but if you're doing stuff like abstract algebra things like ad hoc multi methods end up being more natural though i guess Multi param type classes sort of let you do that.

regardless a gradual type system like clojure is probably the happy medium

in retrospect clojure got a lot of things correct

FamDav
Mar 29, 2008

Subjunctive posted:

is it really that different from dereferencing a pointer as *ptr? string literals and functions often get special syntax, it works pretty well.

it is, because pointer dereference and functions are defined in the stdlib. i just think its odd to take certain parts of the stdlib and give them shorthand compiler magic syntax.

Symbolic Butt posted:

ok then what if your FilteredData creator function is broken, that was my point. type checking doesn't ensure that FilteredData is in fact filtered

"but I'll test it to make sure it's right", and then it's no different than dynamic

it is different, because now i only have to test my filtering function for correctness. i know that if my program compiles that any function demanding filtereddata gets filtereddata, and that the only possible place where unfiltered data can leak is in the function that does the filtering. contrast that with a plang where seeing unfiltereddata could mean a failure at any point along multiple code paths.

Malcolm XML
Aug 8, 2009

I always knew it would end like this.
i like stuff like row polymorphism which gives u documentation and is pretty flexible

one thing haskell got wrong was not having good records.

maybe they'll fix it but the community is off masturbating to lens's 7 type parameters

gonadic io
Feb 16, 2011

>>=
lens are good records that are also first class. feel free to only ever use .~/set and ^./view and you've already got a system that is better than the inbuilt record system

tef
May 30, 2004

-> some l-system crap ->

hepatizon posted:

the way people were talking about returning nil instead of throwing exceptions, i figured there were more facets to it than just the basic data structures. like, there are thousands in methods in ruby core and we're talking about 3 of them. if people just meant array/hash/set retrieval, than i concede that those do behave as stated (whether that's good or not is a separate point, not something i intended as a rebuttal). i don't concede (at least on that basis) that it's a pervasive behavior across the breadth of ruby core

and don't be a jerk, it's bad for your blood pressure

let's pick another example.

rand()

manual says "may give surprising values"

tef
May 30, 2004

-> some l-system crap ->

hepatizon posted:

the stdlib is full of awful cruft that nobody uses

this is far more damning of ruby than anything i've said.

tef
May 30, 2004

-> some l-system crap ->

Shaggar posted:

Got some incomplete documentation for this webzone im trying to integrate with.

Based on what i've tested so far (because they dont list all possible results in their docs) for the initial call they will return:
xml w/out schema in one format if it is successful
xml w/out schema in another format, with a content type of html, if theres an auth failure
html if there is some other error

all responses return 200.

great

hey shaggar, this is what happens when people who aren't you use xml and soap

tef
May 30, 2004

-> some l-system crap ->

Vanadium posted:

but really, ruby treating nil both as a value and the absence of a value is somewhere around the bottom of my list

weirdly enough the community, documentation, and development of ruby were at the top of my list but no-one seems to want to defend those.

gonadic io
Feb 16, 2011

>>=

tef posted:

let's pick another example.

rand()

manual says "may give surprising values"

if i called rand() and got nil that goes beyond "surprising" and into "astonishing"

gonadic io
Feb 16, 2011

>>=

AlsoD posted:

if i called rand() and got nil that goes beyond "surprising" and into "astonishing"

ok i just looked this up and it doesn't like it happens, sadly

Vanadium
Jan 8, 2005

MononcQc posted:

Nooooooooooooo. Crash-early with detection/links is one of the best things to have when doing concurrency. They could have dropped everything but kept this and it would have been cool :argh:


Yeah. I can see why it makes more sense to go their way for desktop apps and client stuff. I keep having the perspective of implementing server stuff and yeah...

The hangup as far as I can tell is that they hate unwinding because it bloats the generated code a lot, but they're nowhere near isolated enough and too committed to RAII to be able to do task failure without it. I guess they want functions returning Result<T, SomeErrorObject> almost universally, returning the error side on contract violations etc. Then task failure would be rare (raw asserts, vec[index] out of bounds/map[key] with a bad key, maybe some few other bits) and you'll be able to turn off unwinding as an optimization compiler option so task failure will immediately take down your whole process (and rust has no real IPC story to speak of, afaik).

I guess the idea is that embedded people are going to be trying really hard to write super robust code since they can't really unwind anyway. I dunno.

I think the story for detection of crashed tasks independent of happening to be listening to a channel the task was supposed to talk to you over is already pretty bad to nonexistent, but I don't recall exactly. It used to be better!

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

FamDav posted:

so is it like they're taking the swift approach to elevating certain novel types to special syntax within the language? i dont like that

we've gone back and forth with swift about exactly how special Optional is. we really want covariance of optionals (T < U => T? < U?), and not having implicit injection into optionals creates huge usability problems (although adding it also introduces a few problems). essentially we do see optionals as structural types worthy of special language support along the same lines as tuples, which similarly have a lot of special behavior for subtyping, pattern-matching, etc. you could in principle model these things with more sophisticated user-defined conversions --- for example, you could support pattern-matching being able to implicitly reverse optionality by adding a notion of a reversible conversion --- but we've actually been moving in the opposite direction, towards eliminating user-defined conversions entirely

certainly we've considered letting arbitrary types opt into the 'if let' syntax via a special protocol, the same way we do a lot of other syntax. but the more we think about what that protocol would look like ("given a value, check whether it's true-ish; if so, extract a value and bind it to this variable; otherwise throw the whole thing away"), the less interesting it actually seems to generalize it. you could imagine using it with a weighted Either type for error handling, but weighted Either is a really lovely language design for error handling unless you're working in an Either monad (i.e. unless you implicitly propagate errors), in which case 'if let' is not normally going to working with the weighted Either type anyway

tef
May 30, 2004

-> some l-system crap ->

AlsoD posted:

ok i just looked this up and it doesn't like it happens, sadly

rand takes a integer from 1..n, but you can pass it anything that has to_i, then it calls abs on the value

in particular they decided it would be better to munge anything into a positive number than require them.

for example: why does rand(0) return a number from 0..1 but not rand(1) who knows

tef
May 30, 2004

-> some l-system crap ->

rjmccall posted:

we've gone back and forth with swift about exactly how special Optional is.

tbh the whole x! style arguments seems like a very nice hack, iirc.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

tef posted:

tbh the whole x! style arguments seems like a very nice hack, iirc.

thank you. i spent a lot of time working out how they'd work, and then a whole lot more time justifying that to everybody else, and then it went Above My Pay Grade for a while, and then finally the official blessing came back down from the heavens, and some muscles i didn't know i had got to unclench for the first time in three months

i did give them really awful syntax at start, though

Vanadium
Jan 8, 2005

There's a (seemingly fairly haskell-inspired) dude in the rust community who has almost but not quite proposed that Rust do checked exceptions where the whole thing is isomorphic to having your checked-exception-throwing function return what I think rjmccall just called weighter Either, it's kinda wild. here's his notes. It looks kinda cool in that it does what rust does right now but with special syntax and the implicit return thing, and it's also gonna piss off people who get mad at java. He's all "people only hate checked exceptions b/c no one's done them right" but I'm not sure his optimism is justified, especially if his scheme is also gonna have to be work out in place of the whole Let It Crash thing and not only for FileNotFound-like stuff.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

FamDav posted:

it is, because pointer dereference and functions are defined in the stdlib. i just think its odd to take certain parts of the stdlib and give them shorthand compiler magic syntax.

I guess you mean "aren't defined in the stdlib"?

what does it mean for something to be in the stdlib vs the language proper? are JS Object and Array and RegExp literals stdlib-syntax? Objective-C's NSString @"butts" form? the operand to Java's throw keyword must inherit from a stdlib type, and iteration syntax knows about an interface, and "literals" create a stdlib type instance. c# has using/IDisposable. C++'s for-: and user-defined literals.

interaction between syntax and type system seem like a part of pretty solid language design, and implementations of those types will naturally live in the stdlib.

Vanadium
Jan 8, 2005

Rust does that whole thing by having a family of attributes that say "hay, compiler, I'm that special ______ type/function/whatever you know about" that the standard library uses (though not for Option), and if you don't like the standard library you can avoid building against it and put those attributes on your own declarations. Like, the compiler knows that there's gotta be a special trait that things the for-loop construct can iterate over must implement and what operations it provides for that, but it doesn't care whether that's defined in std::iter and is called Iterator and what other methods the trait defines.

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Vanadium posted:

There's a (seemingly fairly haskell-inspired) dude in the rust community who has almost but not quite proposed that Rust do checked exceptions where the whole thing is isomorphic to having your checked-exception-throwing function return what I think rjmccall just called weighter Either, it's kinda wild.

this looks neat, i'll take a closer look

by "weighted Either" i just mean a type that's structurally an Either type, except reserved/designed for value-or-error instead of reusing the normal Either type. i.e. the type gives semantic weight to the options. so one, it's a different type and you can't accidentally use a normal Either value as a monadic computation or vice-versa, and two, the constructor names can be something meaningful like Success/Failure instead of Right/Left

Adbot
ADBOT LOVES YOU

Vanadium
Jan 8, 2005

Oh, yeah then, ours is called Result and has Ok and Err arms and they removed the regular Either type in January for whatever reason. :shobon:

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