Settings

Theme

The Lobster Programming Language

strlen.com

387 points by openbasic 7 years ago · 170 comments

Reader

Aardappel 7 years ago

Hi, author of the language here.

Not a great time for HN exposure, as I just added a lot of new functionality, but none of that is documented yet :) But hey, all publicity is good publicity?

For those interested, some recent things that have been happening:

- Compile time reference counting. This does an analysis similar to the Rust borrow checker to infer lifetimes, but unlike Rust doesn't make the programmer jump through hoops.

- "Inline" structs: structs are allocated in their parent, and come at zero overhead compared to individual variables, which is particularly useful for Lobster's heavy use of 2d & 3d vector types.

- Multi-threading that uses separate memory spaces, meaning individual threads can run at max speed with no GIL overhead etc.

- A WebAssembly backend is being worked on.

- A lot of optimization work to make the language run faster.

For reference, it has been on HN before, as early as 2013 (https://news.ycombinator.com/item?id=5904430), but it has changed a TON since then (e.g. it was a dynamically typed language, now it is statically typed, with flow sensitive type inference).

  • kragen 7 years ago

    Hi! I might be an embarrassingly gushing fanboy about everything you do, so I'm probably biased here. (I wrote the FlatBuffers Wikipedia page, for example.) Lobster is pretty inspiring (despite not being nearly as radical as, e.g., Aardappel) with its lightweight lambdas and (like most of your work) a very minimal core language.

    Is there a comparison of different versions of Lobster somewhere? I'd like to be able to make statements like "My new language XYZ, unlike Lobster, is dynamically typed, resulting in difficulties such as plicplocpluc in developing the IDE" but different versions of Lobster now cover such a large part of the language design space that this is becoming difficult. For example, that statement doesn't make sense with respect to old versions of Lobster, which were also dynamically typed.

    • Aardappel 7 years ago

      Hah! Thanks a lot for the wikipedia article :)

      Yes, Lobster is meant to be a much more pragmatic language, for people like myself to actually get the job of making a game done :) Other languages of mine are much more research-y. Though I will say I think the type system and lifetime analysis are pretty novel actually.

      I'd like to think there's really only one Lobster, while older versions are still recoverable, they for practical purposes don't exist anymore :) Have you seen https://htmlpreview.github.io/?https://raw.githubusercontent... ? That actually contains some history.

      • repsilat 7 years ago

        Holy cow, are you the Quake Aardappel? That is a name I haven't heard in a long, long time...

        • Aardappel 7 years ago

          Yup, the one and only :) Do I know you as well?

          • repsilat 7 years ago

            Nah, just a forum lurker who had a folder full of mods and maps and engine binaries much too large much too late.

            Didn't know how to code back then, and probably can't rocket jump anymore now. Mostly just surprised at having that old memory surface out of nowhere.

            Thanks for making that scene cooler way back when.

  • calebwin 7 years ago

    Would you mind elaborating on the "compile time reference counting"? Is this new? How does it handle cycles?

    • Aardappel 7 years ago

      It is so new I haven't even documented it yet.. hence why I said the timing for this HN post isn't great.

      So imagine the current implementation does a lifetime analysis somewhat similar to Rust, but then where Rust would error out, this implementation simply inserts a runtime refc increase. This gets rid of most runtime refc overhead without the programmer needing to be clever about it.

      Then, I intend to add an optional type annotation that gets you the Rust behavior, for those cases where you want maximum control. I don't think its the right default though.

      The algorithm is more lenient than Rust, since I don't have any shared memory concurrency for example.

      I intend to write up more thorough details about the algorithm, but again, haven't gotten to it.

      It does not handle cycles. If you create cycles that you do not manually break, you'll get a cycle report at program exit that prints the kind of values that weren't reclaimed. You're then expected to fix your code accordingly :)

      • alexisread 7 years ago

        This at first glance actually looks similar to http://liu.diva-portal.org/smash/get/diva2:20899/FULLTEXT01....

        And this style of static analysis has been taken even further by Luc Blaeser: http://concurrency.ch/Content/publications/Blaeser_Component...

        The cycle checker I'll have to have a look at - I'd like to crib parts of it for an OS I'm trying to cobble together. Your project looks very interesting, thanks!

        • Aardappel 7 years ago

          Thanks for those, I hadn't seen them. The Ritzau paper indeed appears to be doing something very similar, where in 5.2 he describes "inner references" whose lifetime is bounded by the outer one, I call that "borrowing", where the outer definition (the owner) gets locked from mutation during the borrow.

          What I do is a bit more involved though, as for every language construct I indicate if it wants to own or borrow its children (and wether it wants the parent to own or borrow), to remove maximum refcounts, also for cases which are not simply variables. Again, I will describe this in detail.

          The second paper I don't see how it relates to what I am doing.

        • Aardappel 7 years ago
      • dbaupp 7 years ago

        That sounds more similar to Swift's approach, where the compiler does aggressive optimisation to elide reference counts were possible. Do you agree?

      • childintime 7 years ago

        > I don't think its the right default though.

        I think Rust should allow this kind of relaxed ownership, with ARC behind the scenes, as lots of user level code should not require fussing over ownership details. A "get shit done" mode.

        • 0815test 7 years ago

          Rust supports proc macros, you know-- you can do literally anything with your code. So what you describe is already possible! Make a good proof of concept and submit a proper RFC for it, and it might even be adopted as part of Stable Rust!

        • Aardappel 7 years ago

          Yes, that is exactly my intention, for the majority of code this compile time reference counting is good enough.

          You can of course use Rc types in Rust, but that is verbose, and throws all ownership out the window, unlike Lobster.

      • obastani 7 years ago

        Any chance you could you share some references on this kind of type inference? It sounds very interesting!

    • Aardappel 7 years ago

      More on the compile time reference counting here: http://aardappel.github.io/lobster/memory_management.html

    • steveklabnik 7 years ago

      A comparison to Swift's ARC would also be of interest :)

  • grok2 7 years ago

    Weird, just yesterday, there was a link from a different language that seemed very similar to yours or at least has similar goals: http://cone.jondgoodwin.com/

    • Aardappel 7 years ago

      Not sure if I'd call these similar, Cone looks more low level, with more explicit typing etc. Looks cool though.

  • anonymoushn 7 years ago

    Are the coroutines copyable? This is useful if you want to use time-travel netcode (like ggpo) and coroutines attached to game objects in the same game.

    • Aardappel 7 years ago

      I'm afraid they currently aren't, but there's no reason this couldn't be implemented. There's a "copy" function for reference types that currently errors on co-routines.

      • anonymoushn 7 years ago

        That sounds great :)

        I found it a bit strange that the coroutines run until the first yield at the time they are created, but otherwise I quite like the system.

  • Empact 7 years ago

    Do you plan to accommodate multi-line lambda? Python is hamstrung on this front thanks to the white-space oriented formatting.

    • dragonwriter 7 years ago

      > Python is hamstrung on this front thanks to the white-space oriented formatting.

      You could have multiline lambdas with Python's signficant whitespace, the then-BDFL just didn't think it was important enough to accept any of the syntax options proposed for it or to bother finding another option, believing named functions were sufficient for the multiline case.

    • Aardappel 7 years ago

      It already does multi-line lambdas (lambdas and built-in control structures share the same syntax), see e.g. the call to "fold" here: https://htmlpreview.github.io/?https://raw.githubusercontent...

    • nikofeyn 7 years ago

      f# has white-space oriented formatting.

      • iaabtpbtpnn 7 years ago

        OCaml doesn't care about white space, and I don't think SML does either, although F# does. Maybe you are thinking of Haskell?

        • nikofeyn 7 years ago

          i am sorry. you are right. i misremembered about sml (haven't written in it much and in a while) and incorrectly lumped in ocaml. i should have been more careful. f# was what was really on my mind.

  • cryptonector 7 years ago

      - Multi-threading that uses separate memory spaces, meaning individual threads can run at max speed with no GIL overhead etc.
    
    Hmm? Does that mean that they are actual processes sharing no memory? EDIT: If so then that's a big downside. In Rust you get thread-safety for traditional, shared-memory threading/concurrency. Ideally you should be able to get as good as Rust for threading. Ultimately, I think it all depends on this:

      - Compile time reference counting. This does an analysis similar to the Rust borrow checker to infer lifetimes, but unlike Rust doesn't make the programmer jump through hoops.
    
    I mean, that would be a huge win, but there must be a trade-off. Can you elaborate?
    • Aardappel 7 years ago

      This does not mean separate processes, it simply spawns one "VM" per thread. Lobster VMs are pretty light weight (just a self contained object that has everything for a program to run). The advantage is that everything inside one VM can be single threaded, down to memory allocator. The threads then communicate by sending each other lobster values, similar to a "tuple space". I personally think this explicit communication style of concurrency is safer and easier to use than shared memory concurrency.

      As for the lifetime analysis, see some sibling comments: I need to do a good write-up of the algorithm. I wasn't anticipating this HN post :)

      • cryptonector 7 years ago

        Ah, OK, sure. And I assume that Lobster compiles to bytecode then, that gets interpreted?

    • brianpgordon 7 years ago

      Even if it does mean separate OS processes (which I doubt), keep in mind that on Linux basic POSIX threads are basically just processes with some shared memory mapped in. There's no real performance difference.

  • S4M 7 years ago

    It looks nice! Do you have a gallery of games made with Lobster available somewhere?

  • brianpgordon 7 years ago

    There's a lot of great technical info on the homepage, but it's tough for me to see the forest for the trees here. Could you make a short (probably oversimplified; that's ok) case for what Lobster is especially good at and why it's worth using rather than other programming languages? Or direct me to where one is already written?

    • Bekwnn 7 years ago

      At a glance, one thing that makes it stand out is that it's minimal like a framework, but allows you to code in something with similarities to python, but with more design towards that task. Most python-esque languages are poorly suited for games in terms of performance/features.

      Seems to nail most of the desires of mobile/indie scale development.

    • Aardappel 7 years ago

      I was hoping the current homepage had that function, with a list of special features followed by some examples.

      You want it shorter? Something like "Get Python-like ease of use together with static typing and speed and built-in game programming functionality" ? That really doesn't do it justice. In the end, like most languages, it is a particular cocktail of trade-offs, and to see whether this suits you, you need see the full list of features.

      Maybe you want a list of features with an example for each? It's hard to make it short though, especially the type system.

      • bluetwo 7 years ago

        Not features. Benefits.

        Benefits show an increase in something good or a decrease in something bad.

        Better speed. Less code. Easier distribution. Lower cost.

        • Aardappel 7 years ago

          A lot of the benefits are hard to express in numbers, and I am not a marketing person.

          Does this particular kind of type system help you in your software engineering? Very hard to quantify, and depends on circumstances and even personal preference.

          I don't think I have any hard-number benefits that are meaningful.

  • fossterer 7 years ago

    Heyy @Aardappel Interesting project!

    I wanted to share your language with a game programmer I know but the links to documentation from your homepage look broken.

    Essentially https://htmlpreview.github.io/ is dysfunctional. Try accessing the sample links in that project's Github page.

  • nathanielc 7 years ago

    Looks really interesting. Have you done any write ups on the type inference bits?

    Flow sensitive type inference looks like exactly what I need.

  • trizic 7 years ago

    Do you have any plans to support building statically linked binaries like Go?

    • Aardappel 7 years ago

      Currently the only way to do that is via output to C++. This will give you static binaries, but it is of course a more complex build than Go's direct executable output. Not sure if I'll ever do native codegen myself (as in, direct x86 or ARM), currently working on WebAssembly support, and LLVM IR is also a possibility.

  • k__ 7 years ago

    Pretty cool.

    How does it compare to Dyon?

    https://github.com/PistonDevelopers/dyon

    • Aardappel 7 years ago

      Hadn't seen this, thanks! At first glance, it appears that the difference is that Dyon is dynamically typed and requires the programmer to get lifetimes right manually (though annotations, ordering, or clone), whereas Lobster is statically typed and does all lifetime analysis automatically (and falls back to a runtime reference count increase when analysis fails). You'll be able to force the Rust/Dyon behavior manually with a type annotation in the future.

  • abcd_f 7 years ago

    > all publicity is good publicity

    ... unless it's an obituary :)

    (an old joke)

  • akavel 7 years ago

    On first look, the language seems superficially similar to Nim. Which, per se, is certainly a plus in my book! ...but makes it somewhat difficult to understand when should I pick one or the other. Could you point out some important differentiators? (Apart from the current set of available libraries, which certainly make it appear more useful for the intended target audience at this very moment AFAIU, but in longer perspective are potentially somewhat secondary.)

    • Aardappel 7 years ago

      It does have some similarities, mostly in the sense that both are using a Python-esque syntax, but that doesn't mean they have similar semantics.

      Some difference off the top of my head:

      - Nim so far has been a GC-ed language (I know manual allocation is possible, and an ownership system is planned, but this was the default for most code so far). Lobster has been reference counted (and now compile time reference counted) from the start. Nims proposed ownership system is pretty cool, but still requires a fair bit of programmer cooperation, in that sense it will sit somewhere between Rust and Lobster in terms of programmer friendlyness.

      - Lobster has a type inference algorithm that is able to go further than most languages in terms of allowing code without types to "just work". Nim has nothing even remotely like this.

      - Nim is faster. Nim was designed for near native speeds from the start, Lobster started life a very high level language that slowly become more low level. There's nothing that prevents Lobster being as fast as Nim, it just will take a bit more time.

      - Nim is more mature, in the sense that it has been around longer, has more libraries and tooling etc, and a larger community.

      - Lobster has great support for programming with higher order functions: terse syntax, best possible type inference, zero overhead (compared to manual loops), non-local returns etc.

      So in summary I'd choose Lobster over Nim if you care about Lobsters type and memory management or higher order function features, or if you like the idea of a language that makes games/graphics out of the box easier. If you just want to "get the job done", Nim probably is ahead of Lobster at the moment :)

      • sullyj3 7 years ago

        Lightweight syntax and zero overhead for higher order functions sound fantastic. I'm very interested.

  • gpm 7 years ago

    Btw, you have a bunch of dead links to Google+ (readme, the linked page, etc).

  • nubb 7 years ago

    Is there a list somewhere of games written in Lobster?

  • fouc 7 years ago

    can you drop the need for the : at the end of the line if there's a newline? i.e. it seems like unnecessary syntax

    • Aardappel 7 years ago

      That would make it much harder to parse in certain cases, both for the compiler and the human, given that it uses this same syntax to parse not just control structures, but also higher order functions / lambdas.

  • sytelus 7 years ago

    I have never understood why people create entire programming language when just creating a nice C++ library would been more than sufficient, desirable, integratable and adaptable. You can always export bindings for any target language and users would be saved from learning yet another beast that would be unmaintained in few years. I'm not saying never developing new language... If you have radically new thought, go ahead do it but just keep combining feature1 from this language and feature2 from that language doesn't make a lot of sense (especially the part of taking completely unrelated unsearchable word to name your language).

    • dkersten 7 years ago

      C++ is a complex beast and while I quite like working in it, I'm finding that the latest versions (17 and 20) are filled with features that I'm having trouble understanding. The surface for errors is also huge. I've been programming in C++ since about 2002 and I feel quite proficient in it, but, if given the option, I'll use something that is both safer/less error prone and more productive (and I say that as someone whose argued right here that C++11 and beyond is a very productive language).

      Beyond that and what sibling comment said, the author is known for creating various languages, so he clearly enjoys doing it and is making this language for himself.

      I have never understood why there's always somebody complaining that new languages are unnecessary when a new language is shown on HN. I personally love seeing new languages. I also recently went on a language hunt for something that met a specific need for a side project I'm working on and I came away empty handed because I couldn't find something that met my criteria[1], so I'm always on the lookout for something that might.

      [1] In case somebody has any suggestions for me, I want something with Clojure-like immutable data structures as a default (or something similar, at least), is native compiled to reasonably efficient and low footprint binaries (but is not as complex as Rust or Haskell), is a functional language (but with prettier syntax than OCaml, which was almost my choice, but when I started reading example code, its a complex mess of symbols <insert perl joke>). And... it needs reasonable library support... (at a minimum I need to be able to respond to HTTP requests, make HTTP requests, parse and generate JSON and talk to postgres, ideally using SQL and not an ORM). Haskell is probably my best bet, but I don't have the energy to learn all of its complex features.

      • sytelus 7 years ago

        I'm not against creating new languages. In fact the Lobster language is something I would want (although current syntax is bit repulsive). Python with static types but without getting in the way is pure gold. The problem is that creating interpreter/compiler is one tiny little part of creating language. Much bigger task is creating vast number of libraries that every other popular languages have. Think about everything from numpy to scipy to graphics to networking to web frameworks to OS APIs... Another bigger part is creating tooling and interoperatibility - everything from debugger, refactoring, linting, IDEs, CI, docgen etc. Now put on the top of it all the reusable code that millions of people have already written spending billions of hours in existing languages.

        Without large teams working for years, its very hard for a new languages to break in to general use. There are ofcourse outliers and you can get lucky - but then you have to be terribly lucky. So the end result is that 99.9% of languages just die or become hobby project for a person regardless of their features, benefits, beauty or aesthetics. Again, nothing wrong with becoming personal hobby project but if my goal was to create game engines that becomes force in the industry, I would probably not start by creating entirely new language.

        I'm not experienced as much as the author, so this is my personal opinion and likely not very well informed. I writing this just because I see several people spending years in creating new languages while their goals have been something else. They dream about repeating success of Java while not realizing how rare it is. After they finish their labor of love, I wonder if they find it depressing to become just line item in the list of dead programming languages. What if they would have actually focused on their original goal instead with emphasis on adding new powerful features that integrates and plays well with existing stuff? It's sure not as sexy and respectable as being father (or mother) of new language but has much higher chance of generating desired impact.

        • Aardappel 7 years ago

          You are not wrong. But you are assuming every language author must be wanting to become the next mainstream language. I am already aware Lobster will unlikely be that, and I am fine with it. I am having a ton of fun developing it, and I have used it for many projects. I do not want to have more impact by working on something more boring :)

    • vidarh 7 years ago

      Because the language affects how you think about things, and how productive you are. It matters.

      And in this case, this is someone with a 20+ year background of experimenting with new languages, ranging from production-ready (e.g. I used AmigaE a lot back in the 90's) to crazily experimental ones.

    • brianpgordon 7 years ago

      C++ is a deeply, deeply flawed programming language carrying decades of baggage to stay backwards compatible. Let's not pretend that mere inertia is enough reason to keep using the same tools forever.

dfox 7 years ago

Major reason why many game engines used to have native core and then some kind of "scripting" language for game logic (think Unreal Engine before 3, but many engines are similar) is that then you can trivially serialize the simulation state (ie. save game) and even run the whole thing as either lock-step, forward predicted or fully distributed network game without much effort on the part of whoever is writing the "scripting language" part of the game code.

  • Aardappel 7 years ago

    Agreed, those are nice benefits. But there are also huge downsides, in the sense that you're writing all the glue code in the wrong language :) The amount of speed of iteration you get from having your entire engine + game's structure in a friendlier language is impressive (in my experience).

    Also doing savegames by just serializing the entire scripting VM may work in some cases, but can also be problematic, since you're mixing ephemeral data with gameplay state. Last U3 engine game I worked on had explicit savegame serialization :)

    • dfox 7 years ago

      My point is that having scripting VM that is explicitly designed for game logic allows you to serialize only the relevant state. And if the whole system is designed correctly you can also do checkpointing and streaming replication essentially of the game state for free. This buys you things like rendering thread that is decoupled from the simulation (just draw the snapshot of state that was current on the start of rendering iteration), non-synchronized joins of multiplayer players (send serialized checkpoint and do stream the changes until the client catches up) and so on.

      • Aardappel 7 years ago

        I agree, for that level of integration you want a "gameplay scripting system", whereas Lobster is more of a general purpose programming language that happens to be a nice starting point for simple games & engines. I don't think in its current form it is a great language for a large AAA team anyway, because of its heavy reliance on type inference and lack of separate compilation.

        The language could of course be adopted to these use cases, it simply hasn't, so far.

        Doing simulation on a separate thread from main/rendering is something it is already set up to do (multi-threading uses separate memory spaces so it is easy to ensure there's no data races between the two).

    • erikpukinskis 7 years ago

      Also, you can never update your data structures without ruining all of your safrgames.

baldfat 7 years ago

I use Haxe which is a

Haxe is an open source toolkit based on a modern, high level, strictly typed programming language, a cross-compiler, a complete cross-platform standard library and ways to access each platform's native capabilities.

what would be the benefit for using Lobster since I can work directly with each OS with a great scripting language built in?

https://haxe.org

  • Aardappel 7 years ago

    Haxe can translate to an impressive set of languages and platforms, so if that is your main need, I'd say, stay with Haxe.

    Haxe and Lobster are very different programming languages however, so you may prefer one over the other purely for the language design.

    If you like portability, Lobster already runs on 3 desktop OSes, 2 mobile ones, and the web, using either VM, C++ or soon WebAssembly modes. While not as extensive as Haxe it is pretty good :)

  • all2 7 years ago

    I'd like to know this as well.

aitchnyu 7 years ago

Did you create a VM that is several times faster than Python's, for a static typed language thats as productive as a dynamic language, with true multithreading? How did you outdo entire language communities?

  • Aardappel 7 years ago

    Python's default implementation is so incredibly slow, such that any programmer that implements a new language that doesn't just make "everything dynamic" will automatically end up with a language that is faster than Python without really trying.

    There are probably a 1000+ language implementations out there that are faster than Python, most of which are single person efforts.

    Lobster is a much more static language, and does inlining of functions, inlining of structs, specialization etc that allow it to remove a lot of runtime cost, such that even the VM is fast.

    It also has been in development for about 8 years now. I've been working on compilers in one way or another for almost 30 years.

  • tomp 7 years ago

    I'm a huge proponent of typed languages, but there's no way that a statically typed language could be as productive as Python (with current type systems technology). For example, just the Pandas library offers incredible flexibility (often dynamically based on the arguments that different functions get) that I've yet to see replicated in a static language.

    • brianpgordon 7 years ago

      My experience is that you start out very productive not being weighed down by having to satisfy the type checker... but programs tend to grow over time and you end up regretting it. When you have a medium to large codebase in a dynamically typed language it gets to be more of a hindrance than a help.

      • tomp 7 years ago

        I agree, but my point was rather that you can't typecheck Pandas (or a similarly complex library). Gradual typing for the win!

  • imtringued 7 years ago

    That's a very low bar. It's just that Python programmers don't care about any of this. The productivity is already enough for them.

c3534l 7 years ago

I don't really see the point in using Python syntax and then throwing in a handful of random differences that don't have anything to do with the domain you're working in. Syntax level support for vector operations or for shader interopability I would get. Making for loops follow some randomly different syntax, I don't see the point of that.

  • Aardappel 7 years ago

    It is not intended to be Python compatible, it merely has indentation based syntax that is similar.

    The cases where it differs from Python are actually for good reason: unlike Python that only has built-in control structures, here any function can look like if/for/while if it takes a lambda body.

    • andrelaszlo 7 years ago

      This seems like a cool way to make an ad hoc dsl. I'm not a game programmer but I imagine it could be useful.

      • stcredzero 7 years ago

        This seems like a cool way to make an ad hoc dsl. I'm not a game programmer but I imagine it could be useful

        Smalltalker here. Being able to pass in lambdas very casually is a great way of producing an ad hoc DSL. Imagine a custom control structure which does a database transaction. Just implement a function!

    • yellowapple 7 years ago

      > unlike Python that only has built-in control structures, here any function can look like if/for/while if it takes a lambda body

      That's absolutely fantastic. I've had to do a lot more Python programming for work, and I've been thoroughly disappointed by Python's lack of support for custom blocks/structures like that (contrast with Ruby or Elixir, where any function can take a do ... end, or with Tcl where "blocks" are just strings).

    • vanderZwan 7 years ago

      So is it a bit like Rebol (or Red, or even Joy if we pretend RPL is not a significant difference), or is it a very different style of implementation?

  • threatofrain 7 years ago

    I welcome languages that take the idea of indentation as part of the language. I don't see that as belonging to Python, and I don't believe this language aims to be Python-compatible as opposed to inspired.

  • kodablah 7 years ago

    > I don't really see the point in using Python syntax and then throwing in a handful of random differences that don't have anything to do with the domain you're working in

    I don't think it's using Python syntax, I think it and Python share some similarities. Thinking about it in Python terms is probably why the changes appear random/different/useless. But in general not being constrained by Python or another language has value.

  • NikkiA 7 years ago

    Also 'include'? Why would you add the single most awful part of C/C++ to a python-alike.

    • stcredzero 7 years ago

      It's not supposed to be a python-alike. It just happens to use indentation for blocks.

    • hacksoi 7 years ago

      #include causes the preprocessor to replace it with the specified file. Why is that bad?

      • sonnyblarney 7 years ago

        Because ostensibly we've moved on from that to the concept of actual modules.

        'including' stuff entails a whole host of ugly things including multiple definitions, circular dependencies etc. etc..

        Most languages use some kind of module resolution, which when specified clearly is usually better. Of course sometimes they forget to define things, and leave us in a lurch ... but hey ...

        • Aardappel 7 years ago

          You're reading too much into the keyword.. in Lobster, this does never include anything twice. Circular dependencies just work, without having to pre-declare anything. I should probably rename it.

          • sonnyblarney 7 years ago

            I suggest people might pick up on that pretty quick, maybe no need to rename given some random comment. That said, maybe you want to have a gander through the various languages and see what words are used for what, and if there's a 'standard' go with that :)

            Cool language though. I love everything except for the name, sorry :)

            • Aardappel 7 years ago

              Well, every time Lobster surfaces somewhere, I am always surprised how quickly people can superficially reject it because of some syntax issue, so yes, I agree, using predictable keywords where it makes no real difference matters. I've already made quite a few such changes.

              The name.. I think people will quickly forget about the original meaning. Think of all the languages you know, and how you associate the name with the language, not some snake, a musical note, degraded iron, a french philosopher, etc. Some of these names are actually pretty silly.

              • NikkiA 7 years ago

                The fact that you keep encountering it suggests that it's probably something in human nature to associate words, that ultimately don't matter, with how we've encountered them in languages in the past.

                As for associating the name of the language, the only one I can't get past on that is 'Pony', it just has too much MLP fandom association for me to take it seriously.

              • imtringued 7 years ago

                Because they got third degree burns by the harmless word. Adolf used to be one of the most common German names, obviously now it isn't. [0]

                [0] https://www.beliebte-vornamen.de/wp-content/uploads/adolf-1....

              • newen 7 years ago

                Maybe it's not as superficial, but I tend to ignore all new languages that has significant whitespace. It takes a bit of effort to learn a new language, there are lots of other languages, and I might as well learn a new language that has things I like in it.

              • vanderZwan 7 years ago

                > a french philosopher

                If Sartre isn't already an esolang built around the concept that hell is other programmers, then someone should make it.

              • hyperpallium 7 years ago

                Agree on names, but to be fair, an absurdist comedy troupe is meant to be silly. Speech defect, coffee, an ordinal number. I still feel rust is a bad name.

              • sonnyblarney 7 years ago

                Of course you're right. But 'Oort' or 'Ort' would be a good names as well.

              • eggy 7 years ago

                I thought Lobster was a play on Rust's crab?

throwaway190102 7 years ago

This reminds me of processing. https://processing.org/

jkcxn 7 years ago

This looks really fun: https://github.com/aardappel/lobster/blob/master/lobster/sam...

Are the generators implemented entirely in user space using continuation passing style? And the coroutine function turns it into something pausable?

Edit: I can't wrap my head around how return returns out of all the generators

  • Aardappel 7 years ago

    So the non-coroutine case of that code are all regular functions, without using CPS or anything. The only special feature Lobster has is that when you write "return" it will return out of the lexically enclosing named function, not the function whose body it sits in (which can be an anonymous function). This mean return is implemented by unwinding stack frames until it gets to the named function, almost like a lightweight version of exception handling. It also can't resume these functions, like you typically can in languages that support CPS.

    Now the co-routine functionality takes an existing higher order function, and compiles it such that the call to the function argument instead does a yield. These are really regular co-routines that are implemented by copying stack frames off and onto the stack upon yield and resume. I just thought being able to share code between HOFs and co-routines was cute, since they often express the same patterns. Why would you write an iteration twice?

eggy 7 years ago

I am an old Amiga user Vic-20, A1000, A500, etc., so I am a fan of the author.

I tried running the sierpinski example with a pre-compiled Windows .exe that I placed in the lobster root directory, and it gives me this error: "can't open file: stdtype.lobster".

I placed lobster and lobster/modules in my path, and it still throws the same error. I am assuming I need to build the .exe myself due to some incompatibility with the master branch and this older .exe?

I like a self-contained game PL. I use Raylib for that type of experience right now, but I like the concepts here. Thanks!

EDIT: copied modules to root of lobster, and now I get:

"stdtype.lobster(8): error: end of file expected, found: <"

I tried an included test file and a copy/paste of the sierpinski example, and both throw this error.

  • Aardappel 7 years ago

    Sorry, I need to do better at "getting started" documentation. The exe needs to be placed in the "lobster" dir under the root. It searches for "includes" relative to itself.

    Not sure about the error involving "<".. are the executable and the data from the same version of Lobster? Open an issue on github or email me for more help :)

    • eggy 7 years ago

      I'll build it as the site suggests, since I am using a binary from the release with the master branch modules. I'll follow up on github. Thanks!

hyperpallium 7 years ago

Is the first example's last line:

  var i = find [ 1, 2, 3 ]: _ > r
the same as?:

  var i = find ([ 1, 2, 3 ]) a: a > r
i.e. argument parantheses are optional for one argument; and _ is an implicit argument for a block.

Would multiple functions arguments be done just with parentheses, like this?:

  var i = find [ 1, 2, 3 ] (: _ > r), (: _ < r)
Seems like the syntactic generality of lisp or haskell, with the predictability of performance of C. EDIT I see it's as fast as non-JIT Lua... are there any features that prevent it from theoretically approaching the speed of C?

PS: small detail, but that's got to be the best for-loop I've ever seen.

  • Aardappel 7 years ago

    Yes, those are equivalent.

    Multiple function arguments require a keyword in the caller, much like "else" introduces the second function argument in an if-then-else. So if "find" would take two functions, one for even and one for odd list elements, it would look like: "var i = find_even_odd [ 1, 2, 3 ]: _ > r odd: _ > r"

    There are no features that prevent it from "approaching" C's speed, merely a question of implementation work. The language started out as very high level, so code generation needs to be improved to not do as many things at runtime as it currently does. The language semantics are totally able to be within 1.5x of C.

    • hyperpallium 7 years ago

      Fantastic, thanks.

      The many uses of : syntax are intriguing - lambdas, functions, control, python-style structure, data, globals. I reckon you've established it works in all cases, but I'm not yet familiar enough to see that for myself.

      For initial adoption, I wonder if more regular sample code, without the special-case abbreviations, might be more effective? (Followed by the short version.) OTOH, maybe at this early stage it's best to select for developers interested/capable enough to handle it!

      EDIT if : is used for both blocks and code structure, could everything be one-line (or is \n significant?) Not great style, but helps in understanding the syntax. Maybe returns and vars need their own lines?

        def find(xs, fun): for(xs) x, i: if fun(x): return i return -1
      
        var r = 2 var i = find [ 1, 2, 3 ]: _ > r
      • Aardappel 7 years ago

        Yes, ":" appears a bit overloaded, though many of those cases are actually one and the same.

        What would be more regular sample code? Do you mean just writing "find([ 1, 2, 3 ]) x: x > r" with explicit () and explicit variables? I agree that is easier to read, though the extreme terseness is also a feature..

        Yes, everything can be one line, but in this case it would look a bit ugly:

        def find(xs, fun): (for(xs) x, i: if fun(x): return i); return -1

        • hyperpallium 7 years ago

          > Do you mean just writing "find([ 1, 2, 3 ]) x: x > r" with explicit () and explicit variables? I agree that is easier to read, though the extreme terseness is also a feature..

          Yes, amd yes it depends on the purpose. For learning, it can be impossible to parse; redundancy helps distinguish parts and provides a check you got it right.

          OTOH for showcasing features, IMHO, the generality of : is a more impressive feature to demo.

          Anyway, it's certainly intriguing! And maybe that's the true purpose of showcase code...

Gravityloss 7 years ago

Very personal opinion and matter of taste: Many lambda syntaxes are a bit weird.

    map(my_array)element:element*2 //lobster
    my_array.map{|element|element*2} //ruby
    Arrays.stream(my_array).map(element -> element*2).collect(something list something)  //java?
Lobster feels a bit unbalanced. Ruby has "pipes" which are a bit confusing substitute parentheses. Java has the cool arrow syntax but otherwise it feels very glued on. (edited and fixed, thanks for the comment)
  • Aardappel 7 years ago

    Your Lobster version has a stray comma, it is: map(my_array) element: element * 2

    Note how if you write this example with multiple statements instead of "elements * 2", suddenly the Lobster syntax looks a lot more consistent, and the Ruby example doesn't look that great as it looks completely different from the built-in for loop.

    • yxhuvud 7 years ago

      No-one uses the built-in for loop in Ruby though. Instead, everyone uses the each method which looks the same as map.

      That said, the Ruby syntax can be a bit bulky. Your syntax feels pretty clean TBH.

estomagordo 7 years ago

Really stupid question here, but how do I start compiling Lobster programs on my machine (Windows or Linux)?

sansnomme 7 years ago

This reminds me of the language used in Godot Engine, maybe talk to them and use this in the engine?

z3phyr 7 years ago

I enjoyed playing Cube based games, editing maps live and whatnot. Will check this out too!

tjpnz 7 years ago

I really like the inclusion of basic graphics routines. Not a lot of languages include these out of the box and it's something I've really missed since I first started toying with programming in QBasic.

  • brianpgordon 7 years ago

    It's kind of surprising to me that the language is directly tied into OpenGL given that it's a cutting-edge experimental new language and that seems more the domain of Vulkan.

    • Aardappel 7 years ago

      It's not tied to, it is implemented in it. I could swap out the rendering code for Vulkan, an no Lobster users would need to change anything.

      Also, have you actually programmed in Vulkan? Even a simple primitive can be hundreds of lines of setup code. In Lobster they're often a single line. A direct mapping would not make sense.

qarw 7 years ago

000000128039 000000128034 000000128039 000000128034 000000128034 000000128034 000000128039 000000128008 000000128039 000000128008 000000128013 000000128039 000000128013 000000128034 000000128039 000000128034

jbb67 7 years ago

Oh this looks rather nice. I'll have to take a look at this.

sscarduzio 7 years ago

Why choosing 'value' as a keyword for types? Super odd

  • Aardappel 7 years ago

    I've actually since changed that to be more conventional. Now the "inline" by-value objects are called "structs" and the regular by reference objects are called "classes" much like C#

mshockwave 7 years ago

> Discuss things in the google+ community

google+?

stesch 7 years ago

Yeah, cool Google+ community.

Eire_Banshee 7 years ago

Portable python for games...? Does it compile and run natively?

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection