Skip to main content
23 events
when toggle format what by license comment
Apr 27, 2015 at 17:59 comment added supercat @JimBalter: The intersection and union types sound very powerful, though at a brief glance I'm not quite sure how they handle binding in case of overlapped functionality. Were they not required to be commutative, ordering could be used to establish ranking, but otherwise I'm not quite clear how conflicts would get resolved.
Apr 27, 2015 at 17:55 comment added supercat ...having an assignment operator which would trap immediately if that isn't the case, in addition to the one which would let nulls pass through, would help make such intention clear, and provide fail-fast behavior if the intention is violated.
Apr 27, 2015 at 17:54 comment added supercat @JimBalter: Traps are useful for the scenario where one wishes to ensure that a piece of code will not run when a particular invariant doesn't hold, but where one has no particular means of handling the situation beyond indicating that an operation couldn't be performed because of a broken invariant. Otherwise, I'd say that while it may be useful to have types that must be initialized when created and could only be written using a trap-if-null assignment (or, for parameters, trapping if null when they are passed), for places where a variable, although nullable, is supposed to be non-null...
Apr 27, 2015 at 17:44 comment added Jim Balter ceylon-lang.org/documentation/spec/html/typesystem.html
Apr 27, 2015 at 17:39 comment added Jim Balter Who wants traps? There are far more general mechanisms ... a precondition on a function/method that asserts that a parameter isn't null lets you take whatever action you want if it is. But for nullable references, the combination of Maybe and non-nullable references is far better because it makes it semantically impossible to have a null where it shouldn't be. And Maybe is just a specific example of a disjunctive type ... take a look at Ceylon, which makes powerful use of them.
Apr 27, 2015 at 17:36 comment added supercat @JimBalter: What would you think of having distinct kinds of assignment operators, and allowing parameters to indicate which type of "assignment" should be used when passing them? One kind of assignment operator would allow null to be regarded like any other reference, and the other would assert that the reference in question is not null and trap if it is?
Apr 27, 2015 at 17:35 comment added Jim Balter ... and which might not, so it takes programmer discipline to always check for null in the right places, and invariably this discipline fails. With Maybe, the compiler/language semantics enforces the discipline. The generated code is the same, but Maybe is safe while nullable references are not. This is what type systems can do for you. You should go learn about it.
Apr 27, 2015 at 17:35 comment added Jim Balter ... neither Nothing nor Maybe<T> is a reference type and so cannot be dereferenced. In order to extract a T from Maybe<T> you must test the type first ... this is a compile-time restriction imposed by the semantics of the language and the Maybe type. Thus, it is impossible to dereference null (Nothing). By declaring something as a Maybe<reference> rather than a reference, you have said that this is a thing that might be Nothing, so it is necessary to test the type to see if it is a reference before using it as one. But with T* foo, there is no way to declare which pointers might hold null ...
Apr 27, 2015 at 17:34 comment added Jim Balter Your question is probably meant to be rhetorical, but it just reveals a complete failure to understand or even attempt to understand -- all too common among C programmers who have a good grasp of the hardware level but fail at abstraction. First, on the expense: optimized implementations avoid the extra flag by representing the Nothing case of Maybe<reference type> with an invalid address -- null is a good candidate -- so the representation is identical. But while null is a legal but invalid value for a reference type, so it can be dereferenced, resulting in undefined behavior, ...
Apr 27, 2015 at 2:11 comment added supercat @JimBalter: How is a Maybe<T> which either holds a non-nullable reference to a T or doesn't, different from a reference that can either identify a T or be null? If one wishes to duplicate the state of an array which has had some but not all items written, not necessarily in sequential order, having a type which can hold the state of any numbered element, empty or not, would seem a very useful thing to have, and using a combination of a reference and a flag seems more expensive than using a nullable reference.
Apr 27, 2015 at 1:41 comment added Jim Balter "No, it wouldn't solve the problem -- at least, not without introducing null references all over again." -- Such comments show a complete lack of understanding of type theory.
May 8, 2014 at 13:50 comment added supercat @BT: Probably not all of them (there are likely others I haven't thought of), but I'm glad you like the answer. It's easy to require all variables to be written with "something" before they can be read, but it's not possible to to define something meaningful to write them with; of the meaningless things one could write, null has the advantage of being obviously meaningless.
May 6, 2014 at 3:57 comment added B T +1 for enumerating all the possible ways the problem can be solved
May 3, 2014 at 16:41 comment added supercat @Doval: What would an efficiently-expandable collection type use for backing storage if not a slightly-over-allocated array? I guess maybe the system array type could have separate "allocated" and "valid" sizes, but I don't know of implementations that work that way.
May 3, 2014 at 15:46 comment added Doval ...but to me it makes the most sense from a semantics and correctness point of view. If the performance later turns out to be bad I can always rewrite the critical code later.
May 3, 2014 at 15:45 comment added Doval @supercat No, not particularly. I'm just thinking out loud, and have been programming in Standard ML as of late. The approach there is that the array constructors take either the default value, or a function that takes the array index and returns the value to initialize that index with. If I can't do either, I make it an array of 'a option instead of an array of 'a. And if I still don't like that, I just accept that an array is fundamentally the wrong choice - if I want to add to a collection later, I should pick a collection that I can grow. I'm not sure how efficient that approach is,
May 3, 2014 at 15:37 comment added supercat @Doval: Correct, Maybe<T>[]. Can you see any good way to deal with the fact that the entire array must be created before sensible values can be known for its contents, other than by requiring that the array-element type to have a default value?
May 3, 2014 at 15:21 comment added Doval @cHao Nothing can only be assigned to values of type Maybe, so it's not quite like assigning null. Maybe<T> and T are two distinct types.
May 3, 2014 at 15:19 comment added Doval @supercat I'm not sure how a backing type of Maybe makes sense for List since Maybe holds a single value. Did you mean Maybe<T>[]?
May 3, 2014 at 14:22 comment added supercat @Doval: Should the backing type of a List<T> be a T[] or a Maybe<T>? What about the backing type of a List<Maybe<T>>?
May 3, 2014 at 14:02 comment added cHao @Doval: No, it wouldn't solve the problem -- at least, not without introducing null references all over again. Should a "nothing" act like a member of the type? If so, which one? Or should it throw an exception? In which case, how are you any better off than simply using null correctly/sensibly?
May 3, 2014 at 3:51 comment added Doval Wouldn't a Maybe/Option type solve the problem with #2, since if you don't have a value for your reference yet but will have one in the future, you can just store Nothing in a Maybe <Ref type>?
May 3, 2014 at 3:22 history answered supercat CC BY-SA 3.0