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

GrumpyDoctor posted:

this is infuriating

the dude is not an LtU type theory expert

he does, however, understand how python's half-baked mess gets in the way of implementing pypy

Adbot
ADBOT LOVES YOU

FamDav
Mar 29, 2008

GrumpyDoctor posted:

what the heck is going on here, i thought i had it figured out but then i realized i was wrong

ruby has internal iterators w/ blocks which make chaining operations p simple. that bit of code should give me a hash with all elements whose values are greater than 100 and key length is less than 5.

select returns a copy of the hash with all the elements that satisfied the block. select! does (almost) the same thing except mutates the original hash in place.

the almost part is that select always returns a new hash even if its the same structure as the previous hash, whereas select! returns nil if select! did nothing to the old hash. if the list has no values smaller than 100 then it returns nil, then when trying to do the next select you get a NoMethodFound exception because nil has no method select! on it.

no but you see once you memorize this it makes it perfectly reasonable.

raminasi
Jan 25, 2005

a last drink with no ice

MononcQc posted:

There's a difference between understanding them as a user, and understanding them as a system of axioms implementers would care about. I'm guessing the author doesn't understand the latter, though that may have an impact on its appreciation as a user.


Notorious b.s.d. posted:

the dude is not an LtU type theory expert

he does, however, understand how python's half-baked mess gets in the way of implementing pypy

it actually got a lot better after those two things

tef
May 30, 2004

-> some l-system crap ->
what's an example of this, i don't see it?

> looking up elements in an array?

oh i guess that's an example but I like it


hepatizon posted:

sure, array indexing and hash lookups count as an example, although i personally find this convention works great for me. any others?

die in a fire :3:

tef
May 30, 2004

-> some l-system crap ->

coffeetable posted:

oh okay so in ruby the semipredicate problem isn't so much a problem as a feature

:psyduck:

"0 but true" :q:

hepatizon
Oct 27, 2010

tef posted:

what's an example of this, i don't see it?

> looking up elements in an array?

oh i guess that's an example but I like it


die in a fire :3:

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

hepatizon fucked around with this message at 20:23 on Aug 26, 2014

coffeetable
Feb 5, 2006

TELL ME AGAIN HOW GREAT BRITAIN WOULD BE IF IT WAS RULED BY THE MERCILESS JACKBOOT OF PRINCE CHARLES

YES I DO TALK TO PLANTS ACTUALLY
Yeah I know the wheels are square, but that's only four things. It's a great car otherwise!

Notorious b.s.d.
Jan 25, 2003

by Reene

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

https://github.com/ruby/ruby/search?utf8=%E2%9C%93&q=%22return+nil%22

125 of them in the most cursory search. and most of them are indeed quietly swallowing errors.

this is hilarious

code:
begin
  ::Encoding::Converter.search_convpath(name, 'UTF-8')
rescue ::Encoding::ConverterNotFoundError
  return nil
end
code:
def _ebox_move(idx)
return nil if cget(:state) == 'disabled'
x, y, w, h = bbox(idx)
[...]
x, y, w, h = bbox(idx)
return nil unless y && h
code:
line = line[1..-1]
line = $1 if line[/-\*-\s*(.*?)\s*-*-$/]
return nil unless ENCODING_SPEC_RE =~ line
code:
def previous_sibling_node
  return nil if @parent.nil?
  ind = @parent.index(self)
  return nil if ind == 0

Notorious b.s.d.
Jan 25, 2003

by Reene
hepatizon, go learn a good programming language. something with a working type system, option types, and an error-checking compiler. then come back and tell us how much fun it is to be unable to distinguish between error conditions, nothing being found, and an instance of nil being returned on purpose.

i make this challenge not because i don't think you can learn a good language. i make it because i don't think anyone comes back to scripting languages and sighs with relief because the error handling is hosed

Notorious b.s.d.
Jan 25, 2003

by Reene

coffeetable posted:

Yeah I know the wheels are square, but that's only four things. It's a great car otherwise!

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

the world needs more NaN-like APIs: safely propagate errors including beyond one call chain. maybe even with the ability to turn on signalling so you can easily break on where the error originates. easier to reason about than exception safety too, probably.

cairo has this in that all operations shortcircuit out safely if you operate on a cairo_t in an error state, but it takes a lot of careful API design.

Workaday Wizard
Oct 23, 2009

by Pragmatica
someone please list cases where you would rather use NaN than an exception pls.

FamDav
Mar 29, 2008
haskell called and said EitherT wants to know why nobody wants to play with it

b0lt
Apr 29, 2005

Shinku ABOOKEN posted:

someone please list cases where you would rather use NaN than an exception pls.

simd

raminasi
Jan 25, 2005

a last drink with no ice

Subjunctive posted:

the world needs more NaN-like APIs: safely propagate errors including beyond one call chain. maybe even with the ability to turn on signalling so you can easily break on where the error originates. easier to reason about than exception safety too, probably.

cairo has this in that all operations shortcircuit out safely if you operate on a cairo_t in an error state, but it takes a lot of careful API design.

so, monads?

hepatizon
Oct 27, 2010

Notorious b.s.d. posted:

https://github.com/ruby/ruby/search?utf8=%E2%9C%93&q=%22return+nil%22

125 of them in the most cursory search. and most of them are indeed quietly swallowing errors.

this is hilarious

the stdlib is full of awful cruft that nobody uses -- that's why i've been saying "core". not sure if there's a way to search core libs only

Notorious b.s.d. posted:

hepatizon, go learn a good programming language. something with a working type system, option types, and an error-checking compiler. then come back and tell us how much fun it is to be unable to distinguish between error conditions, nothing being found, and an instance of nil being returned on purpose.

i make this challenge not because i don't think you can learn a good language. i make it because i don't think anyone comes back to scripting languages and sighs with relief because the error handling is hosed

like many ruby programmers, i cut my teeth on java. also currently learning haskell, which i like a lot. i still think ruby has plenty to offer!

Workaday Wizard
Oct 23, 2009

by Pragmatica

thanks

FamDav
Mar 29, 2008

Shinku ABOOKEN posted:

someone please list cases where you would rather use NaN than an exception pls.

NaNs are exceptions, but they are also valid floats and can be passed into functions. plus, all primitive operations on floats handle NaNs by propagating the error, so you only have to check for NaN when you want to do an operation that can't handle NaN.

ShadowHawk
Jun 25, 2000

CERTIFIED PRE OWNED TESLA OWNER

Subjunctive posted:

the world needs more NaN-like APIs: safely propagate errors including beyond one call chain. maybe even with the ability to turn on signalling so you can easily break on where the error originates. easier to reason about than exception safety too, probably.

cairo has this in that all operations shortcircuit out safely if you operate on a cairo_t in an error state, but it takes a lot of careful API design.
NaN is a bit like returning "Translation error" as a string. Sometimes it ends up on a sign post.

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Shinku ABOOKEN posted:

someone please list cases where you would rather use NaN than an exception pls.

code:
vector.map(functionThatMightProduceError);
with NaN, you get NaNs for the cases that are invalid, but the other valid ones are processed. with exceptions you get it partially completed and have to shuffle and restart to get the rest. parallelMap would benefit even more.

exceptions indicate error *events*, and NaN encodes error state or an invalid result. they're not really the same.

ShadowHawk posted:

NaN is a bit like returning "Translation error" as a string. Sometimes it ends up on a sign post.

no, because NaN is explicitly distinguishable from all valid results. you can end up with a serialized exception stacktrace on a user-facing page too, but that's about "how do you handle errors?" and not "how do you represent invalid results?"

Max Facetime
Apr 18, 2009

Subjunctive posted:

yeah, using types to represent narrower classes of data state rather than just representation can be really valuable, but you don't see it very often. Java doesn't have a different type for UnvalidatedCertificate vs ValidatedCertificate, AFAIK. so you're writing tests, and those tests will catch string-vs-int representation mismatch as well. there's a good paper I'll try to dig up.

I like type systems as compiler-enforced documentation, but they're pretty underused from the perspective of actually preventing bugs statically.

Java doesn't come with that as default but there's at least one library/tool where type-enhancements like that can be defined and subsequently checked during compilation, so...

Subjunctive posted:

C++ code:
/* ssl-verify.h */
UnverifiedCert OMGDanger();
SHAVerifiedCert VerifySHA(UnverifiedCert uc);
SHAAndKeyVerifiedCert VerifyKey(SHAVerifiedCert svc);
ContinueHTTPOperation(SHAAndKeyVerifiedCert skvc);

/* ssl-verify.cpp */
UnverifiedCert unverified = OMGDanger();
SHAVerifiedCert shaVerified = VerifySHA(unverified);
SHAAndKeyVerifiedCert fullyVerified = VerifyKey(shaVerified);
ContinueHTTPOperation(fullyVerified);

...might look like:

Java code:
interface SSLVerify {
  Certificate omgDanger() throws IOException;
  @SHAVerified Certificate verifySHA(Certificate c) throws InvalidCertificateException;
  @SHAAndKeyVerified Certificate verifyKey(@SHAVerified Certificate c) throws InvalidCertificateException;  
  void continueHTTPOperation(@SHAAndKeyVerified Certificate c) throws IOException;
}
a verification method would then convert from the not-verified type to the verified type, probably inside a clearly marked area where the enhanced compile-time checking is locally suppressed:

Java code:
  @SHAVerified Certificate verifySHA(Certificate c) {
    if(!isValidSHA(c)) {
      throw new InvalidCertificateException(c);
    }
    @SuppressWarnings("it is valid, afaiac")
    @SHAVerified Certificate c2 = (@SHAVerified Certificate) c;
    return c2;
  }
what's especially nice is that the cast is a no-op at runtime and also that this can be done with an existing type without having to rework it into a whole new type hierarchy

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Max Facetime posted:

Java doesn't come with that as default but there's at least one library/tool where type-enhancements like that can be defined and subsequently checked during compilation

cool -- what's the library/tool? I'd love to check it out, and if it doesn't have runtime overhead then it could be useful for our Android stuff too.

Max Facetime
Apr 18, 2009

Subjunctive posted:

cool -- what's the library/tool? I'd love to check it out, and if it doesn't have runtime overhead then it could be useful for our Android stuff too.

checker-framework

it's actively being developed and closely tracks the latest development version of javac (>1.8 or so) while android is stuck in java 1.6 land so ~ there might be issues with that ~

Shaggar
Apr 26, 2006
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

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord

AlsoD posted:

yes, some kind of way to test your code...statically...all at once

I'm assuming that you'll write tests for your code because it's A GOOD THING no matter what kind of language you're in. so I'm saying that any simple test for invariant that you write will imply the obvious poo poo that static typing would catch. "oh wow, this factorial is actually returning the string 'butt'!"

reiterating this: I never test the type directly like assert(int == type(f(2))), that would be pointless.

fart simpson posted:

quickly someone write a python unit test that catches the implied possible error here:

code:
newtype Celsius = C Float
newtype Fahrenheit = F Float

celsiusToFahrenheit :: Celsius -> Fahrenheit
celsiusToFahrenheit (C c) = F $ 1.8 * (c + 32)

assuming that the error here is that it should've been "(1.8 * c) + 32", how does static typing catch this?

assert(32 == celsiusToFahrenheit(0)) and there you go.

Otto Skorzeny posted:

if you have a function with the signature void foo(filtered_input bar) and call it with an argument of type string or of type unfiltered_input, the compiler gives you an error and prevents a potentially bad bug

good luck catching that with typical unit testing

ok, this is actually an interesting example and I guess it'd depend on the way you structured your code.

spineless answer: maybe make foo a method on the FilteredInput class or something? with complex cases the use of a class will be more natural!

"real" answer: I can't see a program flowing in a way that you have to deal with both unfiltered and filtered data at the same place... so the step where you filter the data before doing stuff would be isolated and easy to see flowing to the rest of the program?

Python code:
def filter(data):
    ...

def foo(filtered_data):
    ...

def do_the_whole_thing(data):
    filtered_data = filter(data)
    return foo(filtered_data)
and then test do_the_whole_thing. :smugmrgw:

Vanadium
Jan 8, 2005

FamDav posted:

, then when trying to do the next select you get a NoMethodFound exception because nil has no method select! on it.

fortunately this is easy to fix in ruby

Arcsech
Aug 5, 2008

Symbolic Butt posted:

assuming that the error here is that it should've been "(1.8 * c) + 32", how does static typing catch this?

assert(32 == celsiusToFahrenheit(0)) and there you go.

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

Arcsech fucked around with this message at 22:43 on Aug 26, 2014

b0lt
Apr 29, 2005

Symbolic Butt posted:

"real" answer: I can't see a program flowing in a way that you have to deal with both unfiltered and filtered data at the same place... so the step where you filter the data before doing stuff would be isolated and easy to see flowing to the rest of the program?

Python code:
def filter(data):
    ...

def foo(filtered_data):
    ...

def do_the_whole_thing(data):
    filtered_data = filter(data)
    return foo(filtered_data)
and then test do_the_whole_thing. :smugmrgw:

this is in no way error prone and strictly worse than just having the compiler make sure you don't make the mistake

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord

hepatizon posted:

the stdlib is full of awful cruft that nobody uses -- that's why i've been saying "core". not sure if there's a way to search core libs only

btw it's not "just" the basic data structures, rails for example is full of methods like that. I think it's a huge cultural thing where returning nil instead of failing is ok.

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord

b0lt posted:

this is in no way error prone and strictly worse than just having the compiler make sure you don't make the mistake

it's never error prone, your FilteredData type may be not even filtered! static typing is a shallow way of ensuring code correctness

Notorious b.s.d.
Jan 25, 2003

by Reene

hepatizon posted:

the stdlib is full of awful cruft that nobody uses -- that's why i've been saying "core". not sure if there's a way to search core libs only

so the basic data structures, the underpinnings of the language, don't count
the stdlib doesn't count, because "cruft"

ruby is excellent, as long as you never look at any ruby code!

Notorious b.s.d.
Jan 25, 2003

by Reene

hepatizon posted:

like many ruby programmers, i cut my teeth on java. also currently learning haskell, which i like a lot. i still think ruby has plenty to offer!

taking java 101 in college does not count as cutting your teeth

Vanadium
Jan 8, 2005

also a thing in ruby:

> x = []
=> []
> x[10] = nil
=> nil
> x
=> [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil]



but really, ruby treating nil both as a value and the absence of a value is somewhere around the bottom of my list of problems with it, far behind the lack of a module system, the many different kinds of function objects and their weird scopes, the encoding-aware strings, and probably a lot of other weird idiosyncraticies i've been sheltered from by not being exposed to the rails ecosystem

FamDav
Mar 29, 2008

Symbolic Butt posted:

it's never error prone, your FilteredData type may be not even filtered! static typing is a shallow way of ensuring code correctness

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

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

Notorious b.s.d. posted:

taking java 101 in college does not count as cutting your teeth

if you didn't bleed, you didn't cut your teeth

Vanadium
Jan 8, 2005

in other news, rust is probably about to change their macro invocation syntax from foo!(x, y, z) to @foo(x, y, z) and i am so irritated about it. they want the ! character freed up as a post-fix operator to go from Option<T> to T.

hepatizon
Oct 27, 2010

Notorious b.s.d. posted:

so the basic data structures, the underpinnings of the language, don't count
the stdlib doesn't count, because "cruft"

ruby is excellent, as long as you never look at any ruby code!

basic data structures do count, but they don't suffice to establish a pattern about ruby core as a whole. as for stdlib, i've been careful to explicitly say "core" all along because the difference between core and stdlib is important

Notorious b.s.d. posted:

taking java 101 in college does not count as cutting your teeth

ok

FamDav
Mar 29, 2008

Vanadium posted:

in other news, rust is probably about to change their macro invocation syntax from foo!(x, y, z) to @foo(x, y, z) and i am so irritated about it. they want the ! character freed up as a post-fix operator to go from Option<T> to T.

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

Symbolic Butt
Mar 22, 2009

(_!_)
Buglord

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
[/code

oh I get it now, this is cool

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

I understand that you can write neat code making good use of a static type system like mononcqc said, and I admit that python is a poor tool for this kind of style (even with type annotations)

but that's what static typing mostly is imo: a style. not a huge bug prevention mechanism that people make it sound like

Adbot
ADBOT LOVES YOU

Notorious b.s.d.
Jan 25, 2003

by Reene

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

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!

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