23 ms·
An Object-Oriented Language for the '20s
- toolslive 6y agomultiple inheritance. c++ : both sides can bring state. has diamond issues. Java : one side can bring state. other just signatures. too restrictive. What you want is: both sides should be able to bring behaviour, but only side can bring state. (iirc, ruby does it like that... )
- howinteresting 6y agoOne of the fundamental issues with OO subtyping continues to be how variance works. I wish the author spent more time talking about how they envision variance. My other big problem with OO is the spaghetti code that results once you start mixing overloads and hooks across superclasses and subclasses. The OO model really seems to be a little too low-fidelity overall.
- ar-nelson 6y agoI didn't really think about variance while writing the examples; I assumed it would just work the way it does in Scala and Kotlin (explicit variance annotations). I do wonder if that's necessary, though--in theory, the compiler could infer variance from how you use the type parameters, which is in a similar spirit to the rest of the language. What do you think are the major problems with variance in OO?
- howinteresting 6y agoExplicit variance, especially for types, is just really confusing. Implicit variance has the risk of breaking APIs or overpromising a particular variance without developers realizing. If you have subtyping you need to think about variance. That's led me to believe that subtyping's simplicity is deceptive, and that it should be avoided as much as possible. (Rust has subtyping but only for lifetimes, and it's confusing enough there.)
- Hermel 6y agoContrary to popular belief, OO is not primarily about inheritance. That’s one of its distinct features. But experienced software engineers tend to prefer composition over inheritance. OO is about encapsulation and about putting conventionally functions close to the data it operates on.
- SomeHacker44 6y agoWhich begs the question: why use OO at all if you prefer composition? I personally am "over" OO, even though I have been doing OO professionally for decades.
- invisiblerobot 6y agoExactly. Polymorphism is the killer feature and it's expressed more simply in functional languages like Clojure.
- blowski 6y agoOver the last 30 years, object oriented languages got more attention, more funding, more companies using them, more jobs available, more developers, more education resources, more libraries. In short, I use OO because everyone else does. Now in my 40s, I’m not going to change merely because another language is more expressive. But yeah, if I could do it all over again, I’d probably choose Clojure.
- mikewarot 6y ago>why use OO at all if you prefer composition? OO is a way to bundle a structure with the methods to manage it. Inheritance is a way to manage the need to customize an object. Composition is a way to bundle objects. Why wouldn't you do both? That's what Delphi did back in the 1990s when they built the Visual Component Library. (VCL) You build your forms in the GUI builder, which composed a form object out of various components which were all eventually derived from tObject. It still lives on, and Lazarus implements something similar for Free Pascal.
- throw0101a 6y ago> OO is about encapsulation and about putting conventionally functions close to the data it operates on. According to Alan Kay, the essential ingredients of OOP are: Message passing, Encapsulation, Dynamic binding. > OOP to me means only messaging, local retention and protection and hiding of state-process, and extreme late-binding of all things. It can be done in Smalltalk and in LISP. There are possibly other systems in which this is possible, but I’m not aware of them. * https://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_kay_oop_en https://userpage.fu-berlin.de/~ram/pub/pub_jf47ht81Ht/doc_ka... * https://medium.com/javascript-scene/the-forgotten-history-of-oop-88d71b9b2d9f https://medium.com/javascript-scene/the-forgotten-history-of... * https://softwareengineering.stackexchange.com/questions/46592/so-what-did-alan-kay-really-mean-by-the-term-object-oriented https://softwareengineering.stackexchange.com/questions/4659... Though it's recognized that Simula invented objects: * https://www.hillelwayne.com/post/alan-kay/ https://www.hillelwayne.com/post/alan-kay/
- transfire 6y agoCLOS (https://lispcookbook.github.io/cl-cookbook/clos.html https://lispcookbook.github.io/cl-cookbook/clos.html)
- throwaway4good 6y ago"First, a few obvious, non-negotiable things any new OO language should have: ..." Well, that's like your opinion, man ...
- throwaway4good 6y agoPersonally I would drop the static type system and reinvent Self.
- agumonkey 6y agotime to dust it off and sell it as new ?
- throwaway4good 6y agoYeah - I think the kids are ready for that.
- agumonkey 6y agorebrand it `selfie`
- protomyth 6y ago...and steal the Soups from NewtonScript on the way.
- sriku 6y agoErlang is perhaps the best OO lang out there that doesn't look like one but it's principles are the heart of OO. PS: I admit I lost the author at "scala is my favourite language" and so am biased.
- hderms 6y agoScala can be one of the most productive, elegant, reasonably performant languages to work in or it can be the opposite of all those. When done right it's amazing but the language is complex enough to permit some questionable choices
- blackrock 6y agoLife is too short to be forever tied to Java. This will be Scala’s downfall. Elixir looks like the more promising approach. I love its pipe forwarding operator.
- zokier 6y agoscala-native exists?
- dw-im-here 6y agoLife is too short to reimplement libraries and have them battle tested. As a scala dev I find this a very weak argument
- weatherlight 6y agoExcept like the BEAM/erlangOTP(and by extension Elixir) is older than the JVM, and arguably as battle tested, if not more....
- dw-im-here 6y agoDo you know the difference between a library and a runtime?
- alkonaut 6y agoI love how rust does interfaces (traits) and allows implementing outside the type. It feels much more natural to create a subsystem on the side without tangling it into other subsystems. E.g. to create a separate rendering subsystem for a game entity you simply impl Drawable for MyEntity void Draw(MyEntity self, Canvas... Which feels quite natural compared to anemic-entity ECS or naive Composition-over-inheritance like so: class MyEntity { EntityDrawingComponent drawer EntityMovingComponent mover; and of course, over the standard Java/C# OO way class MyEntity : Drawable, Movable, ... void Move(Vec..) void Draw(Canvas..) With this type of declaration, I'm forced to mix the code for my different subsystems making it not just likely but inevitable that someone eventually ties these subsystems together. In general, if I were to design a "better" OO language now; i'd make sure to make it almost not OO at all. I'd allow subclass polymorphism, but no virtual methods or classes. Only interfaces/traits and abstract classes. I'd very clearly separate data types from identity types at the language level (which aren't just a difference betweeen stack and heap as with C# structs and classes). I'd want the bare minimum of functional niceness: enumerations and pattern matching which check for exhaustion. Having that in a lanugage easily lets the developer use different implementation for two completely different cases: open and closed polymorphism sets. OO is great when you don't know what variants might exist, but it's useless when you DO want to control it. If I as a developer know that the set of Payment options are Credit/Cash/Invoice - then I want it exhaustively checked. I deliberatel do not want to leave that open. I want to be able to switch on the closed set of 3 cases, and be warned if I fail to check a case. I want to be able to do this without inverting the logic like and calling into the unknown like paymentMethod.HandlePayment(order).
- deleted 6y ago[deleted]
- lukevp 6y agoI wonder if you could implement this all within a linter on top of Rust or some other language? Some of your asks already exist at that level (for example, TypeScript autocomplete in VS Code knows which enums you haven’t checked in a switch, and it also knows if a property has been verified that you’ve narrowed via a type union, so perhaps you could extend this to enforce coverage of switch statements?
- brianberns 6y agoF# is functional-first, but also fully supports OO. It’s a good balance for the 20’s, or any other decade.
- dfgdghdf 6y agoAgreed. F# lacks the HKT that the OP calls for, but it is possible to write plenty of pragmatic functional code without them. They might land soon though.
- dunefox 6y agoIt seems like a great language; I'm going to look into it this year - maybe for advent of code or some data science/ML stuff. For some annoyances there is F#+: https://fsprojects.github.io/FSharpPlus/ https://fsprojects.github.io/FSharpPlus/
- PaulHoule 6y agoBring back Turbo Pascal!
- Graffur 6y agowhy no nulls? and no exceptions? I am no language designer but as a user they seem ... usable.
- noir_lord 6y agoIf you have nulls (or nullable types) then you end up checking for them everywhere (in every codebase I've seen anyway - keeping them on the boundaries only works if that's practical and the language always does it for it's standard libraries etc). Additionally you can no longer say Thing is Thing, it's always Thing or null - which results in special handling if (foo === null){} everywhere and when you don't boom NullPointerException. Exceptions cause problems in other ways (especially when they are allowed to escape up the stack), business logic shouldn't be handling FileNotFoundException that was thrown 6 layers away.
- skwirl 6y ago>Exceptions cause problems in other ways (especially when they are allowed to escape up the stack), business logic shouldn't be handling FileNotFoundException that was thrown 6 layers away. So instead all 6 layers should have to know about it in addition to business logic? In most cases you can't really ignore the fact that a file didn't exist in your business logic.
- dkjaudyeqooe 6y agoThat's an argument for exceptions. If they shouldn't be handling it they shouldn't be catching it. If they're the highest level why didn't the other 6 layers handle it? It's easier to be adaptive with error handling with exceptions, and who's going to (correctly) test for all possible errors on every call?
- Graffur 6y ago> If they're the highest level why didn't the other 6 layers handle it? I would have the same question.
- larzang 6y ago
- wongarsu 6y ago> But, if we made a new statically-typed OO language from scratch in 2021, something in the vein of Java or C#, taking everything we've learned from functional programming and a decade-plus of scathing OO criticism, could we fix this? Modern C# is already a statically-typed OO language that takes lots of lessons from functional programming and decades of scathing OO criticism (after all it's basically "Java done right"). And of course there's also Scala and F# if you want something more functional than OO. I think the author summarizes it best at the end: "I realize there's not much need for a language like this—the space is crowded enough as it is—but it's fun to dream.".
- vips7L 6y agoIMO Java has learned from the mistakes of C# as well. See Task<T> vs Loom's virtual threads. Brian Goetz (the Java language architect) himself even said they're waiting to see how C#'s nullable types plays out before considering them in Java.
- jayd16 6y agoAsync/await and implicit thread scheduling solve different problems. Loom is more about catching up to Go and Kotlin, no?
- anoncake 6y agoNot Kotlin, AFAIK Loom is about the JVM.
- tybit 6y agoThey mostly solve the same problems, albeit in very different ways. Loom is primarily about making threads cheaper, async await is primarily working around threads being too expensive.
- jayd16 6y agoImplicit scheduling like Loom doesn't solve the problem of working with thread based synchronization such as what you often see in UI. You want a paradigm that lets the user easily define what runs on the main/ui thread and what runs else where. Loom's goal is implicit suspension without thinking about threads. Its a different use case. Backend engineers seem unaware of the problems async/await solves.
- vips7L 6y agoPersonally I'd keep exceptions. Result<T> is boiler plate hell.
- dfgdghdf 6y agoNot if you have language support for monads / do-notation / computation expressions. Many "problems" that people have with functional programming occur because they are trying to use FP techniques in a language that isn't really equipped for functional programming (JavaScript, C#, Java, Go...).
- PaulKeeble 6y agoHaving used Go a lot recently the err!=nil boilerplate is only marginally worse than the monad approach which ends up with a lot of match statements. Where monads work better is chaining calls together, but at the cost of the of choice how to handle the errors. Exceptions end up being an elegant way to represent this, you can choose how much you handle and where and match against the types of errors. Everything else I have tried has been worse, forcing me to handle errors I don't care about at that point in the code with a boilerplate response to send it upwards, something exceptions do automatically. I don't get more robust code with explicit error handling I get more verbose code for errors I can't do anything about. In practice it also changes the interface of my methods far more with maintenance and propagates error handling code throughout.
- jstimpfle 6y agoThe key is to collect the errors in the subsystem where they originated and to handle them at an appropriate time. Try not to bubble up errors. Many subsystem interactions can be unidirectional. If an error occurs, it is stored right there. The caller might not even care. The situation can be handled later.
- ivan_gammel 6y agoAppropriate time is quite often at the end of the unit of work. Let’s say, your microservice is doing some interactions with database and querying another services. If an unlikely I/O error happens, DB will take care of the uncommitted transaction and your service is just fine with returning HTTP 5xx. Probability of this happening and impact of not implementing error handlers all over your stack are very low. Since the majority of developers are not writing perfect programs, they will not spend the money/time to avoid this risk. Exceptions may not help writing a better program, but they are practical enough to be supported in the language.
- FpUser 6y ago>"Object-oriented programming is out of fashion now" Start with this one. It is not out of fashion. Supported by many languages. Also languages do not exist to be cool and admired. They are just a tools that help build things. Concepts like OOP or any other style are not universal. Good for doing some things, not so good for doing other things. Hoping that some concept will magically solve world's problems is very naive at least.
- wvenable 6y agoComplaining about OOP is like complaining about vaccines. The positive results of OOP are so ubiquitous that it's invisible to people. Instead the few negative reactions get all the focus.
- jstimpfle 6y agoDepends on what you mean by OOP. If you mean the concept of handles, messages, and fault isolation, then OOP is the right way to structure many solutions. If you're talking about classes, methods, inheritance, and so on, then it's just a syntax equivalent of training wheels. If you want to progress to biking downhill at full speed, most of this needs to come off at some point since the structure is not suitable for more complex situations. This kind of OOP strongly encourages componentization at the smallest level, much much more than is beneficial from an organization standpoint (subsystems).
- FpUser 6y ago>"If you're talking about classes, methods, inheritance, and so on, then it's just a syntax equivalent of training wheels." Everything above microcode is. Abstractions / paradigms when applied adequately help to see the forest beyond the trees.
- jstimpfle 6y agoI've never thought about it this way. To me it's more like, many different paradigms and cleverness are the forest and as well the trees. When I see an object-oriented codebase that makes me jump between 5 or more files to understand the simplest codepaths (because inheritance), and that is not browseable without a properly setup IDE and jump-to support (because of heavy namespacing and non-telling method names), it makes my shy away. On the other hand for example, larger open source projects written in C are often really easy to read. Local ("coherent") code paths, fully qualified function names in calls, no extra foo that gets executed implicitly on data data declaration or cleanup. Nothing hidden, every line just works to solve the actual problem.
- seanalltogether 6y agoAm I wrong or is OP describing most of what swift currently offers. Optionals, extension where syntax, Result<> monads, exceptions collapsed to a single line with try? syntax, safe casting with as?, etc...
- brobdingnagians 6y agoSame with kotlin. It appears that most of the advances are really really great and emerged in a wave in the '10s. We are a decade ahead of the curve ;) I think doing away with checked exceptions was a definite benefit in that direction too.. Having higher kinded types and type classes like Haskell would be nice though. I think there are definitely things in the article which could be even better, but we've definitely moved that way, and the next generation of language designers will probably have even more insight into how to elegantly combine those features as well.
- pjmlp 6y agoOr OCaml, Eiffel, Sather,...
- virtualwhys 6y ago> Having higher kinded types and type classes like Haskell would be nice though. Don't have to leave the JVM, already there in Scala. And Kotlin Arrow may get merged into the compiler, so Kotlin may have first class support for these language features one day...
- hedora 6y agoScala uses type erasure to preserve compatibility with the JVM. No thanks. I want the compiler to statically verify my types, and then optimize based on that. At some point, I realized Java code tends to have many more runtime type errors (in particular, NullPointerExceptions and ClassCastExceptions) than similar C++ code (segfaults). Things like rust should be even better than C++, but that’s practical largely thanks to performance optimizations from llvm. Other than Java compatibility, I don’t see any advantage to the JVM at this point.
- mikewarot 6y agoIt seems to me that you could do almost everything you want (except for the immutable thing) in Free Pascal. Pascal doesn't have the kingdom of nouns problem. It supports good old fashioned procedures and functions. Pascal can deal with nulls in strings, because we always know how long they are. Or perhaps you meant null pointers. Pascal avoids unnecessary pointers, but supports them in a sane manner when you need them. Pascal can deal with multiple inheritance in a sane manner, by composition. Objects can have other objects as properties, and it just works... no weird restructuring of everything horror stories I've heard about in C++, etc. Free Pascal has generics there are libraries that let you do dictionaries and lists and trees of your type <T>. I disagree about exceptions... proper handling of exceptions is a good thing. A function should always return the type you expect, not some weird value you have to test for. As far as "pattern matching" I assumed you were talking about regex (which can be addressed in a library)... but you're talking about RTTI, or "reflection" where you can get type information at runtime, which is a thing in Pascal and many other languages. I don't understand the obsession with immutable variables. [Edit: I think I understand... in Pascal, parameters are passed by value as the default, but can be passed by reference, it depends on how you declare the function or procedure. It has nothing to do with variables that you can't assign new values to, if I'm correct] Did I miss anything?
- mmazing 6y agoBut it's not a hot sexy * new * silver bullet for all of your problems.
- elteto 6y agoHave to disagree on exceptions. The return type is part of the function signature, it’s part of its contract. If a function can fail I want to see it right there on the return type and be forced to handle it on the spot. Exceptions are an invisible, out-of-band mechanism that will crash your program because you forgot yet another try...catch. Sum types with pattern matching are a much better approach for writing safe and robust code. The “proper handling of exceptions” panacea I keep hearing about sounds a lot like “OOP done right”... it’s supposed to exist, yet no one seems to know what it actually is.
- rini17 6y agoIt seems to me more a syntactic sugar than really tackling the main problem with OO: state that tends to get scattered into many interdependent objects, hard to manage, hard to refactor.
- mikewarot 6y ago>state that tends to get scattered into many interdependent objects, hard to manage, hard to refactor. Care to elaborate what you mean by that?
- rini17 6y agoOne example of "state scattered into many interdependent objects" is ORM. If someone wants to make new OO language from scratch, I believe trying to improve the relational database <-> OO language interface would be a good showcase.
- michaelbrave 6y agowhat the author is proposing sure sounds an awful lot like Swift to me.
- ajani 6y agoMost of what he mentions as features needed in this new language have existed in common lisp for a long time. CLOS.
- Traubenfuchs 6y agoSwift? Typescript? Both fairly new and object oriented. Go? Somewhat object oriented.
- deleted 6y ago[deleted]
- ibraheemdev 6y agoIn what way is Go object oriented?
- gher-shyu3i 6y agoIt has everything except explicit inheritance, and embedding covers some aspects of inheritance.
- dale_glass 6y agoCan we get rid of 'sealed'? I really hate that keyword. Sometimes there's a good reason for it, sure, but sometimes it's used gratuitously, and then I have to work around it for no good reason. Eg, in C#, SqlDataReader is sealed. Which means I have to do this: reader.GetString(reader.GetOrdinal("FirstName")); When I just want to skip the verbosity and be able to do this: reader.GetString("FirstName"); So the logical thought there would be just to inherit from it, add an extra overload to those functions, and life got more comfortable, plus you can still pass it to anything that wants a SqlDataReader. But oops, you can't do that, because somebody at Microsoft decided the interface for this thing was perfect is not to be messed with. If there's something that really gets me annoyed is when I run into a limitation that seem completely arbitrary but intentional. It's not there because of the technical limits of the hardware, or because the compiler isn't clever enough, but purely because somebody intentionally decided 'nope, you don't get to do this particular thing you can do all day otherwise'.
- RedNifre 6y agoYou could do this with an extension method, no inheritance required.
- dale_glass 6y agoOh, that's very nice, and just the kind of functionality I've been wanting for some time. That was something I was recalling from a very old project though. I'm not sure right now when that was exactly. Maybe it wasn't in the language yet at the time, or was a new feature still and I didn't find about it, or it wasn't in Mono yet. I've not done C# in a long time, so no doubt I missed a lot of developments.
- jasode 6y ago>Can we get rid of 'sealed'? I really hate that keyword. Sometimes there's a good reason for it, sure, but sometimes it's used gratuitously, and then I have to work around it for no good reason. Fyi... this stackoverflow Q&A has opinions on why 'sealed' is a rational default for the person who designed the class: https://stackoverflow.com/questions/268251/why-seal-a-class/ https://stackoverflow.com/questions/268251/why-seal-a-class/ It doesn't mean the programmer thinks the base class is "perfect". Instead, the author has not deliberately designed the particular class for inheritance and the "sealed" keyword expresses that.
- fouc 6y agoI'm fine with implementing another static Object-Oriented language, but please learn from some of the best non-static Object Oriented languages out there like Ruby and to a lesser extent Erlang/Elixir.
- hedora 6y agoAlso, C++ has solved many of the issues mentioned in the article (especially post C++11). It has not solved the “minimum set of primitives that make OO tenable” problem.
- Kranar 6y agoWhich problems from the article are you referring to? C++ is likely the worst OO language in common usage and C++ developers rightfully avoid using its native OO functionality as much as possible. They will literally jump through hoops and write tons of additional boilerplate code to avoid exposing the language's OO functionality (doing what C++ developers call type-erasure). C++11 didn't improve OO in C++, it gave programmers many features to avoid having to use it altogether.
- AnimalMuppet 6y agoI have literally never seen someone program C++ that way. I mean, it's probably true that some people somewhere are doing that. But saying "C++ developers rightfully avoid using its OO functionality as much as possible" seems like a complete distortion of the actual situation.
- Kranar 6y agoThose some people would be the authors of the standard library who use type erasure for std::function, std::string_view, std::span, std::any, std::ranges, std::fmt, the new class of pmr memory allocators use type erasure, the upcoming coroutines are built on type erasure. Common C++ libraries like boost have an entire library dedicated to type erasure: https://www.boost.org/doc/libs/1_75_0/doc/html/boost_typeerasure.html https://www.boost.org/doc/libs/1_75_0/doc/html/boost_typeera... Facebook's Folly library also provides type erasure functionality: https://github.com/facebook/folly/blob/master/folly/docs/Poly.md https://github.com/facebook/folly/blob/master/folly/docs/Pol... Google's Abseil is full of type erasure: https://abseil.io/ https://abseil.io/ Here is Adobe's C++ library for type erasure: https://stlab.adobe.com/group__poly__related.html https://stlab.adobe.com/group__poly__related.html And here's a talk by Sean Parent about how Adobe uses type erasure to emulate runtime polymorphism without using C++'s native OO features: https://www.youtube.com/watch?v=QGcVXgEVMJg https://www.youtube.com/watch?v=QGcVXgEVMJg I suppose these are just some people somewhere...
- gigatexal 6y agoUgh. Another reminder that high level OO languages and things make my head hurt.
- nesarkvechnep 6y agoNo mention of message passing? Shame.
- ar-nelson 6y agoHow does message passing work with a statically-typed language? (Genuine question, not criticism.) My understanding is that Smalltalk-style message passing's main advantage is that it allows handing or proxying unknown method calls, but unknown method calls are forbidden in a static type system.
- weatherlight 6y agoMake objects Actors (as per the Actor model of computation). You don't call methods on objects, you pass a message to their mailboxes, Objects then choose how to process those messages. To do this though, messages would have to be immutable.
- ar-nelson 6y agoGiven a static type system that constrains the kinds of messages you can send, their arguments, and their response types, how is this meaningfully different from normal method calls? My understanding is that message-passing only starts to have interesting consequences when you do dynamically-typed things.
- weatherlight 6y agoyou could design the mailbox to accept all messages, how the object handles those messages is a separate concern, you could use something like multiple dispatch to then decide which method on the object gets the message. Gleam is a statically typed language on the BEAM, early implementations the messages between processes were not typed, Im not sure if that still the case. Pony is a OO language thats based on the Actor model that has a strong static type system, where typed message passing is central to the language.
- tomp 6y ago
- brokencode 6y agoI think this is really cool, and it elegantly brings together some pretty advanced features from FP and OO into one purely OO language. The only thing I’d like to see more about is how immutability would be handled, because that is harder than it sounds in OO. And for all of you saying this is basically just Kotlin or Swift.. do those languages have higher-kinded types or true multiple inheritance? Not as far as I can tell. And you could argue those aren’t needed, but that does mean this is a different language with potentially different pros and cons.
- fit2rule 6y agoAll of this can be done in Lua.
- enriquto 6y agowhy is OOP still a thing?
- AnimalMuppet 6y agoBecause it's useful.
- enriquto 6y agopeople use the strangest tools
- vanderZwan 6y agoRegarding the "Kingdom of Nouns", I always thought Lobster[0][1] had a really cute idea: x(a, b, c) and a.x(b,c) are equivalent. Don't know if that is original to the language, but it's where I saw it first. It only really makes sense with the other features of the language, though. (Also, I just discovered that it now targets WASM. Maybe I should give it another go!) [0] http://strlen.com/lobster/ http://strlen.com/lobster/ [1] https://github.com/aardappel/lobster https://github.com/aardappel/lobster
- ar-nelson 6y agoAuthor here: unified function call syntax is awesome but sadly out of scope for what I was trying to do with this language. I mention this in the "Class-based discoverability" section: for the sake of uniformity and IDE discoverability (arguably Java's killer feature that its successors have diluted), I'd want every value and function to belong to a class, which means every nonlocal method call should come after a dot.
- vanderZwan 6y agoThis already assumes that unified call syntax would inherently get in the way of that - do you have any reason to believe that? I mean, Lobster has classes, or at least something that it calls classes: https://aardappel.github.io/lobster/language_reference.html#user-defined-types https://aardappel.github.io/lobster/language_reference.html#...
- ar-nelson 6y agoTake Java as an example. In Java, there are no free functions. Every method belongs to an object or a class. So you couldn't write `f(a, b, c)` as `a.f(b, c)`, because `f` as a free function couldn't exist to begin with. Either it would already be `a.f`, or `f` would be a method of the current class or a static method imported via `import static`, in which case using the `a.f` syntax could deceive readers about what class `f` is a member of. That's what I'm going for with this language, for uniformity and discoverability. If you want to add a new method that takes type `A` as its first argument, you should add it as an extension method on type `A`.
- dw-im-here 6y agoI think this is a well written post, but I'm incredibly puzzled at eschewing scalas syntax for type parameters and instead having parentheses do double duty. Other than freeing up brackets for indexing what is gained from this? Other than that I actually think this is a language that deserves to exist so the ideas can be tried out in practice, if nothing else to influence the current OO languages to be better.
- acjohnson55 6y agoSquare brackets for type params is one of my favorite tiny details of Scala. Much easier on the eyes than angles, and since collections are explicitly indexes much less often, little is lost.
- raspasov 6y agoAn Object-Oriented language for the '20s: don't do it.
- maxekman 6y agoHow are Optional named arguments and Generics obvious choices for a new OO language? Good to have, sure, but obvious?
- booleandilemma 6y agoObject-oriented programming is out of fashion now What world does this person live in?
- deleted 6y ago[deleted]
- snidane 6y agoI'll bite. I believe the consensus for the 20s for error handling is to have both exceptions and error types (or just error pairs). Without exceptions the code starts to bloat up with various try's, ?s, unwraps, pattern matches on sum and option types and nonstandard do notations. You start writing a nice and simple code when prototyping, only to end up with unreadable piece of mess when productionizing and wrapping everything with error handling. Most modern languages which boast for not using exceptions have them anyway, but call them panics or aborts and don't provide first class support for them. I believe the next paradigm beyond OO and FP is data oriented programming. One could argue that it is what FP is, but modern FP means more Type Oriented programming than Functional Programming. In contrast with Lisp and APL family, which are also considered FP, but whole another class. OO gets lots is the kingdom of nouns, as the article points out. You often can't even use a stupid function without wrapping it in some class. Type programming makes a type for everything and gets lost in the kingdom of types. You often can't even start programming before you type your data or provide schema for it. In Data Oriented Programming, you try to limit the number of objects or types to minimum, such as simple linked lists (Lisp) or multidimensional vectors (APL, numpy, tensorflow), json dicts (python, jq), streams of text (shell), tables (sql) or primitives - strings, ints, etc. The big benefit is that you can start coding immediately without defining any classes or types and most operations are already defined for you in a performant way. Once you introduce your custom classes or types, you lose the benefit of carefully designed operations on the language primitives that allow you to stay within the algebra of those language primitives. Eg. in APL you have arrays and numbers and they combine in infinite amount of ways which have been carefully explored and designed over decades for very ergonomic use. I believe the future is to have small amount of versatile types, not to create languages which promote complexity by introducing tons of non-interoperable custom types.
- TeMPOraL 6y agoHard disagree on exceptions. Passing sum types types along with every call is annoying - in a good codebase, probably upward of 50% of your code might be returning some kind of Result/Expect type. Exceptions can be done right, and there are solutions to the main objections (implicit, hard to recover from) in various languages - but somehow nobody seems to have managed to put all of them in the same language. Here's what I want from a new OO language, exception-wise: - Checked exceptions only. Every function that can possibly throw, must declare what it throws. Supertypes may be used in declarations to cover a whole family of exception types. Every function must either handle or explicitly declare exceptions that can be thrown from its callees. This is to be baked into type system and enforced at compile-time. - If the language is driven with IDE use in mind, allow "auto" for checked exception declarations. Will cut down on line noise, at the expense of readability (as type deduction always does). But since exception declarations are resolved at compile time, you won't be able to make an actual mistake here. - A condition system, not exception system. Extend the out-of-band signalling mechanism to be used for arbitrary things, not just "exceptional situations". I.e. just as I can say `throw SomeError{someData, someMessage}`, I want to also be able to do e.g. `throw Progress{percentage, total}` to feed a progress bar that's declared few layers above in the stack (which would just execute its code and return control to the thrower; no stack unwinding). This is what you have in Common Lisp. - Stack winding, not just stack unwinding. Also from Common Lisp, I want the exception (condition!) handler to happen prior to stack unwinding, in a way that would allow me to truly recover from the problem and resume execution where the condition was thrown, or somewhere in the middle of the call stack, between the handler and the thrower. - Separating signalling, handling and recovery, both conceptually and in code. Again, from CL's condition system. A thrower throws an exception (condition), a handler decides what to do (or rethrows), and one of the things it can do is pick a "restart" declared down the call stack - then stack is unwound only to the point of that restart, and control resumes from there. Note the programmatic ability to choose a restart. Not 100% sure how to handle it in a type-safe way, but I believe it could be done. - All the other stuff from Common Lisp's condition system. So basically, a statically typed blend of C++, Java and Common Lisp, mashing together their best features into a coherent and powerful system.
- kidfrommars 6y ago
- deleted 6y ago[deleted]
- mangopi 6y agoYou basically want Go, but you haven’t learned it yet.
- lostmsu 6y agoI love C#, but they seriously fucked up Span<T> and Range by restricting them to 32 bit length, which by the time when the features were concepted was already extremely niche. Now language is very clunky to work with in ML/"big" data space. Technically, that is the fault of the runtime, which does not support 64 bit arrays, but naturally teams must be working together.
- deleted 6y ago[deleted]
- alfiedotwtf 6y agoBrain: haha why would they need a programming language for the 19OH THEY’RE TALKING ABOUT THIS DECADE
- ncmncm 6y ago"Object-oriented programming is out of fashion now" For reasons. So, no, we do not need a new language whose chief organizing principle is inheritance--a poor match for the majority of problems. We know better. In fact, we don't need a new language. We have lots of languages already, enough so that the few newer ones that have above-average merit are failing to attract enough users to become viable, and bad old languages (C, Javascript, Java, C#) maintain their lead. If you imagine your new language will be better than any of the already existing languages, think again. A language that doesn't exist has no flaws. Once it starts to exist, you will need to make choices. Sometimes the right choice will not be obvious, with valid arguments for both alternatives. Sometimes there will not be a "right" choice; each alternative leads the language in a different and objectively valid direction. And sometimes a previous choice will box you into the objectively wrong choice, later. For every existing language, those have all happened, over and over again. Languages are products of humans, and each is riddled with imperfections and compromises. That is the human condition. So, right now your language is perfect, like all others that don't exist. Make it, and it joins a large crowd of variously imperfect languages competing for painfully limited attention. Being wrong at the outset on the desirability of a new O-O language (with functional crossover features!), what are the odds it will be even nearly as good as any of the half-dozen best in its target category? Maybe a better choice would be to join in making the current best in that category more viable. That one will probably still fizzle--it is the natural fate of any language, save a miracle--but its odds are a hundred times better than yours. And, who knows? You might even choose right and make a difference.
- clankyclanker 6y agoIf you’re going to handle errors like Go: > Go and Rust provide two alternate approaches to error handling. Both treat errors as values, but Go uses multiple return values to return error states, while Rust uses a Result monad. Then they should consider fixing Go’s greatest oversight: the ability to make exceptions hard and crash your program. I don’t care if the error variable gets set, but I really care if it gets set again before I’ve reset it. That means an error has passed on unnoticed. If “—-hard-errors” could be a compiler flag, that would be perfect.
- deleted 6y ago[deleted]
- JulianMorrison 6y ago> Interfaces are a subset of classes. If you're thinking like Java. Go says: interfaces come after classes, not before. They describe the features you want, and any class can match them if it has the features. Therefore an interface is decoupled from the classes it matches.
- isaiahg 6y agoI've been writing a lot of go lately and it's making me a better programmer. Not just interfaces but methods too
- acjohnson55 6y agoOne of my favorite parts of functional languages like Scala and ML is the compact notation for defining algebraic data types. They provide an incredible amount of mileage for writing maintainable and reliable business logic. Scala 3 really nails this, IMO.
- cutler 6y agoIn the HN echo chamber OO may well be out of fashion but in the job market it's a different story.
- a0-prw 6y agoOh the humanity, and all the passengers! https://www.airships.net/hindenburg/disaster/oh-the-humanity-herbert-morrison-and-the-hindenburg/ https://www.airships.net/hindenburg/disaster/oh-the-humanity...