tag:blogger.com,1999:blog-2447174102813539049.post5605434425459409714..comments2024-03-18T05:13:16.135-07:00Comments on Room 101: Original SinGilad Brachahttp://www.blogger.com/profile/17934280339206214042noreply@blogger.comBlogger40125tag:blogger.com,1999:blog-2447174102813539049.post-27868508700328605092009-06-18T19:19:49.259-07:002009-06-18T19:19:49.259-07:00I haven't looked very closely at Clojure. It&#...I haven't looked very closely at Clojure. It's basically a functional Lisp, which is not a bad thing. I don't think it represents any important new ideas in PL design though. <br /><br />I think you'd be hard pressed to beat Scala;s performance on the JVM though. The new collection libraries in Scala are purely functional BTW.<br /><br />I agree Scala may not be for everyone - it is a sophisticated language.<br /><br />I hope we'll get Newspeak to work well using the dynamic features in the Java 7 VMs. Just to give people some more choice.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-41813637366371963502009-06-17T14:56:30.722-07:002009-06-17T14:56:30.722-07:00> I think [Scala] is superb work, and clearly t...> I think [Scala] is superb work, and clearly the language of choice on the JVM.<br /><br />I played with Scala a bit, and it seemed very complex. To me, Clojure seems to be simpler and more scalable (immutability, stm). What do you think about Clojure?Buddy Casinohttps://www.blogger.com/profile/02909308245218398837noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-63937947295466333602009-06-01T13:24:05.305-07:002009-06-01T13:24:05.305-07:00Zappini:
Obviously, the answer is that there are ...Zappini:<br /><br />Obviously, the answer is that there are no problems with it :-)<br /><br />Seriously, I see very little relationship. David's proposal allowed the programmer to define a bit level representation. <br /><br />In any case, there is a big difference between a design that stands in its own right, and a proposal for changing a widely used system like Java, where compatibility casts its ugly shadow. As I've said repeatedly, I am not proposing any changes to Java.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-64673426995248654512009-06-01T12:11:30.119-07:002009-06-01T12:11:30.119-07:00I once asked you about supporting lightweight obje...I once asked you about supporting lightweight objects as presented in David Bacon's Kava. Your illuminating response was "there were problems with it".<br /><br />How is your suggestion different from Bacon's Kava?Zappinihttps://www.blogger.com/profile/03774518609592812824noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-53576116001796657942009-06-01T08:27:35.617-07:002009-06-01T08:27:35.617-07:00Grey Lens Man:
I wish I had the influence you see...Grey Lens Man:<br /><br />I wish I had the influence you seem to attribute to me. Then there would be vast numbers of Newspeak programmers :-)<br /><br />I have been following Scala since before it was called Scala. I believe I've even, on occasion, had a modest influence on its evolution. I think it is superb work, and clearly the language of choice on the JVM.<br /><br />Hence, I would not reduce it to "Java done right". It is a new language - and could not have been successful at the time Java was developed and introduced. Its type system is far beyond what was possible back then; and culturally, it wouldn't have stood a chance at the time, being too far ahead of the C crowd.<br /><br />This post simply shows how little need be done to plain old Java to make it a pure OO language (for a pretty weak definition of pure OO).<br /><br />I still have some issues with Scala BTW: reflection, constructors, overloading, traces of static, dynamicity. But it is still a tour de force of language design.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-64050142402109213862009-06-01T05:37:26.739-07:002009-06-01T05:37:26.739-07:00Pretty sure Scala does the "right" thing across th...Pretty sure Scala does the "right" thing across the board here (and of course a whole lot more in many areas where Java has fallen). Everything is an object, primitives are optimized, defining new classes with defined operator semantics, ... <br /><br />i.e., val total = base + addon<br />where total, base, addon: Price<br /><br />I view Scala not as a new language, but as an improved, enhanced version of Java washed free of original sin. Java done right as it were. <br /><br />I wish more influencers such as yourself would assist in making it a palatable choice and eventually a prevalent choice.RayRacinehttps://www.blogger.com/profile/12063637186335293030noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-6328125996755540132009-05-29T16:43:24.891-07:002009-05-29T16:43:24.891-07:00Amos,
I hope you're joking. But I can't tell.Amos,<br /><br />I hope you're joking. But I can't tell.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-68263508747613989092009-05-29T15:57:54.329-07:002009-05-29T15:57:54.329-07:00Amos,
Glad you did get it - the comments can be m...Amos,<br /><br />Glad you did get it - the comments can be misleading. Of course, null doesn't need to get boxed - it's already supported by the JVM. I don't know of an implementation that uses 42 - but it's impossible to tell :-)Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-47746307362846634652009-05-29T15:14:48.172-07:002009-05-29T15:14:48.172-07:00Abies and Amos,
It sounds like there is still som...Abies and Amos,<br /><br />It sounds like there is still some misunderstanding.<br /><br />The only case where objects need to be wrapped is where they are passed into a context that expects an object. This is similar to autoboxing today EXCEPT that it is semantically transparent.<br /><br />As I've noted, null is not a member of value types, so there is no issue with the number of values representable in 32 bits.<br /><br />The overhead of treating == as a method is restricted to the top level node of the type hierarchy, where we don't know if we are dealing with a value or a reference.<br /><br />I hope this is finally clear.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-41075570895547051132009-05-29T12:04:43.670-07:002009-05-29T12:04:43.670-07:00No amount of syntax magic, renaming nulls to Optio...No amount of syntax magic, renaming nulls to Options or T|null will allow you to fit 2^32 different int values AND null inside one 32 bit register. Please make a distinction between some language sugar, jvm level changes and between possibility of implementing it in most optimal way on common CPUs.<br /><br />As far as == for 'Int' comparing the contents... This probably would mean that every object would have to implement something like identityEquals(...) method, which would default to old == for reference types and be overwritten to compare for contents for 'primitive' types. In other case, how would<br /><br />boolean myEquals(Object o1, Object o2) {<br /> return o1 == o2;<br />}<br /><br />myEquals(1,2);<br /><br />would work ?Artur Biesiadowskihttps://www.blogger.com/profile/01153887805003519136noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-20598079858057857132009-05-28T08:46:53.513-07:002009-05-28T08:46:53.513-07:00Amos,
Re: you can't tell how many copies of an in...Amos,<br /><br />Re: you can't tell how many copies of an int there are.<br />The post discusses this: == is a method in this proposal, and it does a value comparison on the underlying integer bits (i.e., == is the same as equals).<br /><br />Re: null is not a member of T. Today, null is a member of every reference type, so T v = null; is legal.<br />Suppose null is not a member of T, only of the type Null. T v = null; is illegal. You can write:<br /><br />Null v1 = null; // not very useful <br />(T | Null) v2 = null;<br />(T | Null) v3 = new T();<br /><br />Now, v3.foo() is illegal unless foo() is method of Null (such as ==). You cannot get an NPE. <br /><br />It might be nice to have a construct like<br /><br />ifNonNull {... assume v3 is T ...} else {..}<br /><br />To safely unpack the value. Or general pattern matching.<br /><br />Which brings me to your comment: is the difference vs. Maybe only syntactic? No. The Maybe approach requires you to wrap T values in a Maybe if a "null" result is a possibility. The other approach doesn't.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-34150728423547622052009-05-28T07:58:20.570-07:002009-05-28T07:58:20.570-07:00Re: languages w/o null.
The Maybe solution is one...Re: languages w/o null.<br /><br />The Maybe solution is one possibility. An alternative is to have the type system enforce non-nullness.<br /><br />So null is not a member of a reference type T. If you want to use null, you need to declare the type as:<br /><br />T | Null<br /><br />This is perhaps more natural for programmers in the mainstream tradition - but not completely natural. We considered such a scheme back in the early 90s for Strongtalk, but were too conservative to go with it.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-16415667827073718352009-05-28T07:44:18.605-07:002009-05-28T07:44:18.605-07:00Well, conceptually speaking, *every* type in Java ...Well, conceptually speaking, *every* type in Java is nullable, which can be considered as everything being wrapped in Option by default. If you think about it though, this really negates a lot of the benefit of a dedicated Option type. Making `null` a real object (like `None`) would be nice, but only a marginal benefit over conventional null. I could make the argument that the transparency of Java's nullability is really what causes all of its NPE-related problems.Daniel Spiewakhttps://www.blogger.com/profile/17323566514229790079noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-21642857493537053502009-05-28T07:21:54.038-07:002009-05-28T07:21:54.038-07:00This might help clear things up: http://www.scala-...This might help clear things up: http://www.scala-lang.org/docu/files/api/scala/Option.html<br /><br />In Java terms, you have an interface Option parameterized with type A. This interface has exactly two implementations: Some and None. None is a singleton representing the absence of a value. Some represents exactly one value of the parameterized type. So, any time you want to have a "nullable" value of type String, you need to declare it explicitly in the return type Option[String].<br /><br />In order to do this effectively, the type system does need to support covariant type parameters (Java does not, but Scala does) and a bottom type (`Nothing` in Scala). It's also helpful to have sealed inheritance to prevent an unbounded hierarchy under Option.<br /><br />This is a *very* common pattern in functional languages, which do not support null as a general rule. Haskell has the Maybe ADT, which instantiates to either `Just a` or `Nothing`. IIRC, ML uses `Option`, but it might be `Maybe`. Either way, it's the same idea.<br /><br />The nice thing about this is you can leverage the type system to prevent NPEs at compile time, as well as leverage monadic operations to chain computations together (imagine C# or Groovy's ?: operator on steroids).Daniel Spiewakhttps://www.blogger.com/profile/17323566514229790079noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-84279257843860337002009-05-28T06:00:04.216-07:002009-05-28T06:00:04.216-07:00On char, my idea would be exactly NOT exposing it;...On char, my idea would be exactly NOT exposing it; char's binary representation could be opaque. It could just have an API allowing conversions in a more civilized way, e.g. with a method that queries the maximum integer value (implementation dependent) that can be converted into a char without loss of bits.<br /><br />There are more problems with char. While for some uses you want 32-bit chars, some people go to the trouble of implementing things like XML parsers over raw byte[] strings, because it's much faster when Unicode is not an issue and the encoding fits in 8 bits. Then an OO design demands a hierarchy of char types of different capacities, or just to pick 32 bits and forget about efficiency. Even Java's 16-bit chars are a significant memory overhead for applications that make zero use of Unicode.<br /><br />On the rest... I didn't know Resilient Smalltalk, but from the <A HREF="http://www.daimi.au.dk/~marius/documents/andersen2004esug.pdf" REL="nofollow">paper</A>, it's certainly not an "efficient" language in terms of raw speed (it's even interpreted), seems more focused on other factors like low resource usage and safe access to resources like memory and I/O. Not very relevant to the discussion IMHO; when I say "performance" I mean "in the same ballpark of C". But, I know other examples of OO/managed languages achieving that performance for low-level systems programming: JikesRVM, Maxine, Squeak, Singularity, BulletTrain, etc. But they usually resort to either some bootstraping mechanism, or unsafe language/bytecode extensions, or a boatload of specific compiler tricks to produce lightweight types and low-level operations (even sun.misc.Unsafe has a lot of that). [The paper <A HREF="http://domino.research.ibm.com/comm/research_people.nsf/pages/dgrove.vee09.html" REL="nofollow">Demystifying Magic: High-level Low-level Programming</A> is a great review of these techniques.] I just don't put such solutions in the same ballpark of an "intrinsically efficient" language. And these solutions have tradeoffs... in JikesRVM, for example, there are anotations to extend the Java language semantics, so you can declare e.g. an @Unboxed class that has no object header and controlled field layout. This is indistinguishable from having a 'struct' type in the Java typesystem, except that this type construction is not implemented by the language but rather by a special compiler (which means that it's not type-safe from Java's POV, e.g. javac won't complain if you synchronize on some @Unboxed object, although it has no monitor).<br /><br />I try to keep an open mind, but I also think that there is a reason why some languages are mainsream and others are not; Java's great balance of high-level features and performance (for 1995 anyway) was critical to its success. If Sun had designed something like Ruby, I would probably be still hacking applications in C++. And the "existence proof" is not the only valid argument in such discussions, but it's certaily the only argument that is inquestionable and definitive - if somebody gave me that kind of proof, I would happily shut up and stop whining and trolling about the limitations of pure OOPLs.<br /><br />P.S.: The only "pure" language design that impressed me performance-wise was Haskell with its GHC compiler. But that's a very different domain (functional language; zero dynamic features; massive dependency on closed-world compilation; and unfortunately, a hideously complex typesystem that killed its momentum and any chance of significant adoption). But perhaps there are some lessons to be learned/copied there.Osvaldo Doederleinhttps://www.blogger.com/profile/05264918260779798314noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-28159966046723664902009-05-27T20:43:13.905-07:002009-05-27T20:43:13.905-07:00Daniel,
I am doing an extension of Java so I need...Daniel,<br /><br />I am doing an extension of Java so I need to deal with null. But for a completely different language not having null may well be a good option.<br /><br />Howard.hlovatthttps://www.blogger.com/profile/07048859648718746436noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-69201287394029774842009-05-27T20:40:53.801-07:002009-05-27T20:40:53.801-07:00Thanks Gilad, no your solution is the same as I wa...Thanks Gilad, no your solution is the same as I was thinking of doing (and the same as Scala).<br /><br />Thanks for replying,<br /><br />Howard.hlovatthttps://www.blogger.com/profile/07048859648718746436noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-9844381800725292422009-05-27T19:18:36.263-07:002009-05-27T19:18:36.263-07:00Actually, if you're designing a new language from ...Actually, if you're designing a new language from scratch, I would recommend eliminating null altogether. You need a slightly more robust type system, but it's worth it all around.Daniel Spiewakhttps://www.blogger.com/profile/17323566514229790079noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-11182097138682813332009-05-27T18:58:17.894-07:002009-05-27T18:58:17.894-07:00Howard,
Since ia[1] =x is just a sugar for ia.s...Howard,<br /><br />Since ia[1] =x is just a sugar for ia.setIntElement(1, x), (assuming ia is an int[]) the question is what does the unboxing from x to an int do - especially when x is not an int, or something compatible with int. Say, if x is a String.<br /><br />Of course, this shouldn't happen. It would be a compile time error.<br /><br />Which leads to the general conclusion that null is not a member of Value or any subclass, such as int. Which is what I think you were saying. However, null is an object - it is just unique.<br /><br />Hence the unboxing routine doesn't pay the penalty of testing for these situations.<br /><br />But null gets compiled into the same machine code it always does, which is what I was trying to say.<br /><br />Feel free to let me know of other possible holes/oversights.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-20676943432362722262009-05-27T17:36:48.798-07:002009-05-27T17:36:48.798-07:00Gilad,
You said: "Null is easy. Pretend it's an o...Gilad,<br /><br />You said: "Null is easy. Pretend it's an object, compile as usual." Can you enlighten me, I thought they would be hard. EG:<br /><br />int[] ia = new int[1];<br />// ia points to a packed int array not an Object[]<br />ia[0] = null;<br />// Now I need ia to point to an Object[]<br /><br />You could do something like this:<br /><br />class IntArray {<br /> int[] intValues;<br /> object[] objValues;<br />}<br /><br />and<br /><br />int[] ia = new int[1];<br /><br />gets translated to:<br /><br />IntArray ia = new IntArray();<br />ia.intValues = new int[1];<br /><br />And use intValues if there are no nulls, otherwise use objValues (and switch from intValues to objValues if a null is added). But it isn't ideal and every access needs to check if intValues is null, i.e.:<br /><br />int i = ia[0];<br /><br />Gets translated to:<br /><br />if (ia.intValues == null) { throw ... }<br />int i = ia.intValues[0];<br /><br />Therefore my current thinking is to have classes that are value types that null cannot be assigned to.<br /><br />I ask because I am interested in making immutable types in my extended compiler (<A HREF="http://pec.dev.java.net/nonav/compile/index.html" REL="nofollow">PEC</A>) use primitives. Issues like the above seemed hard to me.<br /><br />Thanks in advance for any hints,<br /><br />Howard.hlovatthttps://www.blogger.com/profile/07048859648718746436noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-24806006257033962582009-05-27T15:57:13.825-07:002009-05-27T15:57:13.825-07:00Abies,
Null is easy. Pretend it's an object, comp...Abies,<br /><br />Null is easy. Pretend it's an object, compile as usual.<br /><br />As for having a single instance for a given integer - the point is, you can't tell.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-91355047008076015362009-05-27T15:54:37.623-07:002009-05-27T15:54:37.623-07:00Osvaldo,
Couldn't disagree with you more.
Wrt ch...Osvaldo,<br /><br />Couldn't disagree with you more.<br /><br />Wrt char - if you expose the representation, you are hosed. That is fundamental. The other issues you mention are easy to handle.<br /><br />One could of course dispense with char altogether. The point was to change the language as little as needed (as the post says explicitly).<br /><br />I agree there are niches where even Java is less efficient than C or Fortran. I said nothing about being more efficient than Java (though I don't necessarily concede the point either).<br /><br />While I don't feel the least bit obliged to provide you with an existence proof of a pure OO language as efficient as Java, others have pointed out Scala.<br /><br />As for "one simply doesn't implement that kind of stuff in a pure OO language" - speak for yourself. <br /><br />Lars Bak's Resilient Smalltalk was used to write device drivers for embedded software for example. Not toys, not something inefficient - the real deal.<br /><br />A language that lets you build nice abstractions can even make byte array manipulations pretty palatable.<br /><br />So I'd suggest keeping a more open mind. Programming languages are a lot more interesting than the mainstream.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-49460191795439104912009-05-27T15:32:27.300-07:002009-05-27T15:32:27.300-07:00Alex,
1. I have not made any proposal to change J...Alex,<br /><br />1. I have not made any proposal to change Java in any way. The post says that quite clearly. Alas, people don't read very carefully. I have no interest in fixing Java unless someone pays me to do so. The best thing to do is simply to move on to more advanced languages.<br /><br />2. This came up in an earlier comment. I think that given the proposed changes, most people would not be able to tell the difference. It could be just as performant and just as successful as it actually was.Gilad Brachahttps://www.blogger.com/profile/17934280339206214042noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-70963269682379233322009-05-27T11:12:58.993-07:002009-05-27T11:12:58.993-07:00[Devil's Advocate mode...]
The example of a c...[Devil's Advocate mode...]<br /><br />The example of a char class looks weak, because we could have just a better spec - IMHO the problem is not that char is primitive, the problem is that the JLS says that char is an IntegralType complete with a public numeric value range, subtytping (int>char), etc. There are other design options, like not having any char type at all, implementing java.lang.String and friends with short[] (that could be later changed to int[]); programs would use a String of length 1 to hold individual characters (e.g. like Sun's own JavaFX Script language does now).<br /><br />The discussion about OO vs primitive types should really start with this challenge: name at least one pure OOPL that doesn't exhibit any sigificant performance penalty over languages with primitive scalars/arrays. And don't fool me with high-level application benchmarks; I want that top performance in math/array microbenchmarks, or real-world low-level algorithms like data compression, video encoding, network stacks, etc.<br /><br />The fact is, in Java even with primitive types we still have significant performance limitations for many niche uses, because we don't have features like lightweight objects (value types / structs / tuples), by-value object fields and arrays, fine control over layout (e.g. alignment) and other typesystem delicacies. For some programs these features would allow faster Java code, for others it would allow MUCH faster interfacing with native code that mandates specific data layouts. If you're writing, say, a OpenGL binding library or a PureJava DBMS, the result is very ugly NIO code that manages complex data structures in byte buffers. A high-level OO view of that data cannot be offered without some cost (copying/marshalling data from buffers to objects and back).<br /><br />Now if the argument is that a high-level OOPL shouldn't be optimized to write those low-level algorithms, then the problem is the whole strategy of the Java platform with its "Pure" mantra. The Java APIs themselves use native code only as a last resort; and for anything that's not in the JRE, say a JavaEE container, it's been many years that using a single byte of native code is considered heresy. But a JavaEE container needs many low-level components like XML parsers, protocol handlers, JMS connectors, database drivers, loads of resource management (several types of pools and caches), etc. One just doesn't implement that kind of stuff in a pure OOPL. I don't say that is impossible, but so far there are no such implementations to prove me wrong.Osvaldo Doederleinhttps://www.blogger.com/profile/05264918260779798314noreply@blogger.comtag:blogger.com,1999:blog-2447174102813539049.post-75560961186842509542009-05-27T11:11:31.077-07:002009-05-27T11:11:31.077-07:00The Javalobby link to your entry is "Would Java Be...The Javalobby link to your entry is "Would Java Be Better Off Without Primitives?". In that vein, I'd like to make two points:<br /><br />1. We can all agree the answer to that question is yes, because a type system split between value types and reference types is injurious. There is no need to think in terms of "getting rid of primitive types", since that attracts a more hysterical reaction of an utterly pointless variety - primitive types (and checked exceptions, and raw types, etc) aren't being removed anytime soon.<br /><br />2. Just because the language would have been easier to learn and use without primitive types, it does not follow conclusively that the language would have been better off without them. Would it have been adopted so enthusiastically in the late 90s had it disdained familiar C-style primitive types and insisted that 'everything is an Object'? I believe the answer is no. (Especially when people realized that boxing and unboxing occur, and that the reference types for integers et al are rather limited.) Two steps forward, one step back.Alex Buckleyhttps://www.blogger.com/profile/12559932534649195508noreply@blogger.com