|
VikingofRock posted:Yeah but compare that to C++ where if you take an object by reference, that object can't be null no matter what. It seems to me like if I couldn't trust that that was true I'd have to write a bunch of checks in every function to make sure that none of the arguments were null. I haven't written Java since high school though so I have no idea how that actually works in practice. In C++ passing by non-const reference is crazy (some people disagree with that, but they are crazy) so you'll pass by pointer. A good API won't allow that pointer to be null, though. Honestly in C++ null pointer segfaults when they do happen are a delightfully benign problem, compared to use-after-free, multithreading bugs, IMO anything that gives you a clear stacktrace like that is a luxury. Null pointer bugs did become a small problem with one new employee though -- the fresher that thought Lisp was good started doing bad poo poo, making functions that accept null pointers whose meaning was redundant with an empty value -- and the fresher that thought Haskell was good did not do that -- also, the Lispic dev introduced dumb use-after-free pointer-escaping bugs that the Haskellite would never have done. So now I'd bet being an insufferable Haskell-programming moron helps young people get better software taste more quickly.
|
# ? Aug 24, 2015 06:47 |
|
|
# ? Jun 11, 2024 19:45 |
At the risk of outing myself as a crazy person, what's wrong with passing by non-const reference? Is it just that using pointer syntax reminds you that you are mutating something?
|
|
# ? Aug 24, 2015 07:14 |
|
sarehu posted:In C++ passing by non-const reference is crazy (some people disagree with that, but they are crazy) so you'll pass by pointer. A good API won't allow that pointer to be null, though. Honestly in C++ null pointer segfaults when they do happen are a delightfully benign problem, compared to use-after-free, multithreading bugs, IMO anything that gives you a clear stacktrace like that is a luxury. Null pointer bugs did become a small problem with one new employee though -- the fresher that thought Lisp was good started doing bad poo poo, making functions that accept null pointers whose meaning was redundant with an empty value -- and the fresher that thought Haskell was good did not do that -- also, the Lispic dev introduced dumb use-after-free pointer-escaping bugs that the Haskellite would never have done. So now I'd bet being an insufferable Haskell-programming moron helps young people get better software taste more quickly. haskell is good.
|
# ? Aug 24, 2015 07:19 |
|
VikingofRock posted:Yeah but compare that to C++ where if you take an object by reference, that object can't be null no matter what. It seems to me like if I couldn't trust that that was true I'd have to write a bunch of checks in every function to make sure that none of the arguments were null. I haven't written Java since high school though so I have no idea how that actually works in practice. in c# we get cool things like ? when you think you might get a null and you want to easily handle the null case when you do a thing with it
|
# ? Aug 24, 2015 12:12 |
|
Bloody posted:in c# we get cool things like ? when you think you might get a null and you want to easily handle the null case when you do a thing with it some on the C# team wish that reference types required ?/Nullable<T> to be nullable too
|
# ? Aug 24, 2015 12:47 |
|
VikingofRock posted:At the risk of outing myself as a crazy person, what's wrong with passing by non-const reference? Is it just that using pointer syntax reminds you that you are mutating something? yeah. the thing is that nowhere else in c/++, with a couple very confusing exceptions, do you have pass-non-const-reference-by-value semantics. so to reduce the cognitive overhead of always having to wonder whether something is mutable, it's better to explicitly show that it is by using ->.
|
# ? Aug 24, 2015 13:08 |
|
Bloody posted:in c# we get cool things like ? when you think you might get a null and you want to easily handle the null case when you do a thing with it pretty sure c# ? is just syntactic sugar for optionals
|
# ? Aug 24, 2015 13:13 |
|
uncurable mlady posted:pretty sure c# ? is just syntactic sugar for optionals it's for any nullable type
|
# ? Aug 24, 2015 15:31 |
Phobeste posted:yeah. the thing is that nowhere else in c/++, with a couple very confusing exceptions, do you have pass-non-const-reference-by-value semantics. so to reduce the cognitive overhead of always having to wonder whether something is mutable, it's better to explicitly show that it is by using ->. I guess I can see that, but personally I don't really think it's that big a cognitive overhead and I'd rather have the compile time guarantee that the value is not null . But it's good to know that passing by pointer is idiomatic in case I ever write C++ on a team.
|
|
# ? Aug 24, 2015 18:34 |
|
VikingofRock posted:I guess I can see that, but personally I don't really think it's that big a cognitive overhead and I'd rather have the compile time guarantee that the value is not null . But it's good to know that passing by pointer is idiomatic in case I ever write C++ on a team. on my team it is very much not the norm. we pass by non-const ref all the time. kind of wish there was a way to annotate that at the call site though (like c#'s ref/out) but it isn't too bad. sometimes we pass pointers by ref lol. this is mainly used to get a reference to an object as an out parameter, since you can't reseat references I actually kind of like it. it's nice to only rarely have to look for a null pointer. we have a strict coding style rule to always annotate your function params with SAL annotations (_In_, _Out_, _Out_maybenull_, etc) and static analysis tools to catch deviations from these promises, so at least all you have to do is look at the declaration to figure this out
|
# ? Aug 24, 2015 18:48 |
|
uncurable mlady posted:pretty sure c# ? is just syntactic sugar for optionals sort of, it's syntactic sugar for Nullable<T>, where T is a value type
|
# ? Aug 24, 2015 18:53 |
|
that's not too bad though, i rather argue that typed cascading nulls is a very effective solution that requires far fewer changes (so a.b.f(x,y) is the appropriate null if a, b, x or y is null, if b::f expects non-null arguments) comes with a cost, but makes the actual programming straightforward and neat (unused values being nonexisting cause no issues etc) while making the failure mode predictable.
|
# ? Aug 24, 2015 19:04 |
|
did anyone, ever, talk about a "contract" between a producer/consumer before those dirty rubyists re-invented everything
|
# ? Aug 24, 2015 19:05 |
|
i think that contracts in their currently-popular incarnation were more of a js thing to try and make node somewhat tractable, most rails code was basically one-thread processes not talking to each other trivial horizontal concurrency for a long time unless i'm mistaken
|
# ? Aug 24, 2015 19:15 |
|
Blotto Skorzany posted:i think that contracts in their currently-popular incarnation were more of a js thing to try and make node somewhat tractable, most rails code was basically one-thread processes not talking to each other trivial horizontal concurrency for a long time unless i'm mistaken are you thinking of promises?
|
# ? Aug 24, 2015 20:38 |
|
probably.
|
# ? Aug 24, 2015 20:44 |
|
yeah the only language I know of that had "contracts" i.e. bits of code that assure various invariants about a method call, was eiffel.
|
# ? Aug 24, 2015 21:03 |
|
design by contract seems like more of a development methodology than a language feature. your contracts are either compile-time invariants (like types) or runtime assertion checks. what else could they possibly be? language-level support might encourage the practice, give better error messages, etc... but you can check pre- and post-conditions in any language if you want to
|
# ? Aug 24, 2015 21:16 |
|
Eiffel had support for class instance invariants too though, which would execute after each method to ensure the invariants were upheld. Language support is nice if you can strip it out of runtime once the contracts are proved over time I guess. edit: But yeah, it's more a dev methodology, works pretty well as it makes it easy to design unit tests using that as it's concept.
|
# ? Aug 24, 2015 21:23 |
|
Zaxxon posted:yeah the only language I know of that had "contracts" i.e. bits of code that assure various invariants about a method call, was eiffel. D has them
|
# ? Aug 24, 2015 21:39 |
|
c# has contracts too but no one uses them
|
# ? Aug 24, 2015 22:12 |
|
VikingofRock posted:At the risk of outing myself as a crazy person, what's wrong with passing by non-const reference? Is it just that using pointer syntax reminds you that you are mutating something? To make the callsite clearer.
|
# ? Aug 24, 2015 22:21 |
|
VikingofRock posted:I guess I can see that, but personally I don't really think it's that big a cognitive overhead and I'd rather have the compile time guarantee that the value is not null . But it's good to know that passing by pointer is idiomatic in case I ever write C++ on a team. On the other hand, using references provides enough information to other tools (for example, clang's undefined behavior sanitizer) to automatically insert runtime sanity checks everywhere appropriate to catch this kind of error and abort with an informative error message and backtrace.
|
# ? Aug 24, 2015 22:35 |
|
No Pants posted:sort of, it's syntactic sugar for Nullable<T>, where T is a value type ah
|
# ? Aug 24, 2015 23:12 |
|
Doesn't Ada also run contracts and range checks and stuff? Ada is pretty much the language with the best track record out there or something isn't it?
|
# ? Aug 25, 2015 04:39 |
|
ok, now name a program in wide use written in Ada. I guess my point is that it's easy to say "but THAT'S the good programming language" when nobody uses it.
|
# ? Aug 25, 2015 04:49 |
|
http://www.seas.gwu.edu/~mfeldman/ada-project-summary.html United States FAA Air Route Traffic Control Centers Display System Replacement (DSR) Boeing 787 Air Conditioning Control Unit European Train Control System (ETCS) Atlas V International Space Station Flight Software U.S. Internal Revenue Service, Product Assurance Division US Navy ejection seat sequencer (f35 lol)
|
# ? Aug 25, 2015 04:54 |
|
in strong typing we trust. that's great
|
# ? Aug 25, 2015 04:56 |
|
yeah i dunno if ada is a great example of a dork language nobody actually uses in the real world
|
# ? Aug 25, 2015 05:47 |
|
GrumpyDoctor posted:yeah i dunno if ada is a great example of a dork language nobody actually uses in the real world lol, it's actually haskell
|
# ? Aug 25, 2015 06:05 |
|
MononcQc posted:Doesn't Ada also run contracts and range checks and stuff? Ada is pretty much the language with the best track record out there or something isn't it? Yes, and it makes it very easy to define e.g. an integer type which must be between 1 and 100. I'd love to work on an ada project
|
# ? Aug 25, 2015 10:01 |
|
i have worked with ada professionally, i liked it
|
# ? Aug 25, 2015 10:10 |
|
hackbunny posted:some on the C# team wish that reference types required ?/Nullable<T> to be nullable too specifically eric lippert has said as much in an earlier column but by the time nullable value types were added it was *wayyyy* too late to go back on that. as i've gotten back into c/c++ i found it interesting that null is *not* a hole in the type system in those languages since you have an explicit syntactic distinction between a value and a reference to a value. in other words null makes perfect sense given c/c++'s type semantics. makes it all the more baffling that java adopted null blindly because, i dunno, "everything's a reference, references are like pointers, therefore references can be null". seems even more obvious you'd want a clearer distinction but maybe that's 20 years of language development hindsight.
|
# ? Sep 1, 2015 21:56 |
|
Dr Monkeysee posted:specifically eric lippert has said as much in an earlier column but by the time nullable value types were added it was *wayyyy* too late to go back on that. yes it is, although C++ has some facilities to mitigate this. https://en.wikipedia.org/wiki/Cyclone_(programming_language) Cyclone is a C dialect that basically fixes the more egregious memory safety issues with C (i.e. some pointers must never be NULL) and not much else. Nobody uses it.
|
# ? Sep 1, 2015 22:00 |
|
Dr Monkeysee posted:makes it all the more baffling that java adopted null blindly because, i dunno, "everything's a reference, references are like pointers, therefore references can be null". seems even more obvious you'd want a clearer distinction but maybe that's 20 years of language development hindsight. You have to have some kind of value for uninitialized references. Class constructors might not initialize all of a class's fields, and arrays have to start out in some state. It might have been a good decision to eliminate null as a keyword. Even more radically, throw a null pointer exception when a null reference is used in a reference comparison (but that would hurt performance). In a software project I'm making right now, the only use of the null keyword is in janitoring objects in and out of their default-constructed state.
|
# ? Sep 1, 2015 23:34 |
|
Mr Dog posted:yes it is, although C++ has some facilities to mitigate this. sure nulls can create dangerous conditions when working with memory in c/c++ but that seems orthogonal to whether it's a hole in the type system. low-level memory manipulation is dangerous. but the pointer-ness is explicit, a my_struct* is not a my_struct and a 0-bit my_struct* is perfectly in line with the semantics of the type my_struct*. c++ makes this even more explicit by distinguishing between pointers and references. as opposed to java/c# etc where a MyClass variable can be treated as an alias for a MyClass value except when it can't.
|
# ? Sep 1, 2015 23:44 |
|
sarehu posted:You have to have some kind of value for uninitialized references. Class constructors might not initialize all of a class's fields, and arrays have to start out in some state. yeah true and i suppose even languages that deal entirely in optional types still have the notion of a "this is a reference to nothing". probably mostly navel-gazing since it's relatively straightforward to organize java/c# code to avoid null references almost entirely and at least on the projects i've ever worked on a thrown null ref exception is treated as a developer error and not a "handle and move on" scenario. i just found it interesting that the languages that popularized null actually incorporate that value in a way that isn't incongruous with the rest of their type systems.
|
# ? Sep 1, 2015 23:48 |
|
sarehu posted:You have to have some kind of value for uninitialized references. Class constructors might not initialize all of a class's fields, and arrays have to start out in some state. it can indeed be painful to do without null altogether in the context of a language like java or c# where you're working with potentially complex class initialization. a less extreme approach would be the ability to specify that a field is never null once a constructor has finished, or that a field never becomes null again if it has ever been assigned. but there are a lot of permutations like that, and supporting too many of them would be unwieldy. in practice, simply requiring non-nullable references always to be initialized at the point of declaration (or within a constructor in a way that the compiler can prove precedes any reads) would be workable in the vast majority of cases. today's @nonnull/@nullable would be tolerable if they had a cleaner syntax and everything already used them consistently. fixed-length arrays are always going to be a problem, but if your code needs to interact directly with them instead of hiding them behind a variable-length list class then you're working at a sufficiently low level that it's reasonable to expect you to take extra care.
|
# ? Sep 1, 2015 23:49 |
|
it's a static vs. dynamic trade-off. optional types can be really frustrating and onerous to work with. general abstractions throw optionals in your face all the time for seemingly pedantic reasons. anything you do to address that becomes a source of language complexity and, potentially, a safety hole. optionals make you put up with an awful lot of poo poo in order to get your job done and i say all this as the person who drove a lot of the design of optionals in swift. of course, overlaying optionals on an existing ubiquitous-null system like c has its own challenges, which we're gradually improving on; but a lot of them are just inherent to optional types. i still think it was 100% the right move, but it is very much a "take your medicine" thing for users which is not something you get to do too many times, and we forsook a lot of language simplicity forever when we did it
|
# ? Sep 2, 2015 07:33 |
|
|
# ? Jun 11, 2024 19:45 |
|
all the rust code i've written is followed by a healthy dose of unwrap() or expect() or unwrap_and_then() etc to make optionals a little more pleasant, does swift have the same sugar?
|
# ? Sep 2, 2015 09:24 |